Merge "Camera: Add one more requirement to BURST_CAPTURE" into lmp-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index 46a0943..c751ef3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1056,6 +1056,7 @@
     field public static final int scrollbars = 16842974; // 0x10100de
     field public static final int scrollingCache = 16843006; // 0x10100fe
     field public static final deprecated int searchButtonText = 16843269; // 0x1010205
+    field public static final int searchHintIcon = 16844038; // 0x1010506
     field public static final int searchIcon = 16843907; // 0x1010483
     field public static final int searchMode = 16843221; // 0x10101d5
     field public static final int searchSettingsDescription = 16843402; // 0x101028a
@@ -3111,6 +3112,7 @@
     method public void removeAllUpdateListeners();
     method public void removeUpdateListener(android.animation.ValueAnimator.AnimatorUpdateListener);
     method public void reverse();
+    method public void setCurrentFraction(float);
     method public void setCurrentPlayTime(long);
     method public android.animation.ValueAnimator setDuration(long);
     method public void setEvaluator(android.animation.TypeEvaluator);
@@ -4412,7 +4414,7 @@
     method public android.content.Intent createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence);
     method public deprecated void exitKeyguardSecurely(android.app.KeyguardManager.OnKeyguardExitResult);
     method public boolean inKeyguardRestrictedInputMode();
-    method public boolean isKeyguardInTrustedState();
+    method public boolean isDeviceLocked();
     method public boolean isKeyguardLocked();
     method public boolean isKeyguardSecure();
     method public deprecated android.app.KeyguardManager.KeyguardLock newKeyguardLock(java.lang.String);
@@ -5402,8 +5404,8 @@
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME";
-    field public static final java.lang.String EXTRA_PROVISIONING_DONT_DISABLE_SYSTEM_APPS = "android.app.extra.PROVISIONING_DONT_DISABLE_SYSTEM_APPS";
     field public static final java.lang.String EXTRA_PROVISIONING_EMAIL_ADDRESS = "android.app.extra.PROVISIONING_EMAIL_ADDRESS";
+    field public static final java.lang.String EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED = "android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED";
     field public static final java.lang.String EXTRA_PROVISIONING_LOCALE = "android.app.extra.PROVISIONING_LOCALE";
     field public static final java.lang.String EXTRA_PROVISIONING_LOCAL_TIME = "android.app.extra.PROVISIONING_LOCAL_TIME";
     field public static final java.lang.String EXTRA_PROVISIONING_TIME_ZONE = "android.app.extra.PROVISIONING_TIME_ZONE";
@@ -28512,8 +28514,8 @@
     method public android.os.Bundle getCarrierConfigValues();
     method public static android.telephony.SmsManager getDefault();
     method public static int getDefaultSmsSubscriptionId();
-    method public static android.telephony.SmsManager getSmsManagerForSubscriber(int);
-    method public int getSubId();
+    method public static android.telephony.SmsManager getSmsManagerForSubscriptionId(int);
+    method public int getSubscriptionId();
     method public void injectSmsPdu(byte[], java.lang.String, android.app.PendingIntent);
     method public void sendDataMessage(java.lang.String, java.lang.String, short, byte[], android.app.PendingIntent, android.app.PendingIntent);
     method public void sendMultimediaMessage(android.content.Context, android.net.Uri, java.lang.String, android.os.Bundle, android.app.PendingIntent);
@@ -28545,6 +28547,7 @@
     field public static final java.lang.String MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED = "enabledNotifyWapMMSC";
     field public static final java.lang.String MMS_CONFIG_RECIPIENT_LIMIT = "recipientLimit";
     field public static final java.lang.String MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES = "sendMultipartSmsAsSeparateMessages";
+    field public static final java.lang.String MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS = "config_cellBroadcastAppLinks";
     field public static final java.lang.String MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED = "enableSMSDeliveryReports";
     field public static final java.lang.String MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD = "smsToMmsTextLengthThreshold";
     field public static final java.lang.String MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD = "smsToMmsTextThreshold";
@@ -28560,7 +28563,6 @@
     field public static final int MMS_ERROR_RETRY = 6; // 0x6
     field public static final int MMS_ERROR_UNABLE_CONNECT_MMS = 3; // 0x3
     field public static final int MMS_ERROR_UNSPECIFIED = 1; // 0x1
-    field public static final java.lang.String MMS_SHOW_CELL_BROADCAST_APP_LINKS = "config_cellBroadcastAppLinks";
     field public static final int RESULT_ERROR_GENERIC_FAILURE = 1; // 0x1
     field public static final int RESULT_ERROR_NO_SERVICE = 4; // 0x4
     field public static final int RESULT_ERROR_NULL_PDU = 3; // 0x3
@@ -28689,7 +28691,7 @@
     method public java.lang.String getSubscriberId();
     method public java.lang.String getVoiceMailAlphaTag();
     method public java.lang.String getVoiceMailNumber();
-    method public int hasCarrierPrivileges();
+    method public boolean hasCarrierPrivileges();
     method public boolean hasIccCard();
     method public boolean iccCloseLogicalChannel(int);
     method public byte[] iccExchangeSimIO(int, int, int, int, int, java.lang.String);
@@ -28703,15 +28705,12 @@
     method public boolean setGlobalPreferredNetworkType();
     method public void setLine1NumberForDisplay(java.lang.String, java.lang.String);
     method public boolean setOperatorBrandOverride(java.lang.String);
+    method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
     field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
     field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
     field public static final int CALL_STATE_IDLE = 0; // 0x0
     field public static final int CALL_STATE_OFFHOOK = 2; // 0x2
     field public static final int CALL_STATE_RINGING = 1; // 0x1
-    field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe
-    field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
-    field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
-    field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff
     field public static final int DATA_ACTIVITY_DORMANT = 4; // 0x4
     field public static final int DATA_ACTIVITY_IN = 1; // 0x1
     field public static final int DATA_ACTIVITY_INOUT = 3; // 0x3
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index 948c9a2..bd34a9c 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -501,7 +501,7 @@
 
         @Override
         public void onExecute(IContentProvider provider) throws Exception {
-            final ParcelFileDescriptor fd = provider.openFile(null, mUri, "r", null);
+            final ParcelFileDescriptor fd = provider.openFile(null, mUri, "r", null, null);
             copy(new FileInputStream(fd.getFileDescriptor()), System.out);
         }
 
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index a9eaf29..3f1845a 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -16,6 +16,7 @@
 
 package android.accessibilityservice;
 
+import android.annotation.NonNull;
 import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
@@ -27,6 +28,7 @@
 import android.view.KeyEvent;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
+import android.view.WindowManagerImpl;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -618,6 +620,23 @@
         }
     }
 
+    @Override
+    public Object getSystemService(@ServiceName @NonNull String name) {
+        if (getBaseContext() == null) {
+            throw new IllegalStateException(
+                    "System services not available to Activities before onCreate()");
+        }
+
+        // Guarantee that we always return the same window manager instance.
+        if (WINDOW_SERVICE.equals(name)) {
+            if (mWindowManager == null) {
+                mWindowManager = (WindowManager) getBaseContext().getSystemService(name);
+            }
+            return mWindowManager;
+        }
+        return super.getSystemService(name);
+    }
+
     /**
      * Implement to return the implementation of the internal accessibility
      * service interface.
@@ -645,8 +664,10 @@
                 mConnectionId = connectionId;
                 mWindowToken = windowToken;
 
-                // Let the window manager know about our shiny new token.
-                WindowManagerGlobal.getInstance().setDefaultToken(mWindowToken);
+                // The client may have already obtained the window manager, so
+                // update the default token on whatever manager we gave them.
+                final WindowManagerImpl wm = (WindowManagerImpl) getSystemService(WINDOW_SERVICE);
+                wm.setDefaultToken(windowToken);
             }
 
             @Override
diff --git a/core/java/android/animation/TimeAnimator.java b/core/java/android/animation/TimeAnimator.java
index f9aa00e..1738ade 100644
--- a/core/java/android/animation/TimeAnimator.java
+++ b/core/java/android/animation/TimeAnimator.java
@@ -1,5 +1,23 @@
+/*
+ * 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 android.view.animation.AnimationUtils;
+
 /**
  * This class provides a simple callback mechanism to listeners that is synchronized with all
  * other animators in the system. There is no duration, interpolation, or object value-setting
@@ -29,6 +47,13 @@
         return false;
     }
 
+    @Override
+    public void setCurrentPlayTime(long playTime) {
+        long currentTime = AnimationUtils.currentAnimationTimeMillis();
+        mStartTime = Math.max(mStartTime, currentTime - playTime);
+        animationFrame(currentTime);
+    }
+
     /**
      * Sets a listener that is sent update events throughout the life of
      * an animation.
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 07f79b8..d65b490 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -79,7 +79,7 @@
      * Set when setCurrentPlayTime() is called. If negative, animation is not currently seeked
      * to a value.
      */
-    long mSeekTime = -1;
+    float mSeekFraction = -1;
 
     /**
      * Set on the next frame after pause() is called, used to calculate a new startTime
@@ -537,14 +537,31 @@
      * @param playTime The time, in milliseconds, to which the animation is advanced or rewound.
      */
     public void setCurrentPlayTime(long playTime) {
+        float fraction = mUnscaledDuration > 0 ? (float) playTime / mUnscaledDuration :
+                playTime == 0 ? 0 : 1;
+        setCurrentFraction(fraction);
+    }
+
+    /**
+     * Sets the position of the animation to the specified fraction. This fraction should
+     * be between 0 and the total fraction of the animation, including any repetition. That is,
+     * a fraction of 0 will position the animation at the beginning, a value of 1 at the end,
+     * and a value of 2 at the beginning of a reversing animator that repeats once. If
+     * the animation has not yet been started, then it will not advance forward after it is
+     * set to this fraction; it will simply set the fraction to this value and perform any
+     * appropriate actions based on that fraction. If the animation is already running, then
+     * setCurrentFraction() will set the current fraction to this value and continue
+     * playing from that point.
+     *
+     * @param fraction The fraction to which the animation is advanced or rewound.
+     */
+    public void setCurrentFraction(float fraction) {
         initAnimation();
-        long currentTime = AnimationUtils.currentAnimationTimeMillis();
         if (mPlayingState != RUNNING) {
-            mSeekTime = playTime;
+            mSeekFraction = fraction;
             mPlayingState = SEEKED;
         }
-        mStartTime = currentTime - playTime;
-        doAnimationFrame(currentTime);
+        animateValue(fraction);
     }
 
     /**
@@ -948,6 +965,7 @@
         }
         mPlayingBackwards = playBackwards;
         mCurrentIteration = 0;
+        int prevPlayingState = mPlayingState;
         mPlayingState = STOPPED;
         mStarted = true;
         mStartedDelay = false;
@@ -957,7 +975,9 @@
         animationHandler.mPendingAnimations.add(this);
         if (mStartDelay == 0) {
             // This sets the initial value of the animation, prior to actually starting it running
-            setCurrentPlayTime(0);
+            if (prevPlayingState != SEEKED) {
+                setCurrentPlayTime(0);
+            }
             mPlayingState = STOPPED;
             mRunning = true;
             notifyStartListeners();
@@ -1221,12 +1241,12 @@
     final boolean doAnimationFrame(long frameTime) {
         if (mPlayingState == STOPPED) {
             mPlayingState = RUNNING;
-            if (mSeekTime < 0) {
+            if (mSeekFraction < 0) {
                 mStartTime = frameTime;
             } else {
-                mStartTime = frameTime - mSeekTime;
-                // Now that we're playing, reset the seek time
-                mSeekTime = -1;
+                long seekTime = (long) (mDuration * mSeekFraction);
+                mStartTime = frameTime - seekTime;
+                mSeekFraction = -1;
             }
         }
         if (mPaused) {
@@ -1292,7 +1312,7 @@
         if (mUpdateListeners != null) {
             anim.mUpdateListeners = new ArrayList<AnimatorUpdateListener>(mUpdateListeners);
         }
-        anim.mSeekTime = -1;
+        anim.mSeekFraction = -1;
         anim.mPlayingBackwards = false;
         anim.mCurrentIteration = 0;
         anim.mInitialized = false;
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index c3028b7..6ec48e5 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1186,6 +1186,18 @@
             return true;
         }
 
+        case CHECK_PERMISSION_WITH_TOKEN_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            String perm = data.readString();
+            int pid = data.readInt();
+            int uid = data.readInt();
+            IBinder token = data.readStrongBinder();
+            int res = checkPermissionWithToken(perm, pid, uid, token);
+            reply.writeNoException();
+            reply.writeInt(res);
+            return true;
+        }
+
         case CHECK_URI_PERMISSION_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             Uri uri = Uri.CREATOR.createFromParcel(data);
@@ -1193,7 +1205,8 @@
             int uid = data.readInt();
             int mode = data.readInt();
             int userId = data.readInt();
-            int res = checkUriPermission(uri, pid, uid, mode, userId);
+            IBinder callerToken = data.readStrongBinder();
+            int res = checkUriPermission(uri, pid, uid, mode, userId, callerToken);
             reply.writeNoException();
             reply.writeInt(res);
             return true;
@@ -3742,7 +3755,7 @@
         mRemote.transact(GET_INTENT_SENDER_TRANSACTION, data, reply, 0);
         reply.readException();
         IIntentSender res = IIntentSender.Stub.asInterface(
-            reply.readStrongBinder());
+                reply.readStrongBinder());
         data.recycle();
         reply.recycle();
         return res;
@@ -3851,6 +3864,22 @@
         reply.recycle();
         return res;
     }
+    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeString(permission);
+        data.writeInt(pid);
+        data.writeInt(uid);
+        data.writeStrongBinder(callerToken);
+        mRemote.transact(CHECK_PERMISSION_WITH_TOKEN_TRANSACTION, data, reply, 0);
+        reply.readException();
+        int res = reply.readInt();
+        data.recycle();
+        reply.recycle();
+        return res;
+    }
     public boolean clearApplicationUserData(final String packageName,
             final IPackageDataObserver observer, final int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
@@ -3866,8 +3895,8 @@
         reply.recycle();
         return res;
     }
-    public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId)
-            throws RemoteException {
+    public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId,
+            IBinder callerToken) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
@@ -3876,6 +3905,7 @@
         data.writeInt(uid);
         data.writeInt(mode);
         data.writeInt(userId);
+        data.writeStrongBinder(callerToken);
         mRemote.transact(CHECK_URI_PERMISSION_TRANSACTION, data, reply, 0);
         reply.readException();
         int res = reply.readInt();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index e3de44e..98a096c 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -84,6 +84,8 @@
 import android.util.SuperNotCalledException;
 import android.view.Display;
 import android.view.HardwareRenderer;
+import android.view.IWindowManager;
+import android.view.IWindowSessionCallback;
 import android.view.View;
 import android.view.ViewDebug;
 import android.view.ViewManager;
@@ -2366,6 +2368,9 @@
         if (localLOGV) Slog.v(
             TAG, "Handling launch of " + r);
 
+        // Initialize before creating the activity
+        WindowManagerGlobal.initialize();
+
         Activity a = performLaunchActivity(r, customIntent);
 
         if (a != null) {
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 7fafc38..1de9b47 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1863,6 +1863,21 @@
         }
     }
 
+    /** @hide */
+    @Override
+    public int checkPermission(String permission, int pid, int uid, IBinder callerToken) {
+        if (permission == null) {
+            throw new IllegalArgumentException("permission is null");
+        }
+
+        try {
+            return ActivityManagerNative.getDefault().checkPermissionWithToken(
+                    permission, pid, uid, callerToken);
+        } catch (RemoteException e) {
+            return PackageManager.PERMISSION_DENIED;
+        }
+    }
+
     @Override
     public int checkCallingPermission(String permission) {
         if (permission == null) {
@@ -1951,7 +1966,19 @@
         try {
             return ActivityManagerNative.getDefault().checkUriPermission(
                     ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags,
-                    resolveUserId(uri));
+                    resolveUserId(uri), null);
+        } catch (RemoteException e) {
+            return PackageManager.PERMISSION_DENIED;
+        }
+    }
+
+    /** @hide */
+    @Override
+    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) {
+        try {
+            return ActivityManagerNative.getDefault().checkUriPermission(
+                    ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags,
+                    resolveUserId(uri), callerToken);
         } catch (RemoteException e) {
             return PackageManager.PERMISSION_DENIED;
         }
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 6433f3f..5362303 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -219,9 +219,11 @@
 
     public int checkPermission(String permission, int pid, int uid)
             throws RemoteException;
-
-    public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId)
+    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken)
             throws RemoteException;
+
+    public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId,
+            IBinder callerToken) throws RemoteException;
     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
             int mode, int userId) throws RemoteException;
     public void revokeUriPermission(IApplicationThread caller, Uri uri, int mode, int userId)
@@ -785,4 +787,5 @@
     int GET_TASK_DESCRIPTION_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+238;
     int LAUNCH_ASSIST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+239;
     int START_IN_PLACE_ANIMATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+240;
+    int CHECK_PERMISSION_WITH_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+241;
 }
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 5038df9..ddd21e6 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -225,28 +225,28 @@
     }
 
     /**
-     * Return whether unlocking the device is currently not requiring a password
-     * because of a trust agent.
+     * Returns whether the device is currently locked and requires a PIN, pattern or
+     * password to unlock.
      *
-     * @return true if the keyguard can currently be unlocked without entering credentials
-     *         because the device is in a trusted environment.
+     * @return true if unlocking the device currently requires a PIN, pattern or
+     * password.
      */
-    public boolean isKeyguardInTrustedState() {
-        return isKeyguardInTrustedState(UserHandle.getCallingUserId());
+    public boolean isDeviceLocked() {
+        return isDeviceLocked(UserHandle.getCallingUserId());
     }
 
     /**
-     * Return whether unlocking the device is currently not requiring a password
-     * because of a trust agent.
+     * Returns whether the device is currently locked and requires a PIN, pattern or
+     * password to unlock.
      *
-     * @param userId the user for which the trusted state should be reported.
-     * @return true if the keyguard can currently be unlocked without entering credentials
-     *         because the device is in a trusted environment.
+     * @param userId the user for which the locked state should be reported.
+     * @return true if unlocking the device currently requires a PIN, pattern or
+     * password.
      * @hide
      */
-    public boolean isKeyguardInTrustedState(int userId) {
+    public boolean isDeviceLocked(int userId) {
         try {
-            return mTrustManager.isTrusted(userId);
+            return mTrustManager.isDeviceLocked(userId);
         } catch (RemoteException e) {
             return false;
         }
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index aa98e97..ece2a33 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -632,55 +632,60 @@
     public void removeContextRegistrations(Context context,
             String who, String what) {
         final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled();
-        ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap =
-                mReceivers.remove(context);
-        if (rmap != null) {
-            for (int i=0; i<rmap.size(); i++) {
-                LoadedApk.ReceiverDispatcher rd = rmap.valueAt(i);
-                IntentReceiverLeaked leak = new IntentReceiverLeaked(
-                        what + " " + who + " has leaked IntentReceiver "
-                        + rd.getIntentReceiver() + " that was " +
-                        "originally registered here. Are you missing a " +
-                        "call to unregisterReceiver()?");
-                leak.setStackTrace(rd.getLocation().getStackTrace());
-                Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
-                if (reportRegistrationLeaks) {
-                    StrictMode.onIntentReceiverLeaked(leak);
-                }
-                try {
-                    ActivityManagerNative.getDefault().unregisterReceiver(
-                            rd.getIIntentReceiver());
-                } catch (RemoteException e) {
-                    // system crashed, nothing we can do
+        synchronized (mReceivers) {
+            ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap =
+                    mReceivers.remove(context);
+            if (rmap != null) {
+                for (int i = 0; i < rmap.size(); i++) {
+                    LoadedApk.ReceiverDispatcher rd = rmap.valueAt(i);
+                    IntentReceiverLeaked leak = new IntentReceiverLeaked(
+                            what + " " + who + " has leaked IntentReceiver "
+                            + rd.getIntentReceiver() + " that was " +
+                            "originally registered here. Are you missing a " +
+                            "call to unregisterReceiver()?");
+                    leak.setStackTrace(rd.getLocation().getStackTrace());
+                    Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
+                    if (reportRegistrationLeaks) {
+                        StrictMode.onIntentReceiverLeaked(leak);
+                    }
+                    try {
+                        ActivityManagerNative.getDefault().unregisterReceiver(
+                                rd.getIIntentReceiver());
+                    } catch (RemoteException e) {
+                        // system crashed, nothing we can do
+                    }
                 }
             }
+            mUnregisteredReceivers.remove(context);
         }
-        mUnregisteredReceivers.remove(context);
-        //Slog.i(TAG, "Receiver registrations: " + mReceivers);
-        ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap =
-            mServices.remove(context);
-        if (smap != null) {
-            for (int i=0; i<smap.size(); i++) {
-                LoadedApk.ServiceDispatcher sd = smap.valueAt(i);
-                ServiceConnectionLeaked leak = new ServiceConnectionLeaked(
-                        what + " " + who + " has leaked ServiceConnection "
-                        + sd.getServiceConnection() + " that was originally bound here");
-                leak.setStackTrace(sd.getLocation().getStackTrace());
-                Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
-                if (reportRegistrationLeaks) {
-                    StrictMode.onServiceConnectionLeaked(leak);
+
+        synchronized (mServices) {
+            //Slog.i(TAG, "Receiver registrations: " + mReceivers);
+            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap =
+                    mServices.remove(context);
+            if (smap != null) {
+                for (int i = 0; i < smap.size(); i++) {
+                    LoadedApk.ServiceDispatcher sd = smap.valueAt(i);
+                    ServiceConnectionLeaked leak = new ServiceConnectionLeaked(
+                            what + " " + who + " has leaked ServiceConnection "
+                            + sd.getServiceConnection() + " that was originally bound here");
+                    leak.setStackTrace(sd.getLocation().getStackTrace());
+                    Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
+                    if (reportRegistrationLeaks) {
+                        StrictMode.onServiceConnectionLeaked(leak);
+                    }
+                    try {
+                        ActivityManagerNative.getDefault().unbindService(
+                                sd.getIServiceConnection());
+                    } catch (RemoteException e) {
+                        // system crashed, nothing we can do
+                    }
+                    sd.doForget();
                 }
-                try {
-                    ActivityManagerNative.getDefault().unbindService(
-                            sd.getIServiceConnection());
-                } catch (RemoteException e) {
-                    // system crashed, nothing we can do
-                }
-                sd.doForget();
             }
+            mUnboundServices.remove(context);
+            //Slog.i(TAG, "Service registrations: " + mServices);
         }
-        mUnboundServices.remove(context);
-        //Slog.i(TAG, "Service registrations: " + mServices);
     }
 
     public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index dfe5cf5..07e8dc5 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -4986,7 +4986,9 @@
         }
 
         /**
-         * Set a hint that this notification's background should not be clipped if possible.
+         * Set a hint that this notification's background should not be clipped if possible,
+         * and should instead be resized to fully display on the screen, retaining the aspect
+         * ratio of the image. This can be useful for images like barcodes or qr codes.
          * @param hintAvoidBackgroundClipping {@code true} to avoid clipping if possible.
          * @return this object for method chaining
          */
@@ -4997,7 +4999,9 @@
         }
 
         /**
-         * Get a hint that this notification's background should not be clipped if possible.
+         * Get a hint that this notification's background should not be clipped if possible,
+         * and should instead be resized to fully display on the screen, retaining the aspect
+         * ratio of the image. This can be useful for images like barcodes or qr codes.
          * @return {@code true} if it's ok if the background is clipped on the screen, false
          * otherwise. The default value is {@code false} if this was never set.
          */
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ad1cf44..57d53aa 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -182,8 +182,8 @@
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
      * provisioning via an NFC bump.
      */
-    public static final String EXTRA_PROVISIONING_DONT_DISABLE_SYSTEM_APPS =
-            "android.app.extra.PROVISIONING_DONT_DISABLE_SYSTEM_APPS";
+    public static final String EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED =
+            "android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED";
 
     /**
      * A String extra holding the time zone {@link android.app.AlarmManager} that the device
@@ -3421,12 +3421,13 @@
     }
 
     /**
-     * Called by profile or device owners to check whether a user has been blocked from
-     * uninstalling a package.
+     * Check whether the current user has been blocked by device policy from uninstalling a package.
+     * Requires the caller to be the profile owner if checking a specific admin's policy.
      *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param admin The name of the admin component whose blocking policy will be checked, or null
+     *        to check if any admin has blocked the uninstallation.
      * @param packageName package to check.
-     * @return true if the user shouldn't be able to uninstall the package.
+     * @return true if uninstallation is blocked.
      */
     public boolean isUninstallBlocked(ComponentName admin, String packageName) {
         if (mService != null) {
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl
index 0193711..68ea0aa 100644
--- a/core/java/android/app/trust/ITrustManager.aidl
+++ b/core/java/android/app/trust/ITrustManager.aidl
@@ -29,5 +29,6 @@
     void reportRequireCredentialEntry(int userId);
     void registerTrustListener(in ITrustListener trustListener);
     void unregisterTrustListener(in ITrustListener trustListener);
-    boolean isTrusted(int userId);
+    void reportKeyguardShowingChanged();
+    boolean isDeviceLocked(int userId);
 }
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index 3d262b1..705a144 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -88,6 +88,19 @@
     }
 
     /**
+     * Reports that the visibility of the keyguard has changed.
+     *
+     * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
+     */
+    public void reportKeyguardShowingChanged() {
+        try {
+            mService.reportKeyguardShowingChanged();
+        } catch (RemoteException e) {
+            onError(e);
+        }
+    }
+
+    /**
      * Registers a listener for trust events.
      *
      * Requires the {@link android.Manifest.permission#TRUST_LISTENER} permission.
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 4c82efd..360f308 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -31,6 +31,7 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.CancellationSignal;
+import android.os.IBinder;
 import android.os.ICancellationSignal;
 import android.os.OperationCanceledException;
 import android.os.ParcelFileDescriptor;
@@ -201,7 +202,7 @@
                 ICancellationSignal cancellationSignal) {
             validateIncomingUri(uri);
             uri = getUriWithoutUserId(uri);
-            if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
+            if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 return rejectQuery(uri, projection, selection, selectionArgs, sortOrder,
                         CancellationSignal.fromTransport(cancellationSignal));
             }
@@ -227,7 +228,7 @@
             validateIncomingUri(uri);
             int userId = getUserIdFromUri(uri);
             uri = getUriWithoutUserId(uri);
-            if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
+            if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 return rejectInsert(uri, initialValues);
             }
             final String original = setCallingPackage(callingPkg);
@@ -242,7 +243,7 @@
         public int bulkInsert(String callingPkg, Uri uri, ContentValues[] initialValues) {
             validateIncomingUri(uri);
             uri = getUriWithoutUserId(uri);
-            if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
+            if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
             }
             final String original = setCallingPackage(callingPkg);
@@ -270,13 +271,13 @@
                     operations.set(i, operation);
                 }
                 if (operation.isReadOperation()) {
-                    if (enforceReadPermission(callingPkg, uri)
+                    if (enforceReadPermission(callingPkg, uri, null)
                             != AppOpsManager.MODE_ALLOWED) {
                         throw new OperationApplicationException("App op not allowed", 0);
                     }
                 }
                 if (operation.isWriteOperation()) {
-                    if (enforceWritePermission(callingPkg, uri)
+                    if (enforceWritePermission(callingPkg, uri, null)
                             != AppOpsManager.MODE_ALLOWED) {
                         throw new OperationApplicationException("App op not allowed", 0);
                     }
@@ -301,7 +302,7 @@
         public int delete(String callingPkg, Uri uri, String selection, String[] selectionArgs) {
             validateIncomingUri(uri);
             uri = getUriWithoutUserId(uri);
-            if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
+            if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
             }
             final String original = setCallingPackage(callingPkg);
@@ -317,7 +318,7 @@
                 String[] selectionArgs) {
             validateIncomingUri(uri);
             uri = getUriWithoutUserId(uri);
-            if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
+            if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
             }
             final String original = setCallingPackage(callingPkg);
@@ -330,11 +331,11 @@
 
         @Override
         public ParcelFileDescriptor openFile(
-                String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
-                throws FileNotFoundException {
+                String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal,
+                IBinder callerToken) throws FileNotFoundException {
             validateIncomingUri(uri);
             uri = getUriWithoutUserId(uri);
-            enforceFilePermission(callingPkg, uri, mode);
+            enforceFilePermission(callingPkg, uri, mode, callerToken);
             final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.openFile(
@@ -350,7 +351,7 @@
                 throws FileNotFoundException {
             validateIncomingUri(uri);
             uri = getUriWithoutUserId(uri);
-            enforceFilePermission(callingPkg, uri, mode);
+            enforceFilePermission(callingPkg, uri, mode, null);
             final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.openAssetFile(
@@ -382,7 +383,7 @@
                 Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException {
             validateIncomingUri(uri);
             uri = getUriWithoutUserId(uri);
-            enforceFilePermission(callingPkg, uri, "r");
+            enforceFilePermission(callingPkg, uri, "r", null);
             final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.openTypedAssetFile(
@@ -402,7 +403,7 @@
             validateIncomingUri(uri);
             int userId = getUserIdFromUri(uri);
             uri = getUriWithoutUserId(uri);
-            if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
+            if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 return null;
             }
             final String original = setCallingPackage(callingPkg);
@@ -418,7 +419,7 @@
             validateIncomingUri(uri);
             int userId = getUserIdFromUri(uri);
             uri = getUriWithoutUserId(uri);
-            if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
+            if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 return null;
             }
             final String original = setCallingPackage(callingPkg);
@@ -429,29 +430,33 @@
             }
         }
 
-        private void enforceFilePermission(String callingPkg, Uri uri, String mode)
-                throws FileNotFoundException, SecurityException {
+        private void enforceFilePermission(String callingPkg, Uri uri, String mode,
+                IBinder callerToken) throws FileNotFoundException, SecurityException {
             if (mode != null && mode.indexOf('w') != -1) {
-                if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
+                if (enforceWritePermission(callingPkg, uri, callerToken)
+                        != AppOpsManager.MODE_ALLOWED) {
                     throw new FileNotFoundException("App op not allowed");
                 }
             } else {
-                if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
+                if (enforceReadPermission(callingPkg, uri, callerToken)
+                        != AppOpsManager.MODE_ALLOWED) {
                     throw new FileNotFoundException("App op not allowed");
                 }
             }
         }
 
-        private int enforceReadPermission(String callingPkg, Uri uri) throws SecurityException {
-            enforceReadPermissionInner(uri);
+        private int enforceReadPermission(String callingPkg, Uri uri, IBinder callerToken)
+                throws SecurityException {
+            enforceReadPermissionInner(uri, callerToken);
             if (mReadOp != AppOpsManager.OP_NONE) {
                 return mAppOpsManager.noteOp(mReadOp, Binder.getCallingUid(), callingPkg);
             }
             return AppOpsManager.MODE_ALLOWED;
         }
 
-        private int enforceWritePermission(String callingPkg, Uri uri) throws SecurityException {
-            enforceWritePermissionInner(uri);
+        private int enforceWritePermission(String callingPkg, Uri uri, IBinder callerToken)
+                throws SecurityException {
+            enforceWritePermissionInner(uri, callerToken);
             if (mWriteOp != AppOpsManager.OP_NONE) {
                 return mAppOpsManager.noteOp(mWriteOp, Binder.getCallingUid(), callingPkg);
             }
@@ -467,7 +472,8 @@
     }
 
     /** {@hide} */
-    protected void enforceReadPermissionInner(Uri uri) throws SecurityException {
+    protected void enforceReadPermissionInner(Uri uri, IBinder callerToken)
+            throws SecurityException {
         final Context context = getContext();
         final int pid = Binder.getCallingPid();
         final int uid = Binder.getCallingUid();
@@ -480,7 +486,8 @@
         if (mExported && checkUser(pid, uid, context)) {
             final String componentPerm = getReadPermission();
             if (componentPerm != null) {
-                if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) {
+                if (context.checkPermission(componentPerm, pid, uid, callerToken)
+                        == PERMISSION_GRANTED) {
                     return;
                 } else {
                     missingPerm = componentPerm;
@@ -497,7 +504,8 @@
                 for (PathPermission pp : pps) {
                     final String pathPerm = pp.getReadPermission();
                     if (pathPerm != null && pp.match(path)) {
-                        if (context.checkPermission(pathPerm, pid, uid) == PERMISSION_GRANTED) {
+                        if (context.checkPermission(pathPerm, pid, uid, callerToken)
+                                == PERMISSION_GRANTED) {
                             return;
                         } else {
                             // any denied <path-permission> means we lose
@@ -518,8 +526,8 @@
         final int callingUserId = UserHandle.getUserId(uid);
         final Uri userUri = (mSingleUser && !UserHandle.isSameUser(mMyUid, uid))
                 ? maybeAddUserId(uri, callingUserId) : uri;
-        if (context.checkUriPermission(userUri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
-                == PERMISSION_GRANTED) {
+        if (context.checkUriPermission(userUri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION,
+                callerToken) == PERMISSION_GRANTED) {
             return;
         }
 
@@ -532,7 +540,8 @@
     }
 
     /** {@hide} */
-    protected void enforceWritePermissionInner(Uri uri) throws SecurityException {
+    protected void enforceWritePermissionInner(Uri uri, IBinder callerToken)
+            throws SecurityException {
         final Context context = getContext();
         final int pid = Binder.getCallingPid();
         final int uid = Binder.getCallingUid();
@@ -545,7 +554,8 @@
         if (mExported && checkUser(pid, uid, context)) {
             final String componentPerm = getWritePermission();
             if (componentPerm != null) {
-                if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) {
+                if (context.checkPermission(componentPerm, pid, uid, callerToken)
+                        == PERMISSION_GRANTED) {
                     return;
                 } else {
                     missingPerm = componentPerm;
@@ -562,7 +572,8 @@
                 for (PathPermission pp : pps) {
                     final String pathPerm = pp.getWritePermission();
                     if (pathPerm != null && pp.match(path)) {
-                        if (context.checkPermission(pathPerm, pid, uid) == PERMISSION_GRANTED) {
+                        if (context.checkPermission(pathPerm, pid, uid, callerToken)
+                                == PERMISSION_GRANTED) {
                             return;
                         } else {
                             // any denied <path-permission> means we lose
@@ -580,8 +591,8 @@
         }
 
         // last chance, check against any uri grants
-        if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
-                == PERMISSION_GRANTED) {
+        if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
+                callerToken) == PERMISSION_GRANTED) {
             return;
         }
 
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index cefc27f..e15ac94 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -288,7 +288,7 @@
                 remoteSignal = mContentProvider.createCancellationSignal();
                 signal.setRemote(remoteSignal);
             }
-            return mContentProvider.openFile(mPackageName, url, mode, remoteSignal);
+            return mContentProvider.openFile(mPackageName, url, mode, remoteSignal, null);
         } catch (DeadObjectException e) {
             if (!mStable) {
                 mContentResolver.unstableProviderDied(mContentProvider);
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index 39286d6..f2e7fc4 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -234,9 +234,10 @@
                     String mode = data.readString();
                     ICancellationSignal signal = ICancellationSignal.Stub.asInterface(
                             data.readStrongBinder());
+                    IBinder callerToken = data.readStrongBinder();
 
                     ParcelFileDescriptor fd;
-                    fd = openFile(callingPkg, url, mode, signal);
+                    fd = openFile(callingPkg, url, mode, signal, callerToken);
                     reply.writeNoException();
                     if (fd != null) {
                         reply.writeInt(1);
@@ -575,7 +576,7 @@
 
     @Override
     public ParcelFileDescriptor openFile(
-            String callingPkg, Uri url, String mode, ICancellationSignal signal)
+            String callingPkg, Uri url, String mode, ICancellationSignal signal, IBinder token)
             throws RemoteException, FileNotFoundException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -586,6 +587,7 @@
             url.writeToParcel(data, 0);
             data.writeString(mode);
             data.writeStrongBinder(signal != null ? signal.asBinder() : null);
+            data.writeStrongBinder(token);
 
             mRemote.transact(IContentProvider.OPEN_FILE_TRANSACTION, data, reply, 0);
 
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index c9b7d0a..a73ba74 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -37,6 +37,7 @@
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Looper;
 import android.os.StatFs;
 import android.os.UserHandle;
@@ -2864,10 +2865,10 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a {@link
-     * android.app.UsageStatsManager} for interacting with the status bar.
+     * android.app.usage.UsageStatsManager} for interacting with the status bar.
      *
      * @see #getSystemService
-     * @see android.app.UsageStatsManager
+     * @see android.app.usage.UsageStatsManager
      * @hide
      */
     public static final String USAGE_STATS_SERVICE = "usagestats";
@@ -2921,6 +2922,11 @@
     @PackageManager.PermissionResult
     public abstract int checkPermission(@NonNull String permission, int pid, int uid);
 
+    /** @hide */
+    @PackageManager.PermissionResult
+    public abstract int checkPermission(@NonNull String permission, int pid, int uid,
+            IBinder callerToken);
+
     /**
      * Determine whether the calling process of an IPC you are handling has been
      * granted a particular permission.  This is basically the same as calling
@@ -3108,6 +3114,10 @@
     public abstract int checkUriPermission(Uri uri, int pid, int uid,
             @Intent.AccessUriMode int modeFlags);
 
+    /** @hide */
+    public abstract int checkUriPermission(Uri uri, int pid, int uid,
+            @Intent.AccessUriMode int modeFlags, IBinder callerToken);
+
     /**
      * Determine whether the calling process and user ID has been
      * granted permission to access a specific URI.  This is basically
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index ad7c350..cfae1cf 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -29,6 +29,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Looper;
 import android.os.UserHandle;
 import android.view.DisplayAdjustments;
@@ -566,6 +567,12 @@
         return mBase.checkPermission(permission, pid, uid);
     }
 
+    /** @hide */
+    @Override
+    public int checkPermission(String permission, int pid, int uid, IBinder callerToken) {
+        return mBase.checkPermission(permission, pid, uid, callerToken);
+    }
+
     @Override
     public int checkCallingPermission(String permission) {
         return mBase.checkCallingPermission(permission);
@@ -608,6 +615,12 @@
         return mBase.checkUriPermission(uri, pid, uid, modeFlags);
     }
 
+    /** @hide */
+    @Override
+    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) {
+        return mBase.checkUriPermission(uri, pid, uid, modeFlags, callerToken);
+    }
+
     @Override
     public int checkCallingUriPermission(Uri uri, int modeFlags) {
         return mBase.checkCallingUriPermission(uri, modeFlags);
diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java
index f92a404..f858406 100644
--- a/core/java/android/content/IContentProvider.java
+++ b/core/java/android/content/IContentProvider.java
@@ -47,7 +47,8 @@
     public int update(String callingPkg, Uri url, ContentValues values, String selection,
             String[] selectionArgs) throws RemoteException;
     public ParcelFileDescriptor openFile(
-            String callingPkg, Uri url, String mode, ICancellationSignal signal)
+            String callingPkg, Uri url, String mode, ICancellationSignal signal,
+            IBinder callerToken)
             throws RemoteException, FileNotFoundException;
     public AssetFileDescriptor openAssetFile(
             String callingPkg, Uri url, String mode, ICancellationSignal signal)
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 57f6028..a13a2ea 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3763,7 +3763,7 @@
      * This flag is used to open a document into a new task rooted at the activity launched
      * by this Intent. Through the use of this flag, or its equivalent attribute,
      * {@link android.R.attr#documentLaunchMode} multiple instances of the same activity
-     * containing different douments will appear in the recent tasks list.
+     * containing different documents will appear in the recent tasks list.
      *
      * <p>The use of the activity attribute form of this,
      * {@link android.R.attr#documentLaunchMode}, is
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index c848993..d469487 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -19,6 +19,7 @@
 import static android.system.OsConstants.AF_INET;
 import static android.system.OsConstants.AF_INET6;
 
+import android.annotation.SystemApi;
 import android.app.Activity;
 import android.app.PendingIntent;
 import android.app.Service;
@@ -164,6 +165,32 @@
     }
 
     /**
+     * Version of {@link #prepare(Context)} which does not require user consent.
+     *
+     * <p>Requires {@link android.Manifest.permission#CONTROL_VPN} and should generally not be
+     * used. Only acceptable in situations where user consent has been obtained through other means.
+     *
+     * <p>Once this is run, future preparations may be done with the standard prepare method as this
+     * will authorize the package to prepare the VPN without consent in the future.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static void prepareAndAuthorize(Context context) {
+        IConnectivityManager cm = getService();
+        String packageName = context.getPackageName();
+        try {
+            // Only prepare if we're not already prepared.
+            if (!cm.prepareVpn(packageName, null)) {
+                cm.prepareVpn(null, packageName);
+            }
+            cm.setVpnPackageAuthorization(true);
+        } catch (RemoteException e) {
+            // ignore
+        }
+    }
+
+    /**
      * Protect a socket from VPN connections. After protecting, data sent
      * through this socket will go directly to the underlying network,
      * so its traffic will not be forwarded through the VPN.
diff --git a/core/java/android/nfc/BeamShareData.java b/core/java/android/nfc/BeamShareData.java
index c30ba14..918ec3d 100644
--- a/core/java/android/nfc/BeamShareData.java
+++ b/core/java/android/nfc/BeamShareData.java
@@ -3,6 +3,7 @@
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.UserHandle;
 
 /**
  * Class to IPC data to be shared over Android Beam.
@@ -14,11 +15,13 @@
 public final class BeamShareData implements Parcelable {
     public final NdefMessage ndefMessage;
     public final Uri[] uris;
+    public final UserHandle userHandle;
     public final int flags;
 
-    public BeamShareData(NdefMessage msg, Uri[] uris, int flags) {
+    public BeamShareData(NdefMessage msg, Uri[] uris, UserHandle userHandle, int flags) {
         this.ndefMessage = msg;
         this.uris = uris;
+        this.userHandle = userHandle;
         this.flags = flags;
     }
 
@@ -35,6 +38,7 @@
         if (urisLength > 0) {
             dest.writeTypedArray(uris, 0);
         }
+        dest.writeParcelable(userHandle, 0);
         dest.writeInt(this.flags);
     }
 
@@ -49,9 +53,10 @@
                 uris = new Uri[numUris];
                 source.readTypedArray(uris, Uri.CREATOR);
             }
+            UserHandle userHandle = source.readParcelable(UserHandle.class.getClassLoader());
             int flags = source.readInt();
 
-            return new BeamShareData(msg, uris, flags);
+            return new BeamShareData(msg, uris, userHandle, flags);
         }
 
         @Override
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 5b926ad..961a3f4 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -60,4 +60,6 @@
 
     void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, in int[] techList);
     void removeNfcUnlockHandler(INfcUnlockHandler unlockHandler);
+
+    void verifyNfcPermission();
 }
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index 8643f2e..d009295 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -18,12 +18,14 @@
 
 import android.app.Activity;
 import android.app.Application;
+import android.content.ContentProvider;
 import android.content.Intent;
 import android.net.Uri;
 import android.nfc.NfcAdapter.ReaderCallback;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -252,7 +254,11 @@
             isResumed = state.resumed;
         }
         if (isResumed) {
+            // requestNfcServiceCallback() verifies permission also
             requestNfcServiceCallback();
+        } else {
+            // Crash API calls early in case NFC permission is missing
+            verifyNfcPermission();
         }
     }
 
@@ -266,7 +272,11 @@
             isResumed = state.resumed;
         }
         if (isResumed) {
+            // requestNfcServiceCallback() verifies permission also
             requestNfcServiceCallback();
+        } else {
+            // Crash API calls early in case NFC permission is missing
+            verifyNfcPermission();
         }
     }
 
@@ -279,7 +289,11 @@
             isResumed = state.resumed;
         }
         if (isResumed) {
+            // requestNfcServiceCallback() verifies permission also
             requestNfcServiceCallback();
+        } else {
+            // Crash API calls early in case NFC permission is missing
+            verifyNfcPermission();
         }
     }
 
@@ -293,7 +307,11 @@
             isResumed = state.resumed;
         }
         if (isResumed) {
+            // requestNfcServiceCallback() verifies permission also
             requestNfcServiceCallback();
+        } else {
+            // Crash API calls early in case NFC permission is missing
+            verifyNfcPermission();
         }
     }
 
@@ -306,7 +324,11 @@
             isResumed = state.resumed;
         }
         if (isResumed) {
+            // requestNfcServiceCallback() verifies permission also
             requestNfcServiceCallback();
+        } else {
+            // Crash API calls early in case NFC permission is missing
+            verifyNfcPermission();
         }
     }
 
@@ -322,6 +344,14 @@
         }
     }
 
+    void verifyNfcPermission() {
+        try {
+            NfcAdapter.sService.verifyNfcPermission();
+        } catch (RemoteException e) {
+            mAdapter.attemptDeadServiceRecovery(e);
+        }
+    }
+
     /** Callback from NFC service, usually on binder thread */
     @Override
     public BeamShareData createBeamShareData() {
@@ -350,19 +380,24 @@
         if (urisCallback != null) {
             uris = urisCallback.createBeamUris(mDefaultEvent);
             if (uris != null) {
+                ArrayList<Uri> validUris = new ArrayList<Uri>();
                 for (Uri uri : uris) {
                     if (uri == null) {
                         Log.e(TAG, "Uri not allowed to be null.");
-                        return null;
+                        continue;
                     }
                     String scheme = uri.getScheme();
                     if (scheme == null || (!scheme.equalsIgnoreCase("file") &&
                             !scheme.equalsIgnoreCase("content"))) {
                         Log.e(TAG, "Uri needs to have " +
                                 "either scheme file or scheme content");
-                        return null;
+                        continue;
                     }
+                    uri = ContentProvider.maybeAddUserId(uri, UserHandle.myUserId());
+                    validUris.add(uri);
                 }
+
+                uris = validUris.toArray(new Uri[validUris.size()]);
             }
         }
         if (uris != null && uris.length > 0) {
@@ -372,7 +407,7 @@
                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
             }
         }
-        return new BeamShareData(message, uris, flags);
+        return new BeamShareData(message, uris, UserHandle.CURRENT, flags);
     }
 
     /** Callback from NFC service, usually on binder thread */
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 461469c..4709443 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -3669,6 +3669,45 @@
         pw.print(suffix);
     }
 
+    private static boolean dumpTimeEstimate(PrintWriter pw, String label, long[] steps,
+            int count, long modesOfInterest, long modeValues) {
+        if (count <= 0) {
+            return false;
+        }
+        long total = 0;
+        int numOfInterest = 0;
+        for (int i=0; i<count; i++) {
+            long initMode = (steps[i] & STEP_LEVEL_INITIAL_MODE_MASK)
+                    >> STEP_LEVEL_INITIAL_MODE_SHIFT;
+            long modMode = (steps[i] & STEP_LEVEL_MODIFIED_MODE_MASK)
+                    >> STEP_LEVEL_MODIFIED_MODE_SHIFT;
+            // If the modes of interest didn't change during this step period...
+            if ((modMode&modesOfInterest) == 0) {
+                // And the mode values during this period match those we are measuring...
+                if ((initMode&modesOfInterest) == modeValues) {
+                    // Then this can be used to estimate the total time!
+                    numOfInterest++;
+                    total += steps[i] & STEP_LEVEL_TIME_MASK;
+                }
+            }
+        }
+        if (numOfInterest <= 0) {
+            return false;
+        }
+
+        // The estimated time is the average time we spend in each level, multipled
+        // by 100 -- the total number of battery levels
+        long estimatedTime = (total / numOfInterest) * 100;
+
+        pw.print(label);
+        StringBuilder sb = new StringBuilder(64);
+        formatTimeMs(sb, estimatedTime);
+        pw.print(sb);
+        pw.println();
+
+        return true;
+    }
+
     private static boolean dumpDurationSteps(PrintWriter pw, String header, long[] steps,
             int count, boolean checkin) {
         if (count <= 0) {
@@ -3923,6 +3962,38 @@
                     TimeUtils.formatDuration(timeRemaining / 1000, pw);
                     pw.println();
                 }
+                dumpTimeEstimate(pw, "  Estimated screen off time: ",
+                        getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
+                        STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
+                        (Display.STATE_OFF-1));
+                dumpTimeEstimate(pw, "  Estimated screen off power save time: ",
+                        getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
+                        STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
+                        (Display.STATE_OFF-1)|STEP_LEVEL_MODE_POWER_SAVE);
+                dumpTimeEstimate(pw, "  Estimated screen on time: ",
+                        getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
+                        STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
+                        (Display.STATE_ON-1));
+                dumpTimeEstimate(pw, "  Estimated screen on power save time: ",
+                        getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
+                        STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
+                        (Display.STATE_ON-1)|STEP_LEVEL_MODE_POWER_SAVE);
+                dumpTimeEstimate(pw, "  Estimated screen doze time: ",
+                        getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
+                        STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
+                        (Display.STATE_DOZE-1));
+                dumpTimeEstimate(pw, "  Estimated screen doze power save time: ",
+                        getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
+                        STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
+                        (Display.STATE_DOZE-1)|STEP_LEVEL_MODE_POWER_SAVE);
+                dumpTimeEstimate(pw, "  Estimated screen doze suspend time: ",
+                        getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
+                        STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
+                        (Display.STATE_DOZE_SUSPEND-1));
+                dumpTimeEstimate(pw, "  Estimated screen doze suspend power save time: ",
+                        getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
+                        STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
+                        (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_POWER_SAVE);
                 pw.println();
             }
             if (dumpDurationSteps(pw, "Charge step durations:", getChargeStepDurationsArray(),
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index bd6eeea..ffbed94 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -383,8 +383,8 @@
      *
      * <p/>Key for application restrictions.
      * <p/>Type: Boolean
-     * @see android.app.admin.DevicePolicyManager#addApplicationRestriction()
-     * @see android.app.admin.DevicePolicyManager#getApplicationRestriction()
+     * @see android.app.admin.DevicePolicyManager#setApplicationRestrictions()
+     * @see android.app.admin.DevicePolicyManager#getApplicationRestrictions()
      */
     public static final String KEY_RESTRICTIONS_PENDING = "restrictions_pending";
 
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 270d786..4135e8b 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -637,7 +637,7 @@
         final Bundle out = new Bundle();
         try {
             if (METHOD_CREATE_DOCUMENT.equals(method)) {
-                enforceWritePermissionInner(documentUri);
+                enforceWritePermissionInner(documentUri, null);
 
                 final String mimeType = extras.getString(Document.COLUMN_MIME_TYPE);
                 final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME);
@@ -651,7 +651,7 @@
                 out.putParcelable(DocumentsContract.EXTRA_URI, newDocumentUri);
 
             } else if (METHOD_RENAME_DOCUMENT.equals(method)) {
-                enforceWritePermissionInner(documentUri);
+                enforceWritePermissionInner(documentUri, null);
 
                 final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME);
                 final String newDocumentId = renameDocument(documentId, displayName);
@@ -675,7 +675,7 @@
                 }
 
             } else if (METHOD_DELETE_DOCUMENT.equals(method)) {
-                enforceWritePermissionInner(documentUri);
+                enforceWritePermissionInner(documentUri, null);
                 deleteDocument(documentId);
 
                 // Document no longer exists, clean up any grants
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1f45f0a..3c12e06 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -984,8 +984,8 @@
      * InputDeviceIdentifier. This field is used by some activities to jump straight into the
      * settings for the given device.
      * <p>
-     * Example: The {@link #INPUT_METHOD_SETTINGS} intent opens the keyboard layout dialog for the
-     * given device.
+     * Example: The {@link #ACTION_INPUT_METHOD_SETTINGS} intent opens the keyboard layout
+     * dialog for the given device.
      * @hide
      */
     public static final String EXTRA_INPUT_DEVICE_IDENTIFIER = "input_device_identifier";
@@ -4816,7 +4816,7 @@
          * The timeout in milliseconds before the device fully goes to sleep after
          * a period of inactivity.  This value sets an upper bound on how long the device
          * will stay awake or dreaming without user activity.  It should generally
-         * be longer than {@link #SCREEN_OFF_TIMEOUT} as otherwise the device
+         * be longer than {@link Settings.System#SCREEN_OFF_TIMEOUT} as otherwise the device
          * will sleep before it ever has a chance to dream.
          * <p>
          * Use -1 to disable this timeout.
@@ -6601,6 +6601,15 @@
         public static final String ENHANCED_4G_MODE_ENABLED = "volte_vt_enabled";
 
         /**
+         * Whether user can enable/disable LTE as a preferred network. A carrier might control
+         * this via gservices, OMA-DM, carrier app, etc.
+         * <p>
+         * Type: int (0 for false, 1 for true)
+         * @hide
+         */
+        public static final String LTE_SERVICE_FORCED = "lte_service_forced";
+
+        /**
          * Settings to backup. This is here so that it's in the same place as the settings
          * keys and easy to update.
          *
diff --git a/core/java/android/service/carriermessaging/CarrierMessagingService.java b/core/java/android/service/carriermessaging/CarrierMessagingService.java
index 101f69b..7aea590 100644
--- a/core/java/android/service/carriermessaging/CarrierMessagingService.java
+++ b/core/java/android/service/carriermessaging/CarrierMessagingService.java
@@ -16,6 +16,7 @@
 
 package android.service.carriermessaging;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.app.Service;
@@ -93,7 +94,7 @@
      * @return True to keep an inbound SMS message and delivered to SMS apps. False to
      * drop the message.
      */
-    public boolean onFilterSms(MessagePdu pdu, String format, int destPort) {
+    public boolean onFilterSms(@NonNull MessagePdu pdu, @NonNull String format, int destPort) {
         // optional
         return true;
     }
@@ -105,9 +106,11 @@
      * @param format the format of the response PDU, typically "3gpp" or "3gpp2"
      * @param destAddress phone number of the recipient of the message
      *
-     * @return a {@link SendSmsResponse}.
+     * @return a possibly {code null} {@link SendSmsResponse}. Upon returning {@code null}, the SMS
+     *         is sent using the carrier network.
      */
-    public SendSmsResponse onSendTextSms(String text, String format, String destAddress) {
+    public @Nullable SendSmsResponse onSendTextSms(
+            @NonNull String text, @NonNull String format, @NonNull String destAddress) {
         // optional
         return null;
     }
@@ -120,10 +123,11 @@
      * @param destAddress phone number of the recipient of the message
      * @param destPort the destination port
      *
-     * @return a {@link SendSmsResponse}
+     * @return a possibly {code null} {@link SendSmsResponse}. Upon returning {@code null}, the SMS
+     *         is sent using the carrier network.
      */
-    public SendSmsResponse onSendDataSms(byte[] data, String format, String destAddress,
-            int destPort) {
+    public @Nullable SendSmsResponse onSendDataSms(@NonNull byte[] data, @NonNull String format,
+            @NonNull String destAddress, int destPort) {
         // optional
         return null;
     }
@@ -135,10 +139,11 @@
      * @param format format the format of the response PDU, typically "3gpp" or "3gpp2"
      * @param destAddress phone number of the recipient of the message
      *
-     * @return a {@link List} of {@link SendSmsResponse}, one for each message part.
+     * @return a possibly {code null} {@link List} of {@link SendSmsResponse}, one for each message
+     *         part. Upon returning {@code null}, the SMS is sent using the carrier network.
      */
-    public List<SendSmsResponse> onSendMultipartTextSms(List<String> parts, String format,
-            String destAddress) {
+    public @Nullable List<SendSmsResponse> onSendMultipartTextSms(@NonNull List<String> parts,
+            @NonNull String format, @NonNull String destAddress) {
         // optional
         return null;
     }
@@ -150,9 +155,10 @@
      * @param locationUrl the optional URL to send this MMS PDU. If this is not specified,
      *                    the PDU should be sent to the default MMSC URL.
      *
-     * @return a {@link SendMmsResult}.
+     * @return a possibly {@code null} {@link SendMmsResult}. Upon returning {@code null}, the
+     *         MMS is sent using the carrier network.
      */
-    public SendMmsResult onSendMms(Uri pduUri, @Nullable String locationUrl) {
+    public @Nullable SendMmsResult onSendMms(@NonNull Uri pduUri, @Nullable String locationUrl) {
         // optional
         return null;
     }
@@ -165,13 +171,13 @@
      *
      * @return a {@link SendMmsResult}.
      */
-    public int onDownloadMms(Uri contentUri, String locationUrl) {
+    public int onDownloadMms(@NonNull Uri contentUri, @NonNull String locationUrl) {
         // optional
         return DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK;
     }
 
     @Override
-    public IBinder onBind(Intent intent) {
+    public @Nullable IBinder onBind(@NonNull Intent intent) {
         if (!SERVICE_INTERFACE.equals(intent.getAction())) {
             return null;
         }
@@ -185,12 +191,24 @@
         private int mResult;
         private byte[] mSendConfPdu;
 
-        public SendMmsResult(int result, byte[] sendConfPdu) {
+        /**
+         * Constructs a SendMmsResult with the MMS send result, and the SenConf PDU.
+         *
+         * @param result the result which is one of {@link #SEND_STATUS_OK},
+         *               {@link #SEND_STATUS_RETRY_ON_CARRIER_NETWORK}, and
+         *               {@link #SEND_STATUS_ERROR}
+         * @param sendConfPdu a possibly {code null} SendConf PDU, which confirms that the message
+         *        was sent. sendConfPdu is ignored if the {@code result} is not
+         *        {@link #SEND_STATUS_OK}
+         */
+        public SendMmsResult(int result, @Nullable byte[] sendConfPdu) {
             mResult = result;
             mSendConfPdu = sendConfPdu;
         }
 
         /**
+         * Returns the result of sending the MMS.
+         *
          * @return the result which is one of {@link #SEND_STATUS_OK},
          *         {@link #SEND_STATUS_RETRY_ON_CARRIER_NETWORK}, and {@link #SEND_STATUS_ERROR}
          */
@@ -199,9 +217,11 @@
         }
 
         /**
-         * @return the SendConf PDU, which confirms that the message was sent.
+         * Returns the SendConf PDU, which confirms that the message was sent.
+         *
+         * @return the SendConf PDU
          */
-        public byte[] getSendConfPdu() {
+        public @Nullable byte[] getSendConfPdu() {
             return mSendConfPdu;
         }
     }
@@ -219,12 +239,15 @@
         private int mErrorCode;
 
         /**
+         * Constructs a SendSmsResponse for the message reference, the ack PDU, and error code for
+         * the just-sent SMS.
+         *
          * @param messageRef message reference of the just-sent SMS
          * @param ackPdu ackPdu for the just-sent SMS
          * @param errorCode error code. See 3GPP 27.005, 3.2.5 for GSM/UMTS,
          *     3GPP2 N.S0005 (IS-41C) Table 171 for CDMA, -1 if unknown or not applicable.
          */
-        public SendSmsResponse(int messageRef, byte[] ackPdu, int errorCode) {
+        public SendSmsResponse(int messageRef, @NonNull byte[] ackPdu, int errorCode) {
             mMessageRef = messageRef;
             mAckPdu = ackPdu;
             mErrorCode = errorCode;
@@ -244,7 +267,7 @@
          *
          * @return the ackPdu
          */
-        public byte[] getAckPdu() {
+        public @NonNull byte[] getAckPdu() {
             return mAckPdu;
         }
 
diff --git a/core/java/android/service/carriermessaging/MessagePdu.java b/core/java/android/service/carriermessaging/MessagePdu.java
index b81719f..3c78568 100644
--- a/core/java/android/service/carriermessaging/MessagePdu.java
+++ b/core/java/android/service/carriermessaging/MessagePdu.java
@@ -16,6 +16,7 @@
 
 package android.service.carriermessaging;
 
+import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -31,9 +32,14 @@
     private final List<byte[]> mPduList;
 
     /**
+     * Constructs a MessagePdu with the list of message PDUs.
+     *
      * @param pduList the list of message PDUs
      */
-    public MessagePdu(List<byte[]> pduList) {
+    public MessagePdu(@NonNull List<byte[]> pduList) {
+        if (pduList == null || pduList.contains(null)) {
+            throw new IllegalArgumentException("pduList must not be null or contain nulls");
+        }
         mPduList = pduList;
     }
 
@@ -42,7 +48,7 @@
      *
      * @return the list of PDUs
      */
-    public List<byte[]> getPdus() {
+    public @NonNull List<byte[]> getPdus() {
         return mPduList;
     }
 
@@ -51,9 +57,6 @@
         return 0;
     }
 
-    /**
-     * Writes the PDU into a {@link Parcel}.
-     */
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         if (mPduList == null) {
diff --git a/core/java/android/service/trust/ITrustAgentService.aidl b/core/java/android/service/trust/ITrustAgentService.aidl
index bb0c2b2..f07d0d0 100644
--- a/core/java/android/service/trust/ITrustAgentService.aidl
+++ b/core/java/android/service/trust/ITrustAgentService.aidl
@@ -25,6 +25,8 @@
 interface ITrustAgentService {
     oneway void onUnlockAttempt(boolean successful);
     oneway void onTrustTimeout();
+    oneway void onDeviceLocked();
+    oneway void onDeviceUnlocked();
     oneway void onConfigure(in List<PersistableBundle> options, IBinder token);
     oneway void setCallback(ITrustAgentServiceCallback callback);
 }
diff --git a/core/java/android/service/trust/TrustAgentService.java b/core/java/android/service/trust/TrustAgentService.java
index d6c997f..62fa978 100644
--- a/core/java/android/service/trust/TrustAgentService.java
+++ b/core/java/android/service/trust/TrustAgentService.java
@@ -92,6 +92,8 @@
     private static final int MSG_UNLOCK_ATTEMPT = 1;
     private static final int MSG_CONFIGURE = 2;
     private static final int MSG_TRUST_TIMEOUT = 3;
+    private static final int MSG_DEVICE_LOCKED = 4;
+    private static final int MSG_DEVICE_UNLOCKED = 5;
 
     /**
      * Class containing raw data for a given configuration request.
@@ -134,6 +136,12 @@
                 case MSG_TRUST_TIMEOUT:
                     onTrustTimeout();
                     break;
+                case MSG_DEVICE_LOCKED:
+                    onDeviceLocked();
+                    break;
+                case MSG_DEVICE_UNLOCKED:
+                    onDeviceUnlocked();
+                    break;
             }
         }
     };
@@ -173,6 +181,20 @@
     public void onTrustTimeout() {
     }
 
+    /**
+     * Called when the device enters a state where a PIN, pattern or
+     * password must be entered to unlock it.
+     */
+    public void onDeviceLocked() {
+    }
+
+    /**
+     * Called when the device leaves a state where a PIN, pattern or
+     * password must be entered to unlock it.
+     */
+    public void onDeviceUnlocked() {
+    }
+
     private void onError(String msg) {
         Slog.v(TAG, "Remote exception while " + msg);
     }
@@ -300,6 +322,16 @@
                     .sendToTarget();
         }
 
+        @Override
+        public void onDeviceLocked() throws RemoteException {
+            mHandler.obtainMessage(MSG_DEVICE_LOCKED).sendToTarget();
+        }
+
+        @Override
+        public void onDeviceUnlocked() throws RemoteException {
+            mHandler.obtainMessage(MSG_DEVICE_UNLOCKED).sendToTarget();
+        }
+
         @Override /* Binder API */
         public void setCallback(ITrustAgentServiceCallback callback) {
             synchronized (mLock) {
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index e82057c..02297e3 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -383,7 +383,6 @@
                                 okBottom = fitBottom;
                         }
                     } else {
-                        final boolean moreChars;
                         int endPos;
                         int above, below, top, bottom;
                         float currentTextWidth;
@@ -395,7 +394,6 @@
                             top = okTop;
                             bottom = okBottom;
                             currentTextWidth = okWidth;
-                            moreChars = (j + 1 < spanEnd);
                         } else if (fit != here) {
                             endPos = fit;
                             above = fitAscent;
@@ -403,7 +401,6 @@
                             top = fitTop;
                             bottom = fitBottom;
                             currentTextWidth = fitWidth;
-                            moreChars = (j + 1 < spanEnd);
                         } else {
                             // must make progress, so take next character
                             endPos = here + 1;
@@ -417,7 +414,6 @@
                             top = fmTop;
                             bottom = fmBottom;
                             currentTextWidth = widths[here - paraStart];
-                            moreChars = (endPos < spanEnd);
                         }
 
                         v = out(source, here, endPos,
@@ -425,7 +421,7 @@
                                 v, spacingmult, spacingadd, chooseHt,chooseHtv, fm, hasTabOrEmoji,
                                 needMultiply, chdirs, dir, easy, bufEnd, includepad, trackpad,
                                 chs, widths, paraStart, ellipsize, ellipsizedWidth,
-                                currentTextWidth, paint, moreChars);
+                                currentTextWidth, paint, true);
 
                         here = endPos;
                         j = here - 1; // restart j-span loop from here, compensating for the j++
diff --git a/core/java/android/transition/ChangeTransform.java b/core/java/android/transition/ChangeTransform.java
index a159b40..9749121 100644
--- a/core/java/android/transition/ChangeTransform.java
+++ b/core/java/android/transition/ChangeTransform.java
@@ -376,7 +376,7 @@
         while (outerTransition.mParent != null) {
             outerTransition = outerTransition.mParent;
         }
-        GhostListener listener = new GhostListener(view, ghostView, endMatrix);
+        GhostListener listener = new GhostListener(view, startValues.view, ghostView);
         outerTransition.addListener(listener);
 
         if (startValues.view != endValues.view) {
@@ -466,13 +466,13 @@
 
     private static class GhostListener extends Transition.TransitionListenerAdapter {
         private View mView;
+        private View mStartView;
         private GhostView mGhostView;
-	private Matrix mEndMatrix;
 
-        public GhostListener(View view, GhostView ghostView, Matrix endMatrix) {
+        public GhostListener(View view, View startView, GhostView ghostView) {
             mView = view;
+            mStartView = startView;
             mGhostView = ghostView;
-            mEndMatrix = endMatrix;
         }
 
         @Override
@@ -481,6 +481,7 @@
             GhostView.removeGhost(mView);
             mView.setTagInternal(R.id.transitionTransform, null);
             mView.setTagInternal(R.id.parentMatrix, null);
+            mStartView.setTransitionAlpha(1);
         }
 
         @Override
diff --git a/core/java/android/transition/SidePropagation.java b/core/java/android/transition/SidePropagation.java
index 623cdd1..ad6c2dd 100644
--- a/core/java/android/transition/SidePropagation.java
+++ b/core/java/android/transition/SidePropagation.java
@@ -44,8 +44,8 @@
      * farther from the edge. The default is {@link Gravity#BOTTOM}.
      *
      * @param side The side that is used to calculate the transition propagation. Must be one of
-     *             {@link Gravity#LEFT}, {@link Gravity#TOP}, {@link Gravity#RIGHT}, or
-     *             {@link Gravity#BOTTOM}.
+     *             {@link Gravity#LEFT}, {@link Gravity#TOP}, {@link Gravity#RIGHT},
+     *             {@link Gravity#BOTTOM}, {@link Gravity#START}, or {@link Gravity#END}.
      */
     public void setSide(int side) {
         mSide = side;
@@ -106,7 +106,7 @@
             epicenterY = (top + bottom) / 2;
         }
 
-        float distance = distance(viewCenterX, viewCenterY, epicenterX, epicenterY,
+        float distance = distance(sceneRoot, viewCenterX, viewCenterY, epicenterX, epicenterY,
                 left, top, right, bottom);
         float maxDistance = getMaxDistance(sceneRoot);
         float distanceFraction = distance/maxDistance;
@@ -119,10 +119,20 @@
         return Math.round(duration * directionMultiplier / mPropagationSpeed * distanceFraction);
     }
 
-    private int distance(int viewX, int viewY, int epicenterX, int epicenterY,
+    private int distance(View sceneRoot, int viewX, int viewY, int epicenterX, int epicenterY,
             int left, int top, int right, int bottom) {
+        final int side;
+        if (mSide == Gravity.START) {
+            final boolean isRtl = sceneRoot.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+            side = isRtl ? Gravity.RIGHT : Gravity.LEFT;
+        } else if (mSide == Gravity.END) {
+            final boolean isRtl = sceneRoot.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+            side = isRtl ? Gravity.LEFT : Gravity.RIGHT;
+        } else {
+            side = mSide;
+        }
         int distance = 0;
-        switch (mSide) {
+        switch (side) {
             case Gravity.LEFT:
                 distance = right - viewX + Math.abs(epicenterY - viewY);
                 break;
@@ -143,6 +153,8 @@
         switch (mSide) {
             case Gravity.LEFT:
             case Gravity.RIGHT:
+            case Gravity.START:
+            case Gravity.END:
                 return sceneRoot.getWidth();
             default:
                 return sceneRoot.getHeight();
diff --git a/core/java/android/transition/Slide.java b/core/java/android/transition/Slide.java
index ae2e4aa..be1d907 100644
--- a/core/java/android/transition/Slide.java
+++ b/core/java/android/transition/Slide.java
@@ -76,6 +76,20 @@
         }
     };
 
+    private static final CalculateSlide sCalculateStart = new CalculateSlideHorizontal() {
+        @Override
+        public float getGoneX(ViewGroup sceneRoot, View view) {
+            final boolean isRtl = sceneRoot.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+            final float x;
+            if (isRtl) {
+                x = view.getTranslationX() + sceneRoot.getWidth();
+            } else {
+                x = view.getTranslationX() - sceneRoot.getWidth();
+            }
+            return x;
+        }
+    };
+
     private static final CalculateSlide sCalculateTop = new CalculateSlideVertical() {
         @Override
         public float getGoneY(ViewGroup sceneRoot, View view) {
@@ -90,6 +104,20 @@
         }
     };
 
+    private static final CalculateSlide sCalculateEnd = new CalculateSlideHorizontal() {
+        @Override
+        public float getGoneX(ViewGroup sceneRoot, View view) {
+            final boolean isRtl = sceneRoot.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+            final float x;
+            if (isRtl) {
+                x = view.getTranslationX() - sceneRoot.getWidth();
+            } else {
+                x = view.getTranslationX() + sceneRoot.getWidth();
+            }
+            return x;
+        }
+    };
+
     private static final CalculateSlide sCalculateBottom = new CalculateSlideVertical() {
         @Override
         public float getGoneY(ViewGroup sceneRoot, View view) {
@@ -144,7 +172,8 @@
      *
      * @param slideEdge The edge of the scene to use for Views appearing and disappearing. One of
      *                  {@link android.view.Gravity#LEFT}, {@link android.view.Gravity#TOP},
-     *                  {@link android.view.Gravity#RIGHT}, {@link android.view.Gravity#BOTTOM}.
+     *                  {@link android.view.Gravity#RIGHT}, {@link android.view.Gravity#BOTTOM},
+     *                  {@link android.view.Gravity#START}, {@link android.view.Gravity#END}.
      * @attr ref android.R.styleable#Slide_slideEdge
      */
     public void setSlideEdge(int slideEdge) {
@@ -161,6 +190,12 @@
             case Gravity.BOTTOM:
                 mSlideCalculator = sCalculateBottom;
                 break;
+            case Gravity.START:
+                mSlideCalculator = sCalculateStart;
+                break;
+            case Gravity.END:
+                mSlideCalculator = sCalculateEnd;
+                break;
             default:
                 throw new IllegalArgumentException("Invalid slide direction");
         }
@@ -175,7 +210,8 @@
      *
      * @return the edge of the scene to use for Views appearing and disappearing. One of
      *         {@link android.view.Gravity#LEFT}, {@link android.view.Gravity#TOP},
-     *         {@link android.view.Gravity#RIGHT}, {@link android.view.Gravity#BOTTOM}.
+     *         {@link android.view.Gravity#RIGHT}, {@link android.view.Gravity#BOTTOM},
+     *         {@link android.view.Gravity#START}, {@link android.view.Gravity#END}.
      * @attr ref android.R.styleable#Slide_slideEdge
      */
     public int getSlideEdge() {
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index 36bac31..8779229 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -63,6 +63,7 @@
 
     private static final String[] sTransitionProperties = {
             PROPNAME_VISIBILITY,
+            PROPNAME_PARENT,
     };
 
     private static class VisibilityInfo {
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 5579c13..2c8a499 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -274,7 +274,7 @@
     }
 
     private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks) {
-        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
+        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()");
         updateViewTreeDisplayList(view);
 
         if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 77c1d7b..b54d462 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -56,6 +56,7 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.Trace;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
@@ -2400,12 +2401,6 @@
      */
     static final int PFLAG3_NESTED_SCROLLING_ENABLED = 0x80;
 
-    /**
-     * Flag indicating that outline was invalidated and should be rebuilt the next time
-     * the DisplayList is updated.
-     */
-    static final int PFLAG3_OUTLINE_INVALID = 0x100;
-
     /* End of masks for mPrivateFlags3 */
 
     static final int DRAG_MASK = PFLAG2_DRAG_CAN_ACCEPT | PFLAG2_DRAG_HOVERED;
@@ -11277,7 +11272,7 @@
      * @see #setOutlineProvider(ViewOutlineProvider)
      */
     public void invalidateOutline() {
-        mPrivateFlags3 |= PFLAG3_OUTLINE_INVALID;
+        rebuildOutline();
 
         notifySubtreeAccessibilityStateChangedIfNeeded();
         invalidateViewProperty(false, false);
@@ -14411,143 +14406,158 @@
     public void buildDrawingCache(boolean autoScale) {
         if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || (autoScale ?
                 mDrawingCache == null : mUnscaledDrawingCache == null)) {
-            mCachingFailed = false;
+            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+                Trace.traceBegin(Trace.TRACE_TAG_VIEW,
+                        "buildDrawingCache/SW Layer for " + getClass().getSimpleName());
+            }
+            try {
+                buildDrawingCacheImpl(autoScale);
+            } finally {
+                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+            }
+        }
+    }
 
-            int width = mRight - mLeft;
-            int height = mBottom - mTop;
+    /**
+     * private, internal implementation of buildDrawingCache, used to enable tracing
+     */
+    private void buildDrawingCacheImpl(boolean autoScale) {
+        mCachingFailed = false;
 
-            final AttachInfo attachInfo = mAttachInfo;
-            final boolean scalingRequired = attachInfo != null && attachInfo.mScalingRequired;
+        int width = mRight - mLeft;
+        int height = mBottom - mTop;
 
-            if (autoScale && scalingRequired) {
-                width = (int) ((width * attachInfo.mApplicationScale) + 0.5f);
-                height = (int) ((height * attachInfo.mApplicationScale) + 0.5f);
+        final AttachInfo attachInfo = mAttachInfo;
+        final boolean scalingRequired = attachInfo != null && attachInfo.mScalingRequired;
+
+        if (autoScale && scalingRequired) {
+            width = (int) ((width * attachInfo.mApplicationScale) + 0.5f);
+            height = (int) ((height * attachInfo.mApplicationScale) + 0.5f);
+        }
+
+        final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor;
+        final boolean opaque = drawingCacheBackgroundColor != 0 || isOpaque();
+        final boolean use32BitCache = attachInfo != null && attachInfo.mUse32BitDrawingCache;
+
+        final long projectedBitmapSize = width * height * (opaque && !use32BitCache ? 2 : 4);
+        final long drawingCacheSize =
+                ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize();
+        if (width <= 0 || height <= 0 || projectedBitmapSize > drawingCacheSize) {
+            if (width > 0 && height > 0) {
+                Log.w(VIEW_LOG_TAG, "View too large to fit into drawing cache, needs "
+                        + projectedBitmapSize + " bytes, only "
+                        + drawingCacheSize + " available");
+            }
+            destroyDrawingCache();
+            mCachingFailed = true;
+            return;
+        }
+
+        boolean clear = true;
+        Bitmap bitmap = autoScale ? mDrawingCache : mUnscaledDrawingCache;
+
+        if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {
+            Bitmap.Config quality;
+            if (!opaque) {
+                // Never pick ARGB_4444 because it looks awful
+                // Keep the DRAWING_CACHE_QUALITY_LOW flag just in case
+                switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) {
+                    case DRAWING_CACHE_QUALITY_AUTO:
+                    case DRAWING_CACHE_QUALITY_LOW:
+                    case DRAWING_CACHE_QUALITY_HIGH:
+                    default:
+                        quality = Bitmap.Config.ARGB_8888;
+                        break;
+                }
+            } else {
+                // Optimization for translucent windows
+                // If the window is translucent, use a 32 bits bitmap to benefit from memcpy()
+                quality = use32BitCache ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
             }
 
-            final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor;
-            final boolean opaque = drawingCacheBackgroundColor != 0 || isOpaque();
-            final boolean use32BitCache = attachInfo != null && attachInfo.mUse32BitDrawingCache;
+            // Try to cleanup memory
+            if (bitmap != null) bitmap.recycle();
 
-            final long projectedBitmapSize = width * height * (opaque && !use32BitCache ? 2 : 4);
-            final long drawingCacheSize =
-                    ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize();
-            if (width <= 0 || height <= 0 || projectedBitmapSize > drawingCacheSize) {
-                if (width > 0 && height > 0) {
-                    Log.w(VIEW_LOG_TAG, "View too large to fit into drawing cache, needs "
-                            + projectedBitmapSize + " bytes, only "
-                            + drawingCacheSize + " available");
+            try {
+                bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(),
+                        width, height, quality);
+                bitmap.setDensity(getResources().getDisplayMetrics().densityDpi);
+                if (autoScale) {
+                    mDrawingCache = bitmap;
+                } else {
+                    mUnscaledDrawingCache = bitmap;
                 }
-                destroyDrawingCache();
+                if (opaque && use32BitCache) bitmap.setHasAlpha(false);
+            } catch (OutOfMemoryError e) {
+                // If there is not enough memory to create the bitmap cache, just
+                // ignore the issue as bitmap caches are not required to draw the
+                // view hierarchy
+                if (autoScale) {
+                    mDrawingCache = null;
+                } else {
+                    mUnscaledDrawingCache = null;
+                }
                 mCachingFailed = true;
                 return;
             }
 
-            boolean clear = true;
-            Bitmap bitmap = autoScale ? mDrawingCache : mUnscaledDrawingCache;
+            clear = drawingCacheBackgroundColor != 0;
+        }
 
-            if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {
-                Bitmap.Config quality;
-                if (!opaque) {
-                    // Never pick ARGB_4444 because it looks awful
-                    // Keep the DRAWING_CACHE_QUALITY_LOW flag just in case
-                    switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) {
-                        case DRAWING_CACHE_QUALITY_AUTO:
-                        case DRAWING_CACHE_QUALITY_LOW:
-                        case DRAWING_CACHE_QUALITY_HIGH:
-                        default:
-                            quality = Bitmap.Config.ARGB_8888;
-                            break;
-                    }
-                } else {
-                    // Optimization for translucent windows
-                    // If the window is translucent, use a 32 bits bitmap to benefit from memcpy()
-                    quality = use32BitCache ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
-                }
-
-                // Try to cleanup memory
-                if (bitmap != null) bitmap.recycle();
-
-                try {
-                    bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(),
-                            width, height, quality);
-                    bitmap.setDensity(getResources().getDisplayMetrics().densityDpi);
-                    if (autoScale) {
-                        mDrawingCache = bitmap;
-                    } else {
-                        mUnscaledDrawingCache = bitmap;
-                    }
-                    if (opaque && use32BitCache) bitmap.setHasAlpha(false);
-                } catch (OutOfMemoryError e) {
-                    // If there is not enough memory to create the bitmap cache, just
-                    // ignore the issue as bitmap caches are not required to draw the
-                    // view hierarchy
-                    if (autoScale) {
-                        mDrawingCache = null;
-                    } else {
-                        mUnscaledDrawingCache = null;
-                    }
-                    mCachingFailed = true;
-                    return;
-                }
-
-                clear = drawingCacheBackgroundColor != 0;
+        Canvas canvas;
+        if (attachInfo != null) {
+            canvas = attachInfo.mCanvas;
+            if (canvas == null) {
+                canvas = new Canvas();
             }
+            canvas.setBitmap(bitmap);
+            // Temporarily clobber the cached Canvas in case one of our children
+            // is also using a drawing cache. Without this, the children would
+            // steal the canvas by attaching their own bitmap to it and bad, bad
+            // thing would happen (invisible views, corrupted drawings, etc.)
+            attachInfo.mCanvas = null;
+        } else {
+            // This case should hopefully never or seldom happen
+            canvas = new Canvas(bitmap);
+        }
 
-            Canvas canvas;
-            if (attachInfo != null) {
-                canvas = attachInfo.mCanvas;
-                if (canvas == null) {
-                    canvas = new Canvas();
-                }
-                canvas.setBitmap(bitmap);
-                // Temporarily clobber the cached Canvas in case one of our children
-                // is also using a drawing cache. Without this, the children would
-                // steal the canvas by attaching their own bitmap to it and bad, bad
-                // thing would happen (invisible views, corrupted drawings, etc.)
-                attachInfo.mCanvas = null;
-            } else {
-                // This case should hopefully never or seldom happen
-                canvas = new Canvas(bitmap);
+        if (clear) {
+            bitmap.eraseColor(drawingCacheBackgroundColor);
+        }
+
+        computeScroll();
+        final int restoreCount = canvas.save();
+
+        if (autoScale && scalingRequired) {
+            final float scale = attachInfo.mApplicationScale;
+            canvas.scale(scale, scale);
+        }
+
+        canvas.translate(-mScrollX, -mScrollY);
+
+        mPrivateFlags |= PFLAG_DRAWN;
+        if (mAttachInfo == null || !mAttachInfo.mHardwareAccelerated ||
+                mLayerType != LAYER_TYPE_NONE) {
+            mPrivateFlags |= PFLAG_DRAWING_CACHE_VALID;
+        }
+
+        // Fast path for layouts with no backgrounds
+        if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
+            mPrivateFlags &= ~PFLAG_DIRTY_MASK;
+            dispatchDraw(canvas);
+            if (mOverlay != null && !mOverlay.isEmpty()) {
+                mOverlay.getOverlayView().draw(canvas);
             }
+        } else {
+            draw(canvas);
+        }
 
-            if (clear) {
-                bitmap.eraseColor(drawingCacheBackgroundColor);
-            }
+        canvas.restoreToCount(restoreCount);
+        canvas.setBitmap(null);
 
-            computeScroll();
-            final int restoreCount = canvas.save();
-
-            if (autoScale && scalingRequired) {
-                final float scale = attachInfo.mApplicationScale;
-                canvas.scale(scale, scale);
-            }
-
-            canvas.translate(-mScrollX, -mScrollY);
-
-            mPrivateFlags |= PFLAG_DRAWN;
-            if (mAttachInfo == null || !mAttachInfo.mHardwareAccelerated ||
-                    mLayerType != LAYER_TYPE_NONE) {
-                mPrivateFlags |= PFLAG_DRAWING_CACHE_VALID;
-            }
-
-            // Fast path for layouts with no backgrounds
-            if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
-                mPrivateFlags &= ~PFLAG_DIRTY_MASK;
-                dispatchDraw(canvas);
-                if (mOverlay != null && !mOverlay.isEmpty()) {
-                    mOverlay.getOverlayView().draw(canvas);
-                }
-            } else {
-                draw(canvas);
-            }
-
-            canvas.restoreToCount(restoreCount);
-            canvas.setBitmap(null);
-
-            if (attachInfo != null) {
-                // Restore the cached Canvas for our siblings
-                attachInfo.mCanvas = canvas;
-            }
+        if (attachInfo != null) {
+            // Restore the cached Canvas for our siblings
+            attachInfo.mCanvas = canvas;
         }
     }
 
@@ -14774,27 +14784,21 @@
      * this view, to which future drawing operations will be clipped.
      */
     public void setClipBounds(Rect clipBounds) {
+        if (clipBounds == mClipBounds
+                || (clipBounds != null && clipBounds.equals(mClipBounds))) {
+            return;
+        }
         if (clipBounds != null) {
-            if (clipBounds.equals(mClipBounds)) {
-                return;
-            }
             if (mClipBounds == null) {
-                invalidate();
                 mClipBounds = new Rect(clipBounds);
             } else {
-                invalidate(Math.min(mClipBounds.left, clipBounds.left),
-                        Math.min(mClipBounds.top, clipBounds.top),
-                        Math.max(mClipBounds.right, clipBounds.right),
-                        Math.max(mClipBounds.bottom, clipBounds.bottom));
                 mClipBounds.set(clipBounds);
             }
         } else {
-            if (mClipBounds != null) {
-                invalidate();
-                mClipBounds = null;
-            }
+            mClipBounds = null;
         }
         mRenderNode.setClipBounds(mClipBounds);
+        invalidateViewProperty(false, false);
     }
 
     /**
@@ -14873,10 +14877,6 @@
      */
     void setDisplayListProperties(RenderNode renderNode) {
         if (renderNode != null) {
-            if ((mPrivateFlags3 & PFLAG3_OUTLINE_INVALID) != 0) {
-                rebuildOutline();
-                mPrivateFlags3 &= ~PFLAG3_OUTLINE_INVALID;
-            }
             renderNode.setHasOverlappingRendering(hasOverlappingRendering());
             if (mParent instanceof ViewGroup) {
                 renderNode.setClipToBounds(
@@ -15478,7 +15478,7 @@
         if (mBackgroundSizeChanged) {
             background.setBounds(0, 0,  mRight - mLeft, mBottom - mTop);
             mBackgroundSizeChanged = false;
-            mPrivateFlags3 |= PFLAG3_OUTLINE_INVALID;
+            rebuildOutline();
         }
 
         // Attempt to use a display list if requested.
@@ -15486,10 +15486,10 @@
                 && mAttachInfo.mHardwareRenderer != null) {
             mBackgroundRenderNode = getDrawableRenderNode(background, mBackgroundRenderNode);
 
-            final RenderNode displayList = mBackgroundRenderNode;
-            if (displayList != null && displayList.isValid()) {
-                setBackgroundDisplayListProperties(displayList);
-                ((HardwareCanvas) canvas).drawRenderNode(displayList);
+            final RenderNode renderNode = mBackgroundRenderNode;
+            if (renderNode != null && renderNode.isValid()) {
+                setBackgroundRenderNodeProperties(renderNode);
+                ((HardwareCanvas) canvas).drawRenderNode(renderNode);
                 return;
             }
         }
@@ -15505,14 +15505,9 @@
         }
     }
 
-    /**
-     * Set up background drawable display list properties.
-     *
-     * @param displayList Valid display list for the background drawable
-     */
-    private void setBackgroundDisplayListProperties(RenderNode displayList) {
-        displayList.setTranslationX(mScrollX);
-        displayList.setTranslationY(mScrollY);
+    private void setBackgroundRenderNodeProperties(RenderNode renderNode) {
+        renderNode.setTranslationX(mScrollX);
+        renderNode.setTranslationY(mScrollY);
     }
 
     /**
@@ -15861,7 +15856,7 @@
             mOverlay.getOverlayView().setRight(newWidth);
             mOverlay.getOverlayView().setBottom(newHeight);
         }
-        mPrivateFlags3 |= PFLAG3_OUTLINE_INVALID;
+        rebuildOutline();
     }
 
     /**
@@ -15897,8 +15892,7 @@
 
             invalidate(dirty.left + scrollX, dirty.top + scrollY,
                     dirty.right + scrollX, dirty.bottom + scrollY);
-
-            mPrivateFlags3 |= PFLAG3_OUTLINE_INVALID;
+            rebuildOutline();
         }
     }
 
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index bae0b12..1a5ff26 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3534,8 +3534,11 @@
     }
 
     /**
-     * By default, children are clipped to the padding of the ViewGroup. This
-     * allows view groups to override this behavior
+     * Sets whether this ViewGroup will clip its children to its padding, if
+     * padding is present.
+     * <p>
+     * By default, children are clipped to the padding of their parent
+     * Viewgroup. This clipping behavior is only enabled if padding is non-zero.
      *
      * @param clipToPadding true to clip children to the padding of the
      *        group, false otherwise
@@ -3549,7 +3552,11 @@
     }
 
     /**
-     * Check if this ViewGroup is configured to clip child views to its padding.
+     * Returns whether this ViewGroup will clip its children to its padding, if
+     * padding is present.
+     * <p>
+     * By default, children are clipped to the padding of their parent
+     * Viewgroup. This clipping behavior is only enabled if padding is non-zero.
      *
      * @return true if this ViewGroup clips children to its padding, false otherwise
      *
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 82b1073..0d82087 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -118,12 +118,13 @@
 
     private Runnable mSystemPropertyUpdater;
 
-    /** Default token to apply to added views. */
-    private IBinder mDefaultToken;
-
     private WindowManagerGlobal() {
     }
 
+    public static void initialize() {
+        getWindowManagerService();
+    }
+
     public static WindowManagerGlobal getInstance() {
         synchronized (WindowManagerGlobal.class) {
             if (sDefaultWindowManager == null) {
@@ -138,6 +139,12 @@
             if (sWindowManagerService == null) {
                 sWindowManagerService = IWindowManager.Stub.asInterface(
                         ServiceManager.getService("window"));
+                try {
+                    sWindowManagerService = getWindowManagerService();
+                    ValueAnimator.setDurationScale(sWindowManagerService.getCurrentAnimatorScale());
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Failed to get WindowManagerService, cannot set animator scale", e);
+                }
             }
             return sWindowManagerService;
         }
@@ -157,7 +164,6 @@
                                 }
                             },
                             imm.getClient(), imm.getInputContext());
-                    ValueAnimator.setDurationScale(windowManager.getCurrentAnimatorScale());
                 } catch (RemoteException e) {
                     Log.e(TAG, "Failed to open window session", e);
                 }
@@ -172,17 +178,6 @@
         }
     }
 
-    /**
-     * Sets the default token to use in {@link #addView} when no parent window
-     * token is available and no token has been explicitly set in the view's
-     * layout params.
-     *
-     * @param token Default window token to apply to added views.
-     */
-    public void setDefaultToken(IBinder token) {
-        mDefaultToken = token;
-    }
-
     public String[] getViewRootNames() {
         synchronized (mLock) {
             final int numRoots = mRoots.size();
@@ -230,10 +225,6 @@
             }
         }
 
-        if (wparams.token == null && mDefaultToken != null) {
-            wparams.token = mDefaultToken;
-        }
-
         ViewRootImpl root;
         View panelParentView = null;
 
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 52d79f8..98e9f54c 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -16,6 +16,9 @@
 
 package android.view;
 
+import android.annotation.NonNull;
+import android.os.IBinder;
+
 /**
  * Provides low-level communication with the system window manager for
  * operations that are bound to a particular context, display or parent window.
@@ -47,6 +50,8 @@
     private final Display mDisplay;
     private final Window mParentWindow;
 
+    private IBinder mDefaultToken;
+
     public WindowManagerImpl(Display display) {
         this(display, null);
     }
@@ -64,16 +69,43 @@
         return new WindowManagerImpl(display, mParentWindow);
     }
 
+    /**
+     * Sets the window token to assign when none is specified by the client or
+     * available from the parent window.
+     *
+     * @param token The default token to assign.
+     */
+    public void setDefaultToken(IBinder token) {
+        mDefaultToken = token;
+    }
+
     @Override
-    public void addView(View view, ViewGroup.LayoutParams params) {
+    public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
+        applyDefaultToken(params);
         mGlobal.addView(view, params, mDisplay, mParentWindow);
     }
 
     @Override
-    public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
+    public void updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
+        applyDefaultToken(params);
         mGlobal.updateViewLayout(view, params);
     }
 
+    private void applyDefaultToken(@NonNull ViewGroup.LayoutParams params) {
+        // Only use the default token if we don't have a parent window.
+        if (mDefaultToken != null && mParentWindow == null) {
+            if (!(params instanceof WindowManager.LayoutParams)) {
+                throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
+            }
+
+            // Only use the default token if we don't already have a token.
+            final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
+            if (wparams.token == null) {
+                wparams.token = mDefaultToken;
+            }
+        }
+    }
+
     @Override
     public void removeView(View view) {
         mGlobal.removeView(view, false);
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index f380d68..ed59ea6 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -17,42 +17,24 @@
 package android.widget;
 
 import android.annotation.Widget;
-import android.app.Service;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
-import android.database.DataSetObserver;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Paint.Align;
-import android.graphics.Paint.Style;
-import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
 import android.util.AttributeSet;
-import android.util.DisplayMetrics;
 import android.util.Log;
-import android.util.TypedValue;
-import android.view.GestureDetector;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
-import android.widget.AbsListView.OnScrollListener;
 
 import com.android.internal.R;
 
+import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Locale;
 import java.util.TimeZone;
 
-import libcore.icu.LocaleData;
-
 /**
  * This class is a calendar widget for displaying and selecting dates. The range
  * of dates supported by this calendar is configurable. A user can select a date
@@ -74,13 +56,12 @@
  */
 @Widget
 public class CalendarView extends FrameLayout {
+    private static final String LOG_TAG = "CalendarView";
 
-    /**
-     * Tag for logging.
-     */
-    private static final String LOG_TAG = CalendarView.class.getSimpleName();
+    private static final int MODE_HOLO = 0;
+    private static final int MODE_MATERIAL = 1;
 
-    private CalendarViewDelegate mDelegate;
+    private final CalendarViewDelegate mDelegate;
 
     /**
      * The callback used to indicate the user changes the date.
@@ -113,7 +94,23 @@
     public CalendarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
 
-        mDelegate = new LegacyCalendarViewDelegate(this, context, attrs, defStyleAttr, defStyleRes);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.CalendarView, defStyleAttr, defStyleRes);
+        final int mode = a.getInt(R.styleable.CalendarView_calendarViewMode, MODE_HOLO);
+        a.recycle();
+
+        switch (mode) {
+            case MODE_HOLO:
+                mDelegate = new CalendarViewLegacyDelegate(
+                        this, context, attrs, defStyleAttr, defStyleRes);
+                break;
+            case MODE_MATERIAL:
+                mDelegate = new CalendarViewMaterialDelegate(
+                        this, context, attrs, defStyleAttr, defStyleRes);
+                break;
+            default:
+                throw new IllegalArgumentException("invalid calendarViewMode attribute");
+        }
     }
 
     /**
@@ -326,16 +323,6 @@
         return mDelegate.getDateTextAppearance();
     }
 
-    @Override
-    public void setEnabled(boolean enabled) {
-        mDelegate.setEnabled(enabled);
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return mDelegate.isEnabled();
-    }
-
     /**
      * Gets the minimal date supported by this {@link CalendarView} in milliseconds
      * since January 1, 1970 00:00:00 in {@link TimeZone#getDefault()} time
@@ -516,14 +503,12 @@
 
     @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-        mDelegate.onInitializeAccessibilityEvent(event);
+        event.setClassName(CalendarView.class.getName());
     }
 
     @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        mDelegate.onInitializeAccessibilityNodeInfo(info);
+        info.setClassName(CalendarView.class.getName());
     }
 
     /**
@@ -560,9 +545,6 @@
         void setDateTextAppearance(int resourceId);
         int getDateTextAppearance();
 
-        void setEnabled(boolean enabled);
-        boolean isEnabled();
-
         void setMinDate(long minDate);
         long getMinDate();
 
@@ -582,21 +564,26 @@
         void setOnDateChangeListener(OnDateChangeListener listener);
 
         void onConfigurationChanged(Configuration newConfig);
-        void onInitializeAccessibilityEvent(AccessibilityEvent event);
-        void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info);
     }
 
     /**
      * An abstract class which can be used as a start for CalendarView implementations
      */
     abstract static class AbstractCalendarViewDelegate implements CalendarViewDelegate {
-        // The delegator
+        /** String for parsing dates. */
+        private static final String DATE_FORMAT = "MM/dd/yyyy";
+
+        /** The default minimal date. */
+        protected static final String DEFAULT_MIN_DATE = "01/01/1900";
+
+        /** The default maximal date. */
+        protected static final String DEFAULT_MAX_DATE = "01/01/2100";
+
+        /** Date format for parsing dates. */
+        protected static final DateFormat DATE_FORMATTER = new SimpleDateFormat(DATE_FORMAT);
+
         protected CalendarView mDelegator;
-
-        // The context
         protected Context mContext;
-
-        // The current locale
         protected Locale mCurrentLocale;
 
         AbstractCalendarViewDelegate(CalendarView delegator, Context context) {
@@ -613,830 +600,6 @@
             }
             mCurrentLocale = locale;
         }
-    }
-
-    /**
-     * A delegate implementing the legacy CalendarView
-     */
-    private static class LegacyCalendarViewDelegate extends AbstractCalendarViewDelegate {
-
-        /**
-         * Default value whether to show week number.
-         */
-        private static final boolean DEFAULT_SHOW_WEEK_NUMBER = true;
-
-        /**
-         * The number of milliseconds in a day.e
-         */
-        private static final long MILLIS_IN_DAY = 86400000L;
-
-        /**
-         * The number of day in a week.
-         */
-        private static final int DAYS_PER_WEEK = 7;
-
-        /**
-         * The number of milliseconds in a week.
-         */
-        private static final long MILLIS_IN_WEEK = DAYS_PER_WEEK * MILLIS_IN_DAY;
-
-        /**
-         * Affects when the month selection will change while scrolling upe
-         */
-        private static final int SCROLL_HYST_WEEKS = 2;
-
-        /**
-         * How long the GoTo fling animation should last.
-         */
-        private static final int GOTO_SCROLL_DURATION = 1000;
-
-        /**
-         * The duration of the adjustment upon a user scroll in milliseconds.
-         */
-        private static final int ADJUSTMENT_SCROLL_DURATION = 500;
-
-        /**
-         * How long to wait after receiving an onScrollStateChanged notification
-         * before acting on it.
-         */
-        private static final int SCROLL_CHANGE_DELAY = 40;
-
-        /**
-         * String for parsing dates.
-         */
-        private static final String DATE_FORMAT = "MM/dd/yyyy";
-
-        /**
-         * The default minimal date.
-         */
-        private static final String DEFAULT_MIN_DATE = "01/01/1900";
-
-        /**
-         * The default maximal date.
-         */
-        private static final String DEFAULT_MAX_DATE = "01/01/2100";
-
-        private static final int DEFAULT_SHOWN_WEEK_COUNT = 6;
-
-        private static final int DEFAULT_DATE_TEXT_SIZE = 14;
-
-        private static final int UNSCALED_SELECTED_DATE_VERTICAL_BAR_WIDTH = 6;
-
-        private static final int UNSCALED_WEEK_MIN_VISIBLE_HEIGHT = 12;
-
-        private static final int UNSCALED_LIST_SCROLL_TOP_OFFSET = 2;
-
-        private static final int UNSCALED_BOTTOM_BUFFER = 20;
-
-        private static final int UNSCALED_WEEK_SEPARATOR_LINE_WIDTH = 1;
-
-        private static final int DEFAULT_WEEK_DAY_TEXT_APPEARANCE_RES_ID = -1;
-
-        private final int mWeekSeperatorLineWidth;
-
-        private int mDateTextSize;
-
-        private Drawable mSelectedDateVerticalBar;
-
-        private final int mSelectedDateVerticalBarWidth;
-
-        private int mSelectedWeekBackgroundColor;
-
-        private int mFocusedMonthDateColor;
-
-        private int mUnfocusedMonthDateColor;
-
-        private int mWeekSeparatorLineColor;
-
-        private int mWeekNumberColor;
-
-        private int mWeekDayTextAppearanceResId;
-
-        private int mDateTextAppearanceResId;
-
-        /**
-         * The top offset of the weeks list.
-         */
-        private int mListScrollTopOffset = 2;
-
-        /**
-         * The visible height of a week view.
-         */
-        private int mWeekMinVisibleHeight = 12;
-
-        /**
-         * The visible height of a week view.
-         */
-        private int mBottomBuffer = 20;
-
-        /**
-         * The number of shown weeks.
-         */
-        private int mShownWeekCount;
-
-        /**
-         * Flag whether to show the week number.
-         */
-        private boolean mShowWeekNumber;
-
-        /**
-         * The number of day per week to be shown.
-         */
-        private int mDaysPerWeek = 7;
-
-        /**
-         * The friction of the week list while flinging.
-         */
-        private float mFriction = .05f;
-
-        /**
-         * Scale for adjusting velocity of the week list while flinging.
-         */
-        private float mVelocityScale = 0.333f;
-
-        /**
-         * The adapter for the weeks list.
-         */
-        private WeeksAdapter mAdapter;
-
-        /**
-         * The weeks list.
-         */
-        private ListView mListView;
-
-        /**
-         * The name of the month to display.
-         */
-        private TextView mMonthName;
-
-        /**
-         * The header with week day names.
-         */
-        private ViewGroup mDayNamesHeader;
-
-        /**
-         * Cached abbreviations for day of week names.
-         */
-        private String[] mDayNamesShort;
-
-        /**
-         * Cached full-length day of week names.
-         */
-        private String[] mDayNamesLong;
-
-        /**
-         * The first day of the week.
-         */
-        private int mFirstDayOfWeek;
-
-        /**
-         * Which month should be displayed/highlighted [0-11].
-         */
-        private int mCurrentMonthDisplayed = -1;
-
-        /**
-         * Used for tracking during a scroll.
-         */
-        private long mPreviousScrollPosition;
-
-        /**
-         * Used for tracking which direction the view is scrolling.
-         */
-        private boolean mIsScrollingUp = false;
-
-        /**
-         * The previous scroll state of the weeks ListView.
-         */
-        private int mPreviousScrollState = OnScrollListener.SCROLL_STATE_IDLE;
-
-        /**
-         * The current scroll state of the weeks ListView.
-         */
-        private int mCurrentScrollState = OnScrollListener.SCROLL_STATE_IDLE;
-
-        /**
-         * Listener for changes in the selected day.
-         */
-        private OnDateChangeListener mOnDateChangeListener;
-
-        /**
-         * Command for adjusting the position after a scroll/fling.
-         */
-        private ScrollStateRunnable mScrollStateChangedRunnable = new ScrollStateRunnable();
-
-        /**
-         * Temporary instance to avoid multiple instantiations.
-         */
-        private Calendar mTempDate;
-
-        /**
-         * The first day of the focused month.
-         */
-        private Calendar mFirstDayOfMonth;
-
-        /**
-         * The start date of the range supported by this picker.
-         */
-        private Calendar mMinDate;
-
-        /**
-         * The end date of the range supported by this picker.
-         */
-        private Calendar mMaxDate;
-
-        /**
-         * Date format for parsing dates.
-         */
-        private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT);
-
-        LegacyCalendarViewDelegate(CalendarView delegator, Context context, AttributeSet attrs,
-                                   int defStyleAttr, int defStyleRes) {
-            super(delegator, context);
-
-            // initialization based on locale
-            setCurrentLocale(Locale.getDefault());
-
-            TypedArray attributesArray = context.obtainStyledAttributes(attrs,
-                    R.styleable.CalendarView, defStyleAttr, defStyleRes);
-            mShowWeekNumber = attributesArray.getBoolean(R.styleable.CalendarView_showWeekNumber,
-                    DEFAULT_SHOW_WEEK_NUMBER);
-            mFirstDayOfWeek = attributesArray.getInt(R.styleable.CalendarView_firstDayOfWeek,
-                    LocaleData.get(Locale.getDefault()).firstDayOfWeek);
-            String minDate = attributesArray.getString(R.styleable.CalendarView_minDate);
-            if (TextUtils.isEmpty(minDate) || !parseDate(minDate, mMinDate)) {
-                parseDate(DEFAULT_MIN_DATE, mMinDate);
-            }
-            String maxDate = attributesArray.getString(R.styleable.CalendarView_maxDate);
-            if (TextUtils.isEmpty(maxDate) || !parseDate(maxDate, mMaxDate)) {
-                parseDate(DEFAULT_MAX_DATE, mMaxDate);
-            }
-            if (mMaxDate.before(mMinDate)) {
-                throw new IllegalArgumentException("Max date cannot be before min date.");
-            }
-            mShownWeekCount = attributesArray.getInt(R.styleable.CalendarView_shownWeekCount,
-                    DEFAULT_SHOWN_WEEK_COUNT);
-            mSelectedWeekBackgroundColor = attributesArray.getColor(
-                    R.styleable.CalendarView_selectedWeekBackgroundColor, 0);
-            mFocusedMonthDateColor = attributesArray.getColor(
-                    R.styleable.CalendarView_focusedMonthDateColor, 0);
-            mUnfocusedMonthDateColor = attributesArray.getColor(
-                    R.styleable.CalendarView_unfocusedMonthDateColor, 0);
-            mWeekSeparatorLineColor = attributesArray.getColor(
-                    R.styleable.CalendarView_weekSeparatorLineColor, 0);
-            mWeekNumberColor = attributesArray.getColor(R.styleable.CalendarView_weekNumberColor, 0);
-            mSelectedDateVerticalBar = attributesArray.getDrawable(
-                    R.styleable.CalendarView_selectedDateVerticalBar);
-
-            mDateTextAppearanceResId = attributesArray.getResourceId(
-                    R.styleable.CalendarView_dateTextAppearance, R.style.TextAppearance_Small);
-            updateDateTextSize();
-
-            mWeekDayTextAppearanceResId = attributesArray.getResourceId(
-                    R.styleable.CalendarView_weekDayTextAppearance,
-                    DEFAULT_WEEK_DAY_TEXT_APPEARANCE_RES_ID);
-            attributesArray.recycle();
-
-            DisplayMetrics displayMetrics = mDelegator.getResources().getDisplayMetrics();
-            mWeekMinVisibleHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                    UNSCALED_WEEK_MIN_VISIBLE_HEIGHT, displayMetrics);
-            mListScrollTopOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                    UNSCALED_LIST_SCROLL_TOP_OFFSET, displayMetrics);
-            mBottomBuffer = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                    UNSCALED_BOTTOM_BUFFER, displayMetrics);
-            mSelectedDateVerticalBarWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                    UNSCALED_SELECTED_DATE_VERTICAL_BAR_WIDTH, displayMetrics);
-            mWeekSeperatorLineWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                    UNSCALED_WEEK_SEPARATOR_LINE_WIDTH, displayMetrics);
-
-            LayoutInflater layoutInflater = (LayoutInflater) mContext
-                    .getSystemService(Service.LAYOUT_INFLATER_SERVICE);
-            View content = layoutInflater.inflate(R.layout.calendar_view, null, false);
-            mDelegator.addView(content);
-
-            mListView = (ListView) mDelegator.findViewById(R.id.list);
-            mDayNamesHeader = (ViewGroup) content.findViewById(com.android.internal.R.id.day_names);
-            mMonthName = (TextView) content.findViewById(com.android.internal.R.id.month_name);
-
-            setUpHeader();
-            setUpListView();
-            setUpAdapter();
-
-            // go to today or whichever is close to today min or max date
-            mTempDate.setTimeInMillis(System.currentTimeMillis());
-            if (mTempDate.before(mMinDate)) {
-                goTo(mMinDate, false, true, true);
-            } else if (mMaxDate.before(mTempDate)) {
-                goTo(mMaxDate, false, true, true);
-            } else {
-                goTo(mTempDate, false, true, true);
-            }
-
-            mDelegator.invalidate();
-        }
-
-        @Override
-        public void setShownWeekCount(int count) {
-            if (mShownWeekCount != count) {
-                mShownWeekCount = count;
-                mDelegator.invalidate();
-            }
-        }
-
-        @Override
-        public int getShownWeekCount() {
-            return mShownWeekCount;
-        }
-
-        @Override
-        public void setSelectedWeekBackgroundColor(int color) {
-            if (mSelectedWeekBackgroundColor != color) {
-                mSelectedWeekBackgroundColor = color;
-                final int childCount = mListView.getChildCount();
-                for (int i = 0; i < childCount; i++) {
-                    WeekView weekView = (WeekView) mListView.getChildAt(i);
-                    if (weekView.mHasSelectedDay) {
-                        weekView.invalidate();
-                    }
-                }
-            }
-        }
-
-        @Override
-        public int getSelectedWeekBackgroundColor() {
-            return mSelectedWeekBackgroundColor;
-        }
-
-        @Override
-        public void setFocusedMonthDateColor(int color) {
-            if (mFocusedMonthDateColor != color) {
-                mFocusedMonthDateColor = color;
-                final int childCount = mListView.getChildCount();
-                for (int i = 0; i < childCount; i++) {
-                    WeekView weekView = (WeekView) mListView.getChildAt(i);
-                    if (weekView.mHasFocusedDay) {
-                        weekView.invalidate();
-                    }
-                }
-            }
-        }
-
-        @Override
-        public int getFocusedMonthDateColor() {
-            return mFocusedMonthDateColor;
-        }
-
-        @Override
-        public void setUnfocusedMonthDateColor(int color) {
-            if (mUnfocusedMonthDateColor != color) {
-                mUnfocusedMonthDateColor = color;
-                final int childCount = mListView.getChildCount();
-                for (int i = 0; i < childCount; i++) {
-                    WeekView weekView = (WeekView) mListView.getChildAt(i);
-                    if (weekView.mHasUnfocusedDay) {
-                        weekView.invalidate();
-                    }
-                }
-            }
-        }
-
-        @Override
-        public int getUnfocusedMonthDateColor() {
-            return mFocusedMonthDateColor;
-        }
-
-        @Override
-        public void setWeekNumberColor(int color) {
-            if (mWeekNumberColor != color) {
-                mWeekNumberColor = color;
-                if (mShowWeekNumber) {
-                    invalidateAllWeekViews();
-                }
-            }
-        }
-
-        @Override
-        public int getWeekNumberColor() {
-            return mWeekNumberColor;
-        }
-
-        @Override
-        public void setWeekSeparatorLineColor(int color) {
-            if (mWeekSeparatorLineColor != color) {
-                mWeekSeparatorLineColor = color;
-                invalidateAllWeekViews();
-            }
-        }
-
-        @Override
-        public int getWeekSeparatorLineColor() {
-            return mWeekSeparatorLineColor;
-        }
-
-        @Override
-        public void setSelectedDateVerticalBar(int resourceId) {
-            Drawable drawable = mDelegator.getContext().getDrawable(resourceId);
-            setSelectedDateVerticalBar(drawable);
-        }
-
-        @Override
-        public void setSelectedDateVerticalBar(Drawable drawable) {
-            if (mSelectedDateVerticalBar != drawable) {
-                mSelectedDateVerticalBar = drawable;
-                final int childCount = mListView.getChildCount();
-                for (int i = 0; i < childCount; i++) {
-                    WeekView weekView = (WeekView) mListView.getChildAt(i);
-                    if (weekView.mHasSelectedDay) {
-                        weekView.invalidate();
-                    }
-                }
-            }
-        }
-
-        @Override
-        public Drawable getSelectedDateVerticalBar() {
-            return mSelectedDateVerticalBar;
-        }
-
-        @Override
-        public void setWeekDayTextAppearance(int resourceId) {
-            if (mWeekDayTextAppearanceResId != resourceId) {
-                mWeekDayTextAppearanceResId = resourceId;
-                setUpHeader();
-            }
-        }
-
-        @Override
-        public int getWeekDayTextAppearance() {
-            return mWeekDayTextAppearanceResId;
-        }
-
-        @Override
-        public void setDateTextAppearance(int resourceId) {
-            if (mDateTextAppearanceResId != resourceId) {
-                mDateTextAppearanceResId = resourceId;
-                updateDateTextSize();
-                invalidateAllWeekViews();
-            }
-        }
-
-        @Override
-        public int getDateTextAppearance() {
-            return mDateTextAppearanceResId;
-        }
-
-        @Override
-        public void setEnabled(boolean enabled) {
-            mListView.setEnabled(enabled);
-        }
-
-        @Override
-        public boolean isEnabled() {
-            return mListView.isEnabled();
-        }
-
-        @Override
-        public void setMinDate(long minDate) {
-            mTempDate.setTimeInMillis(minDate);
-            if (isSameDate(mTempDate, mMinDate)) {
-                return;
-            }
-            mMinDate.setTimeInMillis(minDate);
-            // make sure the current date is not earlier than
-            // the new min date since the latter is used for
-            // calculating the indices in the adapter thus
-            // avoiding out of bounds error
-            Calendar date = mAdapter.mSelectedDate;
-            if (date.before(mMinDate)) {
-                mAdapter.setSelectedDay(mMinDate);
-            }
-            // reinitialize the adapter since its range depends on min date
-            mAdapter.init();
-            if (date.before(mMinDate)) {
-                setDate(mTempDate.getTimeInMillis());
-            } else {
-                // we go to the current date to force the ListView to query its
-                // adapter for the shown views since we have changed the adapter
-                // range and the base from which the later calculates item indices
-                // note that calling setDate will not work since the date is the same
-                goTo(date, false, true, false);
-            }
-        }
-
-        @Override
-        public long getMinDate() {
-            return mMinDate.getTimeInMillis();
-        }
-
-        @Override
-        public void setMaxDate(long maxDate) {
-            mTempDate.setTimeInMillis(maxDate);
-            if (isSameDate(mTempDate, mMaxDate)) {
-                return;
-            }
-            mMaxDate.setTimeInMillis(maxDate);
-            // reinitialize the adapter since its range depends on max date
-            mAdapter.init();
-            Calendar date = mAdapter.mSelectedDate;
-            if (date.after(mMaxDate)) {
-                setDate(mMaxDate.getTimeInMillis());
-            } else {
-                // we go to the current date to force the ListView to query its
-                // adapter for the shown views since we have changed the adapter
-                // range and the base from which the later calculates item indices
-                // note that calling setDate will not work since the date is the same
-                goTo(date, false, true, false);
-            }
-        }
-
-        @Override
-        public long getMaxDate() {
-            return mMaxDate.getTimeInMillis();
-        }
-
-        @Override
-        public void setShowWeekNumber(boolean showWeekNumber) {
-            if (mShowWeekNumber == showWeekNumber) {
-                return;
-            }
-            mShowWeekNumber = showWeekNumber;
-            mAdapter.notifyDataSetChanged();
-            setUpHeader();
-        }
-
-        @Override
-        public boolean getShowWeekNumber() {
-            return mShowWeekNumber;
-        }
-
-        @Override
-        public void setFirstDayOfWeek(int firstDayOfWeek) {
-            if (mFirstDayOfWeek == firstDayOfWeek) {
-                return;
-            }
-            mFirstDayOfWeek = firstDayOfWeek;
-            mAdapter.init();
-            mAdapter.notifyDataSetChanged();
-            setUpHeader();
-        }
-
-        @Override
-        public int getFirstDayOfWeek() {
-            return mFirstDayOfWeek;
-        }
-
-        @Override
-        public void setDate(long date) {
-            setDate(date, false, false);
-        }
-
-        @Override
-        public void setDate(long date, boolean animate, boolean center) {
-            mTempDate.setTimeInMillis(date);
-            if (isSameDate(mTempDate, mAdapter.mSelectedDate)) {
-                return;
-            }
-            goTo(mTempDate, animate, true, center);
-        }
-
-        @Override
-        public long getDate() {
-            return mAdapter.mSelectedDate.getTimeInMillis();
-        }
-
-        @Override
-        public void setOnDateChangeListener(OnDateChangeListener listener) {
-            mOnDateChangeListener = listener;
-        }
-
-        @Override
-        public void onConfigurationChanged(Configuration newConfig) {
-            setCurrentLocale(newConfig.locale);
-        }
-
-        @Override
-        public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-            event.setClassName(CalendarView.class.getName());
-        }
-
-        @Override
-        public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-            info.setClassName(CalendarView.class.getName());
-        }
-
-        /**
-         * Sets the current locale.
-         *
-         * @param locale The current locale.
-         */
-        @Override
-        protected void setCurrentLocale(Locale locale) {
-            super.setCurrentLocale(locale);
-
-            mTempDate = getCalendarForLocale(mTempDate, locale);
-            mFirstDayOfMonth = getCalendarForLocale(mFirstDayOfMonth, locale);
-            mMinDate = getCalendarForLocale(mMinDate, locale);
-            mMaxDate = getCalendarForLocale(mMaxDate, locale);
-        }
-        private void updateDateTextSize() {
-            TypedArray dateTextAppearance = mDelegator.getContext().obtainStyledAttributes(
-                    mDateTextAppearanceResId, R.styleable.TextAppearance);
-            mDateTextSize = dateTextAppearance.getDimensionPixelSize(
-                    R.styleable.TextAppearance_textSize, DEFAULT_DATE_TEXT_SIZE);
-            dateTextAppearance.recycle();
-        }
-
-        /**
-         * Invalidates all week views.
-         */
-        private void invalidateAllWeekViews() {
-            final int childCount = mListView.getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                View view = mListView.getChildAt(i);
-                view.invalidate();
-            }
-        }
-
-        /**
-         * Gets a calendar for locale bootstrapped with the value of a given calendar.
-         *
-         * @param oldCalendar The old calendar.
-         * @param locale The locale.
-         */
-        private static Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
-            if (oldCalendar == null) {
-                return Calendar.getInstance(locale);
-            } else {
-                final long currentTimeMillis = oldCalendar.getTimeInMillis();
-                Calendar newCalendar = Calendar.getInstance(locale);
-                newCalendar.setTimeInMillis(currentTimeMillis);
-                return newCalendar;
-            }
-        }
-
-        /**
-         * @return True if the <code>firstDate</code> is the same as the <code>
-         * secondDate</code>.
-         */
-        private static boolean isSameDate(Calendar firstDate, Calendar secondDate) {
-            return (firstDate.get(Calendar.DAY_OF_YEAR) == secondDate.get(Calendar.DAY_OF_YEAR)
-                    && firstDate.get(Calendar.YEAR) == secondDate.get(Calendar.YEAR));
-        }
-
-        /**
-         * Creates a new adapter if necessary and sets up its parameters.
-         */
-        private void setUpAdapter() {
-            if (mAdapter == null) {
-                mAdapter = new WeeksAdapter(mContext);
-                mAdapter.registerDataSetObserver(new DataSetObserver() {
-                    @Override
-                    public void onChanged() {
-                        if (mOnDateChangeListener != null) {
-                            Calendar selectedDay = mAdapter.getSelectedDay();
-                            mOnDateChangeListener.onSelectedDayChange(mDelegator,
-                                    selectedDay.get(Calendar.YEAR),
-                                    selectedDay.get(Calendar.MONTH),
-                                    selectedDay.get(Calendar.DAY_OF_MONTH));
-                        }
-                    }
-                });
-                mListView.setAdapter(mAdapter);
-            }
-
-            // refresh the view with the new parameters
-            mAdapter.notifyDataSetChanged();
-        }
-
-        /**
-         * Sets up the strings to be used by the header.
-         */
-        private void setUpHeader() {
-            mDayNamesShort = new String[mDaysPerWeek];
-            mDayNamesLong = new String[mDaysPerWeek];
-            for (int i = mFirstDayOfWeek, count = mFirstDayOfWeek + mDaysPerWeek; i < count; i++) {
-                int calendarDay = (i > Calendar.SATURDAY) ? i - Calendar.SATURDAY : i;
-                mDayNamesShort[i - mFirstDayOfWeek] = DateUtils.getDayOfWeekString(calendarDay,
-                        DateUtils.LENGTH_SHORTEST);
-                mDayNamesLong[i - mFirstDayOfWeek] = DateUtils.getDayOfWeekString(calendarDay,
-                        DateUtils.LENGTH_LONG);
-            }
-
-            TextView label = (TextView) mDayNamesHeader.getChildAt(0);
-            if (mShowWeekNumber) {
-                label.setVisibility(View.VISIBLE);
-            } else {
-                label.setVisibility(View.GONE);
-            }
-            for (int i = 1, count = mDayNamesHeader.getChildCount(); i < count; i++) {
-                label = (TextView) mDayNamesHeader.getChildAt(i);
-                if (mWeekDayTextAppearanceResId > -1) {
-                    label.setTextAppearance(mContext, mWeekDayTextAppearanceResId);
-                }
-                if (i < mDaysPerWeek + 1) {
-                    label.setText(mDayNamesShort[i - 1]);
-                    label.setContentDescription(mDayNamesLong[i - 1]);
-                    label.setVisibility(View.VISIBLE);
-                } else {
-                    label.setVisibility(View.GONE);
-                }
-            }
-            mDayNamesHeader.invalidate();
-        }
-
-        /**
-         * Sets all the required fields for the list view.
-         */
-        private void setUpListView() {
-            // Configure the listview
-            mListView.setDivider(null);
-            mListView.setItemsCanFocus(true);
-            mListView.setVerticalScrollBarEnabled(false);
-            mListView.setOnScrollListener(new OnScrollListener() {
-                public void onScrollStateChanged(AbsListView view, int scrollState) {
-                    LegacyCalendarViewDelegate.this.onScrollStateChanged(view, scrollState);
-                }
-
-                public void onScroll(
-                        AbsListView view, int firstVisibleItem, int visibleItemCount,
-                        int totalItemCount) {
-                    LegacyCalendarViewDelegate.this.onScroll(view, firstVisibleItem,
-                            visibleItemCount, totalItemCount);
-                }
-            });
-            // Make the scrolling behavior nicer
-            mListView.setFriction(mFriction);
-            mListView.setVelocityScale(mVelocityScale);
-        }
-
-        /**
-         * This moves to the specified time in the view. If the time is not already
-         * in range it will move the list so that the first of the month containing
-         * the time is at the top of the view. If the new time is already in view
-         * the list will not be scrolled unless forceScroll is true. This time may
-         * optionally be highlighted as selected as well.
-         *
-         * @param date The time to move to.
-         * @param animate Whether to scroll to the given time or just redraw at the
-         *            new location.
-         * @param setSelected Whether to set the given time as selected.
-         * @param forceScroll Whether to recenter even if the time is already
-         *            visible.
-         *
-         * @throws IllegalArgumentException of the provided date is before the
-         *        range start of after the range end.
-         */
-        private void goTo(Calendar date, boolean animate, boolean setSelected,
-                boolean forceScroll) {
-            if (date.before(mMinDate) || date.after(mMaxDate)) {
-                throw new IllegalArgumentException("Time not between " + mMinDate.getTime()
-                        + " and " + mMaxDate.getTime());
-            }
-            // Find the first and last entirely visible weeks
-            int firstFullyVisiblePosition = mListView.getFirstVisiblePosition();
-            View firstChild = mListView.getChildAt(0);
-            if (firstChild != null && firstChild.getTop() < 0) {
-                firstFullyVisiblePosition++;
-            }
-            int lastFullyVisiblePosition = firstFullyVisiblePosition + mShownWeekCount - 1;
-            if (firstChild != null && firstChild.getTop() > mBottomBuffer) {
-                lastFullyVisiblePosition--;
-            }
-            if (setSelected) {
-                mAdapter.setSelectedDay(date);
-            }
-            // Get the week we're going to
-            int position = getWeeksSinceMinDate(date);
-
-            // Check if the selected day is now outside of our visible range
-            // and if so scroll to the month that contains it
-            if (position < firstFullyVisiblePosition || position > lastFullyVisiblePosition
-                    || forceScroll) {
-                mFirstDayOfMonth.setTimeInMillis(date.getTimeInMillis());
-                mFirstDayOfMonth.set(Calendar.DAY_OF_MONTH, 1);
-
-                setMonthDisplayed(mFirstDayOfMonth);
-
-                // the earliest time we can scroll to is the min date
-                if (mFirstDayOfMonth.before(mMinDate)) {
-                    position = 0;
-                } else {
-                    position = getWeeksSinceMinDate(mFirstDayOfMonth);
-                }
-
-                mPreviousScrollState = OnScrollListener.SCROLL_STATE_FLING;
-                if (animate) {
-                    mListView.smoothScrollToPositionFromTop(position, mListScrollTopOffset,
-                            GOTO_SCROLL_DURATION);
-                } else {
-                    mListView.setSelectionFromTop(position, mListScrollTopOffset);
-                    // Perform any after scroll operations that are needed
-                    onScrollStateChanged(mListView, OnScrollListener.SCROLL_STATE_IDLE);
-                }
-            } else if (setSelected) {
-                // Otherwise just set the selection
-                setMonthDisplayed(date);
-            }
-        }
 
         /**
          * Parses the given <code>date</code> and in case of success sets
@@ -1444,718 +607,15 @@
          *
          * @return True if the date was parsed.
          */
-        private boolean parseDate(String date, Calendar outDate) {
+        protected boolean parseDate(String date, Calendar outDate) {
             try {
-                outDate.setTime(mDateFormat.parse(date));
+                outDate.setTime(DATE_FORMATTER.parse(date));
                 return true;
             } catch (ParseException e) {
                 Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT);
                 return false;
             }
         }
-
-        /**
-         * Called when a <code>view</code> transitions to a new <code>scrollState
-         * </code>.
-         */
-        private void onScrollStateChanged(AbsListView view, int scrollState) {
-            mScrollStateChangedRunnable.doScrollStateChange(view, scrollState);
-        }
-
-        /**
-         * Updates the title and selected month if the <code>view</code> has moved to a new
-         * month.
-         */
-        private void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
-                              int totalItemCount) {
-            WeekView child = (WeekView) view.getChildAt(0);
-            if (child == null) {
-                return;
-            }
-
-            // Figure out where we are
-            long currScroll =
-                    view.getFirstVisiblePosition() * child.getHeight() - child.getBottom();
-
-            // If we have moved since our last call update the direction
-            if (currScroll < mPreviousScrollPosition) {
-                mIsScrollingUp = true;
-            } else if (currScroll > mPreviousScrollPosition) {
-                mIsScrollingUp = false;
-            } else {
-                return;
-            }
-
-            // Use some hysteresis for checking which month to highlight. This
-            // causes the month to transition when two full weeks of a month are
-            // visible when scrolling up, and when the first day in a month reaches
-            // the top of the screen when scrolling down.
-            int offset = child.getBottom() < mWeekMinVisibleHeight ? 1 : 0;
-            if (mIsScrollingUp) {
-                child = (WeekView) view.getChildAt(SCROLL_HYST_WEEKS + offset);
-            } else if (offset != 0) {
-                child = (WeekView) view.getChildAt(offset);
-            }
-
-            if (child != null) {
-                // Find out which month we're moving into
-                int month;
-                if (mIsScrollingUp) {
-                    month = child.getMonthOfFirstWeekDay();
-                } else {
-                    month = child.getMonthOfLastWeekDay();
-                }
-
-                // And how it relates to our current highlighted month
-                int monthDiff;
-                if (mCurrentMonthDisplayed == 11 && month == 0) {
-                    monthDiff = 1;
-                } else if (mCurrentMonthDisplayed == 0 && month == 11) {
-                    monthDiff = -1;
-                } else {
-                    monthDiff = month - mCurrentMonthDisplayed;
-                }
-
-                // Only switch months if we're scrolling away from the currently
-                // selected month
-                if ((!mIsScrollingUp && monthDiff > 0) || (mIsScrollingUp && monthDiff < 0)) {
-                    Calendar firstDay = child.getFirstDay();
-                    if (mIsScrollingUp) {
-                        firstDay.add(Calendar.DAY_OF_MONTH, -DAYS_PER_WEEK);
-                    } else {
-                        firstDay.add(Calendar.DAY_OF_MONTH, DAYS_PER_WEEK);
-                    }
-                    setMonthDisplayed(firstDay);
-                }
-            }
-            mPreviousScrollPosition = currScroll;
-            mPreviousScrollState = mCurrentScrollState;
-        }
-
-        /**
-         * Sets the month displayed at the top of this view based on time. Override
-         * to add custom events when the title is changed.
-         *
-         * @param calendar A day in the new focus month.
-         */
-        private void setMonthDisplayed(Calendar calendar) {
-            mCurrentMonthDisplayed = calendar.get(Calendar.MONTH);
-            mAdapter.setFocusMonth(mCurrentMonthDisplayed);
-            final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_MONTH_DAY
-                    | DateUtils.FORMAT_SHOW_YEAR;
-            final long millis = calendar.getTimeInMillis();
-            String newMonthName = DateUtils.formatDateRange(mContext, millis, millis, flags);
-            mMonthName.setText(newMonthName);
-            mMonthName.invalidate();
-        }
-
-        /**
-         * @return Returns the number of weeks between the current <code>date</code>
-         *         and the <code>mMinDate</code>.
-         */
-        private int getWeeksSinceMinDate(Calendar date) {
-            if (date.before(mMinDate)) {
-                throw new IllegalArgumentException("fromDate: " + mMinDate.getTime()
-                        + " does not precede toDate: " + date.getTime());
-            }
-            long endTimeMillis = date.getTimeInMillis()
-                    + date.getTimeZone().getOffset(date.getTimeInMillis());
-            long startTimeMillis = mMinDate.getTimeInMillis()
-                    + mMinDate.getTimeZone().getOffset(mMinDate.getTimeInMillis());
-            long dayOffsetMillis = (mMinDate.get(Calendar.DAY_OF_WEEK) - mFirstDayOfWeek)
-                    * MILLIS_IN_DAY;
-            return (int) ((endTimeMillis - startTimeMillis + dayOffsetMillis) / MILLIS_IN_WEEK);
-        }
-
-        /**
-         * Command responsible for acting upon scroll state changes.
-         */
-        private class ScrollStateRunnable implements Runnable {
-            private AbsListView mView;
-
-            private int mNewState;
-
-            /**
-             * Sets up the runnable with a short delay in case the scroll state
-             * immediately changes again.
-             *
-             * @param view The list view that changed state
-             * @param scrollState The new state it changed to
-             */
-            public void doScrollStateChange(AbsListView view, int scrollState) {
-                mView = view;
-                mNewState = scrollState;
-                mDelegator.removeCallbacks(this);
-                mDelegator.postDelayed(this, SCROLL_CHANGE_DELAY);
-            }
-
-            public void run() {
-                mCurrentScrollState = mNewState;
-                // Fix the position after a scroll or a fling ends
-                if (mNewState == OnScrollListener.SCROLL_STATE_IDLE
-                        && mPreviousScrollState != OnScrollListener.SCROLL_STATE_IDLE) {
-                    View child = mView.getChildAt(0);
-                    if (child == null) {
-                        // The view is no longer visible, just return
-                        return;
-                    }
-                    int dist = child.getBottom() - mListScrollTopOffset;
-                    if (dist > mListScrollTopOffset) {
-                        if (mIsScrollingUp) {
-                            mView.smoothScrollBy(dist - child.getHeight(),
-                                    ADJUSTMENT_SCROLL_DURATION);
-                        } else {
-                            mView.smoothScrollBy(dist, ADJUSTMENT_SCROLL_DURATION);
-                        }
-                    }
-                }
-                mPreviousScrollState = mNewState;
-            }
-        }
-
-        /**
-         * <p>
-         * This is a specialized adapter for creating a list of weeks with
-         * selectable days. It can be configured to display the week number, start
-         * the week on a given day, show a reduced number of days, or display an
-         * arbitrary number of weeks at a time.
-         * </p>
-         */
-        private class WeeksAdapter extends BaseAdapter implements OnTouchListener {
-
-            private int mSelectedWeek;
-
-            private GestureDetector mGestureDetector;
-
-            private int mFocusedMonth;
-
-            private final Calendar mSelectedDate = Calendar.getInstance();
-
-            private int mTotalWeekCount;
-
-            public WeeksAdapter(Context context) {
-                mContext = context;
-                mGestureDetector = new GestureDetector(mContext, new CalendarGestureListener());
-                init();
-            }
-
-            /**
-             * Set up the gesture detector and selected time
-             */
-            private void init() {
-                mSelectedWeek = getWeeksSinceMinDate(mSelectedDate);
-                mTotalWeekCount = getWeeksSinceMinDate(mMaxDate);
-                if (mMinDate.get(Calendar.DAY_OF_WEEK) != mFirstDayOfWeek
-                        || mMaxDate.get(Calendar.DAY_OF_WEEK) != mFirstDayOfWeek) {
-                    mTotalWeekCount++;
-                }
-                notifyDataSetChanged();
-            }
-
-            /**
-             * Updates the selected day and related parameters.
-             *
-             * @param selectedDay The time to highlight
-             */
-            public void setSelectedDay(Calendar selectedDay) {
-                if (selectedDay.get(Calendar.DAY_OF_YEAR) == mSelectedDate.get(Calendar.DAY_OF_YEAR)
-                        && selectedDay.get(Calendar.YEAR) == mSelectedDate.get(Calendar.YEAR)) {
-                    return;
-                }
-                mSelectedDate.setTimeInMillis(selectedDay.getTimeInMillis());
-                mSelectedWeek = getWeeksSinceMinDate(mSelectedDate);
-                mFocusedMonth = mSelectedDate.get(Calendar.MONTH);
-                notifyDataSetChanged();
-            }
-
-            /**
-             * @return The selected day of month.
-             */
-            public Calendar getSelectedDay() {
-                return mSelectedDate;
-            }
-
-            @Override
-            public int getCount() {
-                return mTotalWeekCount;
-            }
-
-            @Override
-            public Object getItem(int position) {
-                return null;
-            }
-
-            @Override
-            public long getItemId(int position) {
-                return position;
-            }
-
-            @Override
-            public View getView(int position, View convertView, ViewGroup parent) {
-                WeekView weekView = null;
-                if (convertView != null) {
-                    weekView = (WeekView) convertView;
-                } else {
-                    weekView = new WeekView(mContext);
-                    android.widget.AbsListView.LayoutParams params =
-                            new android.widget.AbsListView.LayoutParams(LayoutParams.WRAP_CONTENT,
-                                    LayoutParams.WRAP_CONTENT);
-                    weekView.setLayoutParams(params);
-                    weekView.setClickable(true);
-                    weekView.setOnTouchListener(this);
-                }
-
-                int selectedWeekDay = (mSelectedWeek == position) ? mSelectedDate.get(
-                        Calendar.DAY_OF_WEEK) : -1;
-                weekView.init(position, selectedWeekDay, mFocusedMonth);
-
-                return weekView;
-            }
-
-            /**
-             * Changes which month is in focus and updates the view.
-             *
-             * @param month The month to show as in focus [0-11]
-             */
-            public void setFocusMonth(int month) {
-                if (mFocusedMonth == month) {
-                    return;
-                }
-                mFocusedMonth = month;
-                notifyDataSetChanged();
-            }
-
-            @Override
-            public boolean onTouch(View v, MotionEvent event) {
-                if (mListView.isEnabled() && mGestureDetector.onTouchEvent(event)) {
-                    WeekView weekView = (WeekView) v;
-                    // if we cannot find a day for the given location we are done
-                    if (!weekView.getDayFromLocation(event.getX(), mTempDate)) {
-                        return true;
-                    }
-                    // it is possible that the touched day is outside the valid range
-                    // we draw whole weeks but range end can fall not on the week end
-                    if (mTempDate.before(mMinDate) || mTempDate.after(mMaxDate)) {
-                        return true;
-                    }
-                    onDateTapped(mTempDate);
-                    return true;
-                }
-                return false;
-            }
-
-            /**
-             * Maintains the same hour/min/sec but moves the day to the tapped day.
-             *
-             * @param day The day that was tapped
-             */
-            private void onDateTapped(Calendar day) {
-                setSelectedDay(day);
-                setMonthDisplayed(day);
-            }
-
-            /**
-             * This is here so we can identify single tap events and set the
-             * selected day correctly
-             */
-            class CalendarGestureListener extends GestureDetector.SimpleOnGestureListener {
-                @Override
-                public boolean onSingleTapUp(MotionEvent e) {
-                    return true;
-                }
-            }
-        }
-
-        /**
-         * <p>
-         * This is a dynamic view for drawing a single week. It can be configured to
-         * display the week number, start the week on a given day, or show a reduced
-         * number of days. It is intended for use as a single view within a
-         * ListView. See {@link WeeksAdapter} for usage.
-         * </p>
-         */
-        private class WeekView extends View {
-
-            private final Rect mTempRect = new Rect();
-
-            private final Paint mDrawPaint = new Paint();
-
-            private final Paint mMonthNumDrawPaint = new Paint();
-
-            // Cache the number strings so we don't have to recompute them each time
-            private String[] mDayNumbers;
-
-            // Quick lookup for checking which days are in the focus month
-            private boolean[] mFocusDay;
-
-            // Whether this view has a focused day.
-            private boolean mHasFocusedDay;
-
-            // Whether this view has only focused days.
-            private boolean mHasUnfocusedDay;
-
-            // The first day displayed by this item
-            private Calendar mFirstDay;
-
-            // The month of the first day in this week
-            private int mMonthOfFirstWeekDay = -1;
-
-            // The month of the last day in this week
-            private int mLastWeekDayMonth = -1;
-
-            // The position of this week, equivalent to weeks since the week of Jan
-            // 1st, 1900
-            private int mWeek = -1;
-
-            // Quick reference to the width of this view, matches parent
-            private int mWidth;
-
-            // The height this view should draw at in pixels, set by height param
-            private int mHeight;
-
-            // If this view contains the selected day
-            private boolean mHasSelectedDay = false;
-
-            // Which day is selected [0-6] or -1 if no day is selected
-            private int mSelectedDay = -1;
-
-            // The number of days + a spot for week number if it is displayed
-            private int mNumCells;
-
-            // The left edge of the selected day
-            private int mSelectedLeft = -1;
-
-            // The right edge of the selected day
-            private int mSelectedRight = -1;
-
-            public WeekView(Context context) {
-                super(context);
-
-                // Sets up any standard paints that will be used
-                initilaizePaints();
-            }
-
-            /**
-             * Initializes this week view.
-             *
-             * @param weekNumber The number of the week this view represents. The
-             *            week number is a zero based index of the weeks since
-             *            {@link CalendarView#getMinDate()}.
-             * @param selectedWeekDay The selected day of the week from 0 to 6, -1 if no
-             *            selected day.
-             * @param focusedMonth The month that is currently in focus i.e.
-             *            highlighted.
-             */
-            public void init(int weekNumber, int selectedWeekDay, int focusedMonth) {
-                mSelectedDay = selectedWeekDay;
-                mHasSelectedDay = mSelectedDay != -1;
-                mNumCells = mShowWeekNumber ? mDaysPerWeek + 1 : mDaysPerWeek;
-                mWeek = weekNumber;
-                mTempDate.setTimeInMillis(mMinDate.getTimeInMillis());
-
-                mTempDate.add(Calendar.WEEK_OF_YEAR, mWeek);
-                mTempDate.setFirstDayOfWeek(mFirstDayOfWeek);
-
-                // Allocate space for caching the day numbers and focus values
-                mDayNumbers = new String[mNumCells];
-                mFocusDay = new boolean[mNumCells];
-
-                // If we're showing the week number calculate it based on Monday
-                int i = 0;
-                if (mShowWeekNumber) {
-                    mDayNumbers[0] = String.format(Locale.getDefault(), "%d",
-                            mTempDate.get(Calendar.WEEK_OF_YEAR));
-                    i++;
-                }
-
-                // Now adjust our starting day based on the start day of the week
-                int diff = mFirstDayOfWeek - mTempDate.get(Calendar.DAY_OF_WEEK);
-                mTempDate.add(Calendar.DAY_OF_MONTH, diff);
-
-                mFirstDay = (Calendar) mTempDate.clone();
-                mMonthOfFirstWeekDay = mTempDate.get(Calendar.MONTH);
-
-                mHasUnfocusedDay = true;
-                for (; i < mNumCells; i++) {
-                    final boolean isFocusedDay = (mTempDate.get(Calendar.MONTH) == focusedMonth);
-                    mFocusDay[i] = isFocusedDay;
-                    mHasFocusedDay |= isFocusedDay;
-                    mHasUnfocusedDay &= !isFocusedDay;
-                    // do not draw dates outside the valid range to avoid user confusion
-                    if (mTempDate.before(mMinDate) || mTempDate.after(mMaxDate)) {
-                        mDayNumbers[i] = "";
-                    } else {
-                        mDayNumbers[i] = String.format(Locale.getDefault(), "%d",
-                                mTempDate.get(Calendar.DAY_OF_MONTH));
-                    }
-                    mTempDate.add(Calendar.DAY_OF_MONTH, 1);
-                }
-                // We do one extra add at the end of the loop, if that pushed us to
-                // new month undo it
-                if (mTempDate.get(Calendar.DAY_OF_MONTH) == 1) {
-                    mTempDate.add(Calendar.DAY_OF_MONTH, -1);
-                }
-                mLastWeekDayMonth = mTempDate.get(Calendar.MONTH);
-
-                updateSelectionPositions();
-            }
-
-            /**
-             * Initialize the paint instances.
-             */
-            private void initilaizePaints() {
-                mDrawPaint.setFakeBoldText(false);
-                mDrawPaint.setAntiAlias(true);
-                mDrawPaint.setStyle(Style.FILL);
-
-                mMonthNumDrawPaint.setFakeBoldText(true);
-                mMonthNumDrawPaint.setAntiAlias(true);
-                mMonthNumDrawPaint.setStyle(Style.FILL);
-                mMonthNumDrawPaint.setTextAlign(Align.CENTER);
-                mMonthNumDrawPaint.setTextSize(mDateTextSize);
-            }
-
-            /**
-             * Returns the month of the first day in this week.
-             *
-             * @return The month the first day of this view is in.
-             */
-            public int getMonthOfFirstWeekDay() {
-                return mMonthOfFirstWeekDay;
-            }
-
-            /**
-             * Returns the month of the last day in this week
-             *
-             * @return The month the last day of this view is in
-             */
-            public int getMonthOfLastWeekDay() {
-                return mLastWeekDayMonth;
-            }
-
-            /**
-             * Returns the first day in this view.
-             *
-             * @return The first day in the view.
-             */
-            public Calendar getFirstDay() {
-                return mFirstDay;
-            }
-
-            /**
-             * Calculates the day that the given x position is in, accounting for
-             * week number.
-             *
-             * @param x The x position of the touch event.
-             * @return True if a day was found for the given location.
-             */
-            public boolean getDayFromLocation(float x, Calendar outCalendar) {
-                final boolean isLayoutRtl = isLayoutRtl();
-
-                int start;
-                int end;
-
-                if (isLayoutRtl) {
-                    start = 0;
-                    end = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
-                } else {
-                    start = mShowWeekNumber ? mWidth / mNumCells : 0;
-                    end = mWidth;
-                }
-
-                if (x < start || x > end) {
-                    outCalendar.clear();
-                    return false;
-                }
-
-                // Selection is (x - start) / (pixels/day) which is (x - start) * day / pixels
-                int dayPosition = (int) ((x - start) * mDaysPerWeek / (end - start));
-
-                if (isLayoutRtl) {
-                    dayPosition = mDaysPerWeek - 1 - dayPosition;
-                }
-
-                outCalendar.setTimeInMillis(mFirstDay.getTimeInMillis());
-                outCalendar.add(Calendar.DAY_OF_MONTH, dayPosition);
-
-                return true;
-            }
-
-            @Override
-            protected void onDraw(Canvas canvas) {
-                drawBackground(canvas);
-                drawWeekNumbersAndDates(canvas);
-                drawWeekSeparators(canvas);
-                drawSelectedDateVerticalBars(canvas);
-            }
-
-            /**
-             * This draws the selection highlight if a day is selected in this week.
-             *
-             * @param canvas The canvas to draw on
-             */
-            private void drawBackground(Canvas canvas) {
-                if (!mHasSelectedDay) {
-                    return;
-                }
-                mDrawPaint.setColor(mSelectedWeekBackgroundColor);
-
-                mTempRect.top = mWeekSeperatorLineWidth;
-                mTempRect.bottom = mHeight;
-
-                final boolean isLayoutRtl = isLayoutRtl();
-
-                if (isLayoutRtl) {
-                    mTempRect.left = 0;
-                    mTempRect.right = mSelectedLeft - 2;
-                } else {
-                    mTempRect.left = mShowWeekNumber ? mWidth / mNumCells : 0;
-                    mTempRect.right = mSelectedLeft - 2;
-                }
-                canvas.drawRect(mTempRect, mDrawPaint);
-
-                if (isLayoutRtl) {
-                    mTempRect.left = mSelectedRight + 3;
-                    mTempRect.right = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
-                } else {
-                    mTempRect.left = mSelectedRight + 3;
-                    mTempRect.right = mWidth;
-                }
-                canvas.drawRect(mTempRect, mDrawPaint);
-            }
-
-            /**
-             * Draws the week and month day numbers for this week.
-             *
-             * @param canvas The canvas to draw on
-             */
-            private void drawWeekNumbersAndDates(Canvas canvas) {
-                final float textHeight = mDrawPaint.getTextSize();
-                final int y = (int) ((mHeight + textHeight) / 2) - mWeekSeperatorLineWidth;
-                final int nDays = mNumCells;
-                final int divisor = 2 * nDays;
-
-                mDrawPaint.setTextAlign(Align.CENTER);
-                mDrawPaint.setTextSize(mDateTextSize);
-
-                int i = 0;
-
-                if (isLayoutRtl()) {
-                    for (; i < nDays - 1; i++) {
-                        mMonthNumDrawPaint.setColor(mFocusDay[i] ? mFocusedMonthDateColor
-                                : mUnfocusedMonthDateColor);
-                        int x = (2 * i + 1) * mWidth / divisor;
-                        canvas.drawText(mDayNumbers[nDays - 1 - i], x, y, mMonthNumDrawPaint);
-                    }
-                    if (mShowWeekNumber) {
-                        mDrawPaint.setColor(mWeekNumberColor);
-                        int x = mWidth - mWidth / divisor;
-                        canvas.drawText(mDayNumbers[0], x, y, mDrawPaint);
-                    }
-                } else {
-                    if (mShowWeekNumber) {
-                        mDrawPaint.setColor(mWeekNumberColor);
-                        int x = mWidth / divisor;
-                        canvas.drawText(mDayNumbers[0], x, y, mDrawPaint);
-                        i++;
-                    }
-                    for (; i < nDays; i++) {
-                        mMonthNumDrawPaint.setColor(mFocusDay[i] ? mFocusedMonthDateColor
-                                : mUnfocusedMonthDateColor);
-                        int x = (2 * i + 1) * mWidth / divisor;
-                        canvas.drawText(mDayNumbers[i], x, y, mMonthNumDrawPaint);
-                    }
-                }
-            }
-
-            /**
-             * Draws a horizontal line for separating the weeks.
-             *
-             * @param canvas The canvas to draw on.
-             */
-            private void drawWeekSeparators(Canvas canvas) {
-                // If it is the topmost fully visible child do not draw separator line
-                int firstFullyVisiblePosition = mListView.getFirstVisiblePosition();
-                if (mListView.getChildAt(0).getTop() < 0) {
-                    firstFullyVisiblePosition++;
-                }
-                if (firstFullyVisiblePosition == mWeek) {
-                    return;
-                }
-                mDrawPaint.setColor(mWeekSeparatorLineColor);
-                mDrawPaint.setStrokeWidth(mWeekSeperatorLineWidth);
-                float startX;
-                float stopX;
-                if (isLayoutRtl()) {
-                    startX = 0;
-                    stopX = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
-                } else {
-                    startX = mShowWeekNumber ? mWidth / mNumCells : 0;
-                    stopX = mWidth;
-                }
-                canvas.drawLine(startX, 0, stopX, 0, mDrawPaint);
-            }
-
-            /**
-             * Draws the selected date bars if this week has a selected day.
-             *
-             * @param canvas The canvas to draw on
-             */
-            private void drawSelectedDateVerticalBars(Canvas canvas) {
-                if (!mHasSelectedDay) {
-                    return;
-                }
-                mSelectedDateVerticalBar.setBounds(
-                        mSelectedLeft - mSelectedDateVerticalBarWidth / 2,
-                        mWeekSeperatorLineWidth,
-                        mSelectedLeft + mSelectedDateVerticalBarWidth / 2,
-                        mHeight);
-                mSelectedDateVerticalBar.draw(canvas);
-                mSelectedDateVerticalBar.setBounds(
-                        mSelectedRight - mSelectedDateVerticalBarWidth / 2,
-                        mWeekSeperatorLineWidth,
-                        mSelectedRight + mSelectedDateVerticalBarWidth / 2,
-                        mHeight);
-                mSelectedDateVerticalBar.draw(canvas);
-            }
-
-            @Override
-            protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-                mWidth = w;
-                updateSelectionPositions();
-            }
-
-            /**
-             * This calculates the positions for the selected day lines.
-             */
-            private void updateSelectionPositions() {
-                if (mHasSelectedDay) {
-                    final boolean isLayoutRtl = isLayoutRtl();
-                    int selectedPosition = mSelectedDay - mFirstDayOfWeek;
-                    if (selectedPosition < 0) {
-                        selectedPosition += 7;
-                    }
-                    if (mShowWeekNumber && !isLayoutRtl) {
-                        selectedPosition++;
-                    }
-                    if (isLayoutRtl) {
-                        mSelectedLeft = (mDaysPerWeek - 1 - selectedPosition) * mWidth / mNumCells;
-
-                    } else {
-                        mSelectedLeft = selectedPosition * mWidth / mNumCells;
-                    }
-                    mSelectedRight = mSelectedLeft + mWidth / mNumCells;
-                }
-            }
-
-            @Override
-            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-                mHeight = (mListView.getHeight() - mListView.getPaddingTop() - mListView
-                        .getPaddingBottom()) / mShownWeekCount;
-                setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mHeight);
-            }
-        }
-
     }
 
 }
diff --git a/core/java/android/widget/CalendarViewLegacyDelegate.java b/core/java/android/widget/CalendarViewLegacyDelegate.java
new file mode 100644
index 0000000..2ab3548
--- /dev/null
+++ b/core/java/android/widget/CalendarViewLegacyDelegate.java
@@ -0,0 +1,1527 @@
+/*
+ * 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 com.android.internal.R;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.TypedArray;
+import android.database.DataSetObserver;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.GestureDetector;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.Calendar;
+import java.util.Locale;
+
+import libcore.icu.LocaleData;
+
+/**
+ * A delegate implementing the legacy CalendarView
+ */
+class CalendarViewLegacyDelegate extends CalendarView.AbstractCalendarViewDelegate {
+    /**
+     * Default value whether to show week number.
+     */
+    private static final boolean DEFAULT_SHOW_WEEK_NUMBER = true;
+
+    /**
+     * The number of milliseconds in a day.e
+     */
+    private static final long MILLIS_IN_DAY = 86400000L;
+
+    /**
+     * The number of day in a week.
+     */
+    private static final int DAYS_PER_WEEK = 7;
+
+    /**
+     * The number of milliseconds in a week.
+     */
+    private static final long MILLIS_IN_WEEK = DAYS_PER_WEEK * MILLIS_IN_DAY;
+
+    /**
+     * Affects when the month selection will change while scrolling upe
+     */
+    private static final int SCROLL_HYST_WEEKS = 2;
+
+    /**
+     * How long the GoTo fling animation should last.
+     */
+    private static final int GOTO_SCROLL_DURATION = 1000;
+
+    /**
+     * The duration of the adjustment upon a user scroll in milliseconds.
+     */
+    private static final int ADJUSTMENT_SCROLL_DURATION = 500;
+
+    /**
+     * How long to wait after receiving an onScrollStateChanged notification
+     * before acting on it.
+     */
+    private static final int SCROLL_CHANGE_DELAY = 40;
+
+    private static final int DEFAULT_SHOWN_WEEK_COUNT = 6;
+
+    private static final int DEFAULT_DATE_TEXT_SIZE = 14;
+
+    private static final int UNSCALED_SELECTED_DATE_VERTICAL_BAR_WIDTH = 6;
+
+    private static final int UNSCALED_WEEK_MIN_VISIBLE_HEIGHT = 12;
+
+    private static final int UNSCALED_LIST_SCROLL_TOP_OFFSET = 2;
+
+    private static final int UNSCALED_BOTTOM_BUFFER = 20;
+
+    private static final int UNSCALED_WEEK_SEPARATOR_LINE_WIDTH = 1;
+
+    private static final int DEFAULT_WEEK_DAY_TEXT_APPEARANCE_RES_ID = -1;
+
+    private final int mWeekSeperatorLineWidth;
+
+    private int mDateTextSize;
+
+    private Drawable mSelectedDateVerticalBar;
+
+    private final int mSelectedDateVerticalBarWidth;
+
+    private int mSelectedWeekBackgroundColor;
+
+    private int mFocusedMonthDateColor;
+
+    private int mUnfocusedMonthDateColor;
+
+    private int mWeekSeparatorLineColor;
+
+    private int mWeekNumberColor;
+
+    private int mWeekDayTextAppearanceResId;
+
+    private int mDateTextAppearanceResId;
+
+    /**
+     * The top offset of the weeks list.
+     */
+    private int mListScrollTopOffset = 2;
+
+    /**
+     * The visible height of a week view.
+     */
+    private int mWeekMinVisibleHeight = 12;
+
+    /**
+     * The visible height of a week view.
+     */
+    private int mBottomBuffer = 20;
+
+    /**
+     * The number of shown weeks.
+     */
+    private int mShownWeekCount;
+
+    /**
+     * Flag whether to show the week number.
+     */
+    private boolean mShowWeekNumber;
+
+    /**
+     * The number of day per week to be shown.
+     */
+    private int mDaysPerWeek = 7;
+
+    /**
+     * The friction of the week list while flinging.
+     */
+    private float mFriction = .05f;
+
+    /**
+     * Scale for adjusting velocity of the week list while flinging.
+     */
+    private float mVelocityScale = 0.333f;
+
+    /**
+     * The adapter for the weeks list.
+     */
+    private WeeksAdapter mAdapter;
+
+    /**
+     * The weeks list.
+     */
+    private ListView mListView;
+
+    /**
+     * The name of the month to display.
+     */
+    private TextView mMonthName;
+
+    /**
+     * The header with week day names.
+     */
+    private ViewGroup mDayNamesHeader;
+
+    /**
+     * Cached abbreviations for day of week names.
+     */
+    private String[] mDayNamesShort;
+
+    /**
+     * Cached full-length day of week names.
+     */
+    private String[] mDayNamesLong;
+
+    /**
+     * The first day of the week.
+     */
+    private int mFirstDayOfWeek;
+
+    /**
+     * Which month should be displayed/highlighted [0-11].
+     */
+    private int mCurrentMonthDisplayed = -1;
+
+    /**
+     * Used for tracking during a scroll.
+     */
+    private long mPreviousScrollPosition;
+
+    /**
+     * Used for tracking which direction the view is scrolling.
+     */
+    private boolean mIsScrollingUp = false;
+
+    /**
+     * The previous scroll state of the weeks ListView.
+     */
+    private int mPreviousScrollState = AbsListView.OnScrollListener.SCROLL_STATE_IDLE;
+
+    /**
+     * The current scroll state of the weeks ListView.
+     */
+    private int mCurrentScrollState = AbsListView.OnScrollListener.SCROLL_STATE_IDLE;
+
+    /**
+     * Listener for changes in the selected day.
+     */
+    private CalendarView.OnDateChangeListener mOnDateChangeListener;
+
+    /**
+     * Command for adjusting the position after a scroll/fling.
+     */
+    private ScrollStateRunnable mScrollStateChangedRunnable = new ScrollStateRunnable();
+
+    /**
+     * Temporary instance to avoid multiple instantiations.
+     */
+    private Calendar mTempDate;
+
+    /**
+     * The first day of the focused month.
+     */
+    private Calendar mFirstDayOfMonth;
+
+    /**
+     * The start date of the range supported by this picker.
+     */
+    private Calendar mMinDate;
+
+    /**
+     * The end date of the range supported by this picker.
+     */
+    private Calendar mMaxDate;
+
+    CalendarViewLegacyDelegate(CalendarView delegator, Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        super(delegator, context);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                R.styleable.CalendarView, defStyleAttr, defStyleRes);
+        mShowWeekNumber = a.getBoolean(R.styleable.CalendarView_showWeekNumber,
+                DEFAULT_SHOW_WEEK_NUMBER);
+        mFirstDayOfWeek = a.getInt(R.styleable.CalendarView_firstDayOfWeek,
+                LocaleData.get(Locale.getDefault()).firstDayOfWeek);
+        final String minDate = a.getString(R.styleable.CalendarView_minDate);
+        if (TextUtils.isEmpty(minDate) || !parseDate(minDate, mMinDate)) {
+            parseDate(DEFAULT_MIN_DATE, mMinDate);
+        }
+        final String maxDate = a.getString(R.styleable.CalendarView_maxDate);
+        if (TextUtils.isEmpty(maxDate) || !parseDate(maxDate, mMaxDate)) {
+            parseDate(DEFAULT_MAX_DATE, mMaxDate);
+        }
+        if (mMaxDate.before(mMinDate)) {
+            throw new IllegalArgumentException("Max date cannot be before min date.");
+        }
+        mShownWeekCount = a.getInt(R.styleable.CalendarView_shownWeekCount,
+                DEFAULT_SHOWN_WEEK_COUNT);
+        mSelectedWeekBackgroundColor = a.getColor(
+                R.styleable.CalendarView_selectedWeekBackgroundColor, 0);
+        mFocusedMonthDateColor = a.getColor(
+                R.styleable.CalendarView_focusedMonthDateColor, 0);
+        mUnfocusedMonthDateColor = a.getColor(
+                R.styleable.CalendarView_unfocusedMonthDateColor, 0);
+        mWeekSeparatorLineColor = a.getColor(
+                R.styleable.CalendarView_weekSeparatorLineColor, 0);
+        mWeekNumberColor = a.getColor(R.styleable.CalendarView_weekNumberColor, 0);
+        mSelectedDateVerticalBar = a.getDrawable(
+                R.styleable.CalendarView_selectedDateVerticalBar);
+
+        mDateTextAppearanceResId = a.getResourceId(
+                R.styleable.CalendarView_dateTextAppearance, R.style.TextAppearance_Small);
+        updateDateTextSize();
+
+        mWeekDayTextAppearanceResId = a.getResourceId(
+                R.styleable.CalendarView_weekDayTextAppearance,
+                DEFAULT_WEEK_DAY_TEXT_APPEARANCE_RES_ID);
+        a.recycle();
+
+        DisplayMetrics displayMetrics = mDelegator.getResources().getDisplayMetrics();
+        mWeekMinVisibleHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                UNSCALED_WEEK_MIN_VISIBLE_HEIGHT, displayMetrics);
+        mListScrollTopOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                UNSCALED_LIST_SCROLL_TOP_OFFSET, displayMetrics);
+        mBottomBuffer = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                UNSCALED_BOTTOM_BUFFER, displayMetrics);
+        mSelectedDateVerticalBarWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                UNSCALED_SELECTED_DATE_VERTICAL_BAR_WIDTH, displayMetrics);
+        mWeekSeperatorLineWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                UNSCALED_WEEK_SEPARATOR_LINE_WIDTH, displayMetrics);
+
+        LayoutInflater layoutInflater = (LayoutInflater) mContext
+                .getSystemService(Service.LAYOUT_INFLATER_SERVICE);
+        View content = layoutInflater.inflate(R.layout.calendar_view, null, false);
+        mDelegator.addView(content);
+
+        mListView = (ListView) mDelegator.findViewById(R.id.list);
+        mDayNamesHeader = (ViewGroup) content.findViewById(R.id.day_names);
+        mMonthName = (TextView) content.findViewById(R.id.month_name);
+
+        setUpHeader();
+        setUpListView();
+        setUpAdapter();
+
+        // go to today or whichever is close to today min or max date
+        mTempDate.setTimeInMillis(System.currentTimeMillis());
+        if (mTempDate.before(mMinDate)) {
+            goTo(mMinDate, false, true, true);
+        } else if (mMaxDate.before(mTempDate)) {
+            goTo(mMaxDate, false, true, true);
+        } else {
+            goTo(mTempDate, false, true, true);
+        }
+
+        mDelegator.invalidate();
+    }
+
+    @Override
+    public void setShownWeekCount(int count) {
+        if (mShownWeekCount != count) {
+            mShownWeekCount = count;
+            mDelegator.invalidate();
+        }
+    }
+
+    @Override
+    public int getShownWeekCount() {
+        return mShownWeekCount;
+    }
+
+    @Override
+    public void setSelectedWeekBackgroundColor(int color) {
+        if (mSelectedWeekBackgroundColor != color) {
+            mSelectedWeekBackgroundColor = color;
+            final int childCount = mListView.getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                WeekView weekView = (WeekView) mListView.getChildAt(i);
+                if (weekView.mHasSelectedDay) {
+                    weekView.invalidate();
+                }
+            }
+        }
+    }
+
+    @Override
+    public int getSelectedWeekBackgroundColor() {
+        return mSelectedWeekBackgroundColor;
+    }
+
+    @Override
+    public void setFocusedMonthDateColor(int color) {
+        if (mFocusedMonthDateColor != color) {
+            mFocusedMonthDateColor = color;
+            final int childCount = mListView.getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                WeekView weekView = (WeekView) mListView.getChildAt(i);
+                if (weekView.mHasFocusedDay) {
+                    weekView.invalidate();
+                }
+            }
+        }
+    }
+
+    @Override
+    public int getFocusedMonthDateColor() {
+        return mFocusedMonthDateColor;
+    }
+
+    @Override
+    public void setUnfocusedMonthDateColor(int color) {
+        if (mUnfocusedMonthDateColor != color) {
+            mUnfocusedMonthDateColor = color;
+            final int childCount = mListView.getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                WeekView weekView = (WeekView) mListView.getChildAt(i);
+                if (weekView.mHasUnfocusedDay) {
+                    weekView.invalidate();
+                }
+            }
+        }
+    }
+
+    @Override
+    public int getUnfocusedMonthDateColor() {
+        return mFocusedMonthDateColor;
+    }
+
+    @Override
+    public void setWeekNumberColor(int color) {
+        if (mWeekNumberColor != color) {
+            mWeekNumberColor = color;
+            if (mShowWeekNumber) {
+                invalidateAllWeekViews();
+            }
+        }
+    }
+
+    @Override
+    public int getWeekNumberColor() {
+        return mWeekNumberColor;
+    }
+
+    @Override
+    public void setWeekSeparatorLineColor(int color) {
+        if (mWeekSeparatorLineColor != color) {
+            mWeekSeparatorLineColor = color;
+            invalidateAllWeekViews();
+        }
+    }
+
+    @Override
+    public int getWeekSeparatorLineColor() {
+        return mWeekSeparatorLineColor;
+    }
+
+    @Override
+    public void setSelectedDateVerticalBar(int resourceId) {
+        Drawable drawable = mDelegator.getContext().getDrawable(resourceId);
+        setSelectedDateVerticalBar(drawable);
+    }
+
+    @Override
+    public void setSelectedDateVerticalBar(Drawable drawable) {
+        if (mSelectedDateVerticalBar != drawable) {
+            mSelectedDateVerticalBar = drawable;
+            final int childCount = mListView.getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                WeekView weekView = (WeekView) mListView.getChildAt(i);
+                if (weekView.mHasSelectedDay) {
+                    weekView.invalidate();
+                }
+            }
+        }
+    }
+
+    @Override
+    public Drawable getSelectedDateVerticalBar() {
+        return mSelectedDateVerticalBar;
+    }
+
+    @Override
+    public void setWeekDayTextAppearance(int resourceId) {
+        if (mWeekDayTextAppearanceResId != resourceId) {
+            mWeekDayTextAppearanceResId = resourceId;
+            setUpHeader();
+        }
+    }
+
+    @Override
+    public int getWeekDayTextAppearance() {
+        return mWeekDayTextAppearanceResId;
+    }
+
+    @Override
+    public void setDateTextAppearance(int resourceId) {
+        if (mDateTextAppearanceResId != resourceId) {
+            mDateTextAppearanceResId = resourceId;
+            updateDateTextSize();
+            invalidateAllWeekViews();
+        }
+    }
+
+    @Override
+    public int getDateTextAppearance() {
+        return mDateTextAppearanceResId;
+    }
+
+    @Override
+    public void setMinDate(long minDate) {
+        mTempDate.setTimeInMillis(minDate);
+        if (isSameDate(mTempDate, mMinDate)) {
+            return;
+        }
+        mMinDate.setTimeInMillis(minDate);
+        // make sure the current date is not earlier than
+        // the new min date since the latter is used for
+        // calculating the indices in the adapter thus
+        // avoiding out of bounds error
+        Calendar date = mAdapter.mSelectedDate;
+        if (date.before(mMinDate)) {
+            mAdapter.setSelectedDay(mMinDate);
+        }
+        // reinitialize the adapter since its range depends on min date
+        mAdapter.init();
+        if (date.before(mMinDate)) {
+            setDate(mTempDate.getTimeInMillis());
+        } else {
+            // we go to the current date to force the ListView to query its
+            // adapter for the shown views since we have changed the adapter
+            // range and the base from which the later calculates item indices
+            // note that calling setDate will not work since the date is the same
+            goTo(date, false, true, false);
+        }
+    }
+
+    @Override
+    public long getMinDate() {
+        return mMinDate.getTimeInMillis();
+    }
+
+    @Override
+    public void setMaxDate(long maxDate) {
+        mTempDate.setTimeInMillis(maxDate);
+        if (isSameDate(mTempDate, mMaxDate)) {
+            return;
+        }
+        mMaxDate.setTimeInMillis(maxDate);
+        // reinitialize the adapter since its range depends on max date
+        mAdapter.init();
+        Calendar date = mAdapter.mSelectedDate;
+        if (date.after(mMaxDate)) {
+            setDate(mMaxDate.getTimeInMillis());
+        } else {
+            // we go to the current date to force the ListView to query its
+            // adapter for the shown views since we have changed the adapter
+            // range and the base from which the later calculates item indices
+            // note that calling setDate will not work since the date is the same
+            goTo(date, false, true, false);
+        }
+    }
+
+    @Override
+    public long getMaxDate() {
+        return mMaxDate.getTimeInMillis();
+    }
+
+    @Override
+    public void setShowWeekNumber(boolean showWeekNumber) {
+        if (mShowWeekNumber == showWeekNumber) {
+            return;
+        }
+        mShowWeekNumber = showWeekNumber;
+        mAdapter.notifyDataSetChanged();
+        setUpHeader();
+    }
+
+    @Override
+    public boolean getShowWeekNumber() {
+        return mShowWeekNumber;
+    }
+
+    @Override
+    public void setFirstDayOfWeek(int firstDayOfWeek) {
+        if (mFirstDayOfWeek == firstDayOfWeek) {
+            return;
+        }
+        mFirstDayOfWeek = firstDayOfWeek;
+        mAdapter.init();
+        mAdapter.notifyDataSetChanged();
+        setUpHeader();
+    }
+
+    @Override
+    public int getFirstDayOfWeek() {
+        return mFirstDayOfWeek;
+    }
+
+    @Override
+    public void setDate(long date) {
+        setDate(date, false, false);
+    }
+
+    @Override
+    public void setDate(long date, boolean animate, boolean center) {
+        mTempDate.setTimeInMillis(date);
+        if (isSameDate(mTempDate, mAdapter.mSelectedDate)) {
+            return;
+        }
+        goTo(mTempDate, animate, true, center);
+    }
+
+    @Override
+    public long getDate() {
+        return mAdapter.mSelectedDate.getTimeInMillis();
+    }
+
+    @Override
+    public void setOnDateChangeListener(CalendarView.OnDateChangeListener listener) {
+        mOnDateChangeListener = listener;
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        setCurrentLocale(newConfig.locale);
+    }
+
+    /**
+     * Sets the current locale.
+     *
+     * @param locale The current locale.
+     */
+    @Override
+    protected void setCurrentLocale(Locale locale) {
+        super.setCurrentLocale(locale);
+
+        mTempDate = getCalendarForLocale(mTempDate, locale);
+        mFirstDayOfMonth = getCalendarForLocale(mFirstDayOfMonth, locale);
+        mMinDate = getCalendarForLocale(mMinDate, locale);
+        mMaxDate = getCalendarForLocale(mMaxDate, locale);
+    }
+    private void updateDateTextSize() {
+        TypedArray dateTextAppearance = mDelegator.getContext().obtainStyledAttributes(
+                mDateTextAppearanceResId, R.styleable.TextAppearance);
+        mDateTextSize = dateTextAppearance.getDimensionPixelSize(
+                R.styleable.TextAppearance_textSize, DEFAULT_DATE_TEXT_SIZE);
+        dateTextAppearance.recycle();
+    }
+
+    /**
+     * Invalidates all week views.
+     */
+    private void invalidateAllWeekViews() {
+        final int childCount = mListView.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            View view = mListView.getChildAt(i);
+            view.invalidate();
+        }
+    }
+
+    /**
+     * Gets a calendar for locale bootstrapped with the value of a given calendar.
+     *
+     * @param oldCalendar The old calendar.
+     * @param locale The locale.
+     */
+    private static Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
+        if (oldCalendar == null) {
+            return Calendar.getInstance(locale);
+        } else {
+            final long currentTimeMillis = oldCalendar.getTimeInMillis();
+            Calendar newCalendar = Calendar.getInstance(locale);
+            newCalendar.setTimeInMillis(currentTimeMillis);
+            return newCalendar;
+        }
+    }
+
+    /**
+     * @return True if the <code>firstDate</code> is the same as the <code>
+     * secondDate</code>.
+     */
+    private static boolean isSameDate(Calendar firstDate, Calendar secondDate) {
+        return (firstDate.get(Calendar.DAY_OF_YEAR) == secondDate.get(Calendar.DAY_OF_YEAR)
+                && firstDate.get(Calendar.YEAR) == secondDate.get(Calendar.YEAR));
+    }
+
+    /**
+     * Creates a new adapter if necessary and sets up its parameters.
+     */
+    private void setUpAdapter() {
+        if (mAdapter == null) {
+            mAdapter = new WeeksAdapter(mContext);
+            mAdapter.registerDataSetObserver(new DataSetObserver() {
+                @Override
+                public void onChanged() {
+                    if (mOnDateChangeListener != null) {
+                        Calendar selectedDay = mAdapter.getSelectedDay();
+                        mOnDateChangeListener.onSelectedDayChange(mDelegator,
+                                selectedDay.get(Calendar.YEAR),
+                                selectedDay.get(Calendar.MONTH),
+                                selectedDay.get(Calendar.DAY_OF_MONTH));
+                    }
+                }
+            });
+            mListView.setAdapter(mAdapter);
+        }
+
+        // refresh the view with the new parameters
+        mAdapter.notifyDataSetChanged();
+    }
+
+    /**
+     * Sets up the strings to be used by the header.
+     */
+    private void setUpHeader() {
+        mDayNamesShort = new String[mDaysPerWeek];
+        mDayNamesLong = new String[mDaysPerWeek];
+        for (int i = mFirstDayOfWeek, count = mFirstDayOfWeek + mDaysPerWeek; i < count; i++) {
+            int calendarDay = (i > Calendar.SATURDAY) ? i - Calendar.SATURDAY : i;
+            mDayNamesShort[i - mFirstDayOfWeek] = DateUtils.getDayOfWeekString(calendarDay,
+                    DateUtils.LENGTH_SHORTEST);
+            mDayNamesLong[i - mFirstDayOfWeek] = DateUtils.getDayOfWeekString(calendarDay,
+                    DateUtils.LENGTH_LONG);
+        }
+
+        TextView label = (TextView) mDayNamesHeader.getChildAt(0);
+        if (mShowWeekNumber) {
+            label.setVisibility(View.VISIBLE);
+        } else {
+            label.setVisibility(View.GONE);
+        }
+        for (int i = 1, count = mDayNamesHeader.getChildCount(); i < count; i++) {
+            label = (TextView) mDayNamesHeader.getChildAt(i);
+            if (mWeekDayTextAppearanceResId > -1) {
+                label.setTextAppearance(mContext, mWeekDayTextAppearanceResId);
+            }
+            if (i < mDaysPerWeek + 1) {
+                label.setText(mDayNamesShort[i - 1]);
+                label.setContentDescription(mDayNamesLong[i - 1]);
+                label.setVisibility(View.VISIBLE);
+            } else {
+                label.setVisibility(View.GONE);
+            }
+        }
+        mDayNamesHeader.invalidate();
+    }
+
+    /**
+     * Sets all the required fields for the list view.
+     */
+    private void setUpListView() {
+        // Configure the listview
+        mListView.setDivider(null);
+        mListView.setItemsCanFocus(true);
+        mListView.setVerticalScrollBarEnabled(false);
+        mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
+            public void onScrollStateChanged(AbsListView view, int scrollState) {
+                CalendarViewLegacyDelegate.this.onScrollStateChanged(view, scrollState);
+            }
+
+            public void onScroll(
+                    AbsListView view, int firstVisibleItem, int visibleItemCount,
+                    int totalItemCount) {
+                CalendarViewLegacyDelegate.this.onScroll(view, firstVisibleItem,
+                        visibleItemCount, totalItemCount);
+            }
+        });
+        // Make the scrolling behavior nicer
+        mListView.setFriction(mFriction);
+        mListView.setVelocityScale(mVelocityScale);
+    }
+
+    /**
+     * This moves to the specified time in the view. If the time is not already
+     * in range it will move the list so that the first of the month containing
+     * the time is at the top of the view. If the new time is already in view
+     * the list will not be scrolled unless forceScroll is true. This time may
+     * optionally be highlighted as selected as well.
+     *
+     * @param date The time to move to.
+     * @param animate Whether to scroll to the given time or just redraw at the
+     *            new location.
+     * @param setSelected Whether to set the given time as selected.
+     * @param forceScroll Whether to recenter even if the time is already
+     *            visible.
+     *
+     * @throws IllegalArgumentException of the provided date is before the
+     *        range start of after the range end.
+     */
+    private void goTo(Calendar date, boolean animate, boolean setSelected,
+            boolean forceScroll) {
+        if (date.before(mMinDate) || date.after(mMaxDate)) {
+            throw new IllegalArgumentException("Time not between " + mMinDate.getTime()
+                    + " and " + mMaxDate.getTime());
+        }
+        // Find the first and last entirely visible weeks
+        int firstFullyVisiblePosition = mListView.getFirstVisiblePosition();
+        View firstChild = mListView.getChildAt(0);
+        if (firstChild != null && firstChild.getTop() < 0) {
+            firstFullyVisiblePosition++;
+        }
+        int lastFullyVisiblePosition = firstFullyVisiblePosition + mShownWeekCount - 1;
+        if (firstChild != null && firstChild.getTop() > mBottomBuffer) {
+            lastFullyVisiblePosition--;
+        }
+        if (setSelected) {
+            mAdapter.setSelectedDay(date);
+        }
+        // Get the week we're going to
+        int position = getWeeksSinceMinDate(date);
+
+        // Check if the selected day is now outside of our visible range
+        // and if so scroll to the month that contains it
+        if (position < firstFullyVisiblePosition || position > lastFullyVisiblePosition
+                || forceScroll) {
+            mFirstDayOfMonth.setTimeInMillis(date.getTimeInMillis());
+            mFirstDayOfMonth.set(Calendar.DAY_OF_MONTH, 1);
+
+            setMonthDisplayed(mFirstDayOfMonth);
+
+            // the earliest time we can scroll to is the min date
+            if (mFirstDayOfMonth.before(mMinDate)) {
+                position = 0;
+            } else {
+                position = getWeeksSinceMinDate(mFirstDayOfMonth);
+            }
+
+            mPreviousScrollState = AbsListView.OnScrollListener.SCROLL_STATE_FLING;
+            if (animate) {
+                mListView.smoothScrollToPositionFromTop(position, mListScrollTopOffset,
+                        GOTO_SCROLL_DURATION);
+            } else {
+                mListView.setSelectionFromTop(position, mListScrollTopOffset);
+                // Perform any after scroll operations that are needed
+                onScrollStateChanged(mListView, AbsListView.OnScrollListener.SCROLL_STATE_IDLE);
+            }
+        } else if (setSelected) {
+            // Otherwise just set the selection
+            setMonthDisplayed(date);
+        }
+    }
+
+    /**
+     * Called when a <code>view</code> transitions to a new <code>scrollState
+     * </code>.
+     */
+    private void onScrollStateChanged(AbsListView view, int scrollState) {
+        mScrollStateChangedRunnable.doScrollStateChange(view, scrollState);
+    }
+
+    /**
+     * Updates the title and selected month if the <code>view</code> has moved to a new
+     * month.
+     */
+    private void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
+                          int totalItemCount) {
+        WeekView child = (WeekView) view.getChildAt(0);
+        if (child == null) {
+            return;
+        }
+
+        // Figure out where we are
+        long currScroll =
+                view.getFirstVisiblePosition() * child.getHeight() - child.getBottom();
+
+        // If we have moved since our last call update the direction
+        if (currScroll < mPreviousScrollPosition) {
+            mIsScrollingUp = true;
+        } else if (currScroll > mPreviousScrollPosition) {
+            mIsScrollingUp = false;
+        } else {
+            return;
+        }
+
+        // Use some hysteresis for checking which month to highlight. This
+        // causes the month to transition when two full weeks of a month are
+        // visible when scrolling up, and when the first day in a month reaches
+        // the top of the screen when scrolling down.
+        int offset = child.getBottom() < mWeekMinVisibleHeight ? 1 : 0;
+        if (mIsScrollingUp) {
+            child = (WeekView) view.getChildAt(SCROLL_HYST_WEEKS + offset);
+        } else if (offset != 0) {
+            child = (WeekView) view.getChildAt(offset);
+        }
+
+        if (child != null) {
+            // Find out which month we're moving into
+            int month;
+            if (mIsScrollingUp) {
+                month = child.getMonthOfFirstWeekDay();
+            } else {
+                month = child.getMonthOfLastWeekDay();
+            }
+
+            // And how it relates to our current highlighted month
+            int monthDiff;
+            if (mCurrentMonthDisplayed == 11 && month == 0) {
+                monthDiff = 1;
+            } else if (mCurrentMonthDisplayed == 0 && month == 11) {
+                monthDiff = -1;
+            } else {
+                monthDiff = month - mCurrentMonthDisplayed;
+            }
+
+            // Only switch months if we're scrolling away from the currently
+            // selected month
+            if ((!mIsScrollingUp && monthDiff > 0) || (mIsScrollingUp && monthDiff < 0)) {
+                Calendar firstDay = child.getFirstDay();
+                if (mIsScrollingUp) {
+                    firstDay.add(Calendar.DAY_OF_MONTH, -DAYS_PER_WEEK);
+                } else {
+                    firstDay.add(Calendar.DAY_OF_MONTH, DAYS_PER_WEEK);
+                }
+                setMonthDisplayed(firstDay);
+            }
+        }
+        mPreviousScrollPosition = currScroll;
+        mPreviousScrollState = mCurrentScrollState;
+    }
+
+    /**
+     * Sets the month displayed at the top of this view based on time. Override
+     * to add custom events when the title is changed.
+     *
+     * @param calendar A day in the new focus month.
+     */
+    private void setMonthDisplayed(Calendar calendar) {
+        mCurrentMonthDisplayed = calendar.get(Calendar.MONTH);
+        mAdapter.setFocusMonth(mCurrentMonthDisplayed);
+        final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_MONTH_DAY
+                | DateUtils.FORMAT_SHOW_YEAR;
+        final long millis = calendar.getTimeInMillis();
+        String newMonthName = DateUtils.formatDateRange(mContext, millis, millis, flags);
+        mMonthName.setText(newMonthName);
+        mMonthName.invalidate();
+    }
+
+    /**
+     * @return Returns the number of weeks between the current <code>date</code>
+     *         and the <code>mMinDate</code>.
+     */
+    private int getWeeksSinceMinDate(Calendar date) {
+        if (date.before(mMinDate)) {
+            throw new IllegalArgumentException("fromDate: " + mMinDate.getTime()
+                    + " does not precede toDate: " + date.getTime());
+        }
+        long endTimeMillis = date.getTimeInMillis()
+                + date.getTimeZone().getOffset(date.getTimeInMillis());
+        long startTimeMillis = mMinDate.getTimeInMillis()
+                + mMinDate.getTimeZone().getOffset(mMinDate.getTimeInMillis());
+        long dayOffsetMillis = (mMinDate.get(Calendar.DAY_OF_WEEK) - mFirstDayOfWeek)
+                * MILLIS_IN_DAY;
+        return (int) ((endTimeMillis - startTimeMillis + dayOffsetMillis) / MILLIS_IN_WEEK);
+    }
+
+    /**
+     * Command responsible for acting upon scroll state changes.
+     */
+    private class ScrollStateRunnable implements Runnable {
+        private AbsListView mView;
+
+        private int mNewState;
+
+        /**
+         * Sets up the runnable with a short delay in case the scroll state
+         * immediately changes again.
+         *
+         * @param view The list view that changed state
+         * @param scrollState The new state it changed to
+         */
+        public void doScrollStateChange(AbsListView view, int scrollState) {
+            mView = view;
+            mNewState = scrollState;
+            mDelegator.removeCallbacks(this);
+            mDelegator.postDelayed(this, SCROLL_CHANGE_DELAY);
+        }
+
+        public void run() {
+            mCurrentScrollState = mNewState;
+            // Fix the position after a scroll or a fling ends
+            if (mNewState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE
+                    && mPreviousScrollState != AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
+                View child = mView.getChildAt(0);
+                if (child == null) {
+                    // The view is no longer visible, just return
+                    return;
+                }
+                int dist = child.getBottom() - mListScrollTopOffset;
+                if (dist > mListScrollTopOffset) {
+                    if (mIsScrollingUp) {
+                        mView.smoothScrollBy(dist - child.getHeight(),
+                                ADJUSTMENT_SCROLL_DURATION);
+                    } else {
+                        mView.smoothScrollBy(dist, ADJUSTMENT_SCROLL_DURATION);
+                    }
+                }
+            }
+            mPreviousScrollState = mNewState;
+        }
+    }
+
+    /**
+     * <p>
+     * This is a specialized adapter for creating a list of weeks with
+     * selectable days. It can be configured to display the week number, start
+     * the week on a given day, show a reduced number of days, or display an
+     * arbitrary number of weeks at a time.
+     * </p>
+     */
+    private class WeeksAdapter extends BaseAdapter implements View.OnTouchListener {
+
+        private int mSelectedWeek;
+
+        private GestureDetector mGestureDetector;
+
+        private int mFocusedMonth;
+
+        private final Calendar mSelectedDate = Calendar.getInstance();
+
+        private int mTotalWeekCount;
+
+        public WeeksAdapter(Context context) {
+            mContext = context;
+            mGestureDetector = new GestureDetector(mContext, new WeeksAdapter.CalendarGestureListener());
+            init();
+        }
+
+        /**
+         * Set up the gesture detector and selected time
+         */
+        private void init() {
+            mSelectedWeek = getWeeksSinceMinDate(mSelectedDate);
+            mTotalWeekCount = getWeeksSinceMinDate(mMaxDate);
+            if (mMinDate.get(Calendar.DAY_OF_WEEK) != mFirstDayOfWeek
+                    || mMaxDate.get(Calendar.DAY_OF_WEEK) != mFirstDayOfWeek) {
+                mTotalWeekCount++;
+            }
+            notifyDataSetChanged();
+        }
+
+        /**
+         * Updates the selected day and related parameters.
+         *
+         * @param selectedDay The time to highlight
+         */
+        public void setSelectedDay(Calendar selectedDay) {
+            if (selectedDay.get(Calendar.DAY_OF_YEAR) == mSelectedDate.get(Calendar.DAY_OF_YEAR)
+                    && selectedDay.get(Calendar.YEAR) == mSelectedDate.get(Calendar.YEAR)) {
+                return;
+            }
+            mSelectedDate.setTimeInMillis(selectedDay.getTimeInMillis());
+            mSelectedWeek = getWeeksSinceMinDate(mSelectedDate);
+            mFocusedMonth = mSelectedDate.get(Calendar.MONTH);
+            notifyDataSetChanged();
+        }
+
+        /**
+         * @return The selected day of month.
+         */
+        public Calendar getSelectedDay() {
+            return mSelectedDate;
+        }
+
+        @Override
+        public int getCount() {
+            return mTotalWeekCount;
+        }
+
+        @Override
+        public Object getItem(int position) {
+            return null;
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            WeekView weekView = null;
+            if (convertView != null) {
+                weekView = (WeekView) convertView;
+            } else {
+                weekView = new WeekView(mContext);
+                AbsListView.LayoutParams params =
+                        new AbsListView.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
+                                FrameLayout.LayoutParams.WRAP_CONTENT);
+                weekView.setLayoutParams(params);
+                weekView.setClickable(true);
+                weekView.setOnTouchListener(this);
+            }
+
+            int selectedWeekDay = (mSelectedWeek == position) ? mSelectedDate.get(
+                    Calendar.DAY_OF_WEEK) : -1;
+            weekView.init(position, selectedWeekDay, mFocusedMonth);
+
+            return weekView;
+        }
+
+        /**
+         * Changes which month is in focus and updates the view.
+         *
+         * @param month The month to show as in focus [0-11]
+         */
+        public void setFocusMonth(int month) {
+            if (mFocusedMonth == month) {
+                return;
+            }
+            mFocusedMonth = month;
+            notifyDataSetChanged();
+        }
+
+        @Override
+        public boolean onTouch(View v, MotionEvent event) {
+            if (mListView.isEnabled() && mGestureDetector.onTouchEvent(event)) {
+                WeekView weekView = (WeekView) v;
+                // if we cannot find a day for the given location we are done
+                if (!weekView.getDayFromLocation(event.getX(), mTempDate)) {
+                    return true;
+                }
+                // it is possible that the touched day is outside the valid range
+                // we draw whole weeks but range end can fall not on the week end
+                if (mTempDate.before(mMinDate) || mTempDate.after(mMaxDate)) {
+                    return true;
+                }
+                onDateTapped(mTempDate);
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * Maintains the same hour/min/sec but moves the day to the tapped day.
+         *
+         * @param day The day that was tapped
+         */
+        private void onDateTapped(Calendar day) {
+            setSelectedDay(day);
+            setMonthDisplayed(day);
+        }
+
+        /**
+         * This is here so we can identify single tap events and set the
+         * selected day correctly
+         */
+        class CalendarGestureListener extends GestureDetector.SimpleOnGestureListener {
+            @Override
+            public boolean onSingleTapUp(MotionEvent e) {
+                return true;
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * This is a dynamic view for drawing a single week. It can be configured to
+     * display the week number, start the week on a given day, or show a reduced
+     * number of days. It is intended for use as a single view within a
+     * ListView. See {@link WeeksAdapter} for usage.
+     * </p>
+     */
+    private class WeekView extends View {
+
+        private final Rect mTempRect = new Rect();
+
+        private final Paint mDrawPaint = new Paint();
+
+        private final Paint mMonthNumDrawPaint = new Paint();
+
+        // Cache the number strings so we don't have to recompute them each time
+        private String[] mDayNumbers;
+
+        // Quick lookup for checking which days are in the focus month
+        private boolean[] mFocusDay;
+
+        // Whether this view has a focused day.
+        private boolean mHasFocusedDay;
+
+        // Whether this view has only focused days.
+        private boolean mHasUnfocusedDay;
+
+        // The first day displayed by this item
+        private Calendar mFirstDay;
+
+        // The month of the first day in this week
+        private int mMonthOfFirstWeekDay = -1;
+
+        // The month of the last day in this week
+        private int mLastWeekDayMonth = -1;
+
+        // The position of this week, equivalent to weeks since the week of Jan
+        // 1st, 1900
+        private int mWeek = -1;
+
+        // Quick reference to the width of this view, matches parent
+        private int mWidth;
+
+        // The height this view should draw at in pixels, set by height param
+        private int mHeight;
+
+        // If this view contains the selected day
+        private boolean mHasSelectedDay = false;
+
+        // Which day is selected [0-6] or -1 if no day is selected
+        private int mSelectedDay = -1;
+
+        // The number of days + a spot for week number if it is displayed
+        private int mNumCells;
+
+        // The left edge of the selected day
+        private int mSelectedLeft = -1;
+
+        // The right edge of the selected day
+        private int mSelectedRight = -1;
+
+        public WeekView(Context context) {
+            super(context);
+
+            // Sets up any standard paints that will be used
+            initilaizePaints();
+        }
+
+        /**
+         * Initializes this week view.
+         *
+         * @param weekNumber The number of the week this view represents. The
+         *            week number is a zero based index of the weeks since
+         *            {@link android.widget.CalendarView#getMinDate()}.
+         * @param selectedWeekDay The selected day of the week from 0 to 6, -1 if no
+         *            selected day.
+         * @param focusedMonth The month that is currently in focus i.e.
+         *            highlighted.
+         */
+        public void init(int weekNumber, int selectedWeekDay, int focusedMonth) {
+            mSelectedDay = selectedWeekDay;
+            mHasSelectedDay = mSelectedDay != -1;
+            mNumCells = mShowWeekNumber ? mDaysPerWeek + 1 : mDaysPerWeek;
+            mWeek = weekNumber;
+            mTempDate.setTimeInMillis(mMinDate.getTimeInMillis());
+
+            mTempDate.add(Calendar.WEEK_OF_YEAR, mWeek);
+            mTempDate.setFirstDayOfWeek(mFirstDayOfWeek);
+
+            // Allocate space for caching the day numbers and focus values
+            mDayNumbers = new String[mNumCells];
+            mFocusDay = new boolean[mNumCells];
+
+            // If we're showing the week number calculate it based on Monday
+            int i = 0;
+            if (mShowWeekNumber) {
+                mDayNumbers[0] = String.format(Locale.getDefault(), "%d",
+                        mTempDate.get(Calendar.WEEK_OF_YEAR));
+                i++;
+            }
+
+            // Now adjust our starting day based on the start day of the week
+            int diff = mFirstDayOfWeek - mTempDate.get(Calendar.DAY_OF_WEEK);
+            mTempDate.add(Calendar.DAY_OF_MONTH, diff);
+
+            mFirstDay = (Calendar) mTempDate.clone();
+            mMonthOfFirstWeekDay = mTempDate.get(Calendar.MONTH);
+
+            mHasUnfocusedDay = true;
+            for (; i < mNumCells; i++) {
+                final boolean isFocusedDay = (mTempDate.get(Calendar.MONTH) == focusedMonth);
+                mFocusDay[i] = isFocusedDay;
+                mHasFocusedDay |= isFocusedDay;
+                mHasUnfocusedDay &= !isFocusedDay;
+                // do not draw dates outside the valid range to avoid user confusion
+                if (mTempDate.before(mMinDate) || mTempDate.after(mMaxDate)) {
+                    mDayNumbers[i] = "";
+                } else {
+                    mDayNumbers[i] = String.format(Locale.getDefault(), "%d",
+                            mTempDate.get(Calendar.DAY_OF_MONTH));
+                }
+                mTempDate.add(Calendar.DAY_OF_MONTH, 1);
+            }
+            // We do one extra add at the end of the loop, if that pushed us to
+            // new month undo it
+            if (mTempDate.get(Calendar.DAY_OF_MONTH) == 1) {
+                mTempDate.add(Calendar.DAY_OF_MONTH, -1);
+            }
+            mLastWeekDayMonth = mTempDate.get(Calendar.MONTH);
+
+            updateSelectionPositions();
+        }
+
+        /**
+         * Initialize the paint instances.
+         */
+        private void initilaizePaints() {
+            mDrawPaint.setFakeBoldText(false);
+            mDrawPaint.setAntiAlias(true);
+            mDrawPaint.setStyle(Paint.Style.FILL);
+
+            mMonthNumDrawPaint.setFakeBoldText(true);
+            mMonthNumDrawPaint.setAntiAlias(true);
+            mMonthNumDrawPaint.setStyle(Paint.Style.FILL);
+            mMonthNumDrawPaint.setTextAlign(Paint.Align.CENTER);
+            mMonthNumDrawPaint.setTextSize(mDateTextSize);
+        }
+
+        /**
+         * Returns the month of the first day in this week.
+         *
+         * @return The month the first day of this view is in.
+         */
+        public int getMonthOfFirstWeekDay() {
+            return mMonthOfFirstWeekDay;
+        }
+
+        /**
+         * Returns the month of the last day in this week
+         *
+         * @return The month the last day of this view is in
+         */
+        public int getMonthOfLastWeekDay() {
+            return mLastWeekDayMonth;
+        }
+
+        /**
+         * Returns the first day in this view.
+         *
+         * @return The first day in the view.
+         */
+        public Calendar getFirstDay() {
+            return mFirstDay;
+        }
+
+        /**
+         * Calculates the day that the given x position is in, accounting for
+         * week number.
+         *
+         * @param x The x position of the touch event.
+         * @return True if a day was found for the given location.
+         */
+        public boolean getDayFromLocation(float x, Calendar outCalendar) {
+            final boolean isLayoutRtl = isLayoutRtl();
+
+            int start;
+            int end;
+
+            if (isLayoutRtl) {
+                start = 0;
+                end = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
+            } else {
+                start = mShowWeekNumber ? mWidth / mNumCells : 0;
+                end = mWidth;
+            }
+
+            if (x < start || x > end) {
+                outCalendar.clear();
+                return false;
+            }
+
+            // Selection is (x - start) / (pixels/day) which is (x - start) * day / pixels
+            int dayPosition = (int) ((x - start) * mDaysPerWeek / (end - start));
+
+            if (isLayoutRtl) {
+                dayPosition = mDaysPerWeek - 1 - dayPosition;
+            }
+
+            outCalendar.setTimeInMillis(mFirstDay.getTimeInMillis());
+            outCalendar.add(Calendar.DAY_OF_MONTH, dayPosition);
+
+            return true;
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            drawBackground(canvas);
+            drawWeekNumbersAndDates(canvas);
+            drawWeekSeparators(canvas);
+            drawSelectedDateVerticalBars(canvas);
+        }
+
+        /**
+         * This draws the selection highlight if a day is selected in this week.
+         *
+         * @param canvas The canvas to draw on
+         */
+        private void drawBackground(Canvas canvas) {
+            if (!mHasSelectedDay) {
+                return;
+            }
+            mDrawPaint.setColor(mSelectedWeekBackgroundColor);
+
+            mTempRect.top = mWeekSeperatorLineWidth;
+            mTempRect.bottom = mHeight;
+
+            final boolean isLayoutRtl = isLayoutRtl();
+
+            if (isLayoutRtl) {
+                mTempRect.left = 0;
+                mTempRect.right = mSelectedLeft - 2;
+            } else {
+                mTempRect.left = mShowWeekNumber ? mWidth / mNumCells : 0;
+                mTempRect.right = mSelectedLeft - 2;
+            }
+            canvas.drawRect(mTempRect, mDrawPaint);
+
+            if (isLayoutRtl) {
+                mTempRect.left = mSelectedRight + 3;
+                mTempRect.right = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
+            } else {
+                mTempRect.left = mSelectedRight + 3;
+                mTempRect.right = mWidth;
+            }
+            canvas.drawRect(mTempRect, mDrawPaint);
+        }
+
+        /**
+         * Draws the week and month day numbers for this week.
+         *
+         * @param canvas The canvas to draw on
+         */
+        private void drawWeekNumbersAndDates(Canvas canvas) {
+            final float textHeight = mDrawPaint.getTextSize();
+            final int y = (int) ((mHeight + textHeight) / 2) - mWeekSeperatorLineWidth;
+            final int nDays = mNumCells;
+            final int divisor = 2 * nDays;
+
+            mDrawPaint.setTextAlign(Paint.Align.CENTER);
+            mDrawPaint.setTextSize(mDateTextSize);
+
+            int i = 0;
+
+            if (isLayoutRtl()) {
+                for (; i < nDays - 1; i++) {
+                    mMonthNumDrawPaint.setColor(mFocusDay[i] ? mFocusedMonthDateColor
+                            : mUnfocusedMonthDateColor);
+                    int x = (2 * i + 1) * mWidth / divisor;
+                    canvas.drawText(mDayNumbers[nDays - 1 - i], x, y, mMonthNumDrawPaint);
+                }
+                if (mShowWeekNumber) {
+                    mDrawPaint.setColor(mWeekNumberColor);
+                    int x = mWidth - mWidth / divisor;
+                    canvas.drawText(mDayNumbers[0], x, y, mDrawPaint);
+                }
+            } else {
+                if (mShowWeekNumber) {
+                    mDrawPaint.setColor(mWeekNumberColor);
+                    int x = mWidth / divisor;
+                    canvas.drawText(mDayNumbers[0], x, y, mDrawPaint);
+                    i++;
+                }
+                for (; i < nDays; i++) {
+                    mMonthNumDrawPaint.setColor(mFocusDay[i] ? mFocusedMonthDateColor
+                            : mUnfocusedMonthDateColor);
+                    int x = (2 * i + 1) * mWidth / divisor;
+                    canvas.drawText(mDayNumbers[i], x, y, mMonthNumDrawPaint);
+                }
+            }
+        }
+
+        /**
+         * Draws a horizontal line for separating the weeks.
+         *
+         * @param canvas The canvas to draw on.
+         */
+        private void drawWeekSeparators(Canvas canvas) {
+            // If it is the topmost fully visible child do not draw separator line
+            int firstFullyVisiblePosition = mListView.getFirstVisiblePosition();
+            if (mListView.getChildAt(0).getTop() < 0) {
+                firstFullyVisiblePosition++;
+            }
+            if (firstFullyVisiblePosition == mWeek) {
+                return;
+            }
+            mDrawPaint.setColor(mWeekSeparatorLineColor);
+            mDrawPaint.setStrokeWidth(mWeekSeperatorLineWidth);
+            float startX;
+            float stopX;
+            if (isLayoutRtl()) {
+                startX = 0;
+                stopX = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
+            } else {
+                startX = mShowWeekNumber ? mWidth / mNumCells : 0;
+                stopX = mWidth;
+            }
+            canvas.drawLine(startX, 0, stopX, 0, mDrawPaint);
+        }
+
+        /**
+         * Draws the selected date bars if this week has a selected day.
+         *
+         * @param canvas The canvas to draw on
+         */
+        private void drawSelectedDateVerticalBars(Canvas canvas) {
+            if (!mHasSelectedDay) {
+                return;
+            }
+            mSelectedDateVerticalBar.setBounds(
+                    mSelectedLeft - mSelectedDateVerticalBarWidth / 2,
+                    mWeekSeperatorLineWidth,
+                    mSelectedLeft + mSelectedDateVerticalBarWidth / 2,
+                    mHeight);
+            mSelectedDateVerticalBar.draw(canvas);
+            mSelectedDateVerticalBar.setBounds(
+                    mSelectedRight - mSelectedDateVerticalBarWidth / 2,
+                    mWeekSeperatorLineWidth,
+                    mSelectedRight + mSelectedDateVerticalBarWidth / 2,
+                    mHeight);
+            mSelectedDateVerticalBar.draw(canvas);
+        }
+
+        @Override
+        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+            mWidth = w;
+            updateSelectionPositions();
+        }
+
+        /**
+         * This calculates the positions for the selected day lines.
+         */
+        private void updateSelectionPositions() {
+            if (mHasSelectedDay) {
+                final boolean isLayoutRtl = isLayoutRtl();
+                int selectedPosition = mSelectedDay - mFirstDayOfWeek;
+                if (selectedPosition < 0) {
+                    selectedPosition += 7;
+                }
+                if (mShowWeekNumber && !isLayoutRtl) {
+                    selectedPosition++;
+                }
+                if (isLayoutRtl) {
+                    mSelectedLeft = (mDaysPerWeek - 1 - selectedPosition) * mWidth / mNumCells;
+
+                } else {
+                    mSelectedLeft = selectedPosition * mWidth / mNumCells;
+                }
+                mSelectedRight = mSelectedLeft + mWidth / mNumCells;
+            }
+        }
+
+        @Override
+        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            mHeight = (mListView.getHeight() - mListView.getPaddingTop() - mListView
+                    .getPaddingBottom()) / mShownWeekCount;
+            setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mHeight);
+        }
+    }
+
+}
diff --git a/core/java/android/widget/CalendarViewMaterialDelegate.java b/core/java/android/widget/CalendarViewMaterialDelegate.java
new file mode 100644
index 0000000..b0f3740
--- /dev/null
+++ b/core/java/android/widget/CalendarViewMaterialDelegate.java
@@ -0,0 +1,260 @@
+/*
+ * 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 com.android.internal.R;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.MathUtils;
+
+import java.util.Calendar;
+import java.util.Locale;
+
+import libcore.icu.LocaleData;
+
+class CalendarViewMaterialDelegate extends CalendarView.AbstractCalendarViewDelegate {
+    private final DayPickerView mDayPickerView;
+
+    private CalendarView.OnDateChangeListener mOnDateChangeListener;
+
+    public CalendarViewMaterialDelegate(CalendarView delegator, Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        super(delegator, context);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                R.styleable.CalendarView, defStyleAttr, defStyleRes);
+        final int firstDayOfWeek = a.getInt(R.styleable.CalendarView_firstDayOfWeek,
+                LocaleData.get(Locale.getDefault()).firstDayOfWeek);
+
+        final long minDate = parseDateToMillis(a.getString(
+                R.styleable.CalendarView_minDate), DEFAULT_MIN_DATE);
+        final long maxDate = parseDateToMillis(a.getString(
+                R.styleable.CalendarView_maxDate), DEFAULT_MAX_DATE);
+        if (maxDate < minDate) {
+            throw new IllegalArgumentException("max date cannot be before min date");
+        }
+
+        final long setDate = MathUtils.constrain(System.currentTimeMillis(), minDate, maxDate);
+        final int dateTextAppearanceResId = a.getResourceId(
+                R.styleable.CalendarView_dateTextAppearance,
+                R.style.TextAppearance_DeviceDefault_Small);
+
+        a.recycle();
+
+        mDayPickerView = new DayPickerView(context);
+        mDayPickerView.setFirstDayOfWeek(firstDayOfWeek);
+        mDayPickerView.setCalendarTextAppearance(dateTextAppearanceResId);
+        mDayPickerView.setMinDate(minDate);
+        mDayPickerView.setMaxDate(maxDate);
+        mDayPickerView.setDate(setDate, false, true);
+        mDayPickerView.setOnDaySelectedListener(mOnDaySelectedListener);
+
+        delegator.addView(mDayPickerView);
+    }
+
+    private long parseDateToMillis(String dateStr, String defaultDateStr) {
+        final Calendar tempCalendar = Calendar.getInstance();
+        if (TextUtils.isEmpty(dateStr) || !parseDate(dateStr, tempCalendar)) {
+            parseDate(defaultDateStr, tempCalendar);
+        }
+        return tempCalendar.getTimeInMillis();
+    }
+
+    @Override
+    public void setShownWeekCount(int count) {
+        // Deprecated.
+    }
+
+    @Override
+    public int getShownWeekCount() {
+        // Deprecated.
+        return 0;
+    }
+
+    @Override
+    public void setSelectedWeekBackgroundColor(int color) {
+        // TODO: Should use a ColorStateList. Deprecate?
+    }
+
+    @Override
+    public int getSelectedWeekBackgroundColor() {
+        return 0;
+    }
+
+    @Override
+    public void setFocusedMonthDateColor(int color) {
+        // TODO: Should use a ColorStateList. Deprecate?
+    }
+
+    @Override
+    public int getFocusedMonthDateColor() {
+        return 0;
+    }
+
+    @Override
+    public void setUnfocusedMonthDateColor(int color) {
+        // TODO: Should use a ColorStateList. Deprecate?
+    }
+
+    @Override
+    public int getUnfocusedMonthDateColor() {
+        return 0;
+    }
+
+    @Override
+    public void setWeekDayTextAppearance(int resourceId) {
+
+    }
+
+    @Override
+    public int getWeekDayTextAppearance() {
+        return 0;
+    }
+
+    @Override
+    public void setDateTextAppearance(int resourceId) {
+
+    }
+
+    @Override
+    public int getDateTextAppearance() {
+        return 0;
+    }
+
+    @Override
+    public void setWeekNumberColor(int color) {
+        // Deprecated.
+    }
+
+    @Override
+    public int getWeekNumberColor() {
+        // Deprecated.
+        return 0;
+    }
+
+    @Override
+    public void setWeekSeparatorLineColor(int color) {
+        // Deprecated.
+    }
+
+    @Override
+    public int getWeekSeparatorLineColor() {
+        // Deprecated.
+        return 0;
+    }
+
+    @Override
+    public void setSelectedDateVerticalBar(int resourceId) {
+        // Deprecated.
+    }
+
+    @Override
+    public void setSelectedDateVerticalBar(Drawable drawable) {
+        // Deprecated.
+    }
+
+    @Override
+    public Drawable getSelectedDateVerticalBar() {
+        // Deprecated.
+        return null;
+    }
+
+    @Override
+    public void setMinDate(long minDate) {
+        mDayPickerView.setMinDate(minDate);
+    }
+
+    @Override
+    public long getMinDate() {
+        return mDayPickerView.getMinDate();
+    }
+
+    @Override
+    public void setMaxDate(long maxDate) {
+        mDayPickerView.setMaxDate(maxDate);
+    }
+
+    @Override
+    public long getMaxDate() {
+        return mDayPickerView.getMaxDate();
+    }
+
+    @Override
+    public void setShowWeekNumber(boolean showWeekNumber) {
+        // Deprecated.
+    }
+
+    @Override
+    public boolean getShowWeekNumber() {
+        // Deprecated.
+        return false;
+    }
+
+    @Override
+    public void setFirstDayOfWeek(int firstDayOfWeek) {
+        mDayPickerView.setFirstDayOfWeek(firstDayOfWeek);
+    }
+
+    @Override
+    public int getFirstDayOfWeek() {
+        return mDayPickerView.getFirstDayOfWeek();
+    }
+
+    @Override
+    public void setDate(long date) {
+        mDayPickerView.setDate(date, true, false);
+    }
+
+    @Override
+    public void setDate(long date, boolean animate, boolean center) {
+        mDayPickerView.setDate(date, animate, center);
+    }
+
+    @Override
+    public long getDate() {
+        return mDayPickerView.getDate();
+    }
+
+    @Override
+    public void setOnDateChangeListener(CalendarView.OnDateChangeListener listener) {
+        mOnDateChangeListener = listener;
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        // Nothing to do here, configuration changes are already propagated
+        // by ViewGroup.
+    }
+
+    private final DayPickerView.OnDaySelectedListener mOnDaySelectedListener =
+            new DayPickerView.OnDaySelectedListener() {
+        @Override
+        public void onDaySelected(DayPickerView view, Calendar day) {
+            if (mOnDateChangeListener != null) {
+                final int year = day.get(Calendar.YEAR);
+                final int month = day.get(Calendar.MONTH);
+                final int dayOfMonth = day.get(Calendar.DAY_OF_MONTH);
+                mOnDateChangeListener.onSelectedDayChange(mDelegator, year, month, dayOfMonth);
+            }
+        }
+    };
+}
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index cf3dbab..820bf78 100644
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -185,8 +185,9 @@
 
         mDayPickerView = new DayPickerView(mContext);
         mDayPickerView.setFirstDayOfWeek(mFirstDayOfWeek);
-        mDayPickerView.setRange(mMinDate, mMaxDate);
-        mDayPickerView.setDay(mCurrentDate);
+        mDayPickerView.setMinDate(mMinDate.getTimeInMillis());
+        mDayPickerView.setMaxDate(mMaxDate.getTimeInMillis());
+        mDayPickerView.setDate(mCurrentDate.getTimeInMillis());
         mDayPickerView.setOnDaySelectedListener(mOnDaySelectedListener);
 
         mYearPickerView = new YearPickerView(mContext);
@@ -336,7 +337,7 @@
 
         switch (viewIndex) {
             case MONTH_AND_DAY_VIEW:
-                mDayPickerView.setDay(getSelectedDay());
+                mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
                 if (mCurrentView != viewIndex) {
                     mMonthAndDayLayout.setSelected(true);
                     mHeaderYearTextView.setSelected(false);
@@ -414,7 +415,7 @@
             updateDisplay(false);
         }
         mMinDate.setTimeInMillis(minDate);
-        mDayPickerView.setRange(mMinDate, mMaxDate);
+        mDayPickerView.setMinDate(minDate);
         mYearPickerView.setRange(mMinDate, mMaxDate);
     }
 
@@ -436,7 +437,7 @@
             updateDisplay(false);
         }
         mMaxDate.setTimeInMillis(maxDate);
-        mDayPickerView.setRange(mMinDate, mMaxDate);
+        mDayPickerView.setMaxDate(maxDate);
         mYearPickerView.setRange(mMinDate, mMaxDate);
     }
 
@@ -616,7 +617,7 @@
             listener.onDateChanged();
         }
 
-        mDayPickerView.setDay(getSelectedDay());
+        mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
     }
 
     @Override
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index 6cb1c9d..7db3fb9 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -58,6 +58,8 @@
     private Calendar mMinDate = Calendar.getInstance();
     private Calendar mMaxDate = Calendar.getInstance();
 
+    private Calendar mTempCalendar;
+
     private OnDaySelectedListener mOnDaySelectedListener;
 
     // which month should be displayed/highlighted [0-11]
@@ -77,28 +79,65 @@
         setDrawSelectorOnTop(false);
         setUpListView();
 
-        goTo(mSelectedDay, false, true, true);
+        goTo(mSelectedDay.getTimeInMillis(), false, false, true);
 
         mAdapter.setOnDaySelectedListener(mProxyOnDaySelectedListener);
     }
 
-    public void setDay(Calendar day) {
-        goTo(day, false, true, true);
+    /**
+     * Sets the currently selected date to the specified timestamp. Jumps
+     * immediately to the new date. To animate to the new date, use
+     * {@link #setDate(long, boolean, boolean)}.
+     *
+     * @param timeInMillis
+     */
+    public void setDate(long timeInMillis) {
+        setDate(timeInMillis, false, true);
+    }
+
+    public void setDate(long timeInMillis, boolean animate, boolean forceScroll) {
+        goTo(timeInMillis, animate, true, forceScroll);
+    }
+
+    public long getDate() {
+        return mSelectedDay.getTimeInMillis();
     }
 
     public void setFirstDayOfWeek(int firstDayOfWeek) {
         mAdapter.setFirstDayOfWeek(firstDayOfWeek);
     }
 
-    public void setRange(Calendar minDate, Calendar maxDate) {
-        mMinDate.setTimeInMillis(minDate.getTimeInMillis());
-        mMaxDate.setTimeInMillis(maxDate.getTimeInMillis());
+    public int getFirstDayOfWeek() {
+        return mAdapter.getFirstDayOfWeek();
+    }
 
+    public void setMinDate(long timeInMillis) {
+        mMinDate.setTimeInMillis(timeInMillis);
+        onRangeChanged();
+    }
+
+    public long getMinDate() {
+        return mMinDate.getTimeInMillis();
+    }
+
+    public void setMaxDate(long timeInMillis) {
+        mMaxDate.setTimeInMillis(timeInMillis);
+        onRangeChanged();
+    }
+
+    public long getMaxDate() {
+        return mMaxDate.getTimeInMillis();
+    }
+
+    /**
+     * Handles changes to date range.
+     */
+    public void onRangeChanged() {
         mAdapter.setRange(mMinDate, mMaxDate);
 
         // Changing the min/max date changes the selection position since we
-        // don't really have stable IDs.
-        goTo(mSelectedDay, false, true, true);
+        // don't really have stable IDs. Jumps immediately to the new position.
+        goTo(mSelectedDay.getTimeInMillis(), false, false, true);
     }
 
     /**
@@ -136,12 +175,20 @@
         return diffMonths;
     }
 
-    private int getPositionFromDay(Calendar day) {
+    private int getPositionFromDay(long timeInMillis) {
         final int diffMonthMax = getDiffMonths(mMinDate, mMaxDate);
-        final int diffMonth = getDiffMonths(mMinDate, day);
+        final int diffMonth = getDiffMonths(mMinDate, getTempCalendarForTime(timeInMillis));
         return MathUtils.constrain(diffMonth, 0, diffMonthMax);
     }
 
+    private Calendar getTempCalendarForTime(long timeInMillis) {
+        if (mTempCalendar == null) {
+            mTempCalendar = Calendar.getInstance();
+        }
+        mTempCalendar.setTimeInMillis(timeInMillis);
+        return mTempCalendar;
+    }
+
     /**
      * This moves to the specified time in the view. If the time is not already
      * in range it will move the list so that the first of the month containing
@@ -157,14 +204,14 @@
      *            visible
      * @return Whether or not the view animated to the new location
      */
-    private boolean goTo(Calendar day, boolean animate, boolean setSelected, boolean forceScroll) {
+    private boolean goTo(long day, boolean animate, boolean setSelected, boolean forceScroll) {
 
         // Set the selected day
         if (setSelected) {
-            mSelectedDay.setTimeInMillis(day.getTimeInMillis());
+            mSelectedDay.setTimeInMillis(day);
         }
 
-        mTempDay.setTimeInMillis(day.getTimeInMillis());
+        mTempDay.setTimeInMillis(day);
         final int position = getPositionFromDay(day);
 
         View child;
@@ -258,6 +305,10 @@
         mAdapter.setCalendarTextColor(colors);
     }
 
+    void setCalendarTextAppearance(int resId) {
+        mAdapter.setCalendarTextAppearance(resId);
+    }
+
     protected class ScrollStateRunnable implements Runnable {
         private int mNewState;
         private View mParent;
@@ -415,7 +466,7 @@
     }
 
     private String getMonthAndYearString(Calendar day) {
-        StringBuffer sbuf = new StringBuffer();
+        final StringBuilder sbuf = new StringBuilder();
         sbuf.append(day.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()));
         sbuf.append(" ");
         sbuf.append(mYearFormat.format(day.getTime()));
@@ -429,8 +480,8 @@
     @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
-        info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
-        info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD);
+        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD);
     }
 
     /**
@@ -474,7 +525,7 @@
 
         // Go to that month.
         announceForAccessibility(getMonthAndYearString(day));
-        goTo(day, true, false, true);
+        goTo(day.getTimeInMillis(), true, false, true);
         mPerformingScroll = true;
         return true;
     }
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index 0687905..06bb32c 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -1194,17 +1194,37 @@
         return MathUtils.constrain((y - offset) / range, 0f, 1f);
     }
 
+    /**
+     * Calculates the thumb position based on the visible items.
+     *
+     * @param firstVisibleItem First visible item, >= 0.
+     * @param visibleItemCount Number of visible items, >= 0.
+     * @param totalItemCount Total number of items, >= 0.
+     * @return
+     */
     private float getPosFromItemCount(
             int firstVisibleItem, int visibleItemCount, int totalItemCount) {
-        if (mSectionIndexer == null || mListAdapter == null) {
+        final SectionIndexer sectionIndexer = mSectionIndexer;
+        if (sectionIndexer == null || mListAdapter == null) {
             getSectionsFromIndexer();
         }
 
-        final boolean hasSections = mSectionIndexer != null && mSections != null
+        if (visibleItemCount == 0 || totalItemCount == 0) {
+            // No items are visible.
+            return 0;
+        }
+
+        final boolean hasSections = sectionIndexer != null && mSections != null
                 && mSections.length > 0;
         if (!hasSections || !mMatchDragPosition) {
-            return (float) firstVisibleItem / (totalItemCount - visibleItemCount);
+            if (visibleItemCount == totalItemCount) {
+                // All items are visible.
+                return 0;
+            } else {
+                return (float) firstVisibleItem / (totalItemCount - visibleItemCount);
+            }
         }
+
         // Ignore headers.
         firstVisibleItem -= mHeaderCount;
         if (firstVisibleItem < 0) {
@@ -1222,14 +1242,14 @@
         }
 
         // Number of rows in this section.
-        final int section = mSectionIndexer.getSectionForPosition(firstVisibleItem);
-        final int sectionPos = mSectionIndexer.getPositionForSection(section);
+        final int section = sectionIndexer.getSectionForPosition(firstVisibleItem);
+        final int sectionPos = sectionIndexer.getPositionForSection(section);
         final int sectionCount = mSections.length;
         final int positionsInSection;
         if (section < sectionCount - 1) {
             final int nextSectionPos;
             if (section + 1 < sectionCount) {
-                nextSectionPos = mSectionIndexer.getPositionForSection(section + 1);
+                nextSectionPos = sectionIndexer.getPositionForSection(section + 1);
             } else {
                 nextSectionPos = totalItemCount - 1;
             }
diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java
index 24fc2bb..8b01dde 100644
--- a/core/java/android/widget/RadialTimePickerView.java
+++ b/core/java/android/widget/RadialTimePickerView.java
@@ -452,7 +452,10 @@
     }
 
     public void initialize(int hour, int minute, boolean is24HourMode) {
-        mIs24HourMode = is24HourMode;
+        if (mIs24HourMode != is24HourMode) {
+            mIs24HourMode = is24HourMode;
+            initData();
+        }
 
         setCurrentHourInternal(hour, false, false);
         setCurrentMinuteInternal(minute, false);
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index dfdf606..4ee6418 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -45,7 +45,6 @@
 import android.text.style.ImageSpan;
 import android.util.AttributeSet;
 import android.util.Log;
-import android.util.TypedValue;
 import android.view.CollapsibleActionView;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -99,17 +98,21 @@
      */
     private static final String IME_OPTION_NO_MICROPHONE = "nm";
 
-    private final SearchAutoComplete mQueryTextView;
+    private final SearchAutoComplete mSearchSrcTextView;
     private final View mSearchEditFrame;
     private final View mSearchPlate;
     private final View mSubmitArea;
     private final ImageView mSearchButton;
-    private final ImageView mSubmitButton;
+    private final ImageView mGoButton;
     private final ImageView mCloseButton;
     private final ImageView mVoiceButton;
-    private final ImageView mSearchHintIcon;
     private final View mDropDownAnchor;
-    private final int mSearchIconResId;
+
+    /** Icon optionally displayed when the SearchView is collapsed. */
+    private final ImageView mCollapsedIcon;
+
+    /** Drawable used as an EditText hint. */
+    private final Drawable mSearchHintIcon;
 
     // Resources used by SuggestionsAdapter to display suggestions.
     private final int mSuggestionRowLayout;
@@ -262,30 +265,38 @@
                 attrs, R.styleable.SearchView, defStyleAttr, defStyleRes);
         final LayoutInflater inflater = (LayoutInflater) context.getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
-        final int layoutResId = a.getResourceId(R.styleable.SearchView_layout, R.layout.search_view);
+        final int layoutResId = a.getResourceId(
+                R.styleable.SearchView_layout, R.layout.search_view);
         inflater.inflate(layoutResId, this, true);
 
-        mQueryTextView = (SearchAutoComplete) findViewById(R.id.search_src_text);
-        mQueryTextView.setSearchView(this);
+        mSearchSrcTextView = (SearchAutoComplete) findViewById(R.id.search_src_text);
+        mSearchSrcTextView.setSearchView(this);
 
         mSearchEditFrame = findViewById(R.id.search_edit_frame);
         mSearchPlate = findViewById(R.id.search_plate);
         mSubmitArea = findViewById(R.id.submit_area);
         mSearchButton = (ImageView) findViewById(R.id.search_button);
-        mSubmitButton = (ImageView) findViewById(R.id.search_go_btn);
+        mGoButton = (ImageView) findViewById(R.id.search_go_btn);
         mCloseButton = (ImageView) findViewById(R.id.search_close_btn);
         mVoiceButton = (ImageView) findViewById(R.id.search_voice_btn);
-        mSearchHintIcon = (ImageView) findViewById(R.id.search_mag_icon);
+        mCollapsedIcon = (ImageView) findViewById(R.id.search_mag_icon);
 
         // Set up icons and backgrounds.
         mSearchPlate.setBackground(a.getDrawable(R.styleable.SearchView_queryBackground));
         mSubmitArea.setBackground(a.getDrawable(R.styleable.SearchView_submitBackground));
-        mSearchIconResId = a.getResourceId(R.styleable.SearchView_searchIcon, 0);
-        mSearchButton.setImageResource(mSearchIconResId);
-        mSubmitButton.setImageDrawable(a.getDrawable(R.styleable.SearchView_goIcon));
+        mSearchButton.setImageDrawable(a.getDrawable(R.styleable.SearchView_searchIcon));
+        mGoButton.setImageDrawable(a.getDrawable(R.styleable.SearchView_goIcon));
         mCloseButton.setImageDrawable(a.getDrawable(R.styleable.SearchView_closeIcon));
         mVoiceButton.setImageDrawable(a.getDrawable(R.styleable.SearchView_voiceIcon));
-        mSearchHintIcon.setImageDrawable(a.getDrawable(R.styleable.SearchView_searchIcon));
+        mCollapsedIcon.setImageDrawable(a.getDrawable(R.styleable.SearchView_searchIcon));
+
+        // Prior to L MR1, the search hint icon defaulted to searchIcon. If the
+        // style does not have an explicit value set, fall back to that.
+        if (a.hasValueOrEmpty(R.styleable.SearchView_searchHintIcon)) {
+            mSearchHintIcon = a.getDrawable(R.styleable.SearchView_searchHintIcon);
+        } else {
+            mSearchHintIcon = a.getDrawable(R.styleable.SearchView_searchIcon);
+        }
 
         // Extract dropdown layout resource IDs for later use.
         mSuggestionRowLayout = a.getResourceId(R.styleable.SearchView_suggestionRowLayout,
@@ -294,18 +305,18 @@
 
         mSearchButton.setOnClickListener(mOnClickListener);
         mCloseButton.setOnClickListener(mOnClickListener);
-        mSubmitButton.setOnClickListener(mOnClickListener);
+        mGoButton.setOnClickListener(mOnClickListener);
         mVoiceButton.setOnClickListener(mOnClickListener);
-        mQueryTextView.setOnClickListener(mOnClickListener);
+        mSearchSrcTextView.setOnClickListener(mOnClickListener);
 
-        mQueryTextView.addTextChangedListener(mTextWatcher);
-        mQueryTextView.setOnEditorActionListener(mOnEditorActionListener);
-        mQueryTextView.setOnItemClickListener(mOnItemClickListener);
-        mQueryTextView.setOnItemSelectedListener(mOnItemSelectedListener);
-        mQueryTextView.setOnKeyListener(mTextKeyListener);
+        mSearchSrcTextView.addTextChangedListener(mTextWatcher);
+        mSearchSrcTextView.setOnEditorActionListener(mOnEditorActionListener);
+        mSearchSrcTextView.setOnItemClickListener(mOnItemClickListener);
+        mSearchSrcTextView.setOnItemSelectedListener(mOnItemSelectedListener);
+        mSearchSrcTextView.setOnKeyListener(mTextKeyListener);
 
         // Inform any listener of focus changes
-        mQueryTextView.setOnFocusChangeListener(new OnFocusChangeListener() {
+        mSearchSrcTextView.setOnFocusChangeListener(new OnFocusChangeListener() {
 
             public void onFocusChange(View v, boolean hasFocus) {
                 if (mOnQueryTextFocusChangeListener != null) {
@@ -350,7 +361,7 @@
         mVoiceAppSearchIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
         mVoiceAppSearchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
-        mDropDownAnchor = findViewById(mQueryTextView.getDropDownAnchor());
+        mDropDownAnchor = findViewById(mSearchSrcTextView.getDropDownAnchor());
         if (mDropDownAnchor != null) {
             mDropDownAnchor.addOnLayoutChangeListener(new OnLayoutChangeListener() {
                 @Override
@@ -393,7 +404,7 @@
         if (mVoiceButtonEnabled) {
             // Disable the microphone on the keyboard, as a mic is displayed near the text box
             // TODO: use imeOptions to disable voice input when the new API will be available
-            mQueryTextView.setPrivateImeOptions(IME_OPTION_NO_MICROPHONE);
+            mSearchSrcTextView.setPrivateImeOptions(IME_OPTION_NO_MICROPHONE);
         }
         updateViewsVisibility(isIconified());
     }
@@ -416,7 +427,7 @@
      * @attr ref android.R.styleable#SearchView_imeOptions
      */
     public void setImeOptions(int imeOptions) {
-        mQueryTextView.setImeOptions(imeOptions);
+        mSearchSrcTextView.setImeOptions(imeOptions);
     }
 
     /**
@@ -427,7 +438,7 @@
      * @attr ref android.R.styleable#SearchView_imeOptions
      */
     public int getImeOptions() {
-        return mQueryTextView.getImeOptions();
+        return mSearchSrcTextView.getImeOptions();
     }
 
     /**
@@ -439,7 +450,7 @@
      * @attr ref android.R.styleable#SearchView_inputType
      */
     public void setInputType(int inputType) {
-        mQueryTextView.setInputType(inputType);
+        mSearchSrcTextView.setInputType(inputType);
     }
 
     /**
@@ -449,7 +460,7 @@
      * @attr ref android.R.styleable#SearchView_inputType
      */
     public int getInputType() {
-        return mQueryTextView.getInputType();
+        return mSearchSrcTextView.getInputType();
     }
 
     /** @hide */
@@ -461,7 +472,7 @@
         if (!isFocusable()) return false;
         // If it is not iconified, then give the focus to the text field
         if (!isIconified()) {
-            boolean result = mQueryTextView.requestFocus(direction, previouslyFocusedRect);
+            boolean result = mSearchSrcTextView.requestFocus(direction, previouslyFocusedRect);
             if (result) {
                 updateViewsVisibility(false);
             }
@@ -477,7 +488,7 @@
         mClearingFocus = true;
         setImeVisibility(false);
         super.clearFocus();
-        mQueryTextView.clearFocus();
+        mSearchSrcTextView.clearFocus();
         mClearingFocus = false;
     }
 
@@ -536,7 +547,7 @@
      * @return the query string
      */
     public CharSequence getQuery() {
-        return mQueryTextView.getText();
+        return mSearchSrcTextView.getText();
     }
 
     /**
@@ -548,9 +559,9 @@
      * text field.
      */
     public void setQuery(CharSequence query, boolean submit) {
-        mQueryTextView.setText(query);
+        mSearchSrcTextView.setText(query);
         if (query != null) {
-            mQueryTextView.setSelection(mQueryTextView.length());
+            mSearchSrcTextView.setSelection(mSearchSrcTextView.length());
             mUserQuery = query;
         }
 
@@ -711,7 +722,7 @@
     public void setSuggestionsAdapter(CursorAdapter adapter) {
         mSuggestionsAdapter = adapter;
 
-        mQueryTextView.setAdapter(mSuggestionsAdapter);
+        mSearchSrcTextView.setAdapter(mSuggestionsAdapter);
     }
 
     /**
@@ -789,12 +800,12 @@
         // Visibility of views that are visible when collapsed
         final int visCollapsed = collapsed ? VISIBLE : GONE;
         // Is there text in the query
-        final boolean hasText = !TextUtils.isEmpty(mQueryTextView.getText());
+        final boolean hasText = !TextUtils.isEmpty(mSearchSrcTextView.getText());
 
         mSearchButton.setVisibility(visCollapsed);
         updateSubmitButton(hasText);
         mSearchEditFrame.setVisibility(collapsed ? GONE : VISIBLE);
-        mSearchHintIcon.setVisibility(mIconifiedByDefault ? GONE : VISIBLE);
+        mCollapsedIcon.setVisibility(mIconifiedByDefault ? GONE : VISIBLE);
         updateCloseButton();
         updateVoiceButton(!hasText);
         updateSubmitArea();
@@ -827,13 +838,13 @@
                 && (hasText || !mVoiceButtonEnabled)) {
             visibility = VISIBLE;
         }
-        mSubmitButton.setVisibility(visibility);
+        mGoButton.setVisibility(visibility);
     }
 
     private void updateSubmitArea() {
         int visibility = GONE;
         if (isSubmitAreaEnabled()
-                && (mSubmitButton.getVisibility() == VISIBLE
+                && (mGoButton.getVisibility() == VISIBLE
                         || mVoiceButton.getVisibility() == VISIBLE)) {
             visibility = VISIBLE;
         }
@@ -841,12 +852,15 @@
     }
 
     private void updateCloseButton() {
-        final boolean hasText = !TextUtils.isEmpty(mQueryTextView.getText());
+        final boolean hasText = !TextUtils.isEmpty(mSearchSrcTextView.getText());
         // Should we show the close button? It is not shown if there's no focus,
         // field is not iconified by default and there is no text in it.
         final boolean showClose = hasText || (mIconifiedByDefault && !mExpandedInActionView);
         mCloseButton.setVisibility(showClose ? VISIBLE : GONE);
-        mCloseButton.getDrawable().setState(hasText ? ENABLED_STATE_SET : EMPTY_STATE_SET);
+        final Drawable closeButtonImg = mCloseButton.getDrawable();
+        if (closeButtonImg != null){
+            closeButtonImg.setState(hasText ? ENABLED_STATE_SET : EMPTY_STATE_SET);
+        }
     }
 
     private void postUpdateFocusedState() {
@@ -854,9 +868,16 @@
     }
 
     private void updateFocusedState() {
-        boolean focused = mQueryTextView.hasFocus();
-        mSearchPlate.getBackground().setState(focused ? FOCUSED_STATE_SET : EMPTY_STATE_SET);
-        mSubmitArea.getBackground().setState(focused ? FOCUSED_STATE_SET : EMPTY_STATE_SET);
+        final boolean focused = mSearchSrcTextView.hasFocus();
+        final int[] stateSet = focused ? FOCUSED_STATE_SET : EMPTY_STATE_SET;
+        final Drawable searchPlateBg = mSearchPlate.getBackground();
+        if (searchPlateBg != null) {
+            searchPlateBg.setState(stateSet);
+        }
+        final Drawable submitAreaBg = mSubmitArea.getBackground();
+        if (submitAreaBg != null) {
+            submitAreaBg.setState(stateSet);
+        }
         invalidate();
     }
 
@@ -896,11 +917,11 @@
                 onSearchClicked();
             } else if (v == mCloseButton) {
                 onCloseClicked();
-            } else if (v == mSubmitButton) {
+            } else if (v == mGoButton) {
                 onSubmitQuery();
             } else if (v == mVoiceButton) {
                 onVoiceClicked();
-            } else if (v == mQueryTextView) {
+            } else if (v == mSearchSrcTextView) {
                 forceSuggestionQuery();
             }
         }
@@ -925,7 +946,7 @@
         // entered query with the action key
         SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode);
         if ((actionKey != null) && (actionKey.getQueryActionMsg() != null)) {
-            launchQuerySearch(keyCode, actionKey.getQueryActionMsg(), mQueryTextView.getText()
+            launchQuerySearch(keyCode, actionKey.getQueryActionMsg(), mSearchSrcTextView.getText()
                     .toString());
             return true;
         }
@@ -947,25 +968,25 @@
 
             if (DBG) {
                 Log.d(LOG_TAG, "mTextListener.onKey(" + keyCode + "," + event + "), selection: "
-                        + mQueryTextView.getListSelection());
+                        + mSearchSrcTextView.getListSelection());
             }
 
             // If a suggestion is selected, handle enter, search key, and action keys
             // as presses on the selected suggestion
-            if (mQueryTextView.isPopupShowing()
-                    && mQueryTextView.getListSelection() != ListView.INVALID_POSITION) {
+            if (mSearchSrcTextView.isPopupShowing()
+                    && mSearchSrcTextView.getListSelection() != ListView.INVALID_POSITION) {
                 return onSuggestionsKey(v, keyCode, event);
             }
 
             // If there is text in the query box, handle enter, and action keys
             // The search key is handled by the dialog's onKeyDown().
-            if (!mQueryTextView.isEmpty() && event.hasNoModifiers()) {
+            if (!mSearchSrcTextView.isEmpty() && event.hasNoModifiers()) {
                 if (event.getAction() == KeyEvent.ACTION_UP) {
                     if (keyCode == KeyEvent.KEYCODE_ENTER) {
                         v.cancelLongPress();
 
                         // Launch as a regular search.
-                        launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null, mQueryTextView.getText()
+                        launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null, mSearchSrcTextView.getText()
                                 .toString());
                         return true;
                     }
@@ -973,7 +994,7 @@
                 if (event.getAction() == KeyEvent.ACTION_DOWN) {
                     SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode);
                     if ((actionKey != null) && (actionKey.getQueryActionMsg() != null)) {
-                        launchQuerySearch(keyCode, actionKey.getQueryActionMsg(), mQueryTextView
+                        launchQuerySearch(keyCode, actionKey.getQueryActionMsg(), mSearchSrcTextView
                                 .getText().toString());
                         return true;
                     }
@@ -1001,7 +1022,7 @@
             // "click")
             if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_SEARCH
                     || keyCode == KeyEvent.KEYCODE_TAB) {
-                int position = mQueryTextView.getListSelection();
+                int position = mSearchSrcTextView.getListSelection();
                 return onItemClicked(position, KeyEvent.KEYCODE_UNKNOWN, null);
             }
 
@@ -1012,18 +1033,18 @@
                 // left key, at end if right key
                 // TODO: Reverse left/right for right-to-left languages, e.g.
                 // Arabic
-                int selPoint = (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) ? 0 : mQueryTextView
+                int selPoint = (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) ? 0 : mSearchSrcTextView
                         .length();
-                mQueryTextView.setSelection(selPoint);
-                mQueryTextView.setListSelection(0);
-                mQueryTextView.clearListSelection();
-                mQueryTextView.ensureImeVisible(true);
+                mSearchSrcTextView.setSelection(selPoint);
+                mSearchSrcTextView.setListSelection(0);
+                mSearchSrcTextView.clearListSelection();
+                mSearchSrcTextView.ensureImeVisible(true);
 
                 return true;
             }
 
             // Next, check for an "up and out" move
-            if (keyCode == KeyEvent.KEYCODE_DPAD_UP && 0 == mQueryTextView.getListSelection()) {
+            if (keyCode == KeyEvent.KEYCODE_DPAD_UP && 0 == mSearchSrcTextView.getListSelection()) {
                 // TODO: restoreUserQuery();
                 // let ACTV complete the move
                 return false;
@@ -1035,7 +1056,7 @@
                     && ((actionKey.getSuggestActionMsg() != null) || (actionKey
                             .getSuggestActionMsgColumn() != null))) {
                 // launch suggestion using action key column
-                int position = mQueryTextView.getListSelection();
+                int position = mSearchSrcTextView.getListSelection();
                 if (position != ListView.INVALID_POSITION) {
                     Cursor c = mSuggestionsAdapter.getCursor();
                     if (c.moveToPosition(position)) {
@@ -1078,24 +1099,24 @@
     }
 
     private CharSequence getDecoratedHint(CharSequence hintText) {
-        // If the field is always expanded, then don't add the search icon to the hint
-        if (!mIconifiedByDefault) {
+        // If the field is always expanded or we don't have a search hint icon,
+        // then don't add the search icon to the hint.
+        if (!mIconifiedByDefault || mSearchHintIcon == null) {
             return hintText;
         }
 
-        final Drawable searchIcon = getContext().getDrawable(mSearchIconResId);
-        final int textSize = (int) (mQueryTextView.getTextSize() * 1.25);
-        searchIcon.setBounds(0, 0, textSize, textSize);
+        final int textSize = (int) (mSearchSrcTextView.getTextSize() * 1.25);
+        mSearchHintIcon.setBounds(0, 0, textSize, textSize);
 
-        final SpannableStringBuilder ssb = new SpannableStringBuilder("   "); // for the icon
+        final SpannableStringBuilder ssb = new SpannableStringBuilder("   ");
+        ssb.setSpan(new ImageSpan(mSearchHintIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
         ssb.append(hintText);
-        ssb.setSpan(new ImageSpan(searchIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
         return ssb;
     }
 
     private void updateQueryHint() {
         if (mQueryHint != null) {
-            mQueryTextView.setHint(getDecoratedHint(mQueryHint));
+            mSearchSrcTextView.setHint(getDecoratedHint(mQueryHint));
         } else if (mSearchable != null) {
             CharSequence hint = null;
             int hintId = mSearchable.getHintId();
@@ -1103,10 +1124,10 @@
                 hint = getContext().getString(hintId);
             }
             if (hint != null) {
-                mQueryTextView.setHint(getDecoratedHint(hint));
+                mSearchSrcTextView.setHint(getDecoratedHint(hint));
             }
         } else {
-            mQueryTextView.setHint(getDecoratedHint(""));
+            mSearchSrcTextView.setHint(getDecoratedHint(""));
         }
     }
 
@@ -1114,9 +1135,9 @@
      * Updates the auto-complete text view.
      */
     private void updateSearchAutoComplete() {
-        mQueryTextView.setDropDownAnimationStyle(0); // no animation
-        mQueryTextView.setThreshold(mSearchable.getSuggestThreshold());
-        mQueryTextView.setImeOptions(mSearchable.getImeOptions());
+        mSearchSrcTextView.setDropDownAnimationStyle(0); // no animation
+        mSearchSrcTextView.setThreshold(mSearchable.getSuggestThreshold());
+        mSearchSrcTextView.setImeOptions(mSearchable.getImeOptions());
         int inputType = mSearchable.getInputType();
         // We only touch this if the input type is set up for text (which it almost certainly
         // should be, in the case of search!)
@@ -1135,7 +1156,7 @@
                 inputType |= InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
             }
         }
-        mQueryTextView.setInputType(inputType);
+        mSearchSrcTextView.setInputType(inputType);
         if (mSuggestionsAdapter != null) {
             mSuggestionsAdapter.changeCursor(null);
         }
@@ -1144,7 +1165,7 @@
         if (mSearchable.getSuggestAuthority() != null) {
             mSuggestionsAdapter = new SuggestionsAdapter(getContext(),
                     this, mSearchable, mOutsideDrawablesCache);
-            mQueryTextView.setAdapter(mSuggestionsAdapter);
+            mSearchSrcTextView.setAdapter(mSuggestionsAdapter);
             ((SuggestionsAdapter) mSuggestionsAdapter).setQueryRefinement(
                     mQueryRefinement ? SuggestionsAdapter.REFINE_ALL
                     : SuggestionsAdapter.REFINE_BY_ENTRY);
@@ -1161,7 +1182,7 @@
         int visibility = GONE;
         if (mVoiceButtonEnabled && !isIconified() && empty) {
             visibility = VISIBLE;
-            mSubmitButton.setVisibility(GONE);
+            mGoButton.setVisibility(GONE);
         }
         mVoiceButton.setVisibility(visibility);
     }
@@ -1178,7 +1199,7 @@
     };
 
     private void onTextChanged(CharSequence newText) {
-        CharSequence text = mQueryTextView.getText();
+        CharSequence text = mSearchSrcTextView.getText();
         mUserQuery = text;
         boolean hasText = !TextUtils.isEmpty(text);
         updateSubmitButton(hasText);
@@ -1192,7 +1213,7 @@
     }
 
     private void onSubmitQuery() {
-        CharSequence query = mQueryTextView.getText();
+        CharSequence query = mSearchSrcTextView.getText();
         if (query != null && TextUtils.getTrimmedLength(query) > 0) {
             if (mOnQueryChangeListener == null
                     || !mOnQueryChangeListener.onQueryTextSubmit(query.toString())) {
@@ -1206,11 +1227,11 @@
     }
 
     private void dismissSuggestions() {
-        mQueryTextView.dismissDropDown();
+        mSearchSrcTextView.dismissDropDown();
     }
 
     private void onCloseClicked() {
-        CharSequence text = mQueryTextView.getText();
+        CharSequence text = mSearchSrcTextView.getText();
         if (TextUtils.isEmpty(text)) {
             if (mIconifiedByDefault) {
                 // If the app doesn't override the close behavior
@@ -1222,8 +1243,8 @@
                 }
             }
         } else {
-            mQueryTextView.setText("");
-            mQueryTextView.requestFocus();
+            mSearchSrcTextView.setText("");
+            mSearchSrcTextView.requestFocus();
             setImeVisibility(true);
         }
 
@@ -1231,7 +1252,7 @@
 
     private void onSearchClicked() {
         updateViewsVisibility(false);
-        mQueryTextView.requestFocus();
+        mSearchSrcTextView.requestFocus();
         setImeVisibility(true);
         if (mOnSearchClickListener != null) {
             mOnSearchClickListener.onClick(this);
@@ -1266,7 +1287,7 @@
         // Delayed update to make sure that the focus has settled down and window focus changes
         // don't affect it. A synchronous update was not working.
         postUpdateFocusedState();
-        if (mQueryTextView.hasFocus()) {
+        if (mSearchSrcTextView.hasFocus()) {
             forceSuggestionQuery();
         }
     }
@@ -1286,7 +1307,7 @@
         setQuery("", false);
         clearFocus();
         updateViewsVisibility(true);
-        mQueryTextView.setImeOptions(mCollapsedImeOptions);
+        mSearchSrcTextView.setImeOptions(mCollapsedImeOptions);
         mExpandedInActionView = false;
     }
 
@@ -1298,9 +1319,9 @@
         if (mExpandedInActionView) return;
 
         mExpandedInActionView = true;
-        mCollapsedImeOptions = mQueryTextView.getImeOptions();
-        mQueryTextView.setImeOptions(mCollapsedImeOptions | EditorInfo.IME_FLAG_NO_FULLSCREEN);
-        mQueryTextView.setText("");
+        mCollapsedImeOptions = mSearchSrcTextView.getImeOptions();
+        mSearchSrcTextView.setImeOptions(mCollapsedImeOptions | EditorInfo.IME_FLAG_NO_FULLSCREEN);
+        mSearchSrcTextView.setText("");
         setIconified(false);
     }
 
@@ -1326,17 +1347,17 @@
                     ? res.getDimensionPixelSize(R.dimen.dropdownitem_icon_width)
                     + res.getDimensionPixelSize(R.dimen.dropdownitem_text_padding_left)
                     : 0;
-            mQueryTextView.getDropDownBackground().getPadding(dropDownPadding);
+            mSearchSrcTextView.getDropDownBackground().getPadding(dropDownPadding);
             int offset;
             if (isLayoutRtl) {
                 offset = - dropDownPadding.left;
             } else {
                 offset = anchorPadding - (dropDownPadding.left + iconOffset);
             }
-            mQueryTextView.setDropDownHorizontalOffset(offset);
+            mSearchSrcTextView.setDropDownHorizontalOffset(offset);
             final int width = mDropDownAnchor.getWidth() + dropDownPadding.left
                     + dropDownPadding.right + iconOffset - anchorPadding;
-            mQueryTextView.setDropDownWidth(width);
+            mSearchSrcTextView.setDropDownWidth(width);
         }
     }
 
@@ -1394,7 +1415,7 @@
      * Query rewriting.
      */
     private void rewriteQueryFromSuggestion(int position) {
-        CharSequence oldQuery = mQueryTextView.getText();
+        CharSequence oldQuery = mSearchSrcTextView.getText();
         Cursor c = mSuggestionsAdapter.getCursor();
         if (c == null) {
             return;
@@ -1460,9 +1481,9 @@
      * Sets the text in the query box, without updating the suggestions.
      */
     private void setQuery(CharSequence query) {
-        mQueryTextView.setText(query, true);
+        mSearchSrcTextView.setText(query, true);
         // Move the cursor to the end
-        mQueryTextView.setSelection(TextUtils.isEmpty(query) ? 0 : query.length());
+        mSearchSrcTextView.setSelection(TextUtils.isEmpty(query) ? 0 : query.length());
     }
 
     private void launchQuerySearch(int actionKey, String actionMsg, String query) {
@@ -1648,8 +1669,8 @@
     }
 
     private void forceSuggestionQuery() {
-        mQueryTextView.doBeforeTextChanged();
-        mQueryTextView.doAfterTextChanged();
+        mSearchSrcTextView.doBeforeTextChanged();
+        mSearchSrcTextView.doAfterTextChanged();
     }
 
     static boolean isLandscapeMode(Context context) {
diff --git a/core/java/android/widget/SimpleMonthAdapter.java b/core/java/android/widget/SimpleMonthAdapter.java
index ecd2912..24ebb2c 100644
--- a/core/java/android/widget/SimpleMonthAdapter.java
+++ b/core/java/android/widget/SimpleMonthAdapter.java
@@ -16,8 +16,12 @@
 
 package android.widget;
 
+import com.android.internal.R;
+
 import android.content.Context;
 import android.content.res.ColorStateList;
+import android.content.res.TypedArray;
+import android.graphics.Color;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.SimpleMonthView.OnDayClickListener;
@@ -33,15 +37,14 @@
 
     private final Context mContext;
 
-    private Calendar mSelectedDay;
-    private ColorStateList mCalendarTextColors;
+    private Calendar mSelectedDay = Calendar.getInstance();
+    private ColorStateList mCalendarTextColors = ColorStateList.valueOf(Color.BLACK);
     private OnDaySelectedListener mOnDaySelectedListener;
 
     private int mFirstDayOfWeek;
 
     public SimpleMonthAdapter(Context context) {
         mContext = context;
-        mSelectedDay = Calendar.getInstance();
     }
 
     public void setRange(Calendar min, Calendar max) {
@@ -57,6 +60,10 @@
         notifyDataSetInvalidated();
     }
 
+    public int getFirstDayOfWeek() {
+        return mFirstDayOfWeek;
+    }
+
     /**
      * Updates the selected day and related parameters.
      *
@@ -81,6 +88,24 @@
         mCalendarTextColors = colors;
     }
 
+    /**
+     * Sets the text color, size, style, hint color, and highlight color from
+     * the specified TextAppearance resource. This is mostly copied from
+     * {@link TextView#setTextAppearance(Context, int)}.
+     */
+    void setCalendarTextAppearance(int resId) {
+        final TypedArray a = mContext.obtainStyledAttributes(resId, R.styleable.TextAppearance);
+
+        final ColorStateList textColor = a.getColorStateList(R.styleable.TextAppearance_textColor);
+        if (textColor != null) {
+            mCalendarTextColors = textColor;
+        }
+
+        // TODO: Support font size, etc.
+
+        a.recycle();
+    }
+
     @Override
     public int getCount() {
         final int diffYear = mMaxDate.get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR);
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index d8dffe0..044383e 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -35,6 +35,8 @@
 
 import com.android.org.bouncycastle.util.encoders.Base64;
 
+import libcore.io.IoUtils;
+
 import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -559,11 +561,7 @@
     // Full restore handling
 
     private void resetFullRestoreState() {
-        try {
-        mCurFullRestoreStream.close();
-        } catch (IOException e) {
-            Log.w(TAG, "Unable to close full restore input stream");
-        }
+        IoUtils.closeQuietly(mCurFullRestoreStream);
         mCurFullRestoreStream = null;
         mFullRestoreSocketStream = null;
         mFullRestoreBuffer = null;
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 3ccced5..8d3db5b 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -384,8 +384,16 @@
      * @return Whether a saved pattern exists.
      */
     public boolean savedPatternExists() {
+        return savedPatternExists(getCurrentOrCallingUserId());
+    }
+
+    /**
+     * Check to see if the user has stored a lock pattern.
+     * @return Whether a saved pattern exists.
+     */
+    public boolean savedPatternExists(int userId) {
         try {
-            return getLockSettings().havePattern(getCurrentOrCallingUserId());
+            return getLockSettings().havePattern(userId);
         } catch (RemoteException re) {
             return false;
         }
@@ -396,8 +404,16 @@
      * @return Whether a saved pattern exists.
      */
     public boolean savedPasswordExists() {
+        return savedPasswordExists(getCurrentOrCallingUserId());
+    }
+
+     /**
+     * Check to see if the user has stored a lock pattern.
+     * @return Whether a saved pattern exists.
+     */
+    public boolean savedPasswordExists(int userId) {
         try {
-            return getLockSettings().havePassword(getCurrentOrCallingUserId());
+            return getLockSettings().havePassword(userId);
         } catch (RemoteException re) {
             return false;
         }
@@ -955,8 +971,15 @@
      * @return true if the lockscreen method is set to biometric weak
      */
     public boolean usingBiometricWeak() {
-        int quality =
-                (int) getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
+        return usingBiometricWeak(getCurrentOrCallingUserId());
+    }
+
+    /**
+     * @return true if the lockscreen method is set to biometric weak
+     */
+    public boolean usingBiometricWeak(int userId) {
+        int quality = (int) getLong(
+                PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId);
         return quality == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
     }
 
@@ -1096,15 +1119,22 @@
      * @return Whether the lock pattern is enabled, or if it is set as a backup for biometric weak
      */
     public boolean isLockPatternEnabled() {
+        return isLockPatternEnabled(getCurrentOrCallingUserId());
+    }
+
+    /**
+     * @return Whether the lock pattern is enabled, or if it is set as a backup for biometric weak
+     */
+    public boolean isLockPatternEnabled(int userId) {
         final boolean backupEnabled =
                 getLong(PASSWORD_TYPE_ALTERNATE_KEY,
-                        DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED)
+                        DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId)
                                 == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
 
-        return getBoolean(Settings.Secure.LOCK_PATTERN_ENABLED, false)
-                && (getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED)
-                        == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING ||
-                        (usingBiometricWeak() && backupEnabled));
+        return getBoolean(Settings.Secure.LOCK_PATTERN_ENABLED, false, userId)
+                && (getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
+                        userId) == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
+                        || (usingBiometricWeak(userId) && backupEnabled));
     }
 
     /**
@@ -1485,15 +1515,20 @@
     }
 
     public boolean isSecure() {
-        long mode = getKeyguardStoredPasswordQuality();
+        return isSecure(getCurrentOrCallingUserId());
+    }
+
+    public boolean isSecure(int userId) {
+        long mode = getKeyguardStoredPasswordQuality(userId);
         final boolean isPattern = mode == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
         final boolean isPassword = mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
                 || mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX
                 || mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
                 || mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
                 || mode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
-        final boolean secure = isPattern && isLockPatternEnabled() && savedPatternExists()
-                || isPassword && savedPasswordExists();
+        final boolean secure =
+                isPattern && isLockPatternEnabled(userId) && savedPatternExists(userId)
+                || isPassword && savedPasswordExists(userId);
         return secure;
     }
 
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index c5f1d88..1fbd4a1 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -787,6 +787,12 @@
         addOption("-Ximage-compiler-option");
         addOption("--image-classes=/system/etc/preloaded-classes");
 
+        // If there is a compiled-classes file, push it.
+        if (hasFile("/system/etc/compiled-classes")) {
+            addOption("-Ximage-compiler-option");
+            addOption("--compiled-classes=/system/etc/compiled-classes");
+        }
+
         property_get("dalvik.vm.image-dex2oat-flags", dex2oatImageFlagsBuf, "");
         parseExtraOpts(dex2oatImageFlagsBuf, "-Ximage-compiler-option");
 
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 4b4b367..cabe200 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -484,7 +484,8 @@
 
 static jint convertAudioPortConfigToNative(JNIEnv *env,
                                                struct audio_port_config *nAudioPortConfig,
-                                               const jobject jAudioPortConfig)
+                                               const jobject jAudioPortConfig,
+                                               bool useConfigMask)
 {
     jobject jAudioPort = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mPort);
     jobject jHandle = env->GetObjectField(jAudioPort, gAudioPortFields.mHandle);
@@ -503,8 +504,13 @@
     ALOGV("convertAudioPortConfigToNative handle %d role %d type %d",
           nAudioPortConfig->id, nAudioPortConfig->role, nAudioPortConfig->type);
 
+    unsigned int configMask = 0;
+
     nAudioPortConfig->sample_rate = env->GetIntField(jAudioPortConfig,
                                                      gAudioPortConfigFields.mSamplingRate);
+    if (nAudioPortConfig->sample_rate != 0) {
+        configMask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
+    }
 
     bool useInMask = useInChannelMask(nAudioPortConfig->type, nAudioPortConfig->role);
     audio_channel_mask_t nMask;
@@ -518,22 +524,34 @@
         ALOGV("convertAudioPortConfigToNative OUT mask java %x native %x", jMask, nMask);
     }
     nAudioPortConfig->channel_mask = nMask;
+    if (nAudioPortConfig->channel_mask != AUDIO_CHANNEL_NONE) {
+        configMask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
+    }
 
     jint jFormat = env->GetIntField(jAudioPortConfig, gAudioPortConfigFields.mFormat);
     audio_format_t nFormat = audioFormatToNative(jFormat);
     ALOGV("convertAudioPortConfigToNative format %d native %d", jFormat, nFormat);
     nAudioPortConfig->format = nFormat;
+    if (nAudioPortConfig->format != AUDIO_FORMAT_DEFAULT &&
+            nAudioPortConfig->format != AUDIO_FORMAT_INVALID) {
+        configMask |= AUDIO_PORT_CONFIG_FORMAT;
+    }
+
     jobject jGain = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mGain);
     if (jGain != NULL) {
         convertAudioGainConfigToNative(env, &nAudioPortConfig->gain, jGain, useInMask);
         env->DeleteLocalRef(jGain);
+        configMask |= AUDIO_PORT_CONFIG_GAIN;
     } else {
         ALOGV("convertAudioPortConfigToNative no gain");
         nAudioPortConfig->gain.index = -1;
     }
-    nAudioPortConfig->config_mask = env->GetIntField(jAudioPortConfig,
-                                                     gAudioPortConfigFields.mConfigMask);
-
+    if (useConfigMask) {
+        nAudioPortConfig->config_mask = env->GetIntField(jAudioPortConfig,
+                                                         gAudioPortConfigFields.mConfigMask);
+    } else {
+        nAudioPortConfig->config_mask = configMask;
+    }
     env->DeleteLocalRef(jAudioPort);
     env->DeleteLocalRef(jHandle);
     return (jint)AUDIO_JAVA_SUCCESS;
@@ -998,7 +1016,7 @@
             jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
             goto exit;
         }
-        jStatus = convertAudioPortConfigToNative(env, &nPatch.sources[i], jSource);
+        jStatus = convertAudioPortConfigToNative(env, &nPatch.sources[i], jSource, false);
         env->DeleteLocalRef(jSource);
         jSource = NULL;
         if (jStatus != AUDIO_JAVA_SUCCESS) {
@@ -1013,7 +1031,7 @@
             jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
             goto exit;
         }
-        jStatus = convertAudioPortConfigToNative(env, &nPatch.sinks[i], jSink);
+        jStatus = convertAudioPortConfigToNative(env, &nPatch.sinks[i], jSink, false);
         env->DeleteLocalRef(jSink);
         jSink = NULL;
         if (jStatus != AUDIO_JAVA_SUCCESS) {
@@ -1268,7 +1286,7 @@
         return AUDIO_JAVA_BAD_VALUE;
     }
     struct audio_port_config nAudioPortConfig;
-    jint jStatus = convertAudioPortConfigToNative(env, &nAudioPortConfig, jAudioPortConfig);
+    jint jStatus = convertAudioPortConfigToNative(env, &nAudioPortConfig, jAudioPortConfig, true);
     if (jStatus != AUDIO_JAVA_SUCCESS) {
         return jStatus;
     }
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 178bab6..e572d22 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -275,6 +275,7 @@
                         subHeap = HEAP_DALVIK_LINEARALLOC;
                     } else if ((strstr(name, "/dev/ashmem/dalvik-alloc space") == name) ||
                                (strstr(name, "/dev/ashmem/dalvik-main space") == name) ||
+                               (strstr(name, "/dev/ashmem/dalvik-zygote space") == name) ||
                                (strstr(name, "/dev/ashmem/dalvik-non moving space") == name)) {
                         // This is the regular Dalvik heap.
                         whichHeap = HEAP_DALVIK;
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 94098c9..fba7255 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -33,6 +33,7 @@
 
 #include <androidfw/Asset.h>
 #include <androidfw/AssetManager.h>
+#include <androidfw/AttributeFinder.h>
 #include <androidfw/ResourceTypes.h>
 
 #include <private/android_filesystem_config.h> // for AID_SYSTEM
@@ -999,6 +1000,30 @@
     theme->dumpToLog();
 }
 
+class XmlAttributeFinder : public BackTrackingAttributeFinder<XmlAttributeFinder, jsize> {
+public:
+    XmlAttributeFinder(const ResXMLParser* parser)
+        : BackTrackingAttributeFinder(0, parser != NULL ? parser->getAttributeCount() : 0)
+        , mParser(parser) {}
+
+    inline uint32_t getAttribute(jsize index) const {
+        return mParser->getAttributeNameResID(index);
+    }
+
+private:
+    const ResXMLParser* mParser;
+};
+
+class BagAttributeFinder : public BackTrackingAttributeFinder<BagAttributeFinder, const ResTable::bag_entry*> {
+public:
+    BagAttributeFinder(const ResTable::bag_entry* start, const ResTable::bag_entry* end)
+        : BackTrackingAttributeFinder(start, end) {}
+
+    inline uint32_t getAttribute(const ResTable::bag_entry* entry) const {
+        return entry->map.name.ident;
+    }
+};
+
 static jboolean android_content_AssetManager_resolveAttrs(JNIEnv* env, jobject clazz,
                                                           jlong themeToken,
                                                           jint defStyleAttr,
@@ -1074,13 +1099,13 @@
     res.lock();
 
     // Retrieve the default style bag, if requested.
-    const ResTable::bag_entry* defStyleEnt = NULL;
+    const ResTable::bag_entry* defStyleStart = NULL;
     uint32_t defStyleTypeSetFlags = 0;
     ssize_t bagOff = defStyleRes != 0
-            ? res.getBagLocked(defStyleRes, &defStyleEnt, &defStyleTypeSetFlags) : -1;
+            ? res.getBagLocked(defStyleRes, &defStyleStart, &defStyleTypeSetFlags) : -1;
     defStyleTypeSetFlags |= defStyleBagTypeSetFlags;
-    const ResTable::bag_entry* endDefStyleEnt = defStyleEnt +
-        (bagOff >= 0 ? bagOff : 0);;
+    const ResTable::bag_entry* const defStyleEnd = defStyleStart + (bagOff >= 0 ? bagOff : 0);
+    BagAttributeFinder defStyleAttrFinder(defStyleStart, defStyleEnd);
 
     // Now iterate through all of the attributes that the client has requested,
     // filling in each with whatever data we can find.
@@ -1108,20 +1133,15 @@
                     value.dataType, value.data));
         }
 
-        // Skip through the default style values until the end or the next possible match.
-        while (defStyleEnt < endDefStyleEnt && curIdent > defStyleEnt->map.name.ident) {
-            defStyleEnt++;
-        }
-        // Retrieve the current default style attribute if it matches, and step to next.
-        if (defStyleEnt < endDefStyleEnt && curIdent == defStyleEnt->map.name.ident) {
-            if (value.dataType == Res_value::TYPE_NULL) {
-                block = defStyleEnt->stringBlock;
+        if (value.dataType == Res_value::TYPE_NULL) {
+            const ResTable::bag_entry* const defStyleEntry = defStyleAttrFinder.find(curIdent);
+            if (defStyleEntry != defStyleEnd) {
+                block = defStyleEntry->stringBlock;
                 typeSetFlags = defStyleTypeSetFlags;
-                value = defStyleEnt->map.value;
+                value = defStyleEntry->map.value;
                 DEBUG_STYLES(ALOGI("-> From def style: type=0x%x, data=0x%08x",
                         value.dataType, value.data));
             }
-            defStyleEnt++;
         }
 
         uint32_t resid = 0;
@@ -1284,34 +1304,32 @@
     res.lock();
 
     // Retrieve the default style bag, if requested.
-    const ResTable::bag_entry* defStyleEnt = NULL;
+    const ResTable::bag_entry* defStyleAttrStart = NULL;
     uint32_t defStyleTypeSetFlags = 0;
     ssize_t bagOff = defStyleRes != 0
-            ? res.getBagLocked(defStyleRes, &defStyleEnt, &defStyleTypeSetFlags) : -1;
+            ? res.getBagLocked(defStyleRes, &defStyleAttrStart, &defStyleTypeSetFlags) : -1;
     defStyleTypeSetFlags |= defStyleBagTypeSetFlags;
-    const ResTable::bag_entry* endDefStyleEnt = defStyleEnt +
-        (bagOff >= 0 ? bagOff : 0);
+    const ResTable::bag_entry* const defStyleAttrEnd = defStyleAttrStart + (bagOff >= 0 ? bagOff : 0);
+    BagAttributeFinder defStyleAttrFinder(defStyleAttrStart, defStyleAttrEnd);
 
     // Retrieve the style class bag, if requested.
-    const ResTable::bag_entry* styleEnt = NULL;
+    const ResTable::bag_entry* styleAttrStart = NULL;
     uint32_t styleTypeSetFlags = 0;
-    bagOff = style != 0 ? res.getBagLocked(style, &styleEnt, &styleTypeSetFlags) : -1;
+    bagOff = style != 0 ? res.getBagLocked(style, &styleAttrStart, &styleTypeSetFlags) : -1;
     styleTypeSetFlags |= styleBagTypeSetFlags;
-    const ResTable::bag_entry* endStyleEnt = styleEnt +
-        (bagOff >= 0 ? bagOff : 0);
+    const ResTable::bag_entry* const styleAttrEnd = styleAttrStart + (bagOff >= 0 ? bagOff : 0);
+    BagAttributeFinder styleAttrFinder(styleAttrStart, styleAttrEnd);
 
     // Retrieve the XML attributes, if requested.
-    const jsize NX = xmlParser ? xmlParser->getAttributeCount() : 0;
-    jsize ix=0;
-    uint32_t curXmlAttr = xmlParser ? xmlParser->getAttributeNameResID(ix) : 0;
-
     static const ssize_t kXmlBlock = 0x10000000;
+    XmlAttributeFinder xmlAttrFinder(xmlParser);
+    const jsize xmlAttrEnd = xmlParser != NULL ? xmlParser->getAttributeCount() : 0;
 
     // Now iterate through all of the attributes that the client has requested,
     // filling in each with whatever data we can find.
     ssize_t block = 0;
     uint32_t typeSetFlags;
-    for (jsize ii=0; ii<NI; ii++) {
+    for (jsize ii = 0; ii < NI; ii++) {
         const uint32_t curIdent = (uint32_t)src[ii];
 
         DEBUG_STYLES(ALOGI("RETRIEVING ATTR 0x%08x...", curIdent));
@@ -1324,51 +1342,40 @@
         typeSetFlags = 0;
         config.density = 0;
 
-        // Skip through XML attributes until the end or the next possible match.
-        while (ix < NX && curIdent > curXmlAttr) {
-            ix++;
-            curXmlAttr = xmlParser->getAttributeNameResID(ix);
-        }
-        // Retrieve the current XML attribute if it matches, and step to next.
-        if (ix < NX && curIdent == curXmlAttr) {
+        // Walk through the xml attributes looking for the requested attribute.
+        const jsize xmlAttrIdx = xmlAttrFinder.find(curIdent);
+        if (xmlAttrIdx != xmlAttrEnd) {
+            // We found the attribute we were looking for.
             block = kXmlBlock;
-            xmlParser->getAttributeValue(ix, &value);
-            ix++;
-            curXmlAttr = xmlParser->getAttributeNameResID(ix);
+            xmlParser->getAttributeValue(xmlAttrIdx, &value);
             DEBUG_STYLES(ALOGI("-> From XML: type=0x%x, data=0x%08x",
                     value.dataType, value.data));
         }
 
-        // Skip through the style values until the end or the next possible match.
-        while (styleEnt < endStyleEnt && curIdent > styleEnt->map.name.ident) {
-            styleEnt++;
-        }
-        // Retrieve the current style attribute if it matches, and step to next.
-        if (styleEnt < endStyleEnt && curIdent == styleEnt->map.name.ident) {
-            if (value.dataType == Res_value::TYPE_NULL) {
-                block = styleEnt->stringBlock;
+        if (value.dataType == Res_value::TYPE_NULL) {
+            // Walk through the style class values looking for the requested attribute.
+            const ResTable::bag_entry* const styleAttrEntry = styleAttrFinder.find(curIdent);
+            if (styleAttrEntry != styleAttrEnd) {
+                // We found the attribute we were looking for.
+                block = styleAttrEntry->stringBlock;
                 typeSetFlags = styleTypeSetFlags;
-                value = styleEnt->map.value;
+                value = styleAttrEntry->map.value;
                 DEBUG_STYLES(ALOGI("-> From style: type=0x%x, data=0x%08x",
                         value.dataType, value.data));
             }
-            styleEnt++;
         }
 
-        // Skip through the default style values until the end or the next possible match.
-        while (defStyleEnt < endDefStyleEnt && curIdent > defStyleEnt->map.name.ident) {
-            defStyleEnt++;
-        }
-        // Retrieve the current default style attribute if it matches, and step to next.
-        if (defStyleEnt < endDefStyleEnt && curIdent == defStyleEnt->map.name.ident) {
-            if (value.dataType == Res_value::TYPE_NULL) {
-                block = defStyleEnt->stringBlock;
-                typeSetFlags = defStyleTypeSetFlags;
-                value = defStyleEnt->map.value;
+        if (value.dataType == Res_value::TYPE_NULL) {
+            // Walk through the default style values looking for the requested attribute.
+            const ResTable::bag_entry* const defStyleAttrEntry = defStyleAttrFinder.find(curIdent);
+            if (defStyleAttrEntry != defStyleAttrEnd) {
+                // We found the attribute we were looking for.
+                block = defStyleAttrEntry->stringBlock;
+                typeSetFlags = styleTypeSetFlags;
+                value = defStyleAttrEntry->map.value;
                 DEBUG_STYLES(ALOGI("-> From def style: type=0x%x, data=0x%08x",
                         value.dataType, value.data));
             }
-            defStyleEnt++;
         }
 
         uint32_t resid = 0;
@@ -1376,7 +1383,9 @@
             // Take care of resolving the found resource to its final value.
             ssize_t newBlock = theme->resolveAttributeReference(&value, block,
                     &resid, &typeSetFlags, &config);
-            if (newBlock >= 0) block = newBlock;
+            if (newBlock >= 0) {
+                block = newBlock;
+            }
             DEBUG_STYLES(ALOGI("-> Resolved attr: type=0x%x, data=0x%08x",
                     value.dataType, value.data));
         } else {
@@ -1394,7 +1403,9 @@
                     return JNI_FALSE;
                 }
 #endif
-                if (newBlock >= 0) block = newBlock;
+                if (newBlock >= 0) {
+                    block = newBlock;
+                }
                 DEBUG_STYLES(ALOGI("-> Resolved theme: type=0x%x, data=0x%08x",
                         value.dataType, value.data));
             }
@@ -1414,8 +1425,8 @@
         // Write the final value back to Java.
         dest[STYLE_TYPE] = value.dataType;
         dest[STYLE_DATA] = value.data;
-        dest[STYLE_ASSET_COOKIE] =
-            block != kXmlBlock ? reinterpret_cast<jint>(res.getTableCookie(block)) : (jint)-1;
+        dest[STYLE_ASSET_COOKIE] = block != kXmlBlock ?
+            static_cast<jint>(res.getTableCookie(block)) : -1;
         dest[STYLE_RESOURCE_ID] = resid;
         dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
         dest[STYLE_DENSITY] = config.density;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 4d6fc9c..3aaecc7 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2406,6 +2406,15 @@
         android:description="@string/permdesc_controlWifiDisplay"
         android:protectionLevel="signature" />
 
+    <!-- @SystemApi Allows an application to control VPN.
+         <p>Not for use by third-party applications.</p>
+         @hide -->
+    <permission android:name="android.permission.CONTROL_VPN"
+        android:label="@string/permlab_controlVpn"
+        android:description="@string/permdesc_controlVpn"
+        android:protectionLevel="signature|system" />
+    <uses-permission android:name="android.permission.CONTROL_VPN" />
+
     <!-- @SystemApi Allows an application to capture audio output.
          <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"
diff --git a/core/res/res/anim/dock_bottom_enter.xml b/core/res/res/anim/dock_bottom_enter.xml
index 4f2f753..bfb97b6 100644
--- a/core/res/res/anim/dock_bottom_enter.xml
+++ b/core/res/res/anim/dock_bottom_enter.xml
@@ -20,5 +20,5 @@
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/decelerate_cubic">
     <translate android:fromYDelta="100%" android:toYDelta="0"
-        android:duration="250"/>
+        android:duration="@integer/dock_enter_exit_duration"/>
 </set>
diff --git a/core/res/res/anim/dock_bottom_exit.xml b/core/res/res/anim/dock_bottom_exit.xml
index afbe24b..4e15448 100644
--- a/core/res/res/anim/dock_bottom_exit.xml
+++ b/core/res/res/anim/dock_bottom_exit.xml
@@ -20,5 +20,5 @@
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/accelerate_cubic">
     <translate android:fromYDelta="0" android:toYDelta="100%"
-        android:startOffset="100" android:duration="250"/>
+        android:startOffset="100" android:duration="@integer/dock_enter_exit_duration"/>
 </set>
diff --git a/core/res/res/anim/dock_top_enter.xml b/core/res/res/anim/dock_top_enter.xml
index 1f74e48..f763fb5 100644
--- a/core/res/res/anim/dock_top_enter.xml
+++ b/core/res/res/anim/dock_top_enter.xml
@@ -20,5 +20,5 @@
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/decelerate_cubic">
     <translate android:fromYDelta="-100%" android:toYDelta="0"
-        android:duration="250"/>
+        android:duration="@integer/dock_enter_exit_duration"/>
 </set>
diff --git a/core/res/res/anim/dock_top_exit.xml b/core/res/res/anim/dock_top_exit.xml
index 4d2fea94..995b7d0 100644
--- a/core/res/res/anim/dock_top_exit.xml
+++ b/core/res/res/anim/dock_top_exit.xml
@@ -20,5 +20,5 @@
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/accelerate_cubic">
     <translate android:fromYDelta="0" android:toYDelta="-100%"
-        android:startOffset="100" android:duration="250"/>
+        android:startOffset="100" android:duration="@integer/dock_enter_exit_duration"/>
 </set>
diff --git a/core/res/res/drawable-hdpi/ic_sim_card_multi_24px_clr.png b/core/res/res/drawable-hdpi/ic_sim_card_multi_24px_clr.png
new file mode 100644
index 0000000..c4a66bb
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_sim_card_multi_24px_clr.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_sim_card_multi_48px_clr.png b/core/res/res/drawable-hdpi/ic_sim_card_multi_48px_clr.png
new file mode 100644
index 0000000..db901d9
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_sim_card_multi_48px_clr.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_track_mtrl_alpha.9.png b/core/res/res/drawable-hdpi/switch_track_mtrl_alpha.9.png
index 0ebe65e..9415bc0 100644
--- a/core/res/res/drawable-hdpi/switch_track_mtrl_alpha.9.png
+++ b/core/res/res/drawable-hdpi/switch_track_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/switch_track_mtrl_alpha.9.png b/core/res/res/drawable-ldpi/switch_track_mtrl_alpha.9.png
deleted file mode 100644
index a58128f..0000000
--- a/core/res/res/drawable-ldpi/switch_track_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_sim_card_multi_24px_clr.png b/core/res/res/drawable-mdpi/ic_sim_card_multi_24px_clr.png
new file mode 100644
index 0000000..5d21285
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_sim_card_multi_24px_clr.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_sim_card_multi_48px_clr.png b/core/res/res/drawable-mdpi/ic_sim_card_multi_48px_clr.png
new file mode 100644
index 0000000..249379d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_sim_card_multi_48px_clr.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_sim_card_multi_24px_clr.png b/core/res/res/drawable-xhdpi/ic_sim_card_multi_24px_clr.png
new file mode 100644
index 0000000..9675e56
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_sim_card_multi_24px_clr.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_sim_card_multi_48px_clr.png b/core/res/res/drawable-xhdpi/ic_sim_card_multi_48px_clr.png
new file mode 100644
index 0000000..a57a0b9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_sim_card_multi_48px_clr.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_sim_card_multi_24px_clr.png b/core/res/res/drawable-xxhdpi/ic_sim_card_multi_24px_clr.png
new file mode 100644
index 0000000..db26fbf
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_sim_card_multi_24px_clr.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_sim_card_multi_48px_clr.png b/core/res/res/drawable-xxhdpi/ic_sim_card_multi_48px_clr.png
new file mode 100644
index 0000000..dddb0a1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_sim_card_multi_48px_clr.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/ic_sim_card_multi_24px_clr.png b/core/res/res/drawable-xxxhdpi/ic_sim_card_multi_24px_clr.png
new file mode 100644
index 0000000..fbda037
--- /dev/null
+++ b/core/res/res/drawable-xxxhdpi/ic_sim_card_multi_24px_clr.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/ic_sim_card_multi_48px_clr.png b/core/res/res/drawable-xxxhdpi/ic_sim_card_multi_48px_clr.png
new file mode 100644
index 0000000..3316f14
--- /dev/null
+++ b/core/res/res/drawable-xxxhdpi/ic_sim_card_multi_48px_clr.png
Binary files differ
diff --git a/core/res/res/drawable/edit_text_material.xml b/core/res/res/drawable/edit_text_material.xml
index bbc7301..38ac567 100644
--- a/core/res/res/drawable/edit_text_material.xml
+++ b/core/res/res/drawable/edit_text_material.xml
@@ -15,21 +15,23 @@
 -->
 
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
-        android:inset="@dimen/control_inset_material">
-    <ripple android:color="?attr/colorControlActivated">
-        <item>
-            <selector>
-                <item android:state_enabled="false">
-                    <nine-patch android:src="@drawable/textfield_default_mtrl_alpha"
-                        android:tint="?attr/colorControlNormal"
-                        android:alpha="?attr/disabledAlpha" />
-                </item>
-                <item>
-                    <nine-patch android:src="@drawable/textfield_default_mtrl_alpha"
-                        android:tint="?attr/colorControlNormal" />
-                </item>
-            </selector>
+       android:insetLeft="@dimen/edit_text_inset_horizontal_material"
+       android:insetRight="@dimen/edit_text_inset_horizontal_material"
+       android:insetTop="@dimen/edit_text_inset_top_material"
+       android:insetBottom="@dimen/edit_text_inset_bottom_material">
+    <selector>
+        <item android:state_enabled="false">
+            <nine-patch android:src="@drawable/textfield_default_mtrl_alpha"
+                android:tint="?attr/colorControlNormal"
+                android:alpha="?attr/disabledAlpha" />
         </item>
-        <item android:id="@+id/mask" android:drawable="@drawable/textfield_activated_mtrl_alpha" />
-    </ripple>
+        <item android:state_pressed="false" android:state_focused="false">
+            <nine-patch android:src="@drawable/textfield_default_mtrl_alpha"
+                android:tint="?attr/colorControlNormal" />
+        </item>
+        <item>
+            <nine-patch android:src="@drawable/textfield_activated_mtrl_alpha"
+                android:tint="?attr/colorControlActivated" />
+        </item>
+    </selector>
 </inset>
diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml
index 674d7b8..3fdcaf7 100644
--- a/core/res/res/layout/notification_template_material_base.xml
+++ b/core/res/res/layout/notification_template_material_base.xml
@@ -28,6 +28,7 @@
         android:layout_height="@dimen/notification_large_icon_height"
         />
     <LinearLayout
+        android:id="@+id/notification_main_column"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_gravity="top"
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 ef916ed1..935424a 100644
--- a/core/res/res/layout/notification_template_material_big_base.xml
+++ b/core/res/res/layout/notification_template_material_big_base.xml
@@ -28,6 +28,7 @@
         android:layout_height="@dimen/notification_large_icon_height"
         />
     <LinearLayout
+        android:id="@+id/notification_main_column"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="top"
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 3415814..d0c10b2a 100644
--- a/core/res/res/layout/notification_template_material_big_text.xml
+++ b/core/res/res/layout/notification_template_material_big_text.xml
@@ -28,6 +28,7 @@
         android:layout_height="@dimen/notification_large_icon_height"
         />
     <LinearLayout
+        android:id="@+id/notification_main_column"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="top"
diff --git a/core/res/res/layout/notification_template_material_inbox.xml b/core/res/res/layout/notification_template_material_inbox.xml
index 8a66c3f..ac448ee 100644
--- a/core/res/res/layout/notification_template_material_inbox.xml
+++ b/core/res/res/layout/notification_template_material_inbox.xml
@@ -28,6 +28,7 @@
         android:layout_height="@dimen/notification_large_icon_height"
         />
     <LinearLayout
+        android:id="@+id/notification_main_column"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="top"
diff --git a/core/res/res/layout/select_dialog_material.xml b/core/res/res/layout/select_dialog_material.xml
index ee04039..19ad407 100644
--- a/core/res/res/layout/select_dialog_material.xml
+++ b/core/res/res/layout/select_dialog_material.xml
@@ -22,11 +22,14 @@
 -->
 <view class="com.android.internal.app.AlertController$RecycleListView"
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+android:id/select_dialog_listview"
+    android:id="@id/select_dialog_listview"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:cacheColorHint="@null"
-    android:divider="?android:attr/listDividerAlertDialog"
+    android:divider="?attr/listDividerAlertDialog"
     android:scrollbars="vertical"
     android:overScrollMode="ifContentScrolls"
-    android:textAlignment="viewStart" />
+    android:textAlignment="viewStart"
+    android:paddingTop="@dimen/dialog_list_padding_vertical_material"
+    android:paddingBottom="@dimen/dialog_list_padding_vertical_material"
+    android:clipToPadding="false" />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index b3806db..522af95 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> u. <xliff:g id="MINUTES">%2$d</xliff:g> min."</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> u. <xliff:g id="MINUTES">%2$d</xliff:g> min."</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> minute"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> s."</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min. <xliff:g id="SECONDS">%2$d</xliff:g> s."</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sekondes"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Laat die program toe om Wi-Fi-skerms op te stel en daaraan te koppel."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"beheer Wi-Fi-skerms"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Laat die program toe om laevlak-kenmerke van Wi-Fi-skerms te beheer."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"beheer virtuele private netwerke"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Laat die program toe om laevlak-kenmerke van virtuele private netwerke te beheer."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"vang oudio-uitset vas"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Laat die program oudio-uitset vasvang en herlei."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Aktiveerwoord-opsporing"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Laat hierdie program toe om inligting oor huidige Android Straal-oordragte te ontvang."</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"verwyder DRM-sertifikate"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Laat \'n program toe om DRM-sertifikate te verwyder. Behoort nooit vir gewone programme nodig te wees nie."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"bind aan \'n diensverskaffer-boodskapdiens"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Dit laat die houer toe om aan die top-koppelvlak van \'n diensverskaffer-boodskapdiens te bind. Behoort nooit vir gewone programme nodig te wees nie."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Stel wagwoordreëls"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Beheer lengte en watter karakters wat in die skermontsluit-wagwoorde gebruik word."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitor pogings om skerm te ontsluit"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Vou in"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Tot die volgende wekker om <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Tot die volgende wekker"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Gedemp deur <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Daar is \'n interne probleem met jou toestel en dit sal dalk onstabiel wees totdat jy \'n fabriekterugstelling doen."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Daar is \'n interne probleem met jou toestel. Kontak jou vervaardiger vir besonderhede."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 9763569..4efa564 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ሰዓ <xliff:g id="MINUTES">%2$d</xliff:g> ደቂቃ"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ሰዓ <xliff:g id="MINUTES">%2$d</xliff:g> ደቂቃ"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> ደቂቃዎች"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> ደቂቃዎች"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> ደቂቃ <xliff:g id="SECONDS">%2$d</xliff:g> ሴ"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> ደቂቃ <xliff:g id="SECONDS">%2$d</xliff:g> ሴ"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> ሴ"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"መተግበሪያው የWifi ማሳያዎችን እንዲያዋቅርና ከእነሱ ጋር እንዲገናኝ ይፈቅድለታል።"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"የWifi ማሳያዎችን ተቆጣጠር"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"መተግበሪያው በዝቅተኛ ደረጃ ላይ ያሉ የWifi ማሳያዎችን እንዲቆጣጠር ይፈቅድለታል።"</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"ምናባዊ የግል አውታረ መረቦችን ይቆጣጠሩ"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"መተግበሪያው የምናባዊ ግል አውታረ መረቦች ዝቅተኛ ደረጃ ባህሪያትን እንዲቆጣጠር ያስችለዋል።"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"የድምጽ ውጽዓት ይቅረጹ"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"መተግበሪያው የድምጽ ውጽዓት እንዲቀርጽ እና አቅጣጫውን እንዲያዞር ያስችለዋል።"</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"ትኩስ ቃል ማወቅ"</string>
@@ -834,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"የይለፍ ቃል ደንቦች አዘጋጅ"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"በማያ-መክፈት የተፈቀዱ የይለፍ ቃል ርዝመት እና ቁምፊዎች ተቆጣጠር።"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"የማሳያ-ክፈት ሙከራዎችን አሳይ"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"ሰብስብ"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"በ<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ላይ እስከሚቀጥለው ማንቂያ ድረስ"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"እስከሚቀጥለው ማንቂያ ድረስ"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 104dfb3..98821ca 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -564,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"‏للسماح للتطبيق بتهيئة شاشات Wi-Fi والاتصال بها."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"‏التحكم في شاشات Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"‏للسماح للتطبيق بالتحكم في الميزات ذات المستوى المنخفض في شاشات Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"التحكم في الشبكات الظاهرية الخاصة"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"للسماح للتطبيق بالتحكم في ميزات المستوى المنخفض للشبكات الظاهرية الخاصة."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"التقاط إخراج الصوت"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"السماح للتطبيق بالتقاط إخراج الصوت وإعادة توجيهه."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"اكتشاف الكلمة المهمة"</string>
@@ -833,6 +835,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="policylab_limitPassword" msgid="4497420728857585791">"تعيين قواعد كلمة المرور"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"يمكنك التحكم في الطول والأحرف المسموح بها في كلمات مرور إلغاء تأمين الشاشة."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"مراقبة محاولات إلغاء قفل الشاشة"</string>
@@ -1899,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"تصغير"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"حتى التنبيه التالي في <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"حتى التنبيه التالي"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index bfd5dbc..97b8fc5 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ч <xliff:g id="MINUTES">%2$d</xliff:g> мин"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ч <xliff:g id="MINUTES">%2$d</xliff:g> мин"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> мин"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> мин"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> мин <xliff:g id="SECONDS">%2$d</xliff:g> сек"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> мин <xliff:g id="SECONDS">%2$d</xliff:g> сек"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Разрешава на приложението да конфигурира и да се свързва с дисплеите през WiFi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"контролиране на дисплеите през WiFi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Разрешава на приложението да контролира функциите от ниско ниво на дисплеите през WiFi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"управление на виртуалните частни мрежи"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Разрешава на приложението да управлява функциите от ниско ниво на виртуалните частни мрежи."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"записване на възпроизвеждания звук"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Разрешава на приложението да записва и пренасочва възпроизвеждания звук."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Откриване на активиращи думи"</string>
@@ -834,6 +835,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="policylab_limitPassword" msgid="4497420728857585791">"Задаване на правила за паролата"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролирайте дължината и разрешените знаци за паролите за отключване на екрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Наблюдаване на опитите за отключване на екрана"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Свиване"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"До следващия будилник в <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"До следващия будилник"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index f6192cc..cb55c95 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ঘন্টা <xliff:g id="MINUTES">%2$d</xliff:g> মিনিট"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ঘন্টা <xliff:g id="MINUTES">%2$d</xliff:g> মিনিট"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> মিনিট"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> মিনিট"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> মিনিট <xliff:g id="SECONDS">%2$d</xliff:g> সেকেন্ড"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> মিনিট <xliff:g id="SECONDS">%2$d</xliff:g> সেকেন্ড"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> সেকেন্ড"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Wifi প্রদর্শনগুলি অনুযায়ী কনফিগার করে নিতে এবং সংযোগ স্থাপন করতে অ্যাপ্লিকেশানটিকে মঞ্জুর করে৷"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi প্রদর্শনগুলিকে নিয়ন্ত্রণ করুন"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Wifi প্রদর্শনের নিম্ন মানের বৈশিষ্ট্যগুলিকে নিয়ন্ত্রণ করতে অ্যাপ্লিকেশানটিকে মঞ্জুর করে৷"</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"ভার্চুয়াল প্রাইভেট নেটওয়ার্ক নিয়ন্ত্রণ করুন"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"অ্যাপ্লিকেশানটিকে ভার্চুয়াল প্রাইভেট নেটওয়ার্কের নিম্নস্তরের বৈশিষ্ট্য নিয়ন্ত্রণ করতে দেয়৷"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"অডিও আউটপুট গ্রহণ করে"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"অ্যাপ্লিকেশানটিকে অডিও আউটপুট গ্রহণ এবং পুনর্নির্দেশ করতে দেয়৷"</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"হটওয়ার্ড সনাক্তকরণ"</string>
@@ -834,6 +835,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="policylab_limitPassword" msgid="4497420728857585791">"পাসওয়ার্ড নিয়মগুলি সেট করে"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"স্ক্রীন আনলক করার পাসওয়ার্ডগুলিতে অনুমতিপ্রাপ্ত অক্ষর এবং দৈর্ঘ্য নিয়ন্ত্রণ করে৷"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"স্ক্রীণ আনলক করার প্রচেষ্টাগুলি নিরীক্ষণ করে"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"সঙ্কুচিত করুন"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> এ পরবর্তী অ্যালার্ম পর্যন্ত"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"পরবর্তী অ্যালার্ম পর্যন্ত"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 04e5249..3ac2fd80 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> minuts"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> s"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permet a l\'aplicació configurar-se i connectar-se a les pantalles Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"control de les pantalles Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permet a l\'aplicació controlar les funcions de baix nivell de les pantalles Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"controlar xarxes privades virtuals"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Permet que l\'aplicació controli funcions de nivell baix de xarxes privades virtuals."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"captura la sortida d\'àudio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Permet que l\'aplicació capturi i redirigeixi la sortida d\'àudio."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Detecció de paraules actives"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Permet que aquesta aplicació rebi informació sobre les transferències d\'Android Beam actuals."</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"suprimir els certificats DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Permet que una aplicació suprimeixi els certificats DRM. No ha de ser mai necessari per a aplicacions normals."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"vincular-la al servei de missatgeria d\'un operador"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Permet que el propietari la pugui vincular a la interfície principal del servei de missatgeria d\'un operador. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir les normes de contrasenya"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controla la longitud i els caràcters permesos a les contrasenyes de desbloqueig de pantalla."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Controlar els intents de desbloqueig de pantalla"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Replega"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Fins que soni l\'alarma següent a les <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Fins que soni l\'alarma següent"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Silenciat per <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"S\'ha produït un error intern al dispositiu i és possible que funcioni de manera inestable fins que restableixis les dades de fàbrica."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"S\'ha produït un error intern al dispositiu. Contacta amb el fabricant del dispositiu per obtenir més informació."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 0564656..81d2e50 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> s"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Povoluje aplikaci připojit a konfigurovat displeje přes Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ovládat displeje přes Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Povoluje aplikaci ovládat základní funkce displejů přes Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"ovládat virtuální privátní sítě"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Umožňuje aplikaci ovládat nízkoúrovňové funkce virtuálních privátních síti."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"zachytit výstup zvuku"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Umožní aplikaci zachytit a přesměrovat výstup zvuku."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Detekce klíčových slov"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Umožňuje této aplikaci přijímat informace o aktuálních přenosech pomocí technologie Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"odstranění certifikátů DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Povoluje aplikaci odstranit certifikáty DRM. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"navázat se na nejvyšší úroveň rozhraní služby zasílání zpráv prostřednictvím operátora"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Umožňuje držiteli navázat se na nejvyšší úroveň rozhraní služby zasílání zpráv prostřednictvím operátora. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavit pravidla pro heslo"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Řídit délku hesel pro odemčení obrazovky a povolené znaky."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Sledovat pokusy o odemčení obrazovky"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Sbalit"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Do dalšího budíku v <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Do příštího budíku"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Ignorováno stranou <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"V zařízení došlo k internímu problému. Dokud neprovedete obnovení továrních dat, může být nestabilní."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"V zařízení došlo k internímu problému. Další informace vám sdělí výrobce."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index c35f7e8..22c9506 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> t. <xliff:g id="MINUTES">%2$d</xliff:g> min."</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> t. <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> s"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min. <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>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Tillader, at appen konfigurerer og opretter forbindelse til Wi-Fi-skærme."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kontrollér Wi-Fi-skærme"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Tillader, at appen kontrollerer Wi-Fi-skærmfunktioner på lavt niveau."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"styre virtuelle private netværk"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Tillader, at appen styrer basale funktioner i virtuelle private netværk."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"opfang et lydoutput"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Tillader, at appen opfanger og omdirigerer et lydoutput."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Registrering af kommandoord"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Tillader, at applikationen modtager oplysninger om aktuelle Android Beam-overførsler"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"fjerne DRM-certifikater"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Tillader, at en app fjerner DRM-certifikater. Dette bør aldrig være nødvendigt for almindelige apps."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"knytte til et mobilselskabs beskedtjeneste"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Dette giver indehaveren mulighed for at knytte sig til det øverste grænsefladeniveau for et mobilselskabs beskedtjeneste. Dette bør ikke være nødvendigt i normale apps."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Indstil regler for adgangskode"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontroller længden samt tilladte tegn i adgangskoder til oplåsning af skærmen."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Overvåg forsøg på oplåsning af skærm"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Skjul"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Indtil næste alarm kl. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Indtil næste alarm"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Lyden blev afbrudt af <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Der er et internt problem med enheden, og den vil muligvis være ustabil, indtil du gendanner fabriksdataene."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Der er et internt problem med enheden. Kontakt producenten for at få yderligere oplysninger."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 5b8fcdd..cdbe08d 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> Std. <xliff:g id="MINUTES">%2$d</xliff:g> Min."</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> Std. <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> Sek."</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Erlaubt der App, WLAN-Anzeigen zu konfigurieren und eine Verbindung zu diesen herzustellen"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"WLAN-Anzeigen steuern"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Erlaubt der App, untergeordnete Funktionen von WLAN-Anzeigen zu steuern"</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"Virtuelle private Netzwerke steuern"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Ermöglicht der App die Steuerung von Basisfunktionen von virtuellen privaten Netzwerken"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"Audioausgabe erfassen"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Ermöglicht der App die Erfassung und Weiterleitung von Audioausgaben"</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Hotword-Erkennung"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Ermöglicht dieser App, Informationen zu aktuellen Android Beam-Übertragungen zu erhalten"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"DRM-Zertifikate entfernen"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Ermöglicht einer App das Entfernen von DRM-Zertifikaten. Sollte für normale Apps nie benötigt werden."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"An einen Mobilfunkanbieter-SMS/MMS-Dienst binden"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Ermöglicht dem Inhaber die Bindung an die Oberfläche eines Mobilfunkanbieter-SMS/MMS-Dienstes auf oberster Ebene. Für normale Apps sollte dies nie erforderlich sein."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Passwortregeln festlegen"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Zulässige Länge und Zeichen für Passwörter zum Entsperren des Bildschirms festlegen"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Versuche zum Entsperren des Displays überwachen"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Minimieren"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Bis zum nächsten Weckruf um <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Bis zum nächsten Weckruf"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Stummgeschaltet durch <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Es liegt ein internes Problem mit Ihrem Gerät vor. Möglicherweise verhält es sich instabil, bis Sie es auf die Werkseinstellungen zurücksetzen."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Es liegt ein internes Problem mit Ihrem Gerät vor. Bitte wenden Sie sich diesbezüglich an den Hersteller."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 86f0323..c062e42 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ώρα <xliff:g id="MINUTES">%2$d</xliff:g> λ"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ώρα <xliff:g id="MINUTES">%2$d</xliff:g> λ"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> λεπτά"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> λεπτά"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> λ. <xliff:g id="SECONDS">%2$d</xliff:g> δευτ."</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> λ <xliff:g id="SECONDS">%2$d</xliff:g> δευτ."</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> δευτ."</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Επιτρέπει τη διαμόρφωση της εφαρμογής και τη σύνδεσης σε οθόνες Wifi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"έλεγχος οθονών Wifi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Επιτρέπει στην εφαρμογή τον έλεγχο των λειτουργιών χαμηλού επιπέδου των οθονών Wifi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"έλεγχος εικονικών ιδιωτικών δικτύων"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Επιτρέπει στην εφαρμογή να ελέγχει τις λειτουργίες χαμηλού επιπέδου των εικονικών ιδιωτικών δικτύων."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"έγγραφή εξόδου ήχου"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Δίνει στην εφαρμογή τη δυνατότητα εγγραφής και ανακατεύθυνσης εξόδου ήχου."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Ανίχνευση ενεργών λέξεων"</string>
@@ -834,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"Ορισμός κανόνων κωδικού πρόσβασης"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Έλεγχος του μεγέθους και των χαρακτήρων που επιτρέπονται στους κωδικούς πρόσβασης ξεκλειδώματος οθόνης."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Παρακολούθηση προσπαθειών ξεκλειδώματος οθόνης"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Σύμπτυξη"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Έως την επόμενη ειδοποίηση στις <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Έως την επόμενη ειδοποίηση"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 7e1fc9e..98dc0f5 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -564,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Allows the app to configure and connect to Wi-Fi displays."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"control Wi-Fi displays"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Allows the app to control low-level features of Wi-Fi displays."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"control Virtual Private Networks"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Allows the app to control low-level features of Virtual Private Networks."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"capture audio output"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Allows the app to capture and redirect audio output."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Hotword detection"</string>
@@ -833,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Allows this application to receive information about current Android Beam transfers"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"remove DRM certificates"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Allows an application to remove DRM certficates. Should never be needed for normal apps."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"bind to a carrier messaging service"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Allows the holder to bind to the top-level interface of a carrier messaging service. Should never be needed for normal apps."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Control the length and the characters allowed in screen-unlock passwords."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitor screen-unlock attempts"</string>
@@ -1899,4 +1903,13 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Collapse"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Until next alarm at <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Until next alarm"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Muted by <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"There\'s an internal problem with your device. Contact your manufacturer for details."</string>
+    <string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD request is modified to DIAL request."</string>
+    <string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD request is modified to SS request."</string>
+    <string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD request is modified to new USSD request."</string>
+    <string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS request is modified to DIAL request."</string>
+    <string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS request is modified to USSD request."</string>
+    <string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS request is modified to new SS request."</string>
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 7e1fc9e..98dc0f5 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -564,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Allows the app to configure and connect to Wi-Fi displays."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"control Wi-Fi displays"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Allows the app to control low-level features of Wi-Fi displays."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"control Virtual Private Networks"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Allows the app to control low-level features of Virtual Private Networks."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"capture audio output"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Allows the app to capture and redirect audio output."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Hotword detection"</string>
@@ -833,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Allows this application to receive information about current Android Beam transfers"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"remove DRM certificates"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Allows an application to remove DRM certficates. Should never be needed for normal apps."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"bind to a carrier messaging service"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Allows the holder to bind to the top-level interface of a carrier messaging service. Should never be needed for normal apps."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Control the length and the characters allowed in screen-unlock passwords."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitor screen-unlock attempts"</string>
@@ -1899,4 +1903,13 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Collapse"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Until next alarm at <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Until next alarm"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Muted by <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"There\'s an internal problem with your device. Contact your manufacturer for details."</string>
+    <string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD request is modified to DIAL request."</string>
+    <string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD request is modified to SS request."</string>
+    <string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD request is modified to new USSD request."</string>
+    <string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS request is modified to DIAL request."</string>
+    <string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS request is modified to USSD request."</string>
+    <string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS request is modified to new SS request."</string>
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 122b247..e9fd79d 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> s"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite que la aplicación configure y se conecte a pantallas Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar pantallas Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite que la aplicación controle funciones de bajo nivel de las pantallas Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"controlar redes privadas virtuales"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Permite que la aplicación controle las funciones de bajo nivel de las redes privadas virtuales."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"Capturar salida de audio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Permite que la aplicación capture y redirija la salida de audio."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Detectar palabras activas"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Permite que esta aplicación reciba información sobre las transferencias actuales de Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"eliminar certificados DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Permite que una aplicación elimine certificados DRM. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"vincular al servicio de mensajería del proveedor"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Permite al propietario vincularse a la interfaz de nivel superior del servicio de mensajería del proveedor. Las aplicaciones regulares no lo necesitan."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Establecer reglas de contraseña"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar la longitud y los caracteres permitidos en las contraseñas para desbloquear la pantalla"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Supervisa los intentos para desbloquear la pantalla"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Contraer"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Hasta la próxima alarma a la(s) <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Hasta la próxima alarma"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Silenciados por <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Existe un problema interno con el dispositivo, de modo que el dispositivo puede estar inestable hasta que restablezcas la configuración de fábrica."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Existe un problema interno con el dispositivo. Comunícate con el fabricante para obtener más información."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index a4f58ec..a8bdbbd 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> s"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite que la aplicación configure pantallas Wi-Fi y se conecte a ellas."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar pantallas Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite que la aplicación controle funciones de bajo nivel de pantallas Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"controlar redes privadas virtuales"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Permite que la aplicación controle funciones de bajo nivel de redes privadas virtuales."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"capturar salida de audio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Permite que la aplicación capture y redirija la salida de audio."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Detectar palabras activas"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Permite que esta aplicación reciba información sobre las transferencias actuales de Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"eliminar certificados DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Permite a una aplicación eliminar los certificados DRM. Las aplicaciones normales no deberí­an necesitar este permiso."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"enlazar con el servicio de mensajería de un operador"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Permite enlazar con la interfaz de nivel superior del servicio de mensajería de un operador. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Establecimiento de reglas de contraseña"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar la longitud y los caracteres permitidos en las contraseñas de bloqueo de pantalla"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Control de intentos de bloqueo de pantalla"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Contraer"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Hasta la próxima alarma a las <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Hasta la próxima alarma"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Silenciado por <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Se ha producido un problema interno en el dispositivo y es posible que este no sea estable hasta que restablezcas los datos de fábrica."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Se ha producido un problema interno en el dispositivo. Ponte en contacto con el fabricante para obtener más información."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index ab5fe00..d6627da 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> s"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Lubab rakendusel seadistada WiFi-ekraane ja nendega ühendus luua."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"WiFi-ekraanide juhtimine"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Lubab rakendusel juhtida WiFi-ekraanide madala taseme funktsioone."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"virtuaalsete privaatvõrkudega juhtimine"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Lubab rakendusel juhtida virtuaalsete privaatvõrkude alamtaseme funktsioone."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"heliväljundi jäädvustamine"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Lubab rakendusel jäädvustada ja ümber suunata heliväljundit."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Otsetee sõna tuvastamine"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Lubab rakendusel saada teavet praeguste Android Beami ülekannete kohta"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"DRM-sertifikaatide eemaldamine"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Lubab rakendusel eemaldada DRM-sertifikaate. Pole kunagi vajalik tavaliste rakenduste puhul."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"seose loomine operaatori sõnumisideteenusega"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Lubab omanikul luua seose operaatori sõnumisideteenuse ülataseme liidesega. Pole kunagi vajalik tavalise rakenduse puhul."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Parooli reeglite määramine"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrollige ekraaniluku avamise paroolide pikkust ja tähemärke."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekraani avamiskatsed"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Ahendamine"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Kuni järgmise alarmini <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Kuni järgmise alarmini"</string>
+    <string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> vaigistas"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Seadmes ilmnes sisemine probleem ja seade võib olla ebastabiilne seni, kuni lähtestate seadme tehase andmetele."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Seadmes ilmnes sisemine probleem. Üksikasjaliku teabe saamiseks võtke ühendust tootjaga."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index fb24723..aa7d6c4 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> m"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> m"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> m"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> m <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> m <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Wi-Fi pantailak konfiguratzeko eta haietara konektatzeko baimena ematen die aplikazioei."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fi pantailak kontrolatzea"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Wi-Fi pantailetako behe-mailako eginbideak kontrolatzeko baimena ematen die aplikazioei."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"Kontrolatu sare pribatu birtualak"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Sare pribatu birtualen behe-mailako eginbideak kontrolatzea baimentzen die aplikazioei."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"Grabatu audio-irteera"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Audio-irteera grabatzeko eta birbideratzeko aukera ematen die aplikazioei."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Hauteman Hotword"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Uneko Android Beam transferentziei buruzko informazioa jasotzea baimentzen die aplikazioei"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"kendu DRM ziurtagiriak"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"DRM ziurtagiriak kentzea baimentzen die aplikazioei. Aplikazio normalek ez lukete beharko."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"lotu operadorearen mezularitza-zerbitzuari"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Operadore baten mezularitza-zerbitzuaren goi-mailako interfazeari lotzea baimentzen die erabiltzaileei. Aplikazio normalek ez lukete inoiz beharko."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Ezarri pasahitzen arauak"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolatu pantaila desblokeatzeko pasahitzen luzera eta onartutako karaktereak."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Kontrolatu pantaila desblokeatzeko saiakerak"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Tolestu"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Hurrengo alarmara arte (<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Hurrengo alarmara arte"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Audioa desaktibatu da (<xliff:g id="THIRD_PARTY">%1$s</xliff:g>)"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Barneko arazo bat dago zure gailuan eta agian ezegonkor egongo da jatorrizko datuak berrezartzen dituzun arte."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Barneko arazo bat dago zure gailuan. Xehetasunak jakiteko, jarri fabrikatzailearekin harremanetan."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index c864b42..51ba165 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ساعت و <xliff:g id="MINUTES">%2$d</xliff:g> دقیقه"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ساعت و <xliff:g id="MINUTES">%2$d</xliff:g> دقیقه"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> دقیقه"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> دقیقه"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> دقیقه و <xliff:g id="SECONDS">%2$d</xliff:g> ثانیه"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> دقیقه و <xliff:g id="SECONDS">%2$d</xliff:g> ثانیه"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> ثانیه"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"‏به برنامه اجازه می‌دهد تا اتصال به صفحات نمایش Wi‑Fi را پیکربندی کند."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"‏کنترل صفحه نمایش‌های Wi‑Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"‏به برنامه اجازه می‌دهد که ویژگی‌های سطح پایین صفحه‌های نمایش Wi‑Fi را کنترل کند."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"کنترل شبکه‌های خصوصی مجازی"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"به برنامه امکان کنترل ویژگی‌های سطح پایین شبکه‌های خصوصی مجازی را می‌دهد."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ضبط خروجی صدا"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"به برنامه امکان می‌دهد خروجی صدا را ضبط و هدایت کند."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"تشخیص کلیدگفته"</string>
@@ -834,6 +835,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="policylab_limitPassword" msgid="4497420728857585791">"تنظیم قوانین رمز ورود"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"‏طول و نویسه‎های مجاز در گذرواژه‌های بازکردن قفل صفحه را کنترل کنید."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"نمایش تلاش‌های قفل گشایی صفحه"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"کوچک کردن"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"تا هشدار بعدی در <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"تا هشدار بعدی"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 72b7880..f39abf1 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> t <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> t <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> s"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Antaa sovelluksen määrittää wifi-näyttöjä ja muodostaa yhteyden niihin."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"hallitse wifi-näyttöjä"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Antaa sovelluksen hallita wifi-näyttöjen matalan tason ominaisuuksia."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"Hallita virtuaalisia yksityisverkkoja."</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Sallii sovelluksen hallita virtuaalisten yksityisverkkojen alempien tasojen ominaisuuksia."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"äänentoiston kaappaus"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Antaa sovellukselle luvan äänentoiston kaappaamiseen ja uudelleenohjaamiseen."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Toimintosanan tunnistus"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Antaa sovelluksen vastaanottaa tietoja nykyisistä Android Beam -siirroista"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"DRM-varmenteiden poistaminen"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Antaa sovelluksen poistaa DRM-varmenteita. Ei tavallisten sovellusten käyttöön."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"Operaattorin viestipalveluun sitoutuminen"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Antaa sovelluksen sitoutua operaattorin viestipalvelun ylätason liittymään. Ei tavallisten sovellusten käyttöön."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Aseta salasanasäännöt"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Hallinnoi ruudun lukituksenpoistosalasanoissa sallittuja merkkejä ja salasanan pituutta."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Tarkkaile ruudun lukituksen poistoyrityksiä"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Kutista"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Seuraavaan herätykseen saakka (<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Seuraavaan herätykseen saakka"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Mykistänyt <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Laitteellasi on sisäinen ongelma, joka aiheuttaa epävakautta. Voit korjata tilanteen palauttamalla tehdasasetukset."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Laitteesi yhdistäminen ei onnistu sisäisen virheen takia. Saat lisätietoja valmistajalta."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 18db5c6..6925454 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h et <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h et <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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 et <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min et <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permet à l\'application de configurer des écrans Wi-Fi et de s\'y connecter."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"contrôler les écrans Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permet à l\'application de contrôler les fonctionnalités de base des écrans Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"commander les réseaux privés virtuels"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Permet à l\'application de commander les fonctions de bas niveau des réseaux privés virtuels."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"capturer la sortie audio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Autoriser l\'application à capturer et à rediriger la sortie audio."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Détection de mots clés"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Autoriser cette application à recevoir des données sur les transferts Android Beam en cours"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"supprimer des certificats GDN"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Permet à une application de supprimer les certificats GDN. Cela ne devrait jamais être nécessaire pour des applications normales."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"s\'associer à un service de messagerie d\'un fournisseur"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service de messagerie d\'un fournisseur. Les applications standards ne devraient jamais avoir recours à cette fonctionnalité."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Choisir le nombre et le type de caractères autorisés dans les mots de passe de déverrouillage de l\'écran"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Gérer les tentatives de déverrouillage de l\'écran"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Réduire"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Jusqu\'à la prochaine alarme, à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Jusqu\'à la prochaine alarme"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Mis en sourdine par <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Un problème interne est survenu avec votre appareil. Il se peut qu\'il soit instable jusqu\'à ce que vous le réinitialisiez à sa configuration d\'usine."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Un problème interne est survenu avec votre appareil. Communiquez avec le fabricant pour obtenir plus de détails."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 04d23b0..def3d35c 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h et <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h et <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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 et <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min et <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permet à l\'application de configurer des écrans Wi-Fi et de s\'y connecter."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"contrôler les écrans Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permet à l\'application de contrôler les fonctionnalités de base des écrans Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"contrôler les réseaux privés virtuels"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Permettre à l\'application de contrôler les fonctionnalités de base des réseaux privés virtuels"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"enregistrer les sorties audio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Autoriser l\'application à enregistrer et à rediriger les sorties audio"</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Détection de mot clé"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Autoriser cette application à recevoir des informations sur les transferts Android Beam en cours"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"supprimer les certificats de GDN"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Permet à une application de supprimer les certificats de GDN. Ne devrait jamais être nécessaire pour les applications standards."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"s\'associer au service SMS/MMS d\'un opérateur"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Permettre à l\'application de s\'associer à l\'interface de niveau supérieur du service SMS/MMS d\'un opérateur. Ne devrait jamais être nécessaire pour les applications standards."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Choisir le nombre et le type de caractères autorisés dans les mots de passe de déverrouillage de l\'écran"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Gérer les tentatives de déverrouillage de l\'écran"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Réduire"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Jusqu\'à la prochaine alarme à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Jusqu\'à la prochaine alarme"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Son coupé par : <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Un problème interne lié à votre appareil est survenu. Ce dernier risque d\'être instable jusqu\'à ce que vous rétablissiez la configuration d\'usine."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Un problème interne lié à votre appareil est survenu. Veuillez contacter le fabricant pour en savoir plus."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 20a9e43..0380519 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> hr <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> hr <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> minuto"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> seg"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> seg"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> segundos"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite á aplicación configurar e conectarse a pantallas wifi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar pantallas wifi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite á aplicación controlar funcións de baixo nivel de pantallas wifi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"controlar redes virtuais privadas"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Permite que a aplicación controle as funcións de nivel básico das redes virtuais privadas."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"capturar saída de audio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Permite á aplicación capturar e redireccionar a saída de audio."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Detección de palabras activas"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Permite a esta aplicación recibir información acerca das transferencias actuais de Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"eliminar certificados DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Permite a unha aplicación eliminar os certificados DRM. As aplicacións normais non o deberían precisar nunca."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"vincular a un servizo de mensaxería"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Permite ao propietario vincularse á interface de nivel superior dun servizo de mensaxería. As aplicacións normais non deberían necesitar este permiso."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Establecer as normas de contrasinal"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar a lonxitude e os caracteres permitidos nos contrasinais de desbloqueo da pantalla."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Supervisar os intentos de desbloqueo da pantalla"</string>
@@ -1898,6 +1901,21 @@
     <string name="zen_mode_until" msgid="7336308492289875088">"Ata as <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_forever" msgid="4316804956488785559">"Indefinidamente"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Contraer"</string>
-    <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Ata a seguinte alarma ás <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
-    <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Ata a seguinte alarma"</string>
+    <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Ata que soe a seguinte alarma ás <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+    <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Ata que soe a seguinte alarma"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Silenciado por <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Produciuse un problema interno co teu dispositivo e quizais estea inestable ata o restablecemento dos datos de fábrica."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Produciuse un problema interno co teu dispositivo. Contacta co teu fabricante para obter máis detalles."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index fdc68ec..ab2edfc 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> घं. <xliff:g id="MINUTES">%2$d</xliff:g> मि."</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> घं. <xliff:g id="MINUTES">%2$d</xliff:g> मि."</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> मिनट"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> मिनट"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> मि. <xliff:g id="SECONDS">%2$d</xliff:g> से."</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> मि. <xliff:g id="SECONDS">%2$d</xliff:g> से."</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> सेकंड"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"ऐप्स  को कॉन्फ़िगर करने देता है और Wifi डिस्प्ले से कनेक्ट करता है."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi डिस्प्ले को नियंत्रित करें"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"ऐप्स  को Wifi डिस्प्ले की निम्न-स्तर की सुविधाएं नियंत्रित करने देता है."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"आभासी निजी नेटवर्क को नियंत्रित करें"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"ऐप्‍स को आभासी निजी नेटवर्क की निम्‍न-स्‍तर की सुविधाओं को नियंत्रित करने देती है."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ऑडियो आउटपुट को कैप्‍चर करें"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"ऐप्स को ऑडियो आउटपुट को कैप्‍चर और रीडायरेक्‍ट करने देता है."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"हॉटवर्ड पहचान"</string>
@@ -834,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करें"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"स्‍क्रीन-अनलॉक पासवर्ड में अनुमति प्राप्त लंबाई और वर्णों को नियंत्रित करें."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"स्‍क्रीन-अनलॉक के प्रयासों पर निगरानी रखें"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त करें"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> पर अगले अलार्म तक"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"अगले अलार्म तक"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index c8c37e6..2315075 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> s"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Omogućuje aplikaciji konfiguriranje i povezivanje s Wi-Fi zaslonima."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"upravljaj Wifi zaslonima"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Omogućuje aplikaciji upravljanje značajkama Wi-Fi zaslona niske razine."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"upravljanje virtualnim privatnim mrežama"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Aplikaciji omogućuje upravljanje značajkama niske razine na virtualnim privatnim mrežama."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"primanje audioizlaza"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Omogućuje aplikaciji primanje i preusmjeravanje audioizlaza."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Otkrivanje pokretača značajke"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Omogućuje aplikaciji primanje podataka o trenutačnim prijenosima Android Beama"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"uklanjanje DRM certifikata"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Omogućuje aplikaciji uklanjanje DRM certifikata. Ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"povezivanje s uslugom mobilnog operatera za slanje poruka"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Omogućuje nositelju povezivanje sa sučeljem najviše razine usluge mobilnog operatera za slanje poruka. Ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Postavi pravila zaporke"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Upravljajte duljinom zaporki za otključavanje zaslona i dopuštenim znakovima u tim zaporkama."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Nadgledaj pokušaje otključavanja zaslona"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Sažmi"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Do sljedećeg alarma u <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Do sljedećeg alarma"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Zvuk je isklj. treća strana <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Na vašem uređaju postoji interni problem i možda neće biti stabilan dok ga ne vratite na tvorničko stanje."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Na vašem uređaju postoji interni problem. Obratite se proizvođaču za više pojedinosti."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 1f91ef2..1e56caf 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> óra <xliff:g id="MINUTES">%2$d</xliff:g> perc"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> óra <xliff:g id="MINUTES">%2$d</xliff:g> perc"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> perc"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> perc"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> perc <xliff:g id="SECONDS">%2$d</xliff:g> mp"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> perc <xliff:g id="SECONDS">%2$d</xliff:g> mp"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> másodperc"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Lehetővé teszi, hogy az alkalmazás Wi-Fi kijelzőket konfiguráljon, és csatlakozzon hozzájuk."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fi kijelzők irányítása"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Lehetővé teszi, hogy az alkalmazás irányítsa a Wi-Fi kijelzők alacsonyabb szintű funkcióit."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"virtuális magánhálózatok kezelése"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Lehetővé teszi, hogy az alkalmazás kezelje a virtuális magánhálózatok alacsony szintű funkcióit."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"audiokimenet rögzítése"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Engedélyezi az alkalmazásnak a hangkimenet rögzítését és átirányítását."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Hotwordérzékelés"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Lehetővé teszi az alkalmazás számára a folyamatban lévő Android Beam-átvitelekről szóló információk fogadását"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"DRM-tanúsítványok eltávolítása"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Lehetővé teszi, hogy az alkalmazás eltávolítsa a DRM-tanúsítványokat. A normál alkalmazásoknak erre soha nincs szükségük."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"kapcsolódás egy üzenetszolgáltatáshoz"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Lehetővé teszi, hogy a tulajdonos kapcsolódjon egy üzenetszolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Jelszavakkal kapcsolatos szabályok beállítása"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"A képernyőzár-feloldási jelszavakban engedélyezett karakterek és hosszúság vezérlése."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Képernyőzár-feloldási kísérletek figyelése"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Összecsukás"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"A következő ébresztésig ekkor: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"A következő ébresztésig"</string>
+    <string name="muted_by" msgid="6147073845094180001">"A(z) <xliff:g id="THIRD_PARTY">%1$s</xliff:g> elnémította"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Belső probléma van az eszközzel, és instabil lehet, amíg vissza nem állítja a gyári adatokat."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Belső probléma van az eszközzel. A részletekért vegye fel a kapcsolatot a gyártóval."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index eed4f86..018dbb3 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -564,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Թույլ է տալիս հավելվածին կարգավորել և միանալ WiFi ցուցադրիչներին:"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"կառավարել Wifi-ի ցուցադրումը"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Թույլ է տալիս հավելվածին կառավարել WiFi ցուցադրիչների ցածր մակարդակի գործառույթները:"</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"վերահսկել Վիրտուալ մասնավոր ցանցերը"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Թույլ է տալիս հավելվածին վերահսկել Վիրտուալ մասնավոր ցանցերի ցածր մակարդակի գործառույթները:"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"պահել աուդիո արտածումը"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Թույլ է տալիս ծրագրին պահել և վերահղել աուդիո արտածումը:"</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Թեժ բառի հայտնաբերում"</string>
@@ -833,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"Սահմանել գաղտնաբառի կանոնները"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Վերահսկել էկրանի ապակողպման գաղտնաբառերի թույլատրելի երկարությունն ու գրանշանները:"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Վերահսկել էկրանի ապակողպման փորձերը"</string>
@@ -1899,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Թաքցնել"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Մինչև հաջորդ զարթուցիչը՝ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Մինչև հաջորդ զարթուցիչը"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 7e4bc4d..98556a2 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> jam <xliff:g id="MINUTES">%2$d</xliff:g> mnt"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> jam <xliff:g id="MINUTES">%2$d</xliff:g> mnt"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> mnt"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> menit"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> mnt <xliff:g id="SECONDS">%2$d</xliff:g> dtk"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> mnt <xliff:g id="SECONDS">%2$d</xliff:g> dtk"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> dtk"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Izinkan aplikasi mengonfigurasi dan terhubung ke tampilan Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"mengontrol tampilan Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Izinkan aplikasi mengontrol fitur tingkat rendah dari tampilan Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"kontrol Jaringan Pribadi Maya"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Mengizinkan aplikasi untuk mengontrol fitur tingkat rendah dari Jaringan Pribadi Maya."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"tangkap keluaran audio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Memungkinkan aplikasi menangkap dan mengalihkan keluaran audio."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Deteksi kata cepat"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Memungkinkan aplikasi ini menerima informasi tentang transfer Android Beam saat ini"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"membuang serifikat DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Memungkinkan aplikasi membuang sertifikat DRM. Tidak pernah dibutuhkan untuk aplikasi normal."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"ikat ke layanan perpesanan operator"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Mengizinkan pemegang untuk mengikat ke antarmuka tingkat tinggi dari suatu layanan perpesanan operator. Tidak pernah diperlukan oleh aplikasi normal."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Setel aturan sandi"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrol panjang dan karakter yang diizinkan dalam sandi pembuka layar."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Upaya pembukaan kunci layar monitor"</string>
@@ -1878,7 +1881,7 @@
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Meminta sandi sebelum melepas sematan"</string>
     <string name="battery_saver_description" msgid="2510530476513605742">"Guna membantu meningkatkan masa pakai baterai, penghemat baterai mengurangi kinerja perangkat dan membatasi getaran serta sebagian besar data latar belakang. Email, perpesanan, dan aplikasi lain yang bergantung pada sinkronisasi mungkin tidak akan diperbarui kecuali Anda membukanya.\n\nPenghemat baterai dinonaktifkan secara otomatis saat perangkat diisi daya."</string>
     <string name="downtime_condition_summary" msgid="8761776337475705749">"Hingga waktu perbaikan Anda berakhir pukul <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
-    <string name="downtime_condition_line_one" msgid="8762708714645352010">"Hingga waktu henti berakhir"</string>
+    <string name="downtime_condition_line_one" msgid="8762708714645352010">"Hingga waktu non-operasional berakhir"</string>
   <plurals name="zen_mode_duration_minutes_summary">
     <item quantity="one" msgid="3177683545388923234">"Selama semenit (hingga <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
     <item quantity="other" msgid="2787867221129368935">"Selama %1$d menit (hingga <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1898,6 +1901,21 @@
     <string name="zen_mode_until" msgid="7336308492289875088">"Hingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_forever" msgid="4316804956488785559">"Tidak ditentukan"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Ciutkan"</string>
-    <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Hingga alarm berikutnya pukul <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
-    <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Hingga alarm berikutnya"</string>
+    <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Sampai alarm berikutnya pukul <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+    <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Sampai alarm berikutnya"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Dinonaktifkan oleh <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Ada masalah internal dengan perangkat, dan mungkin tidak stabil sampai dikembalikan ke setelan pabrik."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Ada masalah internal dengan perangkat. Hubungi pembuat perangkat untuk detail lengkap."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index a58cb8c..a852cda 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> k. <xliff:g id="MINUTES">%2$d</xliff:g> mín."</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> k. <xliff:g id="MINUTES">%2$d</xliff:g> mín."</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> mín."</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> mín."</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> m. <xliff:g id="SECONDS">%2$d</xliff:g> sek."</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> m. <xliff:g id="SECONDS">%2$d</xliff:g> sek."</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek."</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Leyfir forriti að grunnstilla og tengjast þráðlausum skjáum."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"stjórna þráðlausum skjáum"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Leyfir forriti að stjórna grunnvirkni þráðlausra skjáa."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"stjórna VPN-sýndarnetum"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Leyfir forritinu að stjórna grunneiginleikum VPN-sýndarneta."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"fanga hljóðúttak"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Leyfir forriti að fanga og endurbeina hljóðúttaki."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Greining skipana"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Leyfir þessu forriti að fá upplýsingar um flutning sem fram fer með Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"fjarlægja DRM-vottorð"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Leyfir forriti að fjarlægja DRM-vottorð. Ætti aldrei að vera nauðsynlegt fyrir venjuleg forrit."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"bindast skilaboðaþjónustu símafyrirtækis"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Leyfir forriti að bindast efsta viðmótslagi skilaboðaþjónustu símafyrirtækis. Ætti aldrei að vera nauðsynlegt fyrir venjuleg forrit."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Setja reglur um aðgangsorð"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Stjórna lengd aðgangsorða til að taka skjáinn úr lás og leyfðum stöfum."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Fylgjast með tilraunum til að taka skjáinn úr lás"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Minnka"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Fram að næsta vekjara kl. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Fram að næsta vekjara"</string>
+    <string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> tók hljóðið af"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Innra vandamál kom upp í tækinu og það kann að vera óstöðugt þangað til þú núllstillir það."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Innra vandamál kom upp í tækinu. Hafðu samband við framleiðanda til að fá nánari upplýsingar."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index ffc8aec..8fc5786 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ora <xliff:g id="MINUTES">%2$d</xliff:g> minuti"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ora <xliff:g id="MINUTES">%2$d</xliff:g> minuto"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> minuti"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> minuto <xliff:g id="SECONDS">%2$d</xliff:g> secondi"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> minuto <xliff:g id="SECONDS">%2$d</xliff:g> secondo"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> secondi"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Consente all\'applicazione di configurare schermi Wi-Fi e di collegarsi a essi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controllo di schermi Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Consente all\'applicazione di controllare le funzioni di basso livello di schermi Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"controllo di reti private virtuali"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Consente all\'app di controllare le funzioni di basso livello di reti private virtuali."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"acquisizione dell\'uscita audio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Consente all\'app di acquisire e reindirizzare l\'uscita audio."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Rilevamento hotword"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Consente all\'applicazione di ricevere informazioni sugli attuali trasferimenti Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"rimozione di certificati DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Consente a un\'applicazione di rimuovere certificati DRM. Non dovrebbe mai essere necessaria per le normali applicazioni."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"associazione a un servizio di messaggi dell\'operatore"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Consente l\'associazione di un servizio di messaggi dell\'operatore all\'interfaccia principale. Non dovrebbe mai essere necessaria per le normali applicazioni."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Impostazione regole password"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlla la lunghezza e i caratteri ammessi nelle password di sblocco dello schermo."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Controllo tentativi di sblocco dello schermo"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Comprimi"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Fino alla prossima sveglia alle ore <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Fino alla prossima sveglia"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Audio disattivato da <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Si è verificato un problema interno con il dispositivo, che potrebbe essere instabile fino al ripristino dei dati di fabbrica."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Si è verificato un problema interno con il dispositivo. Per informazioni dettagliate, contatta il produttore."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 2e630df..d469ca8 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"שעה <xliff:g id="HOURS">%1$d</xliff:g> ‏<xliff:g id="MINUTES">%2$d</xliff:g> דק\'"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> שעות <xliff:g id="MINUTES">%2$d</xliff:g> דק\'"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> דקות"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> דקות"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"דקה <xliff:g id="MINUTES">%1$d</xliff:g> ‏<xliff:g id="SECONDS">%2$d</xliff:g> שנ\'"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"דקה <xliff:g id="MINUTES">%1$d</xliff:g> שנ\' <xliff:g id="SECONDS">%2$d</xliff:g>"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> שניות"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"‏מאפשר לאפליקציה להגדיר ולהתחבר לתצוגות Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"‏שלוט בתצוגות Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"‏מאפשר לאפליקציה לשלוט בתכונות ברמה נמוכה של תצוגות Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"שליטה על רשתות וירטואליות פרטיות"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"מאפשר לאפליקציה לקבוע תכונות ברמה נמוכה של רשתות וירטואליות פרטיות."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"קליטת פלט אודיו"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"מאפשרת לאפליקציה לקלוט ולהפנות מחדש פלט אודיו."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"זיהוי של מילת הפעלה"</string>
@@ -834,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"הגדר כללי סיסמה"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"שלוט באורך ובתווים המותרים בסיסמאות לביטול נעילת מסך."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"עקוב אחר ניסיונות לביטול נעילת מסך"</string>
@@ -1900,4 +1903,13 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"כווץ"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"עד ההתראה הבאה ב-<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"עד ההתראה הבאה"</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="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>
+    <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>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index fb1741f..93f6f79 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g>時間<xliff:g id="MINUTES">%2$d</xliff:g>分"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g>時間<xliff:g id="MINUTES">%2$d</xliff:g>分"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g>分"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g>分"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g>分<xliff:g id="SECONDS">%2$d</xliff:g>秒"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g>分<xliff:g id="SECONDS">%2$d</xliff:g>秒"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g>秒"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Wi-Fiディスプレイを設定して接続することをアプリに許可します。"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fiディスプレイの制御"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Wi-Fiディスプレイの低レベル機能を制御することをアプリに許可します。"</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"仮想プライベートネットワークの制御"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"仮想プライベートネットワークの低レベル機能を制御することをアプリに許可します。"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"音声出力のキャプチャ"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"音声出力のキャプチャとリダイレクトをアプリに許可します。"</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"注目ワード検出"</string>
@@ -834,6 +835,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">"携帯通信会社のSMSサービスへのバインド"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"携帯通信会社のSMSサービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"パスワードルールの設定"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"画面ロック解除パスワードの長さと使用できる文字を制御します。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"画面ロック解除試行の監視"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"折りたたむ"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"次のアラーム(<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)まで"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"次のアラームまで"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 235c754..eebaabf 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> სთ <xliff:g id="MINUTES">%2$d</xliff:g> წთ"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> სთ <xliff:g id="MINUTES">%2$d</xliff:g> წთ"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> წთ"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> წთ"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> წთ <xliff:g id="SECONDS">%2$d</xliff:g> წმ"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> წთ <xliff:g id="SECONDS">%2$d</xliff:g> წმ"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> წმ"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"აპს შეეძლება Wifi ეკრანებთან დაკავშირება და დაკონფიგურირება."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi ეკრანების მართვა"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"აპს შეეძლება აკონტროლოს Wifi ეკრანების დაბალი დონის ფუნქციები."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"ვირტუალური კერძო ქსელების კონტროლი"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"საშუალებას აძლევს აპლიკაციას აკონტროლოს ვირტუალური პირადი ქსელების დაბალი დონის ფუნქციები."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"გამომავალი აუდიოს დაჭერა"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"საშუალებას აძლევს აპს დაიჭიროს და გადაამისამართოს გამომავალი აუდიო."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"ჯადოსნური სიტყვის პოვნა"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"ნებას რთავს ამ აპლიკაციას, მიიღოს ინფორმაცია მიმდინარე Android Beam-ის ტრანსფერების შესახებ"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"DRM სერტიფიკატების ამოშლა"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"საშუალებას აძლევს აპლიკაციას ამოშალოს DRM სერtიფიკატები. ეს წესით ჩვეულებრივ აპებს არ უნდა დაჭირდეს."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"აკავშირებს შეტყობინების გაცვლის მომსახურებას"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"საშუალებას აძლევს მფლობელს შექმნას შეტყობინების გაცვლის მომსახურების უმახლესი დონის ინტერფეისი. არასდროს იქნება საჭირო ნორმალური აპლიკაციებისათვის."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"პაროლის წესების დაყენება"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"გააკონტროლეთ ეკრანის განბლოკვის პაროლში დაშვებული სიმბოლოები და მისი სიგრძე."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ეკრანის განბლოკვის მცდელობების გაკონტროლება"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"აკეცვა"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"შემდეგ მაღვიძარამდე <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-ში"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"შემდეგ მაღვიძარამდე"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 7b810a4..97b435a 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> сағ. <xliff:g id="MINUTES">%2$d</xliff:g> м."</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> сағ. <xliff:g id="MINUTES">%2$d</xliff:g> м."</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> мин."</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> мин"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> мин. <xliff:g id="SECONDS">%2$d</xliff:g> с."</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> мин. <xliff:g id="SECONDS">%2$d</xliff:g> с."</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек."</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Қолданбаларға Wifi дисплейлерін конфигурациялау және қосылу мүмкіндігін береді."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi дисплейлерін басқару"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Қолданбаларға Wifi дисплейлерінің төмен деңгейлі функцияларын басқару мүмкіндігін береді."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"control Virtual Private Networks"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Allows the app to control low-level features of Virtual Private Networks."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"аудио шығысын жазып алу"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Қолданбаға аудио сигналды қабылдап, басқа бағытта жөнелту мүмкіндігін ұсынады."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Байланыс сөзін анықтау"</string>
@@ -834,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"Кілтсөз ережелерін тағайындау"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Экранды ашу кілтсөздерінің ұзындығы мен қолдануға болатын таңбаларды басқару."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Экранды ашу әркеттерін бақылау"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Тасалау"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> уақытындағы келесі дабылға дейін"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Келесі дабылға дейін"</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">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"There\'s an internal problem with your device. Contact your manufacturer for details."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 566351a..9b13133 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -564,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"ឲ្យ​កម្មវិធី​កំណត់​រចនាសម្ព័ន្ធ​ និង​ភ្ជាប់​ទៅ​ការ​បង្ហាញ​វ៉ាយហ្វាយ។"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ពិនិត្យ​ការ​បង្ហាញ​វ៉ាយហ្វាយ"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"ឲ្យ​កម្មវិធី​ពិនិត្យ​លក្ខណៈ​កម្រិត​ទាប​​នៃ​ការ​បង្ហាញ​វ៉ាយហ្វាយ។"</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"គ្រប់គ្រង បណ្តាញឯកជននិមិត្ម"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"អនុញ្ញាតឲ្យកម្មវិធីគ្រប់គ្រងលក្ខណៈពិសេសកម្រិតទាបនៃបណ្តាញឯកជននិមិត្ម Virtual Private Networks។"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ចាប់​យក​លទ្ធផល​អូឌីយ៉ូ"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"​ឱ្យ​កម្មវិធី​ដើម្បី​ចាប់​យក​ និង​​ប្ដូរ​​ទិស​លទ្ធផល​អូឌីយ៉ូ​។"</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"ការ​រក​ឃើញ​ពាក្យ"</string>
@@ -833,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"កំណត់​ក្បួន​ពាក្យ​សម្ងាត់"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"ពិនិត្យ​ប្រវែង និង​តួអក្សរ​ដែល​បាន​អនុញ្ញាត​ក្នុង​ពាក្យ​សម្ងាត់​ចាក់​សោ​អេក្រង់។"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ពិនិត្យ​ការ​ព្យាយាម​ដោះ​សោ​អេក្រង់"</string>
@@ -1901,4 +1905,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"បង្រួម"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"រហូត​ដល់​ការ​ជូន​ដំណឹង​បន្ទាប់​នៅ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"រហូត​ការ​ជូន​ដំណឹង​បន្ទាប់"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 0211057..e53fb1e 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ಗಂಟೆ <xliff:g id="MINUTES">%2$d</xliff:g> ನಿಮಿಷಗಳು"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ಗಂಟೆ <xliff:g id="MINUTES">%2$d</xliff:g> ನಿಮಿಷ"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> ನಿಮಿಷಗಳು"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> ನಿಮಿಷ"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> ನಿಮಿ <xliff:g id="SECONDS">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳು"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> ನಿಮಿ <xliff:g id="SECONDS">%2$d</xliff:g> ಸೆ"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> ಸೆಕೆಂಡುಗಳು"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"ವೈಫೈ ಪ್ರದರ್ಶನಗಳಿಗೆ ಕಾನ್ಫಿಗರ್ ಮಾಡಲು ಮತ್ತು ಸಂಪರ್ಕಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ವೈಫೈ ಪ್ರದರ್ಶನಗಳನ್ನು ನಿಯಂತ್ರಿಸಿ"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"ವೈಫೈ ಪ್ರದರ್ಶನಗಳ ಕೆಳ-ಮಟ್ಟದ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ನಿಯಂತ್ರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅವಕಾಶ ಕಲ್ಪಿಸುತ್ತದೆ."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"ವರ್ಚುವಲ್ ಖಾಸಗಿ ನೆಟ್‌ವರ್ಕ್‌ಗಳನ್ನು ನಿಯಂತ್ರಿಸಿ"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"ವರ್ಚುವಲ್ ಖಾಸಗಿ ನೆಟ್‌ವರ್ಕ್‌ಗಳ ಕೆಳ ಮಟ್ಟದ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ನಿಯಂತ್ರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ಆಡಿಯೊ ಔಟ್‌ಪುಟ್ ಸೆರೆಹಿಡಿಯಿರಿ"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"ಆಡಿಯೊ ಔಟ್‌ಪುಟ್ ಸೆರೆಹಿಡಿಯಲು ಮತ್ತು ಮರುನಿರ್ದೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"ಹಾಟ್‌ವರ್ಡ್ ಪತ್ತೆಹಚ್ಚುವಿಕೆ"</string>
@@ -834,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"ಪಾಸ್‌ವರ್ಡ್ ನಿಮಯಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"ಪರದೆ-ಅನ್‍‍ಲಾಕ್ ಪಾಸ್‍‍ವರ್ಡ್‌ಗಳಲ್ಲಿ ಅನುಮತಿಸಿರುವ ಅಳತೆ ಮತ್ತು ಅಕ್ಷರಗಳನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ಪರದೆಯ-ಅನ್‌ಲಾಕ್ ಪ್ರಯತ್ನಗಳನ್ನು ಮಾನಿಟರ್ ಮಾಡಿ"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"ಸಂಕುಚಿಸು"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"ಮುಂದಿನ ಅಲಾರಮ್ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ವರೆಗೆ"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"ಮುಂದಿನ ಅಲಾರಮ್‌ವರೆಗೆ"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 490f64e..f7b8052 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g>시간 <xliff:g id="MINUTES">%2$d</xliff:g>분"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g>시간 <xliff:g id="MINUTES">%2$d</xliff:g>분"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g>분"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g>분"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g>분 <xliff:g id="SECONDS">%2$d</xliff:g>초"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g>분 <xliff:g id="SECONDS">%2$d</xliff:g>초"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g>초"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"앱이 Wi-Fi 디스플레이를 설정하고 연결하도록 허용합니다."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fi 디스플레이 제어"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"앱이 Wi-Fi 디스플레이의 하위 수준 기능을 제어하도록 허용합니다."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"가상 사설망(VPN) 관리"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"앱에서 가상 사설망(VPN)의 하위 수준 기능을 관리하도록 허용하세요."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"오디오 출력 캡처"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"앱이 오디오 출력을 캡처하고 리디렉션하도록 허용합니다."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"핫워드 감지"</string>
@@ -834,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"비밀번호 규칙 설정"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"화면 잠금해제 비밀번호에 허용되는 길이 및 문자 수를 제어합니다."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"화면 잠금해제 시도 모니터링"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"접기"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"다음 <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> 알람까지"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"다음 알람까지"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 8882bf6..be5b499 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -40,8 +40,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> с. <xliff:g id="MINUTES">%2$d</xliff:g> мүн"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> саат <xliff:g id="MINUTES">%2$d</xliff:g> мүн"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> мүн"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> мүн."</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> мүн. <xliff:g id="SECONDS">%2$d</xliff:g> сек"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> мүн. <xliff:g id="SECONDS">%2$d</xliff:g> сек"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
@@ -729,6 +728,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Колдонмого тууралоолорду жүргүзүп, Wifi-дисплейлерге туташуу уруксатын берет."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi дисплейлерин башкаруу"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Колдонмого Wifi-дисплейлердин төмөнкү деңгээл мүмкүнчүлүктөрүн башкаруу уруксатын берет."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"Виртуалдык жеке тармактарды көзөмөлдөө"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Колдонмо Виртуалдык жеке тармактардын төмөнкү деңгээлдеги мүмкүнчүлүктөрүн көзөмөлдөй алат."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"аудио чыгарылышты жаздыруу"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Колдонмого аудио чыгарылышты жаздырып, аны кайра багыттоо мүмкүнчүлүгүн берет."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Ачкыч сөз таануу"</string>
@@ -1047,6 +1048,8 @@
     <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>
     <!-- no translation found for policylab_limitPassword (4497420728857585791) -->
     <skip />
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Экранды бөгөттөн чыгаруу сырсөзүнүн узундугун жана уруксат берилген белгилерди башкаруу."</string>
@@ -2380,4 +2383,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Жыйнап коюу"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Саат <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> боло турган кийинки айгайга чейин"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Кийинки айгайга чейин"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 25b9cec1..fbb8857 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -564,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"ອະນຸຍາດໃຫ້ແອັບຯຕັ້ງຄ່າ ແລະເຊື່ອມຕໍ່ຈໍສະແດງຜົນ WiFi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ຄວບຄຸມການສະແດງ WiFi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"ອະນຸຍາດໃຫ້ແອັບຯ ຄວບຄຸມຄວາມສາມາດລະດັບຕໍ່າຂອງການສະແດງຜົນ Wifi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"ຄວບ​ຄຸມ​ເຄືອ​ຂ່າຍ​ສ່ວນ​ຕົວ​ສະ​ເໝືອນ"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບ​ຄວບ​ຄຸມ​ຄຸນ​ສົມ​ບັດ​ເຄືອ​ຂ່າຍ​ສ່ວນ​ຕົວ​​ສະ​ເໝືອນລະ​ດັບ​ຕ່ຳ."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ບັນທຶກສຽງອອກ"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"ອະນຸຍາດໃຫ້ແອັບຯບັນທຶກ ແລະປ່ຽນເສັ້ນທາງການປ້ອນຂໍ້ມູນອອກຂອງສຽງ."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"ການກວດຫາ Hotword"</string>
@@ -833,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"ຕັ້ງຄ່າກົດຂອງລະຫັດຜ່ານ"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"ຄວບຄຸມຄວາມຍາວຂອງໂຕອັກສອນທີ່ສາມາດໃຊ້ກັບລະຫັດປົດລັອກໜ້າຈໍ"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ຕິດຕາມການພະຍາຍາມປົດລັອກໜ້າຈໍ"</string>
@@ -1899,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"ຫຍໍ້"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"​ຈົນ​ກວ່າ​ໂມງ​ປຸກ​ຄັ້ງ​ຕໍ່​ໄປ​ໃນ​ເວ​ລາ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"​ຈົນ​ກວ່າ​ໂມງ​ປຸກ​ຄັ້ງຕໍ່​ໄປ"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 6b9b3ac..273ff62 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -564,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Leidžiama programai konfigūruoti ir prisijungti prie „Wi-Fi“ pateikčių."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"valdyti „Wi-Fi“ pateiktis"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Leidžiama programai valdyti „Wi-Fi“ pateikčių žemo lygio funkcijas."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"valdyti virtualiuosius privačiuosius tinklus"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Programai leidžiama valdyti pagrindines virtualiųjų privačiųjų tinklų funkcijas."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"fiksuoti garso išvestį"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Programai leidžiama fiksuoti ir peradresuoti garso išvestį."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Aktyvinamųjų žodžių aptikimas"</string>
@@ -833,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Programai leidžiama gauti informaciją apie dabartinius „Android“ perdavimo funkcijos perkėlimus"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"pašalinti DRM sertifikatus"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Programai leidžiama pašalinti DRM sertifikatus. Neturėtų prireikti naudojant įprastas programas."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"susaistyti su operatoriaus susirašinėjimo žinutėmis paslauga"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Leidžiama savininkui susisaistyti su aukščiausio lygio operatoriaus susirašinėjimo žinutėmis paslaugos sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nustatyti slaptažodžio taisykles"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Valdyti leidžiamą ekrano atrakinimo slaptažodžių ilgį ir leidžiamus naudoti simbolius."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Stebėti bandymus atrakinti ekraną"</string>
@@ -1899,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Sutraukti"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Iki kito įspėjimo <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Iki kito įspėjimo"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Nutildė <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Iškilo vidinė su jūsų įrenginiu susijusi problema, todėl įrenginys gali veikti nestabiliai, kol neatkursite gamyklinių duomenų."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Iškilo vidinė su jūsų įrenginiu susijusi problema. Jei reikia išsamios informacijos, susisiekite su gamintoju."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index ded0f76..4c96dd9 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> s"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Ļauj lietotnei konfigurēt Wi-Fi displejus un veidot savienojumu ar tiem."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fi displeju vadība"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Ļauj lietotnei kontrolēt zema līmeņa funkcijas Wi-Fi displejos."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"Virtuālo privāto tīklu kontrolēšana"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Ļauj lietotnei kontrolēt virtuālo privāto tīklu zema līmeņa funkcijas."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"tvert audio izvadi"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Ļauj lietotnei tvert un novirzīt audio izvadi."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Īsinājumvārda noteikšana"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Ļauj šai lietojumprogrammai saņemt informāciju par pašreizēju Android Beam pārsūtīšanu"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"noņemt DRM sertifikātus"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Ļauj lietojumprogrammai noņemt DRM sertifikātus. Parastās lietotnēs tas nebūs nepieciešams."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"Savienojuma izveide ar mobilo sakaru operatora ziņojumapmaiņas pakalpojumu"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Ļauj īpašniekam izveidot savienojumu ar mobilo sakaru operatora ziņojumapmaiņas pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Paroles kārtulu iestatīšana"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolē ekrāna atbloķēšanas parolē atļautās rakstzīmes un garumu."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekrāna atbloķēšanas mēģinājumu pārraudzīšana"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Sakļaut"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Līdz nākamajam signālam: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Līdz nākamajam signālam"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Skaņu izslēdza <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Jūsu ierīcē ir radusies iekšēja problēma, un ierīce var darboties nestabili. Lai to labotu, veiciet rūpnīcas datu atiestatīšanu."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Jūsu ierīcē ir radusies iekšēja problēma. Lai iegūtu plašāku informāciju, lūdzu, sazinieties ar ražotāju."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mcc202-mnc05/config.xml b/core/res/res/values-mcc202-mnc05/config.xml
index ec5ecaf..c74f2d7 100644
--- a/core/res/res/values-mcc202-mnc05/config.xml
+++ b/core/res/res/values-mcc202-mnc05/config.xml
@@ -33,8 +33,11 @@
 
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">Vf Tethering,internet.vodafone.gr,,,,,,,,,202,05,,DUN</string>
+    <string-array translatable="false" name="config_tether_apndata">
+      <item>Vf Tethering,internet.vodafone.gr,,,,,,,,,202,05,,DUN</item>
+    </string-array>
 
 </resources>
diff --git a/core/res/res/values-mcc204-mnc04/config.xml b/core/res/res/values-mcc204-mnc04/config.xml
index 0e67669..2cc7374 100644
--- a/core/res/res/values-mcc204-mnc04/config.xml
+++ b/core/res/res/values-mcc204-mnc04/config.xml
@@ -43,4 +43,24 @@
         <item>true;BAE0000000000000</item>
         <item>false</item>
     </string-array>
+
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+        <item>1</item>
+        <item>4</item>
+        <item>7</item>
+        <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string-array translatable="false" name="config_tether_apndata">
+        <item>Vodafone NL,live.vodafone.com,,,vodafone,vodafone,,,,,204,04,,DUN</item>
+        <item>[ApnSettingV3]SaskTel Tethering,inet.stm.sk.ca,,,,,,,,,204,04,,DUN,,,true,0,,,,,,,gid,5A</item>
+    </string-array>
 </resources>
diff --git a/core/res/res/values-mcc208-mnc01/config.xml b/core/res/res/values-mcc208-mnc01/config.xml
new file mode 100644
index 0000000..7e44624
--- /dev/null
+++ b/core/res/res/values-mcc208-mnc01/config.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds.  Do not translate. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+        <item>1</item>
+        <item>4</item>
+        <item>7</item>
+        <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string-array translatable="false" name="config_tether_apndata">
+        <item>Orange Internet,orange.fr,,,orange,orange,,,,,208,01,1,DUN</item>
+        <item>[ApnSettingV3]Carrefour WAP,ofnew.fr,,,orange,orange,,,,,208,01,1,DUN,,,true,0,,,,,,,gid,33</item>
+        <item>[ApnSettingV3]VM WAP,ofnew.fr,,,orange,orange,,,,,208,01,1,DUN,,,true,0,,,,,,,gid,52</item>
+        <item>[ApnSettingV3]NRJWEB,ofnew.fr,,,orange,orange,,,,,208,01,1,DUN,,,true,0,,,,,,,gid,4E</item>
+    </string-array>
+
+</resources>
diff --git a/core/res/res/values-mcc208-mnc10/config.xml b/core/res/res/values-mcc208-mnc10/config.xml
index 10a6c5d..10e8dcc 100644
--- a/core/res/res/values-mcc208-mnc10/config.xml
+++ b/core/res/res/values-mcc208-mnc10/config.xml
@@ -31,9 +31,18 @@
 
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">SFR option modem,websfr,,,,,,,,,208,10,,DUN</string>
+    <string-array translatable="false" name="config_tether_apndata">
+        <item>SFR option modem,websfr,,,,,,,,,208,10,,DUN</item>
+        <item>[ApnSettingV3]INTERNET NRJ,internetnrj,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,gid,4E</item>
+        <item>[ApnSettingV3]Auchan,wap65,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,spn,A MOBILE</item>
+        <item>[ApnSettingV3]LeclercMobile,wap66,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,spn,LeclercMobile</item>
+        <item>[ApnSettingV3]Coriolis,fnetcoriolis,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,gid,12</item>
+        <item>[ApnSettingV3]WEB La Poste Mobile,wapdebitel,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,gid,4C</item>
+        <item>[ApnSettingV3]Darty Surf Mails,wap68,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,gid,44</item>
+    </string-array>
 
     <string-array translatable="false" name="config_operatorConsideredNonRoaming">
         <item>21401</item>
diff --git a/core/res/res/values-mcc214-mnc01/config.xml b/core/res/res/values-mcc214-mnc01/config.xml
index ecd8124..895b770 100644
--- a/core/res/res/values-mcc214-mnc01/config.xml
+++ b/core/res/res/values-mcc214-mnc01/config.xml
@@ -33,9 +33,12 @@
 
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">INTERNET,airtelnet.es,,,vodafone,vodafone,,,,,214,01,1,DUN</string>
+    <string-array translatable="false" name="config_tether_apndata">
+      <item>INTERNET,airtelnet.es,,,vodafone,vodafone,,,,,214,01,1,DUN</item>
+    </string-array>
 
     <string-array translatable="false" name="config_operatorConsideredNonRoaming">
         <item>21402</item>
diff --git a/core/res/res/values-mcc214-mnc03/config.xml b/core/res/res/values-mcc214-mnc03/config.xml
new file mode 100644
index 0000000..2599707
--- /dev/null
+++ b/core/res/res/values-mcc214-mnc03/config.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds.  Do not translate. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+        <item>1</item>
+        <item>4</item>
+        <item>7</item>
+        <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string-array translatable="false" name="config_tether_apndata">
+      <item>Orange Internet PC,internet,,,orange,orange,,,,,214,03,1,DUN</item>
+    </string-array>
+
+</resources>
diff --git a/core/res/res/values-mcc214-mnc07/config.xml b/core/res/res/values-mcc214-mnc07/config.xml
index ce7526c..b8328df 100644
--- a/core/res/res/values-mcc214-mnc07/config.xml
+++ b/core/res/res/values-mcc214-mnc07/config.xml
@@ -33,8 +33,12 @@
 
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">Conexion Compartida,movistar.es,,,MOVISTAR,MOVISTAR,,,,,214,07,1,DUN</string>
+    <string-array translatable="false" name="config_tether_apndata">
+        <item>Conexión Compartida,movistar.es,,,MOVISTAR,MOVISTAR,,,,,214,07,1,DUN</item>
+        <item>[ApnSettingV3]Jazztel Internet,jazzinternet,,,,,,,,,214,07,,DUN,,,true,0,,,,,,,spn,JAZZTEL</item>
+    </string-array>
 
 </resources>
diff --git a/core/res/res/values-mcc222-mnc01/config.xml b/core/res/res/values-mcc222-mnc01/config.xml
new file mode 100644
index 0000000..0d61c6e
--- /dev/null
+++ b/core/res/res/values-mcc222-mnc01/config.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds.  Do not translate. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+        <item>1</item>
+        <item>4</item>
+        <item>7</item>
+        <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string-array translatable="false" name="config_tether_apndata">
+      <item>TIM WEB,ibox.tim.it,,,,,,,,,222,01,,DUN</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc222-mnc10/config.xml b/core/res/res/values-mcc222-mnc10/config.xml
index 67467a0..5a74462 100644
--- a/core/res/res/values-mcc222-mnc10/config.xml
+++ b/core/res/res/values-mcc222-mnc10/config.xml
@@ -32,9 +32,12 @@
 
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">Tethering Internet,web.omnitel.it,,,,,,,,,222,10,,DUN</string>
+    <string-array translatable="false" name="config_tether_apndata">
+      <item>Tethering Internet,web.omnitel.it,,,,,,,,,222,10,,DUN</item>
+    </string-array>
 
     <string-array translatable="false" name="config_operatorConsideredNonRoaming">
         <item>21401</item>
diff --git a/core/res/res/values-mcc234-mnc20/config.xml b/core/res/res/values-mcc234-mnc20/config.xml
index 619e517..814960a 100644
--- a/core/res/res/values-mcc234-mnc20/config.xml
+++ b/core/res/res/values-mcc234-mnc20/config.xml
@@ -35,7 +35,9 @@
          TETHER_DUN_APN.  Value is a comma separated series of strings:
          "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">3hotspot,3hotspot,,,,,,,,,234,20,0,DUN</string>
+    <string-array translatable="false" name="config_tether_apndata">
+        <item>3hotspot,3hotspot,,,,,,,,,234,20,0,DUN</item>
+    </string-array>
 
     <!-- Configure mobile network MTU. Carrier specific value is set here.
     -->
diff --git a/core/res/res/values-mcc234-mnc33/config.xml b/core/res/res/values-mcc234-mnc33/config.xml
index 776b570..e9d3bdb 100644
--- a/core/res/res/values-mcc234-mnc33/config.xml
+++ b/core/res/res/values-mcc234-mnc33/config.xml
@@ -29,4 +29,23 @@
         <item>23434</item>
         <item>23486</item>
     </string-array>
+
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+        <item>1</item>
+        <item>4</item>
+        <item>7</item>
+        <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string-array translatable="false" name="config_tether_apndata">
+      <item>Consumer Broadband,consumerbroadband,,,,,,,,,234,33,,DUN</item>
+    </string-array>
 </resources>
diff --git a/core/res/res/values-mcc235-mnc94/config.xml b/core/res/res/values-mcc235-mnc94/config.xml
index 723af3d..d527304 100644
--- a/core/res/res/values-mcc235-mnc94/config.xml
+++ b/core/res/res/values-mcc235-mnc94/config.xml
@@ -35,7 +35,9 @@
          TETHER_DUN_APN.  Value is a comma separated series of strings:
          "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">3hotspot,3hotspot,,,,,,,,,235,94,0,DUN</string>
+    <string-array translatable="false" name="config_tether_apndata">
+        <item>3hotspot,3hotspot,,,,,,,,,235,94,0,DUN</item>
+    </string-array>
 
     <!-- Configure mobile network MTU. Carrier specific value is set here.
     -->
diff --git a/core/res/res/values-mcc268-mnc03/config.xml b/core/res/res/values-mcc268-mnc03/config.xml
index 0d5fe57..2f5171b 100644
--- a/core/res/res/values-mcc268-mnc03/config.xml
+++ b/core/res/res/values-mcc268-mnc03/config.xml
@@ -33,8 +33,10 @@
 
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,270,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">Optimus HotSpot,modem,,,,,,,,,268,03,,DUN</string>
-
+    <string-array translatable="false" name="config_tether_apndata">
+        <item>Optimus HotSpot,modem,,,,,,,,,268,03,,DUN</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 06b6efe..3872922 100644
--- a/core/res/res/values-mcc302-mnc220/config.xml
+++ b/core/res/res/values-mcc302-mnc220/config.xml
@@ -17,7 +17,10 @@
 */
 -->
 
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
     <string-array translatable="false" name="config_operatorConsideredNonRoaming">
         <item>302370</item>
         <item>302610</item>
@@ -27,4 +30,26 @@
     </string-array>
 
     <integer name="config_mobile_mtu">1410</integer>
+
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+      <item>1</item>
+      <item>4</item>
+      <item>7</item>
+      <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string-array translatable="false" name="config_tether_apndata">
+        <item>[ApnSettingV3]TELUS ISP,isp.telus.com,,,,,,,,,302,220,,DUN,,,true,0,,,,,,,gid,54</item>
+        <item>[ApnSettingV3]Tethered PC Mobile,isp.mb.com,,,,,,,,,302,220,,DUN,,,true,0,,,,,,,gid,50</item>
+        <item>[ApnSettingV3]Koodo,sp.koodo.com,,,,,,,,,302,220,,DUN,,,true,0,,,,,,,gid,4B</item>
+    </string-array>
+
 </resources>
diff --git a/core/res/res/values-mcc302-mnc221/config.xml b/core/res/res/values-mcc302-mnc221/config.xml
new file mode 100644
index 0000000..3a453b7
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc221/config.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+      <item>1</item>
+      <item>4</item>
+      <item>7</item>
+      <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string-array translatable="false" name="config_tether_apndata">
+        <item>[ApnSettingV3]TELUS ISP,isp.telus.com,,,,,,,,,302,221,,DUN,,,true,0,,,,,,,gid,54</item>
+        <item>[ApnSettingV3]Tethered PC Mobile,isp.mb.com,,,,,,,,,302,221,,DUN,,,true,0,,,,,,,gid,50</item>
+        <item>[ApnSettingV3]Koodo,sp.koodo.com,,,,,,,,,302,221,,DUN,,,true,0,,,,,,,gid,4B</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 9cfe31f..13f19f7 100644
--- a/core/res/res/values-mcc302-mnc370/config.xml
+++ b/core/res/res/values-mcc302-mnc370/config.xml
@@ -32,9 +32,13 @@
 
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">Fido LTE Tethering,ltedata.apn,,,,,,,,,302,370,,DUN</string>
+    <string-array translatable="false" name="config_tether_apndata">
+        <item>Fido LTE Tethering,ltedata.apn,,,,,,,,,302,370,,DUN</item>
+        <item>[ApnSettingV3]MTS Tethering,internet.mts,,,,,,,,,302,370,,DUN,,,true,0,,,,,,,gid,2C</item>
+    </string-array>
 
     <!-- Configure mobile network MTU. Carrier specific value is set here.
     -->
diff --git a/core/res/res/values-mcc302-mnc660/config.xml b/core/res/res/values-mcc302-mnc660/config.xml
index 000f897..c689d22 100644
--- a/core/res/res/values-mcc302-mnc660/config.xml
+++ b/core/res/res/values-mcc302-mnc660/config.xml
@@ -32,9 +32,12 @@
 
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">MTS -Tethering,internet.mts,,,,,,,,,302,660,,DUN</string>
+    <string-array translatable="false" name="config_tether_apndata">
+      <item>MTS -Tethering,internet.mts,,,,,,,,,302,660,,DUN</item>
+    </string-array>
 
     <!-- Configure mobile network MTU. Carrier specific value is set here.
     -->
diff --git a/core/res/res/values-mcc302-mnc720/config.xml b/core/res/res/values-mcc302-mnc720/config.xml
index dfc58fe..c20ca12 100644
--- a/core/res/res/values-mcc302-mnc720/config.xml
+++ b/core/res/res/values-mcc302-mnc720/config.xml
@@ -32,9 +32,13 @@
 
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">Rogers LTE Tethering,ltedata.apn,,,,,,,,,302,720,,DUN</string>
+    <string-array translatable="false" name="config_tether_apndata">
+        <item>Rogers LTE Tethering,ltedata.apn,,,,,,,,,302,720,,DUN</item>
+        <item>[ApnSettingV3]chatr Tethering,chatrisp.apn,,,,,,,,,302,720,,DUN,,,true,0,,,,,,,imsi,302720x94</item>
+    </string-array>
 
     <!-- Configure mobile network MTU. Carrier specific value is set here.
     -->
diff --git a/core/res/res/values-mcc302-mnc780/config.xml b/core/res/res/values-mcc302-mnc780/config.xml
index cd40191..51abd36 100644
--- a/core/res/res/values-mcc302-mnc780/config.xml
+++ b/core/res/res/values-mcc302-mnc780/config.xml
@@ -33,9 +33,12 @@
 
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">SaskTel Tethering,inet.stm.sk.ca,,,,,,,,,302,780,,DUN</string>
+    <string-array translatable="false" name="config_tether_apndata">
+      <item>SaskTel Tethering,inet.stm.sk.ca,,,,,,,,,302,780,,DUN</item>
+    </string-array>
 
     <!-- Don't use roaming icon for considered operators -->
     <string-array translatable="false" name="config_operatorConsideredNonRoaming">
diff --git a/core/res/res/values-mcc311-mnc190/config.xml b/core/res/res/values-mcc311-mnc190/config.xml
index a6c4d1b..c17a07c 100644
--- a/core/res/res/values-mcc311-mnc190/config.xml
+++ b/core/res/res/values-mcc311-mnc190/config.xml
@@ -35,6 +35,8 @@
          TETHER_DUN_APN.  Value is a comma separated series of strings:
          "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">Tether,broadband.cellular1.net,,,,,,,,,311,190,,DUN</string>
+    <string-array translatable="false" name="config_tether_apndata">
+        <item>Tether,broadband.cellular1.net,,,,,,,,,311,190,,DUN</item>
+    </string-array>
 
 </resources>
diff --git a/core/res/res/values-mcc334-mnc050/config.xml b/core/res/res/values-mcc334-mnc050/config.xml
index 00c4155..f6777d0 100644
--- a/core/res/res/values-mcc334-mnc050/config.xml
+++ b/core/res/res/values-mcc334-mnc050/config.xml
@@ -33,8 +33,11 @@
 
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">Modem,modem.iusacellgsm.mx,,,iusacellgsm,iusacellgsm,,,,,334,050,1,DUN</string>
+    <string-array translatable="false" name="config_tether_apndata">
+      <item>Modem,modem.iusacellgsm.mx,,,iusacellgsm,iusacellgsm,,,,,334,050,1,DUN</item>
+    </string-array>
 
 </resources>
diff --git a/core/res/res/values-mcc340-mnc01/config.xml b/core/res/res/values-mcc340-mnc01/config.xml
index bb491ed..cfc1380 100644
--- a/core/res/res/values-mcc340-mnc01/config.xml
+++ b/core/res/res/values-mcc340-mnc01/config.xml
@@ -32,9 +32,12 @@
 
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">Orangeweb,orangeweb,,,orange,orange,,,,,340,01,1,DUN</string>
+    <string-array translatable="false" name="config_tether_apndata">
+        <item>Orangeweb,orangeweb,,,orange,orange,,,,,340,01,1,DUN</item>
+    </string-array>
 
     <string-array translatable="false" name="config_operatorConsideredNonRoaming">
         <item>20801</item>
diff --git a/core/res/res/values-mcc425-mnc07/config.xml b/core/res/res/values-mcc425-mnc07/config.xml
index 51a9934..a092fb9 100644
--- a/core/res/res/values-mcc425-mnc07/config.xml
+++ b/core/res/res/values-mcc425-mnc07/config.xml
@@ -33,9 +33,12 @@
 
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">PC HOT mobile,pc.hotm,,,,,,,,,425,07,,DUN</string>
+    <string-array translatable="false" name="config_tether_apndata">
+      <item>PC HOT mobile,pc.hotm,,,,,,,,,425,07,,DUN</item>
+    </string-array>
 
     <!-- Don't use roaming icon for considered operators -->
     <string-array translatable="false" name="config_operatorConsideredNonRoaming">
diff --git a/core/res/res/values-mcc454-mnc10/config.xml b/core/res/res/values-mcc454-mnc10/config.xml
new file mode 100644
index 0000000..e7622a0
--- /dev/null
+++ b/core/res/res/values-mcc454-mnc10/config.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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 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:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+    <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+    <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+    <integer-array translatable="false" name="config_tether_upstream_types">
+      <item>1</item>
+      <item>4</item>
+      <item>7</item>
+      <item>9</item>
+    </integer-array>
+
+    <!-- String containing the apn value for tethering.  May be overriden by secure settings
+         TETHER_DUN_APN.  Value is a comma separated series of strings:
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+    <string-array translatable="false" name="config_tether_apndata">
+      <item>one2free Tethering,internet,,,,,,,,,454,10,0,DUN</item>
+    </string-array>
+
+</resources>
diff --git a/core/res/res/values-mcc505-mnc01/config.xml b/core/res/res/values-mcc505-mnc01/config.xml
index 7331c50..1705e4a 100644
--- a/core/res/res/values-mcc505-mnc01/config.xml
+++ b/core/res/res/values-mcc505-mnc01/config.xml
@@ -33,9 +33,12 @@
 
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata">Telstra Tethering,telstra.internet,,,,,,,,,505,01,,DUN</string>
+    <string-array translatable="false" name="config_tether_apndata">
+      <item>Telstra Tethering,telstra.internet,,,,,,,,,505,01,,DUN</item>
+    </string-array>
 
     <!-- Configure mobile network MTU. Carrier specific value is set here.
     -->
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index fab4ecf..531b6c1 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ч. <xliff:g id="MINUTES">%2$d</xliff:g> мин."</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ч. <xliff:g id="MINUTES">%2$d</xliff:g> мин."</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> мин."</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> мин."</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> мин. <xliff:g id="SECONDS">%2$d</xliff:g> с."</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> мин. <xliff:g id="SECONDS">%2$d</xliff:g> с."</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек."</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Овозможува апликацијата да конфигурира и да се поврзува со Wi-Fi прикази."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"контролирај прикази на Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Овозможува апликацијата да контролира карактеристики на ниско ниво на Wi-fi прикази."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"Контролирајте виртуелни приватни мрежи"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Дозволува апликацијата да ги контролира функциите на ниско ниво на виртуелните приватни мрежи."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"сними аудио излез"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Овозможува апликацијата да снима и пренасочува аудио излез."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Откривање клучни зборови"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Ѝ дозволува на оваа апликација да добива информации за моменталните трансфери на Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"отстранување ДРМ-сетификати"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Дозволува апликација да отстранува ДРМ-сертификати. Не треба да се користи за стандардни апликации."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"сврзување со давателот на услугата за пораки"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Дозволува сопственикот да се сврзе со интерфејсот од највисоко ниво на давателот на услугата за пораки. Не треба да се користи за стандардни апликации."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Подеси правила за лозинката"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролирај ги должината и знаците што се дозволени за лозинки за отклучување екран."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Следи ги обидите за отклучување на екранот"</string>
@@ -1902,4 +1905,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Собери"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"До следниот аларм во <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"До следниот аларм"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 12975e4..0c32045 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> മണിക്കൂർ <xliff:g id="MINUTES">%2$d</xliff:g> മിനിറ്റ്"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> മണിക്കൂർ <xliff:g id="MINUTES">%2$d</xliff:g> മിനിറ്റ്"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> മിനിറ്റ്"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> മി."</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> മിനിറ്റ് <xliff:g id="SECONDS">%2$d</xliff:g> സെക്കൻഡ്"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> മിനിറ്റ് <xliff:g id="SECONDS">%2$d</xliff:g> സെക്കൻഡ്"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> സെക്കൻഡ്"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"വൈഫൈ ഡിസ്പ്ലേകൾ കോൺഫിഗർ ചെയ്യാനും അതിലേക്ക് കണക്റ്റുചെയ്യാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"വൈഫൈ ഡിസ്‌പ്ലേകൾ നിയന്ത്രിക്കുക"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"വൈഫൈ ഡിസ്‌പ്ലേകളുടെ കുറഞ്ഞ നിലയിലുള്ള സവിശേഷതകൾ നിയന്ത്രിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"വെർച്വൽ സ്വകാര്യ നെറ്റ്‌വർക്കുകൾ നിയന്ത്രിക്കുക"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"വെർച്വൽ സ്വകാര്യ നെറ്റ്‌വർക്കുകളുടെ താഴ്‌ന്ന നിലയിലുള്ള ഫീച്ചറുകൾ നിയന്ത്രിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ഓഡിയോ ഔട്ട്പുട്ട് ക്യാപ്‌ചർ ചെയ്യുക"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"ഓഡിയോ ഔട്ട്‌പുട്ട് ക്യാപ്‌ചർ ചെയ്‌ത് റീഡയറക്‌ടുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"ഹോട്ട്‌വേഡ് തിരിച്ചറിയൽ"</string>
@@ -834,6 +835,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="policylab_limitPassword" msgid="4497420728857585791">"പാസ്‌വേഡ് നിയമങ്ങൾ സജ്ജീകരിക്കുക"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"സ്‌ക്രീൻ-അൺലോക്ക് പാസ്‌വേഡുകളിൽ അനുവദിച്ചിരിക്കുന്ന ദൈർഘ്യവും പ്രതീകങ്ങളും നിയന്ത്രിക്കുക."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"സ്‌ക്രീൻ അൺലോക്ക് ശ്രമങ്ങൾ നിരീക്ഷിക്കുക"</string>
@@ -1898,4 +1901,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"ചുരുക്കുക"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-നുള്ള അടുത്ത അലാറം വരെ"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"അടുത്ത അലാറം വരെ"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 52fe1b5..8074a99 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> цаг <xliff:g id="MINUTES">%2$d</xliff:g> минут"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> цаг <xliff:g id="MINUTES">%2$d</xliff:g> мин"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> мин"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> минут"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> мин <xliff:g id="SECONDS">%2$d</xliff:g> секунд"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> мин <xliff:g id="SECONDS">%2$d</xliff:g> сек"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Апп нь Wifi дэлгэцийг тохируулах болон холбогдох боломжтой."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi дэлгэцийг удирдах"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Апп нь Wifi дэлгэцний доод-төвшиний функцийг удирдах боломжтой."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"Виртуал Хувийн Сүлжээнүүдийг удирдах"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Виртуал Хувийн Сүлжээнүүдийн доод түвшний функцүүдийг тус апликейшнээр удирдахыг зөвшөөрдөг."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"аудио гаралтыг барих"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Апп-т аудио гаралтыг барих, дахин чиглүүлэхийг зөвшөөрнө."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Хотворд таних"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Одоогийн Андройд Бийм дамжуулалтын мэдээллийг хүлээн авахыг аппликешнд зөвшөөрөх"</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="policylab_limitPassword" msgid="4497420728857585791">"Нууц үгний дүрмийг тохируулах"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Дэлгэц түгжих нууц үгэнд зөвшөөрөгдсөн тэмдэгт болон уртыг удирдах"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Дэлгэц тайлах оролдлогыг хянах"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Хумих"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> дахь дараагийн анхааруулга хүртэл"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Дараагийн анхааруулга хүртэл"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 7f286b8..1f51ecb 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ता <xliff:g id="MINUTES">%2$d</xliff:g> मि"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ता <xliff:g id="MINUTES">%2$d</xliff:g> मि"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> मिनिटे"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> मिनिट"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> मि <xliff:g id="SECONDS">%2$d</xliff:g> से"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> मि <xliff:g id="SECONDS">%2$d</xliff:g> से"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> सेकंद"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"वायफाय प्रदर्शने कॉन्फिगर करण्यासाठी आणि त्यावर कनेक्ट करण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"वायफाय प्रदर्शने नियंत्रित करा"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"वायफाय प्रदर्शनांची निम्न-स्तर वैशिष्ट्ये नियंत्रित करण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"व्हर्च्युअल प्रायव्हेट नेटवर्क नियंत्रित करा"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"अ‍ॅपला व्हर्च्युअल प्रायव्हेट नेटवर्कच्या निम्न-दर्जाच्या वैशिष्‍ट्यांना नियंत्रित करण्‍याची अनुमती देते."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ऑडिओ आउटपुट कॅप्‍चर करा"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"अ‍ॅपला ऑडिओ आउटपुट कॅप्‍चर करण्‍याची आणि पुनर्निर्देशित करण्‍याची अनुमती देते."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Hotword शोध"</string>
@@ -834,6 +835,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="policylab_limitPassword" msgid="4497420728857585791">"संकेतशब्द नियम सेट करा"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"स्क्रीन-अनलॉक संकेतशब्दांमध्ये अनुमती दिलेली लांबी आणि वर्ण नियंत्रित करा."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"स्क्रीन-अनलॉक प्रयत्नांचे परीक्षण करा"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त करा"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> वाजता पुढील अलार्मपर्यंत"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"पुढील अलार्मपर्यंत"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 117274e..01d1bbb 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> jam <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> jam <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> minit"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> minit"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> saat"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> saat"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> saat"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Membenarkan apl mengkonfigurasi dan menyambung ke paparan Wifi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kawal paparan Wifi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Membenarkan apl mengawal ciri tahap rendah paparan Wifi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"kawal Rangkaian Peribadi Maya"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Membenarkan apl mengawal ciri tahap rendah Rangkaian Peribadi Maya."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"tangkap output audio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Membenarkan apl menangkap dan mengubah hala output audio."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Pengesanan sebutan laluan"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Membenarkan aplikasi ini menerima maklumat mengenai pemindahan Pancaran Android semasa"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"alih keluar sijil DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Membenarkan aplikasi mengalih keluar sijil DRM. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"terikat kepada perkhidmatan pemesejan pembawa"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi perkhidmatan pemesejan pembawa. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Tetapkan peraturan kata laluan"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Mengawal panjang dan aksara yang dibenarkan dalam kata laluan buka kunci skrin."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Memantau percubaan buka kunci skrin"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Runtuhkan"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Sehingga penggera seterusnya pada <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Sehingga penggera seterusnya"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Diredam oleh <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Terdapat masalah dalaman dengan peranti anda. Peranti mungkin tidak stabil sehingga anda membuat tetapan semula data kilang."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Terdapat masalah dalaman dengan peranti anda. Hubungi pengilang untuk mengetahui butirannya."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 0766243..c2ea4bd 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> နာရီ <xliff:g id="MINUTES">%2$d</xliff:g> မိနစ်"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> နာရီ <xliff:g id="MINUTES">%2$d</xliff:g> မိနစ်"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> မိနစ်"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> မိနစ်"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> မိနစ် <xliff:g id="SECONDS">%2$d</xliff:g> စက္ကန့်"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> မိနစ် <xliff:g id="SECONDS">%2$d</xliff:g> စက္ကန့်"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> စက္ကန့်"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"အပလီကေးရှင်းအား ဝိုင်ဖိုင်မှ တဆင့် ပြသမှုအား ပြင်ဆင်ခြင်း၊ ဆက်သွယ်ခြင်း ခွင့်ပြုပါ"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ဝိုင်ဖိုင်ဖြင့် ပြသမှု အား ထိန်းချုပ်ရန်"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"အပလီကေးရှင်းအား စက်ရဲ့ အနိမ့်ပိုင်းမှာ ရှိသော ဝိုင်ဖိုင် ပြသမှုအား ထိန်းချုပ်ခွင့်ပြုပါ"</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"ကိုယ်ပိုင်ကွန်ယက်အတုကို ထိန်းချုပ်ရန်"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"ကိုယ်ပိုင်ကွန်ယက်အတု၏ အရည်အသွေးနိမ့်လုပ်ဆောင်ချက်များကို ထိန်းချုပ်ရန် app အား ခွင့်ပြုပါ။"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"အသံထွက်မှု အား ဖမ်းယူခြင်း"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"အပလီကေးရှင်းကို အသံဖမ်းခွင့် လမ်းကြောင်းလွှဲခွင့်များ ခွင့်ပြုခြင်း"</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"အသံဖြင့်ညွှန်ကြားရန်အတိုကောက်များအား ဖမ်းယူ သိနိုင်မှု"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"ဒီအပလီကေးရှင်းအား အန်ဒရွိုက်၏ လက်ရှိ အလင်းတန်းထိုး လွှဲပြောင်းမှု အကြောင်း အချက်အလက်ကို ရယူခွင့် ပြုသည်"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"DRM လက်မှတ်များ ဖယ်ရှားရန်"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"အပလီကေးရှင်းအား DRM လက်မှတ်များကို ဖယ်ရှားခွင့် ပြုသည်။  သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"စာပို့စာယူ ဆက်သွယ်ရေးဝန်ဆောင်မှုတစ်ခုအား ပူးပေါင်းခွင့်ပြုရန်"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"စာပို့စာယူဆက်သွယ်ရေးဝန်ဆောင်မှုတစ်ခု၏ ထိပ်ဆုံးရှိအင်တာဖေ့စ်ဖြင့် ပူးပေါင်းရန် ပိုင်ရှင်အားခွင့်ပြုပါ။ ပုံမှန် app များအတွက် မလိုအပ်ပါ။"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"စကားဝှက်စည်းမျဥ်းကိုသတ်မှတ်ရန်"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"မျက်နှာပြင် သော့ဖွင့်ရန် လိုအပ်သော စကားလုံးအရေအတွက်နှင့် အမျိုးအစားအား ထိန်းချုပ်ရန်"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"မော်နီတာမျက်နှာပြင်ဖွင့်ရန် ကြိုးစားခွင့်များ"</string>
@@ -1898,4 +1901,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"ခေါက်ရန်"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"နောက်ထပ် <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ၌နိုးစက်အထိ"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"နောက်ထပ်နိုးစက်အထိ"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 2363a36..101f201 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> t <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> t <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Tillater appen å konfigurere og koble til Wi-Fi-skjermer."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kontrollere Wi-Fi-skjermer"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Tillater appen å kontrollere lavnivåfunksjoner i Wi-Fi-skjermer."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"kontrollér virtuelle private nettverk"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Lar appen kontrollere de grunnleggende funksjonene for virtuelle private nettverk."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ta opp fra lydutdata"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Lar appen ta opp og omdirigere lydutdata."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Gjenkjennelse av kommandoord"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Lar appen motta informasjon om aktuelle Android Beam-overføringer"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"fjern sertifikater for digital rettighetsadministrasjon"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Gir en app tillatelse til å fjerne sertifikater for digital rettighetsadministrasjon. Skal ikke være nødvendig for vanlige apper."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"bindes til en operatørmeldingstjeneste"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Tillater at innehaveren binder seg til det øverste nivået av grensesnittet til en operatørtjeneste. Dette skal aldri være nødvendig for vanlige apper."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Angi passordregler"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontroller tillatt lengde og tillatte tegn i passord for opplåsing av skjerm."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Overvåk forsøk på opplåsing av skjerm"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Skjul"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Inntil neste alarm kl. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Inntil neste alarm"</string>
+    <string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> har kuttet lyden"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Det har oppstått et internt problem på enheten din, og den kan være ustabil til du tilbakestiller den til fabrikkdata."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Det har oppstått et internt problem på enheten din. Ta kontakt med produsenten for mer informasjon."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index ccd3f47..c8193c2 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> घण्टा <xliff:g id="MINUTES">%2$d</xliff:g> मि"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> घण्टा <xliff:g id="MINUTES">%2$d</xliff:g> मिनेट"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> मिनेट"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> मिनेट"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> मिनेट <xliff:g id="SECONDS">%2$d</xliff:g> से"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> मिनेट <xliff:g id="SECONDS">%2$d</xliff:g> से"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> सेकेन्ड"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"अनुप्रयोगलाई कन्फिगर गर्न र वाइफाइ प्रदर्शनहरूसँग जोड्न अनुमति दिन्छ।"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"वाइफाइ प्रदर्शनहरू नियन्त्रण गर्नुहोस्"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"वाइफाइ प्रदर्शनीका तल्लो तह विषेशताहरू नियन्त्रण गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"भर्चुअल निजी नेटवर्कलाई नियन्त्रण गर्छ"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"भर्चुअल निजी नेटवर्कहरूको कम-स्तर सुविधाहरू नियन्त्रण गर्न एपलाई अनुमति दिन्छ।"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"अडियो आउटपुट कैद गर्नुहोस्"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"अनुप्रयोगलाई अडियो आउटपुट कैद गर्न र रिडाइरेक्ट गर्न अनुमति दिन्छ।"</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Hotword पत्ता लगाउने कार्य"</string>
@@ -834,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियमहरू मिलाउनुहोस्"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"स्क्रिन-अनलक पासवर्डहरूमा अनुमति दिइएको लम्बाइ र अक्षरहरू नियन्त्रण गर्नुहोस्।"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"मोनिटर स्क्रिन-अनलक प्रयत्नहरू"</string>
@@ -1908,4 +1911,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त पार्नुहोस्"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> मा अर्को अलार्म सम्म"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"अर्को अलार्म सम्म"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 254bc6f..668d7b0 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> uur <xliff:g id="MINUTES">%2$d</xliff:g> min."</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> uur <xliff:g id="MINUTES">%2$d</xliff:g> min."</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> minuten"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> sec"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sec"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> seconden"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"De app toestaan wifi-displays te configureren en hiermee verbinding te maken."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"wifi-displays beheren"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"De app toestaan minder belangrijke functies van wifi-displays te beheren."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"VPN\'s (Virtual Private Networks) beheren"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Hiermee kan de app VPN-functies (Virtual Private Networks) op laag niveau beheren."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"audio-uitvoer vastleggen"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Hiermee kan de app audio-uitvoer vastleggen en verwerken."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Detectie van hotwords"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Hiermee kan deze app informatie over huidige Android Beam-overdrachten ontvangen"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"DRM-certificaten verwijderen"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Toestaan dat een app DRM-certificaten verwijdert. Nooit vereist voor normale apps."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"binden aan de berichtenservice van een provider"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Hiermee wordt de houder toegestaan te binden aan de berichteninterface van een provider. Nooit vereist voor normale apps."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Wachtwoordregels instellen"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"De lengte en tekens beheren die zijn toegestaan in wachtwoorden voor schermontgrendeling."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Pogingen voor schermontgrendeling bijhouden"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Samenvouwen"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Tot het volgende alarm om <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Tot het volgende alarm"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Gedempt door <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Er is een intern probleem met uw apparaat. Het apparaat kan instabiel zijn totdat u het apparaat terugzet naar de fabrieksinstellingen."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Er is een intern probleem met uw apparaat. Neem contact op met de fabrikant voor meer informatie."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 6e78fd2..83303b7 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> godz. <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> godz. <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> s"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Zezwala aplikacji na konfigurację wyświetlaczy Wi-Fi i łączenie z nimi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"zarządzanie wyświetlaczami Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Zezwala aplikacji na zarządzanie niskopoziomowymi funkcjami wyświetlaczy Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"kontrola nad wirtualnymi sieciami prywatnymi (VPN)"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Zezwala aplikacji na kontrolę nad niskopoziomowymi funkcjami wirtualnych sieci prywatnych (VPN)."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"przechwyć wyjście audio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Zezwala aplikacji na przechwytywanie i przekierowywanie wyjścia audio."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Wykrywanie słów-kluczy"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Zezwala tej aplikacji na otrzymywanie informacji o aktualnych transmisjach Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"usuwanie certyfikatów DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Zezwala aplikacji na usuwanie certyfikatów DRM. Nie powinno być nigdy potrzebne w zwykłych aplikacjach."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"powiąż z usługą przesyłania wiadomości przez operatora"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Zezwala posiadaczowi na tworzenie powiązania z interfejsem najwyższego poziomu w usłudze przesyłania wiadomości przez operatora. Nie powinno być nigdy potrzebne dla zwykłych aplikacji."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Określ reguły hasła"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolowanie długości haseł odblokowania ekranu i dozwolonych w nich znaków"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitoruj próby odblokowania ekranu"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Zwiń"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Do następnego alarmu o <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Do następnego alarmu"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Ściszone przez: <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"W Twoim urządzeniu wystąpił problem wewnętrzny. Może być ono niestabilne, dopóki nie przywrócisz danych fabrycznych."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"W Twoim urządzeniu wystąpił problem wewnętrzny. Skontaktuj się z jego producentem, by otrzymać szczegółowe informacje."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 6d88235..b1ebcc9 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> seg"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> seg"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> seg"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite que a aplicação se configure e se ligue a visores Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar visores Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite que a aplicação controle funcionalidades de baixo nível em visores Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"controlar Redes privadas virtuais"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Permite que a aplicação controle funcionalidades de baixo nível de Redes privadas virtuais"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"capturar saída de áudio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Permite à aplicação capturar e redirecionar a saída de áudio."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Deteção de palavra de ativação"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Permite que esta aplicação receba informações acerca das transferências atuais do Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"remover certificados DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Permite que uma aplicação remova certificados DRM. Nunca deverá ser necessário para aplicações normais."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"ligar ao serviço de mensagens de um operador"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Permite ao titular ligar à interface de nível superior do serviço de mensagens de um operador. Nunca deve ser necessário para aplicações normais."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras de palavra-passe"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar o comprimento e os caracteres permitidos nas palavras-passe de desbloqueio do ecrã."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizar tentativas de desbloqueio do ecrã"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Reduzir"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Até ao próximo alarme, às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Até ao próximo alarme"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Som desativado por <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Existe um problema interno no seu dispositivo e pode ficar instável até efetuar uma reposição de dados de fábrica."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Existe um problema interno no seu dispositivo. Contacte o fabricante para obter mais informações."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 1d3cf00..00b82be 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> m"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite que o app configure e conecte a monitores Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar monitores Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite que o app controle recursos de baixo nível de monitores Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"controlar Redes Privadas Virtuais"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Permite que o app controle os recursos de nível inferior das Redes Privadas Virtuais."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"capturar saída de áudio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Permite que o app capture e redirecione a saída de áudio."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Detecção de hotwords"</string>
@@ -796,14 +797,10 @@
     <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Permite que o app leia e grave o sistema de arquivos cache."</string>
     <string name="permlab_use_sip" msgid="2052499390128979920">"fazer/receber chamadas SIP"</string>
     <string name="permdesc_use_sip" msgid="2297804849860225257">"Permite que o app faça e receba chamadas SIP."</string>
-    <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
-    <skip />
-    <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
-    <skip />
-    <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
-    <skip />
-    <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
-    <skip />
+    <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"registrar novas conexões SIM de telecomunicações"</string>
+    <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"Permite que o app registre novas conexões SIM de telecomunicações."</string>
+    <string name="permlab_register_call_provider" msgid="108102120289029841">"registrar novas conexões de telecomunicações"</string>
+    <string name="permdesc_register_call_provider" msgid="7034310263521081388">"Permite que o app registre novas conexões de telecomunicações."</string>
     <string name="permlab_connection_manager" msgid="1116193254522105375">"gerenciar conexões de telecomunicações"</string>
     <string name="permdesc_connection_manager" msgid="5925480810356483565">"Permite que o app gerencie conexões de telecomunicações."</string>
     <string name="permlab_bind_incall_service" msgid="6773648341975287125">"interagir com chamada na tela"</string>
@@ -838,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Permite que este app receba informações sobre as atuais transferências do Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"remover certificados de DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Permite que um app remova certificados de DRM. Não deve ser necessário para apps comuns."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"vincular a um serviço de mensagens de operadora"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Permite que o proprietário use a interface de nível superior de um serviço de mensagens de operadora. Não deve ser necessária para apps comuns."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras para senha"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar o tamanho e os caracteres permitidos nas senhas de desbloqueio de tela."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorar tentativas de desbloqueio da tela"</string>
@@ -1904,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Recolher"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Até o próximo alarme em <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Até o próximo alarme"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Som desativado por <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Há um problema interno com seu dispositivo. Ele pode ficar instável até que você faça a redefinição para configuração original."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Há um problema interno com seu dispositivo. Entre em contato com o fabricante para saber mais detalhes."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index b44d8dc..57e72a8 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> (de) min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> sec"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sec"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sec"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite aplicaţiei să configureze şi să se conecteze la afişaje Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlează afişaje Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite aplicaţiei să controleze funcţiile de nivel redus ale afişajelor Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"controlează rețelele private virtuale"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Permite aplicației să controleze funcțiile de nivel inferior ale rețelelor private virtuale."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"să intercepteze ieșirea audio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Permite aplicației să intercepteze și să redirecționeze ieșirea audio."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"detectarea expresiei de activare"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Permite acestei aplicații să primească informații despre transferurile actuale Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"eliminarea certificatelor DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Permite unei aplicații să elimine certificatele DRM. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"se conectează la un serviciu de mesagerie oferit de operator"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Permite aplicației să se conecteze la interfața de nivel superior a unui serviciu de mesagerie oferit de operator. Nu ar trebui să fie niciodată necesară pentru aplicațiile obișnuite."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Setaţi reguli pentru parolă"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Stabiliţi lungimea şi tipul de caractere permise în parolele pentru deblocarea ecranului."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizaţi încercările de deblocare a ecranului"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Restrângeți"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Până la alarma următoare, la <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Până la alarma următoare"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Dezactivate de <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"A apărut o problemă internă pe dispozitiv, iar acesta poate fi instabil până la revenirea la setările din fabrică."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"A apărut o problemă internă pe dispozitiv. Pentru detalii, contactați producătorul."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 5f75fd7..768b071 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ч. <xliff:g id="MINUTES">%2$d</xliff:g> мин."</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ч. <xliff:g id="MINUTES">%2$d</xliff:g> мин."</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> мин."</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> мин."</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> мин. <xliff:g id="SECONDS">%2$d</xliff:g> с"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> мин. <xliff:g id="SECONDS">%2$d</xliff:g> с"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> с"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Приложение сможет подключаться к экранам с помощью Wi-Fi и настраивать их."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Управление мониторами, подключенными через Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Приложение сможет управлять низкоуровневыми функциями экранов, подключенных через Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"управление виртуальными частными сетями"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Управление низкоуровневыми функциями виртуальных частных сетей."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"захват аудиосигнала"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Приложение сможет захватывать и перенаправлять аудиосигнал."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"распознавать голосовые команды"</string>
@@ -834,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"Правила выбора паролей"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролировать длину и символы при вводе паролей для снятия блокировки экрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Отслеживать попытки снятия блокировки экрана"</string>
@@ -1878,7 +1881,7 @@
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запрашивать пароль для отключения блокировки"</string>
     <string name="battery_saver_description" msgid="2510530476513605742">"Чтобы продлить время работы устройства от батареи, в режиме энергосбережения снижается производительность, а также ограничивается использование вибросигнала и фоновой передачи данных. Данные, требующие синхронизации, могут обновляться только когда вы откроете приложение.\n\nРежим энергосбережения автоматически отключается во время зарядки устройства."</string>
     <string name="downtime_condition_summary" msgid="8761776337475705749">"До отключения режима (в <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)"</string>
-    <string name="downtime_condition_line_one" msgid="8762708714645352010">"На весь период простоя"</string>
+    <string name="downtime_condition_line_one" msgid="8762708714645352010">"До отключения режима"</string>
   <plurals name="zen_mode_duration_minutes_summary">
     <item quantity="one" msgid="3177683545388923234">"На 1 мин. (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
     <item quantity="other" msgid="2787867221129368935">"На %1$d мин. (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Свернуть"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"До следующего будильника в <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"До следующего будильника"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 704d828..3460606 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"පැය <xliff:g id="HOURS">%1$d</xliff:g> මිනි <xliff:g id="MINUTES">%2$d</xliff:g>"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"පැය <xliff:g id="HOURS">%1$d</xliff:g> මිනි <xliff:g id="MINUTES">%2$d</xliff:g>"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"මිනි <xliff:g id="MINUTES">%1$d</xliff:g>"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"මිනිත්තු <xliff:g id="MINUTES">%1$d</xliff:g>"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"මිනි <xliff:g id="MINUTES">%1$d</xliff:g> තත් <xliff:g id="SECONDS">%2$d</xliff:g>"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"මිනි <xliff:g id="MINUTES">%1$d</xliff:g> තත් <xliff:g id="SECONDS">%2$d</xliff:g>"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"තත් <xliff:g id="SECONDS">%1$d</xliff:g>"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"වින්‍යාස කිරීමට සහ Wifi සංදර්ශක වෙත සම්බන්ධ වීමට යෙදුමට අවසර දෙන්න."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi සංදර්ශක පාලනය"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Wifi සංදර්ශකයේ පහළ මට්ටමේ විශේෂාංග පාලනයට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"අතථ්‍ය පුද්ගලික ජාල පාලනය කරන්න"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"යෙදුමට අතථ්‍ය පුද්ගලික ජාලවල පහළ-මට්ටම් විශේෂාංග පාලනය කිරීමට ඉඩ දෙයි."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ශබ්ද ප්‍රතිදානය ග්‍රහණය"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"යෙදුමට ශබ්ද ප්‍රතිදානය ග්‍රහණය කර හරවා යැවීමට ඉඩ දේ."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Hotword හදුනා ගැනීම"</string>
@@ -796,14 +797,10 @@
     <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"හැඹිලි ගොනු පද්ධති කියවීමට සහ ලිවීමට යෙදුමට අවසර දෙන්න."</string>
     <string name="permlab_use_sip" msgid="2052499390128979920">"SIP ඇමතුම් සිදුකිරීමට/ලබාගැනීමට"</string>
     <string name="permdesc_use_sip" msgid="2297804849860225257">"SIP ඇමතුම් සිදුකිරීමට සහ ලබාගැනීමට යෙදුමට ඉඩ දෙන්න."</string>
-    <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
-    <skip />
-    <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
-    <skip />
-    <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
-    <skip />
-    <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
-    <skip />
+    <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"අලුත් විදුලි සංදේශ SIM සම්බන්ධතාවක් ලියාපදිංචි කරන්න"</string>
+    <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"අලුත් විදුලි සංදේශ SIM සම්බන්ධතාවක් ලියාපදිංචි කිරීමට යෙදුමට ඉඩ දෙන්න."</string>
+    <string name="permlab_register_call_provider" msgid="108102120289029841">"අලුත් විදුලි සංදේශ සම්බන්ධතාවක් ලියාපදිංචි කරන්න"</string>
+    <string name="permdesc_register_call_provider" msgid="7034310263521081388">"අලුත් විදුලි සංදේශන සම්බන්ධතා ලියාපදිංචි කිරීමට යෙදුමට ඉඩ දෙන්න."</string>
     <string name="permlab_connection_manager" msgid="1116193254522105375">"විදුලි සංදේශන සම්බන්ධතා කළමණාකරණය කරන්න"</string>
     <string name="permdesc_connection_manager" msgid="5925480810356483565">"විදුලි සංදේශන සම්බන්ධතා කළමණාකරණය කිරීමට යෙදුමට ඉඩ දෙන්න."</string>
     <string name="permlab_bind_incall_service" msgid="6773648341975287125">"ලැබෙන ඇමතුම් තිරය සමග අන්තර් ක්‍රියාකාරී වන්න"</string>
@@ -838,6 +835,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="policylab_limitPassword" msgid="4497420728857585791">"මුරපද නීති සකස් කිරීම"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"තිරය අගුළු ඇරීමේ මුරපදයට අනුමත අකුරු සහ දිග පාලනය කරන්න."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"තිරය අගුළු ඇරීමේ උත්සාහයන් නිරීක්ෂණය කරන්න"</string>
@@ -1884,8 +1883,7 @@
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ගැලවීමට පෙර මුරපදය විමසන්න"</string>
     <string name="battery_saver_description" msgid="2510530476513605742">"බැටරියේ ජීව කාලය දියුණු කිරීමට උදව් කිරීමට, ඔබගේ උපාංගයේ ක්‍රියාකාරිත්වය සහ සීමා කළ කම්පනයන් සහ බොහොමයක් පසුබිම් දත්ත බැටරි සුරැකීමෙන් අඩු කරයි. සමමුහුර්ත කිරීම බලාපොරොත්තු වෙන ඊ-තැපෑල, පණිවිඩ යැවීම සහ වෙනත් යෙදුම් යාවත්කාලීන වන්නේ ඔබ ඒවා විවෘත කළ විට පමණි.\n\nඔබගේ උපාංගය ආරෝපණය වන විට බැටරි සුරැකීම ස්වයංක්‍රීයව අක්‍රිය වේ."</string>
     <string name="downtime_condition_summary" msgid="8761776337475705749">"ඔබගේ බිඳවැටුම් වේලාව <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> දී අවසන්වන තුරු"</string>
-    <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
-    <skip />
+    <string name="downtime_condition_line_one" msgid="8762708714645352010">"ඔබගේ බිදවැටුම් කාලය අවසන් වන තෙක්"</string>
   <plurals name="zen_mode_duration_minutes_summary">
     <item quantity="one" msgid="3177683545388923234">"මිනිත්තු එකක් සඳහා (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> තෙක්)"</item>
     <item quantity="other" msgid="2787867221129368935">"මිනිත්තු %1$d සඳහා (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> තෙක්)"</item>
@@ -1905,8 +1903,21 @@
     <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> තෙක්"</string>
     <string name="zen_mode_forever" msgid="4316804956488785559">"අනියත ආකාරයට"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"හකුළන්න"</string>
-    <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
+    <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> හි ඊළඟ සීනුව තෙක්"</string>
+    <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"ඊළඟ සීනුව තෙක්"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
     <skip />
-    <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
     <skip />
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index f623be8..d29ef6b 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> hod. <xliff:g id="MINUTES">%2$d</xliff:g> min."</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> hod. <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> s"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min. <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Umožňuje aplikácii konfigurovať displeje a pripojiť sa k nim cez siete Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ovládať displeje cez sieť Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Umožňuje aplikácii ovládať základné funkcie displejov cez siete Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"ovládanie virtuálnych súkromných sietí"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Umožňuje aplikáciám ovládať funkcie nízkej úrovne virtuálnych súkromných sietí."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"zachytiť výstup zvuku"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Umožňuje aplikácii zachytiť a presmerovať výstup zvuku."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Rozpoznanie kľúčových slov"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Povoľuje tejto aplikácii prijímať informácie o aktuálnych prenosoch funkcie Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"odstránenie certifikátov DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Umožňuje aplikácii odstraňovať certifikáty DRM. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"viazať sa na službu na odosielanie správ SMS a MMS operátora"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania služby na odosielanie správ SMS a MMS operátora. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastaviť pravidlá pre heslo"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Ovládanie dĺžky hesiel na odomknutie obrazovky a v nich používané znaky."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Sledovať pokusy o odomknutie obrazovky"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Zbaliť"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Do ďalšieho budíka o <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Do ďalšieho budíka"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Stlmené aplikáciou <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Vo vašom zariadení došlo k internému problému. Môže byť nestabilné, kým neobnovíte jeho továrenské nastavenia."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Vo vašom zariadení došlo k internému problému. Ak chcete získať podrobné informácie, obráťte sa na jeho výrobcu."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 370ebfd..8880265 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <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>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> s"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Omogoča aplikaciji konfiguriranje zaslonov Wi-Fi in povezovanje z njimi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"nadzor zaslonov Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Omogoča aplikaciji nadzor osnovnih funkcij zaslonov Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"upravljanje navideznih zasebnih omrežij"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Aplikaciji omogoča upravljanje funkcij nizke ravni navideznih zasebnih omrežij."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"zajem avdioizhoda"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Omogoči aplikaciji, da zajame in preusmeri avdioizhod."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Zaznavanje sprožilnih besed"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Omogoči tej aplikaciji prejemanje podatkov o trenutnih prenosih s funkcijo Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"odstranjevanje potrdil za upravljanje digitalnih pravic"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Aplikaciji omogoča odstranjevanje potrdil za upravljanje digitalnih pravic. Tega ni treba nikoli uporabiti za navadne aplikacije."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"povezovanje z operaterjevo sporočilno storitvijo"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Imetniku omogoča povezovanje z vmesnikom operaterjeve sporočilne storitve najvišje ravni. To naj ne bi bilo nikoli potrebno za navadne aplikacije."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavitev pravil za geslo"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Nadzor nad dolžino in znaki, ki so dovoljeni v geslih za odklepanje zaslona."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"nadzor nad poskusi odklepanja zaslona"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Strni"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Do naslednjega alarma ob <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Do naslednjega alarma"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Izklop zvoka: <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Vaša naprava ima notranjo napako in bo morda nestabilna, dokler je ne ponastavite na tovarniške nastavitve."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Vaša naprava ima notranjo napako. Če želite več informacij, se obrnite na proizvajalca."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index b7923b4..e91a58b 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> с <xliff:g id="MINUTES">%2$d</xliff:g> мин"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> с <xliff:g id="MINUTES">%2$d</xliff:g> мин"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> мин"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> мин"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> мин <xliff:g id="SECONDS">%2$d</xliff:g> сек"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> мин <xliff:g id="SECONDS">%2$d</xliff:g> сек"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Дозвољава апликацији да конфигурише Wi-Fi екране и повезује се са њима."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"контрола Wi-Fi екрана"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Дозвољава апликацији да контролише функције Wi-Fi екрана ниског нивоа."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"контролиши виртуелне приватне мреже"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Дозвољава апликацији да контролише функције ниског нивоа виртуелних приватних мрежа."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"снимање аудио садржаја"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Дозвољава апликацији да снима и преусмерава аудио садржај."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Откривање актуелних речи"</string>
@@ -834,6 +835,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="policylab_limitPassword" msgid="4497420728857585791">"Подешавање правила за лозинку"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролишите дужину и знакове дозвољене у лозинкама за откључавање екрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Надгледање покушаја откључавања екрана"</string>
@@ -986,10 +989,10 @@
     <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Број за хитне случајеве"</string>
     <string name="lockscreen_carrier_default" msgid="8963839242565653192">"Нема услуге."</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="5347633784401285225">"Хитни позив"</string>
+    <string name="lockscreen_emergency_call" msgid="5347633784401285225">"Хитан позив"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Назад на позив"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Тачно!"</string>
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Покушајте поново"</string>
@@ -1639,7 +1642,7 @@
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Нема више 4G података"</string>
     <string name="data_usage_mobile_limit_title" msgid="557158376602636112">"Нема више подат. за мобил. уређ."</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_limit_body" msgid="291731708279614081">"Потрошили сте податке за овај месец"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Прекорачен пренос 2G-3G података"</string>
     <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Прекорачење преноса 4G података"</string>
     <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Ограничење мобилних података је прекорачено"</string>
@@ -1697,7 +1700,7 @@
     <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>×<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_emergency_call_label" msgid="684946192523830531">"Хитни позив"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Хитан позив"</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>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Скупи"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"До следећег аларма у <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"До следећег аларма"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 3cec045..2023f5a 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -564,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Tillåter att appen konfigurerar och ansluter till Wi-Fi-skärmar."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kontrollerar Wi-Fi-skärmar"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Tillåter att appen kontrollerar grundläggande funktioner för Wi-Fi-skärmar."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"styra virtuella privata nätverk"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Tillåter att appen styr grundläggande funktioner i virtuella privata nätverk."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"fånga upp ljudutgång"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Tillåt att appen fångar upp och omdirigerar ljudutgången."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Kommandoordsidentifiering"</string>
@@ -833,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Tillåter att appen tar emot information om aktuella Android Beam-överföringar"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"ta bort DRM-certifikat"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Tillåter ett program att ta bort DRM-certifikat. Behövs inte för vanliga appar."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"binda till en operatörs meddelandetjänst"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en operatörs meddelandetjänst. Ska inte behövas för vanliga appar."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Ange lösenordsregler"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Bestäm hur många och vilka tecken som är tillåtna i skärmlåsets lösenord."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Övervaka försök att låsa upp skärmen"</string>
@@ -1899,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Komprimera"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Till nästa alarm kl. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Till nästa alarm"</string>
+    <string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> har stängt av ljudet"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Ett internt problem har uppstått i enheten, och det kan hända att problemet kvarstår tills du återställer standardinställningarna."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Ett internt problem har uppstått i enheten. Kontakta tillverkaren om du vill veta mer."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index fb06ce6..b9237ce 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"Saa <xliff:g id="HOURS">%1$d</xliff:g> dak <xliff:g id="MINUTES">%2$d</xliff:g>"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"Saa <xliff:g id="HOURS">%1$d</xliff:g> dak <xliff:g id="MINUTES">%2$d</xliff:g>"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"Dakika <xliff:g id="MINUTES">%1$d</xliff:g>"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"Dak <xliff:g id="MINUTES">%1$d</xliff:g>"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"Dak <xliff:g id="MINUTES">%1$d</xliff:g> sek <xliff:g id="SECONDS">%2$d</xliff:g>"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"Dak <xliff:g id="MINUTES">%1$d</xliff:g> sek <xliff:g id="SECONDS">%2$d</xliff:g>"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"Sekunde <xliff:g id="SECONDS">%1$d</xliff:g>"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Inaruhusu programu kusanidi na kuunganika kwenye maonyesho ya Wifi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"dhibiti maonyesho ya Wifi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Inaruhusu programu kudhibiti vipengele vya kiwango cha chini vya maonyesho ya Wifi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"dhibiti Virtual Private Networks"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Huruhusu programu kudhibiti vipengele vya viwango vya chini vya Virtual Private Networks."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"nasa sauti"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Inaruhusu programu kunasa na kuelekeza sauti kwingine."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Kutambua neno tekelezi"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Huruhusu programu hii kupokea taarifa kuhusu uhamisho wa Boriti ya Android"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"ondoa vyeti vya DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Huruhusu programu kuondoa vyeti vya DRM. Haipaswi kuhitajika kwa programu za kawaida kamwe."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"Shurutisha kwa huduma ya ujumbe ya mtoa huduma"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Huruhusu kishikiliaji kushurutisha kwa kiolesura cha hali ya juu cha huduma ya ujumbe ya mtoa huduma. Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Kuweka kanuni za nenosiri"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kudhibiti urefu na herufi zinazoruhusiwa katika manenosiri ya kufungua skrini."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Kuhesabu mara ambazo skrini inajaribu kufunguliwa"</string>
@@ -1699,7 +1702,7 @@
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", salama"</string>
     <string name="kg_emergency_call_label" msgid="684946192523830531">"Simu ya dharura"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Umesahau Ruwaza"</string>
-    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Mchoro Usio sahihi"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Mchoro huo si sahihi"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Nenosiri Lisilo sahihi"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Nambari ya PIN si sahihi"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Jaribu tena baada ya sekunde <xliff:g id="NUMBER">%1$d</xliff:g>."</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Kunja"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Hadi kengele inayofuata saa <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Hadi kengele inayofuata"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Sauti imezimwa na <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Kuna hitilafu ya ndani ya kifaa chako, na huenda kisiwe thabiti mpaka urejeshe mipangilio ya kiwandani."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Kuna hitilafu ya ndani ya kifaa chako. Wasiliana na mtengenezaji wa kifaa chako kwa maelezo."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index e66bf26..809d354 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ம.நே. <xliff:g id="MINUTES">%2$d</xliff:g> நிமி."</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> மநே <xliff:g id="MINUTES">%2$d</xliff:g> நிமி"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> நிமிடங்கள்"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> நிமி."</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> நிமி <xliff:g id="SECONDS">%2$d</xliff:g> வி"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> நிமி <xliff:g id="SECONDS">%2$d</xliff:g> வி"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> வினாடிகள்"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Wifi காட்சிகளை உள்ளமைத்து அவற்றுடன் இணையப் பயன்பாட்டை அனுமதிக்கிறது."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi காட்சிகளைக் கட்டுப்படுத்துதல்"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Wifi காட்சிகளில் கீழ்-நிலை அம்சங்களைக் கட்டுப்படுத்தப் பயன்பாட்டை அனுமதிக்கிறது."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"மெய்நிகர் தனியார் பிணையங்களைக் கட்டுப்படுத்துதல்"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"மெய்நிகர் தனியார் பிணையங்களின் குறை-நிலை அம்சங்களைக் கட்டுப்படுத்த பயன்பாட்டை அனுமதிக்கும்."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ஆடியோ வெளியீட்டைப் பதிவுசெய்தல்"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"ஆடியோ வெளியீட்டைப் பதிவுசெய்ய மற்றும் திசைதிருப்ப பயன்பாட்டை அனுமதிக்கிறது."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"குறிப்பிட்ட சொல்லைக் கண்டறிதல்"</string>
@@ -834,6 +835,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="policylab_limitPassword" msgid="4497420728857585791">"கடவுச்சொல் விதிகளை அமைக்கவும்"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"திரையைத் திறக்க கடவுச்சொற்களில் அனுமதிக்கப்பட்ட நீளத்தையும், எழுத்துக்குறிகளையும் கட்டுப்படுத்தலாம்."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"திரைத் திறக்க முயற்சிகளைக் கண்காணித்தல்"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"சுருக்கு"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>க்கு ஒலிக்கும் அடுத்த அலாரம் வரை"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"அடுத்த அலாரம் வரை"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 513d892..a1b28e3 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> గం <xliff:g id="MINUTES">%2$d</xliff:g> నిమి"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> గం <xliff:g id="MINUTES">%2$d</xliff:g> నిమి"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> నిమిషాలు"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> నిమి"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> నిమి <xliff:g id="SECONDS">%2$d</xliff:g> సె"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> నిమి <xliff:g id="SECONDS">%2$d</xliff:g> సె"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> సెకన్లు"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"వైఫై డిస్‌ప్లేలను కాన్ఫిగర్ చేయడానికి మరియు వాటికి కనెక్ట్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"వైఫై డిస్‌ప్లేలను నియంత్రించడం"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"వైఫై డిస్‌ప్లేల యొక్క తక్కువ-స్థాయి లక్షణాలను నియంత్రించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"వర్చువల్ ప్రైవేట్ నెట్‌వర్క్‌లను నియంత్రించడం"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"వర్చువల్ ప్రైవేట్ నెట్‌వర్క్‌ల తక్కువ-స్థాయి లక్షణాలను నియంత్రించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ఆడియో అవుట్‌పుట్‌ను క్యాప్చర్ చేయడం"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"ఆడియో అవుట్‌పుట్‌ను క్యాప్చర్ చేసి, దారి మళ్లించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"హాట్‌వర్డ్ గుర్తింపు"</string>
@@ -834,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"పాస్‌వర్డ్ నియమాలను సెట్ చేయండి"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"స్క్రీన్-అన్‌లాక్ పాస్‌వర్డ్‌ల్లో అనుమతించబడే అక్షరాల  సంఖ్యను మరియు అక్షరాలను నియంత్రించండి."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"స్క్రీన్-అన్‌లాక్ ప్రయత్నాలను పర్యవేక్షించండి"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"కుదించండి"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>కి సెట్ చేసిన తదుపరి అలారం వరకు"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"తదుపరి అలారం వరకు"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 6696082..852054f 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ชม. <xliff:g id="MINUTES">%2$d</xliff:g> นาที"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ชม. <xliff:g id="MINUTES">%2$d</xliff:g> นาที"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> นาที"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> นาที"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> นาที <xliff:g id="SECONDS">%2$d</xliff:g> วิ."</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> นาที <xliff:g id="SECONDS">%2$d</xliff:g> วิ."</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> วินาที"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"อนุญาตให้แอปกำหนดค่าและเชื่อมต่อกับจอแสดงผล WiFi ได้"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ควบคุมการแสดงผลด้วย WiFi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"อนุญาตให้แอปควบคุมคุณลักษณะต่างๆ ในระดับล่างของการแสดงผลด้วย WiFi"</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"ควบคุมเครือข่ายส่วนตัวเสมือน"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"อนุญาตให้แอปควบคุมคุณลักษณะระดับต่ำของเครือข่ายส่วนตัวเสมือน"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"บันทึกเอาต์พุตเสียง"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"อนุญาตให้แอปบันทึกและเปลี่ยนเส้นทางเอาต์พุตเสียง"</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"การตรวจหาคำที่นิยม"</string>
@@ -834,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"ตั้งค่ากฎรหัสผ่าน"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"ควบคุมความยาวและอักขระที่อนุญาตให้ใช้ในรหัสผ่านการปลดล็อกหน้าจอ"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ตรวจสอบความพยายามในการปลดล็อกหน้าจอ"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"ยุบ"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"จนถึงการตั้งปลุกครั้งถัดไปในเวลา <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"จนถึงการตั้งปลุกครั้งถัดไป"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 1b3e7a0..5a4063f 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> oras <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> oras <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> (na) min"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <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> seg"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> seg"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> (na) seg"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Pinapayagan ang app na mag-configure at kumonekta sa mga Wifi display."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"magkontrol ng mga Wifi display"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Pinapayagan ang app na magkontrol ng mga tampok sa mababang antas ng mga dispay ng Wifi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"kontrolin ang mga Virtual Private Network"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Nagbibigay-daan sa app na kontrolin ang mga nasa mababang antas na feature ng mga Virtual Private Network."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"kumuha ng audio output"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Pinapayagan ang app na kumuha at mag-redirect ng audio output."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Paghahanap ng hotword"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Pinapayagan ang application na ito na tumanggap ng impormasyon tungkol sa mga kasalukuyang paglilipat ng Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"alisin ang mga DRM certificate"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Nagbibigay-daan sa isang application na alisin ang mga DRM certficate. Hindi dapat kailanman kailanganin para sa karaniwang apps."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"sumailalim sa isang serbisyo ng pagmemensahe ng carrier"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Binibigyang-daan ang may-ari na sumailalim sa interface sa nangungunang antas ng isang serbisyo ng pagmemensahe ng carrier. Hindi kailanman dapat kailanganin para sa mga normal na app."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Magtakda ng mga panuntunan sa password"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolin ang haba at mga character na pinapayagan sa mga password sa pag-unlock ng screen."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Subaybayan ang mga pagsubok sa pag-unlock ng screen"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"I-collapse"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Hanggang sa susunod na alarma sa <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Hanggang sa susunod na alarma"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Na-mute ng <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"May internal na problema sa iyong device, at maaaring hindi ito maging stable hanggang sa i-reset mo ang factory data."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"May internal na problema sa iyong device. Makipag-ugnayan sa iyong manufacturer upang malaman ang mga detalye."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 249bae7..45cac47 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> sa. <xliff:g id="MINUTES">%2$d</xliff:g> dk."</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> sa. <xliff:g id="MINUTES">%2$d</xliff:g> dk."</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> dk."</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> dk."</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> dk. <xliff:g id="SECONDS">%2$d</xliff:g> sn."</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> dk. <xliff:g id="SECONDS">%2$d</xliff:g> sn."</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sn."</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Uygulamaya kablosuz ekranları yapılandırma ve bunlara bağlanma izni verir."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Kablosuz ekranları denetle"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Uygulamaya kablosuz ekranların alt düzey özelliklerini kontrol etme izni verir."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"Sanal Özel Ağları denetle"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Uygulamaya, Sanal Özel Ağların düşük seviye özelliklerini denetleme izni verir."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ses çıkışını yakala"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Uygulamaya, ses çıkışını yakalayıp yönlendirme izni verir."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Özel kelime algılama"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Bu uygulamanın mevcut Android Beam aktarımlarıyla ilgili bilgi almasına izin verir"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"DRM sertifikalarını kaldırma"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Uygulamaya, DRM sertifikalarını kaldırma izin verir. Normal uygulamalar için asla gerekmemelidir."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"operatör mesajlaşma hizmetine bağlan"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"İzin sahibinin, operatör mesajlaşma hizmetinin üst düzey arayüzüne bağlanmasına olanak verir. Normal uygulamalarda hiçbir zaman gerekmez."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Şifre kuralları ayarla"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Ekran kilidini açma şifrelerinde izin verilen uzunluğu ve karakterleri denetleme."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekran kilidini açma denemelerini izle"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Daralt"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> saatindeki bir sonraki alarma kadar"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Bir sonraki alarma kadar"</string>
+    <string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> tarafından kapatıldı"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Cihazınızla ilgili dahili bir sorun oluştu ve fabrika verilerine sıfırlama işlemi gerçekleştirilene kadar kararsız çalışabilir."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Cihazınızla ilgili dahili bir sorun oluştu. Ayrıntılı bilgi için üreticinizle iletişim kurun."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 69bea78..591bc2a 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> год <xliff:g id="MINUTES">%2$d</xliff:g> хв"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> год <xliff:g id="MINUTES">%2$d</xliff:g> хв"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> хв"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> хв"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> хв <xliff:g id="SECONDS">%2$d</xliff:g> с"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> хв <xliff:g id="SECONDS">%2$d</xliff:g> с"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> с"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Дозволяє програмі налаштовувати екрани Wi-Fi і під’єднуватися до них."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"керувати екранами Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Дозволяє програмі керувати низькорівневими функціями екранів Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"керування віртуальними приватними мережами"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Додаток може керувати низькорівневими функціями віртуальних приватних мереж."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"отримувати доступ до аудіовиходу"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Дозволяє програмі отримувати доступ до аудіовиходу й переспрямовувати його."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"виявляти команди швидкого запуску"</string>
@@ -834,6 +835,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="policylab_limitPassword" msgid="4497420728857585791">"Устан. правила пароля"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролювати довжину паролів для розблокування екрана та дозволені в них символи."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Відстежув. спроби розблок. екрана"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Згорнути"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"До наступного сигналу о <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"До наступного сигналу"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 859ac03..bf8c64f 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> گھنٹہ <xliff:g id="MINUTES">%2$d</xliff:g> منٹ"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> گھنٹہ <xliff:g id="MINUTES">%2$d</xliff:g> منٹ"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> منٹ"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> منٹ"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> منٹ <xliff:g id="SECONDS">%2$d</xliff:g> سیکنڈ"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> منٹ <xliff:g id="SECONDS">%2$d</xliff:g> سیکنڈ"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> سیکنڈ"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"‏ایپ کو Wifi ڈسپلیز کے ساتھ ترتیب دینے اور مربوط کرنے کی اجازت دیتا ہے۔"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"‏Wifi ڈسپلیز کنٹرول کریں"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"‏ایپ کو Wifi ڈسپلیز کی کم سطح والی خصوصیات کو کنٹرول کرنے کی اجازت دیتا ہے۔"</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"ورچوئل نجی نیٹ ورکس کو کنٹرول کریں"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"ایپ کو ورچوئل نجی نیٹ ورکس کی کم سطحی خصوصیات کو کنٹرول کرنے کی اجازت دیتی ہے۔"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"آڈیو آؤٹ پٹ کیپچر کریں"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"ایپ کو آڈیو آؤٹ پٹ کو کیپچر کرنے اور ری ڈائریکٹ کرنے کی اجازت دیتا ہے۔"</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"ہاٹ ورڈ کا پتہ لگانا"</string>
@@ -834,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"پاس ورڈ کے اصول سیٹ کریں"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"اسکرین غیر مقفل کرنے کے پاس ورڈز میں مجاز طوالت اور حروف کو کنٹرول کریں۔"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"اسکرین غیر مقفل کرنے کی کوششیں مانیٹر کریں"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"سکیڑیں"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"اگلے الارم تک بوقت <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"اگلے الارم تک"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index f2b31fd..c6f44e8 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> soat <xliff:g id="MINUTES">%2$d</xliff:g> daq"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> soat <xliff:g id="MINUTES">%2$d</xliff:g> daq"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> daqiqa"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> daqiqa"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> daq <xliff:g id="SECONDS">%2$d</xliff:g> son"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> daq <xliff:g id="SECONDS">%2$d</xliff:g> son"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> soniya"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Ilovaga Wifi ekranlarini sozlashga va ularga ulanishga ruxsat beradi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi ekranlarini boshqarish"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Ilovaga Wifi ekranlarining past darajali xususiyatlarini boshqarishga ruxsat beradi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"virtual xususiy tarmoqlarni (VPN) boshqarish"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Ilovaga virtual xususiy tarmoqlarning (VPN) quyi darajali funksiyalarini boshqarish uchun ruxsat beradi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"audio chiqishni yozib olish"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Dasturga ovoz lavhasini yozib olib, qayta yo‘llashga ruxsat beradi."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Hotword aniqlash"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Ushbu ilovaga joriy Android Beam uzatishlari haqida ma\'lumotlarni olish ruxsati berilsin."</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"DRM sertifikatlarini o‘chirib tashlash"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Ilovaga DRM sertifikatlarini o‘chirib tashlash uchun ruxsat beradi. Oddiy ilovalar uchun talab qilinmaydi."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"aloqa operatorining xabar almashinuv xizmatiga bog‘lanish"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Egasiga aloqa operatorining xabar almashinuv xizmatining yuqori darajali interfeysiga bog‘lanish uchun ruxsat beradi. Oddiy ilovalar uchun hech qachon kerak bo‘lmaydi."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Parol qoidalarini o‘rnatish"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Ekran qulfini ochish parollariga ruxsat berilgan belgilar va ularning uzunligini boshqarish."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekranni qulfdan chiqarish urinishlarini nazorat qilish"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Yig‘ish"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Keyingi uyg‘otkich vaqtigacha (<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Keyingi uyg‘otkich vaqtigacha"</string>
+    <string name="muted_by" msgid="6147073845094180001">"“<xliff:g id="THIRD_PARTY">%1$s</xliff:g>” tomonidan ovozsiz qilingan"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Qurilmangiz bilan bog‘liq ichki muammo mavjud. U zavod sozlamalari tiklanmaguncha barqaror ishlamasligi mumkin."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Qurilmangiz bilan bog‘liq ichki muammo mavjud. Tafsilotlar uchun qurilmangiz ishlab chiqaruvchisiga murojaat qiling."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index a99f0aa..c9ded6d 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> giờ <xliff:g id="MINUTES">%2$d</xliff:g> phút"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> giờ <xliff:g id="MINUTES">%2$d</xliff:g> phút"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> phút"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> phút"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> phút <xliff:g id="SECONDS">%2$d</xliff:g> giây"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> phút <xliff:g id="SECONDS">%2$d</xliff:g> giây"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> giây"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Cho phép ứng dụng định cấu hình và kết nối với màn hình Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kiểm soát màn hình Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Cho phép ứng dụng kiểm soát các tính năng cấp thấp của màn hình Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"kiểm soát Mạng riêng ảo"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Cho phép ứng dụng kiểm soát các tính năng cấp thấp của Mạng riêng ảo."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"thu thập dữ liệu đầu ra âm thanh"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Cho phép ứng dụng thu thập và chuyển hướng dữ liệu đầu ra âm thanh."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Phát hiện từ nóng"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Cho phép ứng dụng này nhận thông tin về các lần chuyển hiện tại của Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"xóa chứng chỉ DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Cho phép ứng dụng xóa chứng chỉ DRM. Không cần thiết cho các ứng dụng thông thường."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"liên kết với dịch vụ nhắn tin của nhà cung cấp dịch vụ"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ nhắn tin của nhà cung cấp dịch vụ. Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Đặt quy tắc mật khẩu"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kiểm soát độ dài và ký tự được phép trong mật khẩu mở khóa màn hình."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Giám sát những lần thử mở khóa màn hình"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Thu gọn"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Cho đến lần báo thức tiếp theo vào <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Cho đến lần báo thức tiếp theo"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Do <xliff:g id="THIRD_PARTY">%1$s</xliff:g> tắt tiếng"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Đã xảy ra sự cố nội bộ với thiết bị của bạn và thiết bị có thể sẽ không ổn định cho tới khi bạn thiết lập lại dữ liệu ban đầu."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Đã xảy ra sự cố nội bộ với thiết bị. Hãy liên hệ với nhà sản xuất của bạn để biết chi tiết."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index a562a39..54040d6 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g>小时<xliff:g id="MINUTES">%2$d</xliff:g>分钟"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g>小时<xliff:g id="MINUTES">%2$d</xliff:g>分钟"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g>分钟"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> 分钟"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g>分钟<xliff:g id="SECONDS">%2$d</xliff:g>秒"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g>分钟<xliff:g id="SECONDS">%2$d</xliff:g>秒"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g>秒"</string>
@@ -565,6 +564,10 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"允许应用配置并连接到WLAN显示设备。"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"控制WLAN显示设备"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"允许应用控制WLAN显示设备的基础功能。"</string>
+    <!-- no translation found for permlab_controlVpn (2618442789397588200) -->
+    <skip />
+    <!-- no translation found for permdesc_controlVpn (762852603315861214) -->
+    <skip />
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"捕获音频输出"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"允许该应用捕获和重定向音频输出。"</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"启动指令检测"</string>
@@ -834,6 +837,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"设置密码规则"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制屏幕解锁密码所允许的长度和字符。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"监视屏幕解锁尝试次数"</string>
@@ -1900,4 +1905,21 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"收起"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"到下次闹钟时间(<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"到下次闹钟时间"</string>
+    <string name="muted_by" msgid="6147073845094180001">"已被<xliff:g id="THIRD_PARTY">%1$s</xliff:g>设为静音"</string>
+    <!-- no translation found for system_error_wipe_data (6608165524785354962) -->
+    <skip />
+    <!-- no translation found for system_error_manufacturer (8086872414744210668) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 3fc82cf..8e888da 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> 小時 <xliff:g id="MINUTES">%2$d</xliff:g> 分鐘"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> 小時 <xliff:g id="MINUTES">%2$d</xliff:g> 分鐘"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> 分鐘"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> 分鐘"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> 分鐘 <xliff:g id="SECONDS">%2$d</xliff:g> 秒"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> 分鐘 <xliff:g id="SECONDS">%2$d</xliff:g> 秒"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> 秒"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"允許應用程式設定及連接 WiFi Display。"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"控制 WiFi Display"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"允許應用程式控制 WiFi Display 的低階功能。"</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"控制虛擬私人網絡"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"允許應用程式控制虛擬私人網絡的低層級功能。"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"擷取音頻輸出"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"允許應用程式擷取及重新導向音頻輸出。"</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"啟動字詞偵測"</string>
@@ -834,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制螢幕解鎖密碼所允許的長度和字元。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"監控螢幕解鎖嘗試次數"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"收合"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"直到下一個在 <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> 的鬧鐘"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"直到下一個鬧鐘"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 000243b..bccdd483 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> 小時 <xliff:g id="MINUTES">%2$d</xliff:g> 分鐘"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> 小時 <xliff:g id="MINUTES">%2$d</xliff:g> 分鐘"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> 分鐘"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> 分鐘"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> 分鐘 <xliff:g id="SECONDS">%2$d</xliff:g> 秒"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> 分鐘 <xliff:g id="SECONDS">%2$d</xliff:g> 秒"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> 秒"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"允許應用程式設定及連接 Wi-Fi 顯示裝置。"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"控制 Wi-Fi 顯示裝置"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"允許應用程式控制 Wi-Fi 顯示裝置的低階功能。"</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"控制虛擬私人網路"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"允許應用程式控制虛擬私人網路的低階功能。"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"擷取音訊輸出"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"允許應用程式擷取及重新導向音訊輸出。"</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"啟動字詞偵測"</string>
@@ -834,6 +835,8 @@
     <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="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制螢幕解鎖密碼所允許的長度和字元。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"監視螢幕解鎖嘗試次數"</string>
@@ -1878,7 +1881,7 @@
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"取消固定時必須輸入密碼"</string>
     <string name="battery_saver_description" msgid="2510530476513605742">"節約耗電量功能會降低裝置的效能,並限制震動和大多數背景資料,藉此延長電池續航力。此外,電子郵件、聊天工具和其他需要使用同步功能的應用程式若未開啟,將不會自動更新。\n\n當您為裝置充電時,節約耗電量功能會自動關閉。"</string>
     <string name="downtime_condition_summary" msgid="8761776337475705749">"直到 <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> 停機時間結束"</string>
-    <string name="downtime_condition_line_one" msgid="8762708714645352010">"到停機時間結束時"</string>
+    <string name="downtime_condition_line_one" msgid="8762708714645352010">"直到停機時間結束"</string>
   <plurals name="zen_mode_duration_minutes_summary">
     <item quantity="one" msgid="3177683545388923234">"1 分鐘 (結束時間:<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
     <item quantity="other" msgid="2787867221129368935">"%1$d 分鐘 (結束時間:<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1898,6 +1901,21 @@
     <string name="zen_mode_until" msgid="7336308492289875088">"結束時間:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_forever" msgid="4316804956488785559">"無限期"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"收合"</string>
-    <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"到下次鬧鐘鈴響時:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
-    <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"到下次鬧鐘鈴響時"</string>
+    <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"直到下次鬧鐘鈴響:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+    <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"直到下次鬧鐘鈴響"</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>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index df16513..116b2a61 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -34,8 +34,7 @@
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ihora <xliff:g id="MINUTES">%2$d</xliff:g> amaminithi"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ihora <xliff:g id="MINUTES">%2$d</xliff:g> iminithi"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> amaminithi"</string>
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> iminithi"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> iminithi <xliff:g id="SECONDS">%2$d</xliff:g> amasekhondi"</string>
     <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> iminithi <xliff:g id="SECONDS">%2$d</xliff:g> isekhondi"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> amasekhondi"</string>
@@ -565,6 +564,8 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Ivumela uhlelo lokusebenza ukulungisa nokuxhuma ekubukisweni kwe-Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"lawula ukubukwa kwe-Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Uvumela uhlelo lokusebenza ukulawula izici zeleveli ephansi zokuboniswa kwe-Wi-Fi."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"lawula Amanethiwekhi Wemfihlo Abonakalayo"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Ivumela uhlelo lokusebenza ukulawula izici zeleveli ephansi Zamanethiwekhi Wemfihlo Abonakalayo."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"shutha okukhipha umsindo"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Kuvumela uhlelo lokusebenza ukuba lushuthe futhi luqondise kabusha okukhipha umsindo."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Ukutholwa kwe-Hotword"</string>
@@ -834,6 +835,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Ivumela lolu hlelo lokusebenza ukuthi luthole ulwazi mayelana nokundluliswa kwamanje kwe-Android Beam"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"susa izitifiketi ze-DRM"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Ivumela uhlelo lokusebenza ukususa izitifiketi ze-DRM. Akufanele idingeke ngezinhlelo zokusebenza ezivamile."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"bophezela kusevisi yomlayezo yenkampani yenethiwekhi"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Ivumela isibambi ukuhlanganisa isixhumanisi sokubona esiphezulu sesevisi yomlayezo yenkampani yenethiwekhi. Akufanele idingeke kuzinhlelo zokusebenza ezivamile."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Misa imithetho yephasiwedi"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Lawula ubude nezinhlamvu ezivunyelwe kumaphasiwedi okuvula isikrini"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Gaka imizamo yokuvula isikrini"</string>
@@ -1900,4 +1903,19 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Goqa"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Kuze kube yi-alamu elandelayo ngo-<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Kuze kube yi-alamu elandelayo"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Ithuliswe ngu-<xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Kukhona inkinga yangaphakathi ngedivayisi yakho, futhi ingase ibe engazinzile kuze kube yilapho usetha kabusha yonke idatha."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Kukhona inkinga yangaphakathi ngedivayisi yakho. Xhumana nomkhiqizi wakho ukuze uthole imininingwane."</string>
+    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
+    <skip />
+    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
+    <skip />
+    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 4f8acdb..2fd7d30 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2639,8 +2639,8 @@
              to allow the children to draw outside of their bounds. The default value of
              this property is true. -->
         <attr name="clipChildren" format="boolean" />
-        <!-- Defines whether the ViewGroup will clip its drawing surface so as to exclude
-             the padding area. This property is set to true by default. -->
+        <!-- Defines whether the ViewGroup will clip its children to its padding, if
+             padding is not zero. This property is set to true by default. -->
         <attr name="clipToPadding" format="boolean" />
         <!-- Defines the layout animation to use the first time the ViewGroup is laid out.
              Layout animations can also be started manually after the first layout. -->
@@ -4662,6 +4662,11 @@
         <attr name="weekDayTextAppearance" format="reference" />
         <!-- The text appearance for the calendar dates. -->
         <attr name="dateTextAppearance" format="reference" />
+        <!-- The number of weeks to be shown. -->
+        <attr name="calendarViewMode">
+            <enum name="holo" value="0" />
+            <enum name="material" value="1" />
+        </attr>
     </declare-styleable>
 
     <declare-styleable name="NumberPicker">
@@ -5660,6 +5665,10 @@
             <enum name="right" value="0x05" />
             <!-- Slide to and from the bottom edge of the Scene. -->
             <enum name="bottom" value="0x50" />
+            <!-- Slide to and from the x-axis position at the start of the Scene root. -->
+            <enum name="start" value="0x00800003"/>
+            <!-- Slide to and from the x-axis position at the end of the Scene root. -->
+            <enum name="end" value="0x00800005"/>
         </attr>
     </declare-styleable>
 
@@ -7215,6 +7224,8 @@
         <attr name="goIcon" format="reference" />
         <!-- Search icon -->
         <attr name="searchIcon" format="reference" />
+        <!-- Search icon displayed as a text field hint -->
+        <attr name="searchHintIcon" format="reference" />
         <!-- Voice button icon -->
         <attr name="voiceIcon" format="reference" />
         <!-- Commit icon shown in the query suggestion row -->
diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml
index 46ec838..a8fd8d4 100644
--- a/core/res/res/values/colors_material.xml
+++ b/core/res/res/values/colors_material.xml
@@ -22,7 +22,7 @@
     <color name="background_floating_material_light">#ffeeeeee</color>
 
     <color name="primary_material_dark">#ff212121</color>
-    <color name="primary_material_light">#ffe0e0e0</color>
+    <color name="primary_material_light">#ffefefef</color>
     <color name="primary_dark_material_dark">#ff000000</color>
     <color name="primary_dark_material_light">#ff757575</color>
 
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index e4641ce..6e635f31 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -323,9 +323,14 @@
 
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
-         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
-         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
-    <string translatable="false" name="config_tether_apndata"></string>
+         "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
+         Or string format of ApnSettingV3.
+         note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN"
+         Multiple entries are separated by using string-array:
+         "<item>[ApnSettingV3]Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,14,,,,,,,spn,testspn</item>
+          <item>[ApnSettingV3]Name1,apn2,,,,,,,,,123,46,,mms|*,IPV6,IP,true,12,,,,,,,,</item>" -->
+    <string-array translatable="false" name="config_tether_apndata">
+    </string-array>
 
     <!-- Boolean indicating whether the wifi chipset has dual frequency band support -->
     <bool translatable="false" name="config_wifi_dual_band_support">false</bool>
@@ -1937,4 +1942,8 @@
     <string-array translatable="false" name="config_sms_convert_destination_number_support">
         <item>false</item>
     </string-array>
+
+    <!-- The maximum bitmap size that can be written to a MediaMetadata object. This value
+         is the max width/height allowed in dips.-->
+    <dimen name="config_mediaMetadataBitmapMaxSize">320dp</dimen>
 </resources>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index 4a2119b..54f483d 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -91,6 +91,13 @@
     <!-- Default rounded corner for controls -->
     <dimen name="control_corner_material">2dp</dimen>
 
+    <dimen name="edit_text_inset_horizontal_material">4dp</dimen>
+    <dimen name="edit_text_inset_top_material">4dp</dimen>
+    <dimen name="edit_text_inset_bottom_material">8dp</dimen>
+
     <dimen name="dialog_padding_material">24dp</dimen>
     <dimen name="dialog_padding_top_material">18dp</dimen>
+
+    <!-- Padding above and below selection dialog lists. -->
+    <dimen name="dialog_list_padding_vertical_material">8dp</dimen>
 </resources>
diff --git a/core/res/res/values/integers.xml b/core/res/res/values/integers.xml
index 0343cfa..8e27226 100644
--- a/core/res/res/values/integers.xml
+++ b/core/res/res/values/integers.xml
@@ -22,4 +22,5 @@
     <integer name="button_pressed_animation_duration">100</integer>
     <integer name="button_pressed_animation_delay">100</integer>
     <integer name="disabled_alpha_animation_duration">100</integer>
+    <integer name="dock_enter_exit_duration">250</integer>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index c661c33..c01d406 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2600,5 +2600,6 @@
     <public type="attr" name="accessibilityTraversalBefore" />
     <public type="attr" name="accessibilityTraversalAfter" />
     <public type="attr" name="dialogPreferredPadding" />
+    <public type="attr" name="searchHintIcon" />
 
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index c4b9c5f..7bc24c3 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -212,6 +212,12 @@
     <!-- Displayed to tell the user that all service is blocked by access control. -->
     <string name="RestrictedOnAll">All voice/data/SMS services are blocked.</string>
 
+    <!-- Displayed to tell the user that peer changed TTY mode -->
+    <string name="peerTtyModeFull">Peer requested TTY Mode FULL</string>
+    <string name="peerTtyModeHco">Peer requested TTY Mode HCO</string>
+    <string name="peerTtyModeVco">Peer requested TTY Mode VCO</string>
+    <string name="peerTtyModeOff">Peer requested TTY Mode OFF</string>
+
     <!-- Mappings between TS 27.007 +CFCC/+CLCK "service classes" and human-readable strings--> <skip />
     <!-- Example: Service was enabled for: Voice, Data -->
     <string name="serviceClassVoice">Voice</string>
@@ -1652,6 +1658,11 @@
     <string name="permdesc_controlWifiDisplay">Allows the app to control low-level features of Wifi displays.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_controlVpn">control Virtual Private Networks</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_controlVpn">Allows the app to control low-level features of Virtual Private Networks.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_captureAudioOutput">capture audio output</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_captureAudioOutput">Allows the app to capture and redirect audio output.</string>
@@ -3301,6 +3312,8 @@
     <!-- This is the default button label in the system-wide search UI.
          It is also used by the home screen's search "widget". It should be short -->
     <string name="search_go">Search</string>
+    <!-- Default hint text for the system-wide search UI's text field. [CHAR LIMIT=30] -->
+    <string name="search_hint">Search…</string>
     <!-- SearchView accessibility description for search button [CHAR LIMIT=NONE] -->
     <string name="searchview_description_search">Search</string>
     <!-- SearchView accessibility description for search text field [CHAR LIMIT=NONE] -->
@@ -5072,7 +5085,7 @@
     <string name="lock_to_app_unlock_password">Ask for password before unpinning</string>
 
     <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description -->
-    <string name="battery_saver_description">To help improve battery life, battery saver reduces your device’s performance and limits vibration and most background data. Email, messaging, and other apps that rely on syncing may not update unless you open them.\n\nBattery saver turns off automatically when your device is charging.</string>
+    <string name="battery_saver_description">To help improve battery life, battery saver reduces your device’s performance and limits vibration, location services, and most background data. Email, messaging, and other apps that rely on syncing may not update unless you open them.\n\nBattery saver turns off automatically when your device is charging.</string>
 
     <!-- [CHAR_LIMIT=NONE] Zen mode: Condition summary for built-in downtime condition, if active -->
     <string name="downtime_condition_summary">Until your downtime ends at <xliff:g id="formattedTime" example="10:00 PM">%1$s</xliff:g></string>
@@ -5127,4 +5140,13 @@
     <!-- Error message shown when there is a system error which can be solved by the manufacturer. [CHAR LIMIT=NONE] -->
     <string name="system_error_manufacturer">There\'s an internal problem with your device. Contact your manufacturer for details.</string>
 
+    <!-- Displayed when the USSD/SS request is modified by STK CC to a
+    different request. This will be displayed in a toast. -->
+    <string name="stk_cc_ussd_to_dial">USSD request is modified to DIAL request.</string>
+    <string name="stk_cc_ussd_to_ss">USSD request is modified to SS request.</string>
+    <string name="stk_cc_ussd_to_ussd">USSD request is modified to new USSD request.</string>
+    <string name="stk_cc_ss_to_dial">SS request is modified to DIAL request.</string>
+    <string name="stk_cc_ss_to_ussd">SS request is modified to USSD request.</string>
+    <string name="stk_cc_ss_to_ss">SS request is modified to new SS request.</string>
+
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 5a59afe..c520a46 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -565,6 +565,7 @@
         <item name="selectedDateVerticalBar">@drawable/day_picker_week_view_dayline_holo</item>
         <item name="weekDayTextAppearance">@style/TextAppearance.Small.CalendarViewWeekDayView</item>
         <item name="dateTextAppearance">?attr/textAppearanceSmall</item>
+        <item name="calendarViewMode">holo</item>
     </style>
 
     <style name="Widget.NumberPicker">
diff --git a/core/res/res/values/styles_holo.xml b/core/res/res/values/styles_holo.xml
index c7d2db1..41b8b25 100644
--- a/core/res/res/values/styles_holo.xml
+++ b/core/res/res/values/styles_holo.xml
@@ -358,6 +358,7 @@
         <item name="submitBackground">@drawable/textfield_searchview_right_holo_dark</item>
         <item name="closeIcon">@drawable/ic_clear_holo_dark</item>
         <item name="searchIcon">@drawable/ic_search_api_holo_dark</item>
+        <item name="searchHintIcon">@drawable/ic_search_api_holo_dark</item>
         <item name="goIcon">@drawable/ic_go_search_api_holo_dark</item>
         <item name="voiceIcon">@drawable/ic_voice_search_api_holo_dark</item>
         <item name="commitIcon">@drawable/ic_commit_search_api_holo_dark</item>
@@ -444,6 +445,7 @@
         <item name="weekSeparatorLineColor">#19FFFFFF</item>
         <item name="selectedDateVerticalBar">@drawable/day_picker_week_view_dayline_holo</item>
         <item name="weekDayTextAppearance">@style/TextAppearance.Holo.CalendarViewWeekDayView</item>
+        <item name="calendarViewMode">holo</item>
     </style>
 
     <style name="Widget.Holo.ImageButton" parent="Widget.ImageButton">
@@ -881,6 +883,7 @@
         <item name="weekNumberColor">#7F080021</item>
         <item name="weekSeparatorLineColor">#7F08002A</item>
         <item name="weekDayTextAppearance">@style/TextAppearance.Holo.Light.CalendarViewWeekDayView</item>
+        <item name="calendarViewMode">holo</item>
     </style>
 
     <style name="Widget.Holo.Light.NumberPicker" parent="Widget.Holo.NumberPicker" />
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index e04d901..6749441 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -517,12 +517,20 @@
         <item name="submitBackground">@drawable/textfield_search_material</item>
         <item name="closeIcon">@drawable/ic_clear_material</item>
         <item name="searchIcon">@drawable/ic_search_api_material</item>
+        <item name="searchHintIcon">@drawable/ic_search_api_material</item>
         <item name="goIcon">@drawable/ic_go_search_api_material</item>
         <item name="voiceIcon">@drawable/ic_voice_search_api_material</item>
         <item name="commitIcon">@drawable/ic_commit_search_api_material</item>
         <item name="suggestionRowLayout">@layout/search_dropdown_item_icons_2line</item>
     </style>
 
+    <style name="Widget.Material.SearchView.ActionBar">
+        <item name="queryBackground">@empty</item>
+        <item name="submitBackground">@empty</item>
+        <item name="searchHintIcon">@empty</item>
+        <item name="queryHint">@string/search_hint</item>
+    </style>
+
     <style name="Widget.Material.SegmentedButton" parent="SegmentedButton">
         <item name="background">@drawable/btn_group_holo_dark</item>
     </style>
@@ -612,6 +620,7 @@
         <item name="weekSeparatorLineColor">#19FFFFFF</item>
         <item name="selectedDateVerticalBar">@drawable/day_picker_week_view_dayline_holo</item>
         <item name="weekDayTextAppearance">@style/TextAppearance.Material.CalendarViewWeekDayView</item>
+        <item name="calendarViewMode">material</item>
     </style>
 
     <style name="Widget.Material.ImageButton" parent="Widget.ImageButton">
@@ -961,6 +970,7 @@
     <style name="Widget.Material.Light.ButtonBar" parent="Widget.Material.ButtonBar"/>
     <style name="Widget.Material.Light.ButtonBar.AlertDialog" parent="Widget.Material.ButtonBar.AlertDialog"/>
     <style name="Widget.Material.Light.SearchView" parent="Widget.Material.SearchView"/>
+    <style name="Widget.Material.Light.SearchView.ActionBar" parent="Widget.Material.SearchView.ActionBar"/>
 
     <style name="Widget.Material.Light.SegmentedButton" parent="Widget.Material.SegmentedButton">
         <item name="background">@drawable/btn_group_holo_light</item>
@@ -999,6 +1009,7 @@
         <item name="weekNumberColor">#7F080021</item>
         <item name="weekSeparatorLineColor">#7F08002A</item>
         <item name="weekDayTextAppearance">@style/TextAppearance.Material.CalendarViewWeekDayView</item>
+        <item name="calendarViewMode">material</item>
     </style>
 
     <style name="Widget.Material.Light.NumberPicker" parent="Widget.Material.NumberPicker"/>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f6d0836..cbc379b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -202,6 +202,7 @@
   <java-symbol type="id" name="status_bar_latest_event_content" />
   <java-symbol type="id" name="action_divider" />
   <java-symbol type="id" name="overflow_divider" />
+  <java-symbol type="id" name="notification_main_column" />
   <java-symbol type="id" name="sms_short_code_confirm_message" />
   <java-symbol type="id" name="sms_short_code_detail_layout" />
   <java-symbol type="id" name="sms_short_code_detail_message" />
@@ -538,7 +539,6 @@
   <java-symbol type="string" name="config_mms_user_agent" />
   <java-symbol type="string" name="config_mms_user_agent_profile_url" />
   <java-symbol type="string" name="config_ntpServer" />
-  <java-symbol type="string" name="config_tether_apndata" />
   <java-symbol type="string" name="config_useragentprofile_url" />
   <java-symbol type="string" name="config_wifi_p2p_device_type" />
   <java-symbol type="string" name="contentServiceSync" />
@@ -716,6 +716,10 @@
   <java-symbol type="string" name="perms_description_app" />
   <java-symbol type="string" name="perms_new_perm_prefix" />
   <java-symbol type="string" name="petabyteShort" />
+  <java-symbol type="string" name="peerTtyModeFull" />
+  <java-symbol type="string" name="peerTtyModeHco" />
+  <java-symbol type="string" name="peerTtyModeVco" />
+  <java-symbol type="string" name="peerTtyModeOff" />
   <java-symbol type="string" name="phoneTypeAssistant" />
   <java-symbol type="string" name="phoneTypeCallback" />
   <java-symbol type="string" name="phoneTypeCar" />
@@ -919,6 +923,12 @@
   <java-symbol type="string" name="default_audio_route_name_dock_speakers" />
   <java-symbol type="string" name="default_media_route_name_hdmi" />
   <java-symbol type="string" name="default_audio_route_category_name" />
+  <java-symbol type="string" name="stk_cc_ss_to_dial" />
+  <java-symbol type="string" name="stk_cc_ss_to_ss" />
+  <java-symbol type="string" name="stk_cc_ss_to_ussd" />
+  <java-symbol type="string" name="stk_cc_ussd_to_dial" />
+  <java-symbol type="string" name="stk_cc_ussd_to_ss" />
+  <java-symbol type="string" name="stk_cc_ussd_to_ussd" />
   <java-symbol type="string" name="safe_media_volume_warning" />
   <java-symbol type="string" name="media_route_status_scanning" />
   <java-symbol type="string" name="media_route_status_connecting" />
@@ -1206,6 +1216,9 @@
   <java-symbol type="drawable" name="sim_dark_orange" />
   <java-symbol type="drawable" name="sim_dark_purple" />
 
+  <java-symbol type="drawable" name="ic_sim_card_multi_24px_clr" />
+  <java-symbol type="drawable" name="ic_sim_card_multi_48px_clr" />
+
   <java-symbol type="drawable" name="ic_account_circle" />
   <java-symbol type="color" name="user_icon_1" />
   <java-symbol type="color" name="user_icon_2" />
@@ -1546,6 +1559,7 @@
   <java-symbol type="array" name="config_tether_bluetooth_regexs" />
   <java-symbol type="array" name="config_tether_dhcp_range" />
   <java-symbol type="array" name="config_tether_upstream_types" />
+  <java-symbol type="array" name="config_tether_apndata" />
   <java-symbol type="array" name="config_tether_usb_regexs" />
   <java-symbol type="array" name="config_tether_wifi_regexs" />
   <java-symbol type="array" name="config_usbHostBlacklist" />
@@ -1796,6 +1810,8 @@
   <java-symbol type="color" name="notification_progress_background_color" />
   <java-symbol type="id" name="media_actions" />
 
+  <java-symbol type="dimen" name="config_mediaMetadataBitmapMaxSize" />
+
     <!-- From SystemUI -->
   <java-symbol type="anim" name="push_down_in" />
   <java-symbol type="anim" name="push_down_out" />
@@ -1845,6 +1861,7 @@
   <java-symbol type="string" name="usb_storage_stop_title" />
   <java-symbol type="string" name="usb_storage_title" />
   <java-symbol type="style" name="Animation.RecentApplications" />
+  <java-symbol type="integer" name="dock_enter_exit_duration" />
 
   <!-- ImfTest -->
   <java-symbol type="layout" name="auto_complete_list" />
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index b320ae5..3f2062dc 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -828,6 +828,7 @@
          secondary text color, with the primary text color. -->
     <style name="ThemeOverlay.Material.ActionBar">
         <item name="colorControlNormal">?attr/textColorPrimary</item>
+        <item name="searchViewStyle">@style/Widget.Material.Light.SearchView.ActionBar</item>
     </style>
 
     <!-- Theme overlay that replaces colors with their dark versions and replaces the normal
@@ -835,6 +836,7 @@
          text color. -->
     <style name="ThemeOverlay.Material.Dark.ActionBar">
         <item name="colorControlNormal">?attr/textColorPrimary</item>
+        <item name="searchViewStyle">@style/Widget.Material.SearchView.ActionBar</item>
     </style>
 
     <!-- Variant of the material (dark) theme with no action bar. -->
diff --git a/core/tests/ConnectivityManagerTest/AndroidManifest.xml b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
index 1649268..6bd8f6e 100644
--- a/core/tests/ConnectivityManagerTest/AndroidManifest.xml
+++ b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
@@ -68,8 +68,9 @@
 
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
     <!-- This permission is added for API call setAirplaneMode() in ConnectivityManager -->
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index f3d5c87..e04c214 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -199,7 +199,7 @@
                 Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0);
         // set wifi sleep policy to never on while in sleep
         Settings.Global.putInt(mRunner.getContext().getContentResolver(),
-                Settings.Global.WIFI_SLEEP_POLICY, Settings.Global.WIFI_SLEEP_POLICY_NEVER);
+                Settings.Global.WIFI_SLEEP_POLICY, Settings.Global.WIFI_SLEEP_POLICY_DEFAULT);
         // set idle timeout for wifi to 15s
         Settings.Global.putLong(mRunner.getContext().getContentResolver(),
                 Settings.Global.WIFI_IDLE_MS, WIFI_IDLE_MS);
diff --git a/docs/html/auto/images/assets/icons/auto_app_in_simulator.png b/docs/html/auto/images/assets/icons/auto_app_in_simulator.png
new file mode 100644
index 0000000..085b82b
--- /dev/null
+++ b/docs/html/auto/images/assets/icons/auto_app_in_simulator.png
Binary files differ
diff --git a/docs/html/auto/images/assets/icons/gp-auto-quality.png.png b/docs/html/auto/images/assets/icons/gp-auto-quality.png.png
new file mode 100644
index 0000000..483f418
--- /dev/null
+++ b/docs/html/auto/images/assets/icons/gp-auto-quality.png.png
Binary files differ
diff --git a/docs/html/auto/images/assets/icons/media_app_playback.png b/docs/html/auto/images/assets/icons/media_app_playback.png
new file mode 100644
index 0000000..3de04bf
--- /dev/null
+++ b/docs/html/auto/images/assets/icons/media_app_playback.png
Binary files differ
diff --git a/docs/html/auto/images/assets/icons/messaging_app_notifications.png b/docs/html/auto/images/assets/icons/messaging_app_notifications.png
new file mode 100644
index 0000000..3236fdf
--- /dev/null
+++ b/docs/html/auto/images/assets/icons/messaging_app_notifications.png
Binary files differ
diff --git a/docs/html/auto/images/assets/landing/01.gif b/docs/html/auto/images/assets/landing/01.gif
new file mode 100644
index 0000000..34c9fa8
--- /dev/null
+++ b/docs/html/auto/images/assets/landing/01.gif
Binary files differ
diff --git a/docs/html/auto/images/assets/landing/02.gif b/docs/html/auto/images/assets/landing/02.gif
new file mode 100644
index 0000000..d50e06b
--- /dev/null
+++ b/docs/html/auto/images/assets/landing/02.gif
Binary files differ
diff --git a/docs/html/auto/images/assets/landing/03.gif b/docs/html/auto/images/assets/landing/03.gif
new file mode 100644
index 0000000..7992021
--- /dev/null
+++ b/docs/html/auto/images/assets/landing/03.gif
Binary files differ
diff --git a/docs/html/auto/images/assets/landing/04.png b/docs/html/auto/images/assets/landing/04.png
new file mode 100644
index 0000000..a0e75f3
--- /dev/null
+++ b/docs/html/auto/images/assets/landing/04.png
Binary files differ
diff --git a/docs/html/auto/images/assets/landing/05.png b/docs/html/auto/images/assets/landing/05.png
new file mode 100644
index 0000000..f3d2ab8
--- /dev/null
+++ b/docs/html/auto/images/assets/landing/05.png
Binary files differ
diff --git a/docs/html/auto/images/assets/landing/06.png b/docs/html/auto/images/assets/landing/06.png
new file mode 100644
index 0000000..b19a6bb
--- /dev/null
+++ b/docs/html/auto/images/assets/landing/06.png
Binary files differ
diff --git a/docs/html/auto/images/assets/landing/07.png b/docs/html/auto/images/assets/landing/07.png
new file mode 100644
index 0000000..380e8da
--- /dev/null
+++ b/docs/html/auto/images/assets/landing/07.png
Binary files differ
diff --git a/docs/html/auto/images/assets/landing/08.png b/docs/html/auto/images/assets/landing/08.png
new file mode 100644
index 0000000..9889b39
--- /dev/null
+++ b/docs/html/auto/images/assets/landing/08.png
Binary files differ
diff --git a/docs/html/auto/images/assets/landing/FrameA.png b/docs/html/auto/images/assets/landing/FrameA.png
new file mode 100644
index 0000000..2a78380
--- /dev/null
+++ b/docs/html/auto/images/assets/landing/FrameA.png
Binary files differ
diff --git a/docs/html/auto/images/assets/landing/FrameB.png b/docs/html/auto/images/assets/landing/FrameB.png
new file mode 100644
index 0000000..cb7a3c4
--- /dev/null
+++ b/docs/html/auto/images/assets/landing/FrameB.png
Binary files differ
diff --git a/docs/html/auto/images/logos/apps/TextMe.png b/docs/html/auto/images/logos/apps/TextMe.png
new file mode 100644
index 0000000..b96f81a
--- /dev/null
+++ b/docs/html/auto/images/logos/apps/TextMe.png
Binary files differ
diff --git a/docs/html/auto/images/logos/apps/kik.png b/docs/html/auto/images/logos/apps/kik.png
new file mode 100644
index 0000000..056ef7e5
--- /dev/null
+++ b/docs/html/auto/images/logos/apps/kik.png
Binary files differ
diff --git a/docs/html/auto/images/logos/apps/npr.png b/docs/html/auto/images/logos/apps/npr.png
new file mode 100644
index 0000000..5234201
--- /dev/null
+++ b/docs/html/auto/images/logos/apps/npr.png
Binary files differ
diff --git a/docs/html/auto/images/logos/apps/soundcloud.png b/docs/html/auto/images/logos/apps/soundcloud.png
new file mode 100644
index 0000000..a5bdbe3
--- /dev/null
+++ b/docs/html/auto/images/logos/apps/soundcloud.png
Binary files differ
diff --git a/docs/html/auto/images/logos/apps/textplus.png b/docs/html/auto/images/logos/apps/textplus.png
new file mode 100644
index 0000000..2a640c4
--- /dev/null
+++ b/docs/html/auto/images/logos/apps/textplus.png
Binary files differ
diff --git a/docs/html/auto/images/logos/apps/whatsapp.png b/docs/html/auto/images/logos/apps/whatsapp.png
new file mode 100644
index 0000000..fb5866e
--- /dev/null
+++ b/docs/html/auto/images/logos/apps/whatsapp.png
Binary files differ
diff --git a/docs/html/auto/images/ui/gearhead_custom_UI.png b/docs/html/auto/images/ui/gearhead_custom_UI.png
new file mode 100644
index 0000000..345db12
--- /dev/null
+++ b/docs/html/auto/images/ui/gearhead_custom_UI.png
Binary files differ
diff --git a/docs/html/auto/images/ui/gearhead_custom_user_actions.png b/docs/html/auto/images/ui/gearhead_custom_user_actions.png
new file mode 100644
index 0000000..6cc0dcb
--- /dev/null
+++ b/docs/html/auto/images/ui/gearhead_custom_user_actions.png
Binary files differ
diff --git a/docs/html/auto/images/ui/gearhead_day.png b/docs/html/auto/images/ui/gearhead_day.png
new file mode 100644
index 0000000..81ead75
--- /dev/null
+++ b/docs/html/auto/images/ui/gearhead_day.png
Binary files differ
diff --git a/docs/html/auto/images/ui/gearhead_drawer_generic.png b/docs/html/auto/images/ui/gearhead_drawer_generic.png
new file mode 100644
index 0000000..d203aed
--- /dev/null
+++ b/docs/html/auto/images/ui/gearhead_drawer_generic.png
Binary files differ
diff --git a/docs/html/auto/images/ui/gearhead_drawers_customized.png b/docs/html/auto/images/ui/gearhead_drawers_customized.png
new file mode 100644
index 0000000..44915b5
--- /dev/null
+++ b/docs/html/auto/images/ui/gearhead_drawers_customized.png
Binary files differ
diff --git a/docs/html/auto/images/ui/gearhead_generic_UI.png b/docs/html/auto/images/ui/gearhead_generic_UI.png
new file mode 100644
index 0000000..beb0701
--- /dev/null
+++ b/docs/html/auto/images/ui/gearhead_generic_UI.png
Binary files differ
diff --git a/docs/html/auto/images/ui/gearhead_lens_switching.png b/docs/html/auto/images/ui/gearhead_lens_switching.png
new file mode 100644
index 0000000..9dbfe6c
--- /dev/null
+++ b/docs/html/auto/images/ui/gearhead_lens_switching.png
Binary files differ
diff --git a/docs/html/auto/images/ui/gearhead_night.png b/docs/html/auto/images/ui/gearhead_night.png
new file mode 100644
index 0000000..3f8c593
--- /dev/null
+++ b/docs/html/auto/images/ui/gearhead_night.png
Binary files differ
diff --git a/docs/html/auto/images/ui/gearhead_overview.png b/docs/html/auto/images/ui/gearhead_overview.png
new file mode 100644
index 0000000..4332ddf3
--- /dev/null
+++ b/docs/html/auto/images/ui/gearhead_overview.png
Binary files differ
diff --git a/docs/html/auto/index.jd b/docs/html/auto/index.jd
index 63ac287..129478a 100644
--- a/docs/html/auto/index.jd
+++ b/docs/html/auto/index.jd
@@ -77,17 +77,20 @@
             <div class="col-10">
               <div class="landing-section-header">
                 <div class="landing-h1 hero">Android Auto</div>
-                <div class="landing-subhead hero">Entertainment and services on your dashboard</div>
+                <div class="landing-subhead hero">Audio entertainment and
+                  messaging services in the car</div>
                 <div class="landing-hero-description">
-                  <p style="width:450px">Display and control your Android app in vehicles.
-                   Integrate your content with easy-to-use APIs and let Android Auto take
-                   care of the rest.</p>
+                  <p style="width:450px">Let drivers listen to and control
+                    content in your music and other audio apps. Allow drivers to
+                    hear and respond to your messaging service via the
+                    car's controls and screen.</p>
                 </div>
 
               <div class="landing-body">
-                <a href="{@docRoot}auto/overview.html" class="landing-button landing-primary"
+                <a href="{@docRoot}training/auto/index.html"
+                   class="landing-button landing-primary"
                    style="margin-top:40px;">
-                  Developer Overview
+                  Get Started
                 </a>
               </div>
             </div>
@@ -103,149 +106,114 @@
     </div> <!-- end .landing-section .landing-hero -->
   </div> <!-- end .landing-hero-container -->
 
-    <div class="landing-rest-of-page">
+  <div class="landing-rest-of-page">
 
-      <div class="landing-section landing-gray-background" id="android-in-car">
-        <div class="wrap">
-          <div class="landing-section-h1">
-            <div class="landing-h1">Extending Android to Cars</div>
-          </div>
-          <div class="landing-body">
-            <div class="landing-subhead">Android Auto brings the Android experience to
-            cars with apps like Google Now and Maps.</div>
-            <div class="cols">
-              <div class="col-8">
-                <div class="auto-img-container-cols">
-                  <img class="auto-img-frame-cols" src="{@docRoot}auto/images/assets/00_frame.png" />
-                  <img class="auto-img-shot-cols" src="{@docRoot}auto/images/assets/01_b_now.png" />
-                </div>
-              </div>
-              <div class="col-8">
-                <div class="auto-img-container-cols">
-                  <img class="auto-img-frame-cols" src="{@docRoot}auto/images/assets/00_frame.png" />
-                  <img class="auto-img-shot-cols" src="{@docRoot}auto/images/assets/01_a_maps.png" />
-                </div>
+    <div class="landing-section landing-gray-background" id="android-in-car">
+      <div class="wrap">
+        <div class="landing-section-h1">
+          <div class="landing-h1">Extending Android to Cars</div>
+          <div class="landing-subhead">Android Auto brings the Android
+              platform into the car with a user interface that's optimized for driving.</div>
+        </div>
+
+        <div class="landing-body">
+          <div class="cols">
+            <div class="col-8">
+              <div class="auto-img-container-cols">
+                <img class="auto-img-frame-cols" src="/auto/images/assets/landing/FrameA.png" />
+                <img class="auto-img-shot-cols" src="/auto/images/assets/landing/01.gif" />
               </div>
             </div>
-
-            <p>When users connect their Android phones to compatible vehicles, Android Auto
-             shows a standard interface that lets them start enabled apps and services.
-             Android Auto locks the handheld device when connected, so drivers
-            interact with Auto by using the vehicle's input controls, touch display, and voice.</p>
-            </p>
+            <div class="col-8">
+              <div class="auto-img-container-cols">
+                <img class="auto-img-frame-cols" src="/auto/images/assets/landing/FrameA.png" />
+                <img class="auto-img-shot-cols" src="/auto/images/assets/landing/02.gif" />
+              </div>
+            </div>
           </div>
-        </div> <!-- end .wrap -->
-      </div> <!-- end .landing-section -->
+          <p>Before you start building, check out the
+              <a href="http://youtu.be/ctiaVxgclsg" class="external-link">Introduction to Android Auto</a> video to understand how
+              users see and interact with your app in Android Auto.
+          </p>
+        </div>
+      </div> <!-- end .wrap -->
+    </div> <!-- end .landing-section -->
 
-
-      <div class="landing-section">
+    <div class="landing-section">
         <div class="wrap">
           <div class="landing-section-header">
             <div class="landing-h1">Build for One Platform</div>
-            <div class="landing-subhead">Create apps with the Android APIs you're familiar with
-            and extend them to cars with the Auto SDK.
+            <div class="landing-subhead">Create apps with the Android APIs
+              you’re familiar with and extend them to cars.
             </div>
           </div>
 
           <div class="landing-body">
-
-            <div class="cols">
-              <div class="col-8">
-                <div class="auto-img-container-cols">
-                  <img class="auto-img-frame-cols" src="{@docRoot}auto/images/assets/00_frame.png" />
-                  <img class="auto-img-shot-cols" src="{@docRoot}auto/images/assets/02_b_switcher.gif" />
-                </div>
-              </div>
-              <div class="col-8">
-                <div class="auto-img-container-cols">
-                  <img class="auto-img-frame-cols" src="{@docRoot}auto/images/assets/00_frame.png" />
-                  <img class="auto-img-shot-cols" src="{@docRoot}auto/images/assets/02_a_notif.gif" />
-                </div>
-              </div>
-            </div>
-            <p>Write your apps without having
-            to worry about vehicle-specific hardware differences like screen resolution, software
-            interfaces, knobs, and touch controls. Your users get the same experience on any compatible
-            vehicle such as a consistent app launcher and system events such as notifications.</p>
-          </div>
-        </div> <!-- end .wrap -->
-      </div> <!-- end .landing-section -->
-
-
-      <div class="landing-section landing-gray-background">
-        <div class="wrap">
-          <div class="landing-section-header">
-            <div class="landing-h1">Minimize Distraction</div>
-            <div class="landing-subhead">
-             Android Auto displays different UIs for several app categories that let users focus on the road.
-            </div>
-          </div>
-          <div class="landing-body">
             <div class="cols">
               <div class="col-8">
                 <div class="auto-img-container-cols">
-                  <img class="auto-img-frame-cols" src="{@docRoot}auto/images/assets/00_frame.png" />
-                  <img class="auto-img-shot-cols" src="{@docRoot}auto/images/assets/03_b_voice.gif" />
+                  <img class="auto-img-frame-cols" src="/auto/images/assets/landing/FrameA.png" />
+                  <img class="auto-img-shot-cols" src="/auto/images/assets/landing/05.png" />
                 </div>
               </div>
               <div class="col-8">
                 <div class="auto-img-container-cols">
-                  <img class="auto-img-frame-cols" src="{@docRoot}auto/images/assets/00_frame.png" />
-                  <img class="auto-img-shot-cols" src="{@docRoot}auto/images/assets/03_a_musict.png" />
+                  <img class="auto-img-frame-cols" src="/auto/images/assets/landing/FrameA.png" />
+                  <img class="auto-img-shot-cols" src="/auto/images/assets/landing/06.png" />
                 </div>
               </div>
             </div>
-            <p>Android Auto defines the user interaction model for all
-             apps and let you hook into a standard UI with touch and voice controls. The interface
-             is designed to reduce driver distraction while still letting you customize and brand them to properly deliver your content.
-             </p>
+            <p>Write your apps without having to worry about vehicle-specific
+            hardware differences like screen resolution, software interfaces,
+            knobs, and touch controls. Your users get the same experience on any
+            compatible vehicle such as a consistent app launcher and system
+            events such as notifications.</p>
           </div>
         </div> <!-- end .wrap -->
       </div> <!-- end .landing-section -->
 
-      <div class="landing-section" style="background-color:#f5f5f5">
+    <div class="landing-section" style="background-color:#f5f5f5" id="developing-for-auto">
         <div class="wrap">
           <div class="landing-section-header">
-            <div class="landing-pre-h1">Coming soon</div>
-            <div class="landing-h1">Android Auto SDK</div>
+            <div class="landing-pre-h1">Now Available</div>
+            <div class="landing-h1">Developing for Android Auto</div>
+            <div class="landing-subhead">The APIs for building Auto-enabled apps
+              are available now! When connected to compatible vehicles, apps on
+              handheld devices running Android 5.0 or higher can communicate
+              with Android Auto.</div>
           </div>
 
           <div class="landing-body">
-            <p>In the coming months, we’ll be releasing the Android Auto SDK, which includes APIs
-              and tools to make your existing apps compatible with Android Auto. The first version
-              of the SDK will provide APIs for music, podcast, live radio, and audio
-              news apps, as well as limited voice actions.</p>
-
-            <div class="cols" style="margin-top:40px">
-              <div class="col-3-wide">
-                <p class="sdk-link-title">Updates</p>
-                <p class="sdk-link-desc">
-                  Register to receive more information and be notified when the SDK is available.
+            <div class="cols">
+              <div class="col-8">
+                <div class="auto-img-container-cols">
+                  <img class="auto-img-frame-cols" src="/auto/images/assets/landing/FrameA.png" />
+                  <img class="auto-img-shot-cols" src="/auto/images/assets/landing/03.gif" />
+                </div>
+                <div class="landing-h3">Play Music on the Road from Your App</div>
+                <p class="landing-small" style="padding-left:0px; padding-top:15px;">
+                  Extend audio apps such as music, radio, and audiobook players
+                  into the car. Build apps that let users browse and play their
+                  music in the car.<br><a href="{@docRoot}training/auto/audio/index.html">Learn how to build audio apps</a>
                 </p>
-                <a class="sdk-link" href="https://docs.google.com/a/google.com/forms/d/1ANgYOoYLkfyZ2JRPSU34Nep5yNaU-Ha2syXJ9b4xLrA/viewform">Sign up for updates</a>
               </div>
-              <div class="col-3-wide">
-                <p class="sdk-link-title">Google+ Community</p>
-                <p class="sdk-link-desc">
-                  Stay involved, get updates, and exchange experiences with other developers.
+              <div class="col-8">
+                <div class="auto-img-container-cols">
+                  <img class="auto-img-frame-cols" src="/auto/images/assets/landing/FrameA.png" />
+                  <img class="auto-img-shot-cols" src="/auto/images/assets/landing/04.png" />
+                </div>
+                <div class="landing-h3">Keep Users Connected with In-Vehicle Messaging</div>
+                <p class="landing-small" style="padding-left:0px; padding-top:15px;">
+                  Create messaging apps that receive incoming notifications,
+                  read messages via text-to-speech, and let users reply by voice
+                  input in the car.<br><a href="{@docRoot}training/auto/messaging/index.html">Learn how to build messaging apps</a>
                 </p>
-                <a class="sdk-link" href="http://g.co/androidautodev">Discuss on Google+</a>
-              </div>
-              <div class="col-3-wide">
-                <p class="sdk-link-title">Developer Overview</p>
-                <p class="sdk-link-desc">
-                  Learn more about developing apps for Android Auto when the SDK is available.
-                </p>
-                <a class="sdk-link" href="{@docRoot}auto/overview.html">Learn about the platform</a>
               </div>
             </div>
           </div>
-
         </div> <!-- end .wrap -->
       </div> <!-- end .landing-section -->
 
-
-
       <div class="landing-section landing-gray-background" >
         <div class="wrap">
           <div class="landing-section-header">
@@ -255,15 +223,25 @@
           </div>
           <div class="landing-body">
           <div class="cols">
-
+            <div class="col-4">
+              <img src="{@docRoot}auto/images/logos/apps/iheartradio.png"
+                   width="160" height="160" class="img-logo" />
+            </div>
             <div class="col-4">
               <img src="{@docRoot}auto/images/logos/apps/joyride.png"
                    width="160" height="160" class="img-logo" />
             </div>
             <div class="col-4">
+              <img src="{@docRoot}auto/images/logos/apps/kik.png"
+                   width="120" height="120" class="img-logo" style="margin-top:30px" />
+            </div>
+            <div class="col-4">
               <img src="{@docRoot}auto/images/logos/apps/mlb.png"
                    width="160" height="160" class="img-logo" />
             </div>
+          </div>
+
+          <div class="cols">
             <div class="col-4">
               <img src="{@docRoot}auto/images/logos/apps/pandora.png"
                    width="160" height="160" class="img-logo" />
@@ -272,43 +250,75 @@
               <img src="{@docRoot}auto/images/logos/apps/pocketcasts.png"
                    width="160" height="160" class="img-logo" />
             </div>
-          </div>
-          <div class="cols">
             <div class="col-4">
               <img src="{@docRoot}auto/images/logos/apps/songza.png"
                    width="160" height="160" class="img-logo" />
             </div>
             <div class="col-4">
+              <img src="/auto/images/logos/apps/soundcloud.png"
+                   width="100" height="100" class="img-logo"
+                   style="margin-top:30px" />
+            </div>
+          </div>
+
+          <div class="cols">
+            <div class="col-4">
+              <img src="/auto/images/logos/apps/spotify.png"
+                   width="160" height="160" class="img-logo" />
+            </div>
+            <div class="col-4">
               <img src="{@docRoot}auto/images/logos/apps/stitcher.png"
                    width="160" height="160" class="img-logo" />
             </div>
             <div class="col-4">
+              <img src="/auto/images/logos/apps/TextMe.png"
+                   width="100" height="100" class="img-logo" style="margin-top:30px" />
+            </div>
+            <div class="col-4">
+              <img src="/auto/images/logos/apps/textplus.png"
+                   width="120" height="24" class="img-logo" style="margin-top:70px" />
+            </div>
+          </div>
+
+          <div class="cols">
+            <div class="col-4">
               <img src="{@docRoot}auto/images/logos/apps/tunein.png"
-                   width="160" height="160" class="img-logo" />
+                   width="160" height="160" class="img-logo" style="margin-left:160px" />
             </div>
             <div class="col-4">
               <img src="{@docRoot}auto/images/logos/apps/umano.png"
-                   width="160" height="160" class="img-logo" />
+                   width="160" height="160" class="img-logo" style="margin-left:370px" />
             </div>
           </div>
+
           <div class="cols" style="margin-top:40px">
               <div class="col-4">
-                <img src="{@docRoot}auto/images/logos/apps/iheartradio.png"
-                     width="160" height="160" class="img-logo" />
+                <img src="/auto/images/logos/apps/whatsapp.png"
+                     width="120" height="120" class="img-logo" />
               </div>
-              <div class="col-12">
+              <div class="col-8">
                 <p><em>
-                "The Android Auto APIs provide an easy way to integrate the most important features and functionality of iHeartRadio’s robust music service into a safety-minded automotive infotainment solution. The process was seamless, utilizing a flexible construct that allowed us to quickly adapt our existing product without losing any of the core experience our listeners know and love."</em></p>
+                "We were able to get messaging functionality for text
+                implemented easily on Android Auto, with minimal development
+                effort. We're excited to participate in Android Auto which
+                provides a notification interface for the car that is both
+                user-friendly and highly safety-minded."</em></p>
               </div>
           </div>
+
           <div class="cols" style="margin-top:60px">
 
               <div class="col-4">
-                <img src="{@docRoot}auto/images/logos/apps/spotify.png"
-                     width="160" height="160" class="img-logo" />
+                <img src="/auto/images/logos/apps/npr.png"
+                     width="100" height="128" class="img-logo" />
               </div>
-              <div class="col-12"><p style="margin-top:20px"><em>
-              "Android Auto offers Spotify the exciting opportunity to easily enable safe access to millions of songs while driving. We were able to quickly develop for the platform using the new Android voice and media API extensions. As a result, Android users will soon be able to continue the Spotify experience in their cars, including being able to play any song, artist, album or playlist by voice.</em></p>
+              <div class="col-8"><p style="margin-top:0px"><em>
+              "Android Auto connects NPR One listeners to a personalized stream
+              of public radio news and stories to catch up on in the car. It's
+              an engaging and driver-safe user experience that was developed
+              using the media APIs provided in Android 5.0. The available
+              development tools made the integration and testing process simple
+              for launching in a short period of time."</em></p>
               </div>
               </div>
           </div>
@@ -316,8 +326,6 @@
       </div> <!-- end .landing-section -->
 
 
-
-
       <div class="landing-section landing-white-background">
         <div class="wrap">
           <div class="landing-section-header">
@@ -456,24 +464,47 @@
           </div>
         </div>
       </div>
-    </div> <!-- end .landing-rest-of-page -->
-    <div class="content-footer wrap" itemscope="" itemtype="http://schema.org/SiteNavigationElement"
-    style="border-top: none;">
-      <div class="layout-content-col col-16" style="padding-top:4px">
-        <style>#___plusone_0 {float:right !important;}</style>
-        <div class="g-plusone" data-size="medium"></div>
+
+      <div class="landing-section landing-red-background">
+        <div class="wrap">
+          <div class="landing-section-header">
+            <div class="landing-h1 landing-align-left">Get Started with Android Auto</div>
+
+            <div class="landing-subhead landing-subhead-red">
+              <p>
+                Set up your development environment and start working with the APIs.
+                We’re excited about the experiences you'll create and can't
+                wait to see what you do next.</p>
+            </div>
+          </div>
+          <div class="landing-body">
+            <a href="{@docRoot}training/auto/index.html"
+            class="landing-button landing-primary" style="margin-top: 20px;">
+              Get Started
+            </a>
+          </div>
+        </div>
       </div>
+  </div>
+  <div class="content-footer wrap" itemscope="" itemtype="http://schema.org/SiteNavigationElement"
+    style="border-top: none;">
+
+    <div class="layout-content-col col-16" style="padding-top:4px">
+      <style>#___plusone_0 {float:right !important;}</style>
+      <div class="g-plusone" data-size="medium"></div>
     </div>
-    <div id="footer" class="wrap" style="width:940px;position:relative;top:-35px;z-index:-1">
-      <div id="copyright">
+  </div>
+
+  <div id="footer" class="wrap" style="width:940px;position:relative;top:-35px;z-index:-1">
+    <div id="copyright">
         Except as noted, this content is
         licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
         Creative Commons Attribution 2.5</a>. For details and
         restrictions, see the <a href="{@docRoot}license.html">Content
         License</a>.
-      </div>
     </div>
-  </div> <!-- end .landing-hero-container -->
+  </div>
+</div> <!-- end .landing-hero-container -->
 
   <script>
   $("a.landing-down-arrow").on("click", function(e) {
diff --git a/docs/html/auto/overview.jd b/docs/html/auto/overview.jd
deleted file mode 100644
index ae1efec..0000000
--- a/docs/html/auto/overview.jd
+++ /dev/null
@@ -1,411 +0,0 @@
-fullpage=true
-page.viewport_width=970
-no_footer_links=true
-excludeFromSuggestions=true
-page.metaDescription=Android Auto
-
-@jd:body
-
-<style>
-.jd-descr {
-    height:auto;
-}
-#copyright {
-    margin-top:-35px;
-}
-.auto-img-container {
-  position:relative;
-}
-.auto-img-frame {
-  z-index:2;
-  position:relative;
-}
-.auto-img-shot {
-  position:absolute;
-  top:9px;
-  left:8px;
-  z-index:1;
-}
-.auto-img-container-cols {
-  position:relative;
-  margin-top:10px;
-}
-.auto-img-frame-cols {
-  width:380px;
-  z-index:2;
-  position:relative;
-}
-.auto-img-shot-cols {
-  width:369px;
-  position:absolute;
-  top:7px;
-  left:6px;
-  z-index:1;
-}
-.auto-col-2 {
-  width:380px;
-  display: inline;
-  float: left;
-  margin-left: 10px;
-  margin-right: 10px;
-}
-.auto-img-container-single {
-  width:380px;
-  margin:0 auto;
-  margin-top:20px;
-}
-</style>
-
-<div style="width:780px; margin:0 auto;">
-
-<div id="qv-wrapper">
-<div id="qv">
-<h2>In this document</h2>
-<ol>
-  <li><a href="#design">Design</a>
-    <ol>
-      <li><a href="#designprinciples">Design Principles</a></li>
-      <li><a href="#uioverview">UI Overview</a></li>
-    </ol>
-  </li>
-  <li><a href="#architecture">Architecture</a></li>
-  <li><a href="#ui">User Interface</a>
-    <ol>
-      <li><a href="#launchapp">Launch App</a></li>
-      <li><a href="#useractions">User Actions</a></li>
-      <li><a href="#drawertransitions">Drawer Transitions</a></li>
-      <li><a href="#daynighttransitions">Day and Night Transitions</a></li>
-      <li><a href="#customizeui">Customizing the UI</a></li>
-    </ol>
-  </li>
-  <li><a href="#devprocess">Development Process</a></li>
-  <li><a href="#emulator">Testing Your App</a></li>
-  <li><a href="#running">Running Your App</a></li>
-</ol>
-</div>
-</div>
-
-<h1>Android Auto Developer Overview</h1>
-
-<p>Android Auto extends the Android platform into the car. When users connect
-their Android handheld device to a compatible vehicle, Android Auto provides a car-optimized
-Android experience on the vehicle's screen. Users interact with compatible apps and services
-through voice actions and the vehicle's input controls.</p>
-
-<p>The Android Auto SDK lets you easily extend your existing apps to work in the car, without
-having to worry about vehicle-specific hardware differences. You can use many Android APIs and
-services you are already familiar with. Android Auto provides an easy to use UI model and
-supports notifications and voice actions:</p>
-
-<dl>
-<dt style="margin-bottom:10px"><strong>Media UI</strong></dt>
-<dd style="margin-bottom:20px">
-Android Auto defines interaction models and car-specific UI patterns for apps. The
-first version of Android Auto supports media apps, such as music, podcast, live radio, and
-audio news apps.
-</dd>
-<dt style="margin-bottom:10px"><strong>Notifications</strong></dt>
-<dd style="margin-bottom:20px">
-The platform will integrate with existing Android APIs for notifications. Users will get
-car appropiate notifications from Android apps on the vehicle's screen.</dd>
-
-<dt style="margin-bottom:10px"><strong>Voice Actions</strong></dt>
-<dd style="margin-bottom:20px">
-Android Auto supports a set of voice actions to interact with compatible apps and services.
-Apps can respond to the voice actions they're interested in, such as playing a particular song
-or taking a note.</dd>
-
-<dt style="margin-bottom:10px"><strong>Easy Development Workflow</strong></dt>
-<dd style="margin-bottom:20px">
-To extend an existing Android app for Android Auto, you implement a set of interfaces and
-services defined in the platform. You can reuse existing functionality and many Android APIs
-you already know.</dd>
-</dl>
-
-<p>We’ll release the Android Auto SDK in the coming months, which will let you test your
-Android Auto experience on a regular Android device.</p>
-
-
-<h2 id="design">Design</h2>
-
-<p>Android Auto extends users' digital ecosystem into their cars, allowing drivers to stay
-connected to their virtual worlds while staying focused on the road ahead.</p>
-
-<p>Because driving is the primary activity in the car, any digital experiences should be designed
-to complement and augment that activity. They should never demand the user's attention.</p>
-
-<p>Designing for cars is fundamentally different than designing for phones or tablets, and
-requires rethinking how experiences unfold. Because attention is limited and not all tasks are
-possible in the car, effective apps leverage the entire set of devices that drivers have,
-leveraging the app experience on those devices, outside of the car, to set the stage for simple
-experiences while driving.</p>
-
-<p>Android Auto experiences are:</p>
-
-<p><strong>Glanceable and simple</strong>. Driving requires users' full attention. In-car software
-should not. Android Auto was designed to simplify not only the UI, but to optimize interactions
-and require less thinking, induce lower cognitive load, and ultimately, be safer. Effective apps
-provide just enough information in the minimum amount of time the user needs to glance at it and
-return their attention back to the road. Apps should also reduce the number of features to only
-those that are safe and drive-appropriate.</p>
-
-<p><strong>Predictive, yet predictable</strong>. Android Auto leverages rich, contextual awareness
-to keep the driver informed about important situations during the drive. Rich, timely help is
-combined with predictable functions. Effective apps make use of the patterns for common tasks and
-show timely information only when relevant.</p>
-
-<p><strong>Connected</strong>. By leveraging the user's personal ecosystem of apps and services,
-Android Auto promotes a continuous experience from phone to car to other devices. The user's
-music, destinations, and virtual ecosystem are always available to augment the drive. Experiences
-that leverage personal context and other devices are naturally part of Android Auto.</p>
-
-<p><strong>Naturally integrated</strong>. Android Auto blends the user's apps with the car,
-creating a truly integrated experience that leverages what is unique about each car. By using
-the screens, controls, and capabilities of the vehicle, Android Auto feels like an extension of
-the car.</p>
-
-
-
-
-<h2 id="architecture">Architecture</h2>
-
-<p>The Android Auto app shows your app's customized UI on the vehicle's screen. To communicate
-with the Android Auto app, your media app implements a set of media interfaces.</p>
-
-<div style="width:750px;margin:0 auto">
-<img src="{@docRoot}auto/images/figure01.png" alt="" />
-<p class="img-caption">
-  <strong>Figure 1</strong> - Architecture of Android Auto.
-</p>
-</div>
-
-<p>The architecture consists of the following components:</p>
-
-<p><strong>Media App</strong> - Runs a media service that exposes content through browsing and
-playback APIs. The service provides content to the Android Auto app. This is your Android app.</p>
-
-<p><strong>Android Auto App</strong> - Creates the UI and handles user interactions.
-This app uses a media client to request content from the media service running in the media
-app. The client requests data from the media service and monitors service states.</p>
-
-<p><strong>Vehicle Display</strong> - Shows app content and supports user interaction via
-on-screen soft buttons and other components, such as physical buttons or steering
-wheel controls.</p>
-
-<p>Android media apps must implement binders to these APIs:</p>
-
-<ul>
-<li><strong>Browsing</strong> - Enables a media client to browse a hierarchy of a user’s
-media collection, presented as a virtual file system with containers (similar to directories)
-and items (similar to files).</li>
-<li><strong>Playback</strong> - Enables a media client to control media playback and monitor
-playback state through callbacks.</li>
-</ul>
-
-
-<h2 id="ui">User Interface</h2>
-
-<p>The Android Auto app uses a car-specific UI model to display content and user interaction
-opportunities. Android Auto provides you with a standard UI designed to minimize driver
-distraction. You do not have to test a custom UI for driver distraction, which is a
-lengthy and expensive process involving multiple legislations across the globe and different
-standards for each vehicle OEM.</p>
-
-<p>The UI defines interfaces for browsing, searching, and listening to content from
-media apps. You can customize the UI colors, action icons, background images, and more.</p>
-
-<h3 id="launchapp">Launcher</h3>
-
-<p>The launcher shows all the compatible media apps installed on the user’s
-Android device and lets users select one of them from a scrollable list:</p>
-
-<div class="auto-img-container-single">
-  <div class="auto-img-container">
-    <img class="auto-img-frame-cols" src="/auto/images/assets/00_frame.png" />
-    <img class="auto-img-shot-cols" src="/auto/images/assets/do_01_switcher.png" />
-  </div>
-  <p class="img-caption" style="margin-top:0px">
-    <strong>Figure 2.</strong> The launcher.
-  </p>
-</div>
-
-<h3>Primary App UI</h3>
-
-<p>After the user selects a media app, the display shows the primary app UI.
-You can customize this UI to show your own icons, app name, and
-background images. Figure 3 shows an example of a customized UI:</p>
-
-<div class="cols">
-<div class="auto-col-2">
-  <div class="auto-img-container-cols">
-    <img class="auto-img-frame-cols" src="{@docRoot}auto/images/assets/00_frame.png" />
-    <img class="auto-img-shot-cols" src="{@docRoot}auto/images/assets/do_05_template.png" />
-  </div>
-</div>
-<div class="auto-col-2">
-  <div class="auto-img-container-cols">
-    <img class="auto-img-frame-cols" src="{@docRoot}auto/images/assets/00_frame.png" />
-    <img class="auto-img-shot-cols" src="{@docRoot}auto/images/assets/do_02_music.png" />
-  </div>
-</div>
-</div>
-<p class="img-caption">
-  <strong>Figure 3.</strong> A customized UI.
-</p>
-
-
-
-<h3 id="useractions">User Actions</h3>
-
-<p>The primary app UI supports four main actions on the action bar, four auxiliary actions
-on the overflow bar, and the <em>Return</em> action. You can use standard controls and customize
-the actions and icons, as shown in Figure 4.</p>
-
-<div class="auto-img-container-single">
-  <div class="auto-img-container">
-    <img class="auto-img-frame-cols" src="/auto/images/assets/00_frame.png" />
-    <img class="auto-img-shot-cols" src="/auto/images/assets/do_03_more.png" />
-  </div>
-  <p class="img-caption" style="margin-top:0px">
-    <strong>Figure 4.</strong> Custom extra actions.
-  </p>
-</div>
-
-<h3 id="drawertransitions">Drawer Transitions</h3>
-
-<p>For browse actions, the display shows the drawer transition as shown in Figure 5.</p>
-
-<div class="cols">
-<div class="auto-col-2">
-  <div class="auto-img-container-cols">
-    <img class="auto-img-frame-cols" src="{@docRoot}auto/images/assets/00_frame.png" />
-    <img class="auto-img-shot-cols" src="{@docRoot}auto/images/assets/do_06_gdrawer.png" />
-  </div>
-</div>
-<div class="auto-col-2">
-  <div class="auto-img-container-cols">
-    <img class="auto-img-frame-cols" src="{@docRoot}auto/images/assets/00_frame.png" />
-    <img class="auto-img-shot-cols" src="{@docRoot}auto/images/assets/do_04_mdrawer.png" />
-  </div>
-</div>
-</div>
-<p class="img-caption">
-  <strong>Figure 5.</strong> Generic and customized drawers.
-</p>
-
-<p>After the transition from the primary app UI to the drawer UI, the drawer
-appears on the center. The customized drawer UI shows the media containers and
-media files provided by the media service in your app. You can also customize drawers
-with icons for list items.</p>
-
-
-<h3 id="daynighttransitions">Day and Night Transitions</h3>
-
-<p>All the UIs support different color schemes for day and night.
-The platform provides the state (day or night) and makes adjustments automatically.</p>
-
-<div class="cols">
-<div class="auto-col-2">
-  <div class="auto-img-container-cols">
-    <img class="auto-img-frame-cols" src="{@docRoot}auto/images/assets/00_frame.png" />
-    <img class="auto-img-shot-cols" src="{@docRoot}auto/images/assets/do_02_music.png" />
-  </div>
-</div>
-<div class="auto-col-2">
-  <div class="auto-img-container-cols">
-    <img class="auto-img-frame-cols" src="{@docRoot}auto/images/assets/00_frame.png" />
-    <img class="auto-img-shot-cols" src="{@docRoot}auto/images/assets/do_02_music_night.png" />
-  </div>
-</div>
-</div>
-<p class="img-caption">
-  <strong>Figure 6.</strong> Day and night modes.
-</p>
-
-<h3 id="customizeui">Customizing UIs</h3>
-
-<p>To customize the UI, you provide the following app-specific resources and actions
-to the Android Auto media client:</p>
-
-<ul>
-<li><strong>Resources</strong> - App logo, app name, theme colors, and background images.</li>
-<li><strong>Actions</strong> - Multiple custom actions; for example: <em>Thumbs Up/Down</em>,
-<em>Favorite</em>, and <em>Bookmark</em>. These actions are app-specific.</li>
-</ul>
-
-<p>If provided, the media client automatically uses them in the UI.</p>
-
-
-<h2 id="devprocess">Development Process</h2>
-
-<p class="note"><strong>Note:</strong> When released, the Android Auto SDK will provide
-media service interfaces, an APK for handheld devices that simulates the Android Auto
-app, and other tools for Android Auto development.</p>
-
-<p>To create a media app for Android Auto, you include an Android service in your app
-that implements the media service interfaces provided by the Android Auto SDK. These
-interfaces define functionality for browsing and finding content, playing media,
-customizing the UI, and performing app-specific actions.</p>
-
-<p>The media service interfaces present the content library as a navigable tree and enable
-clients to play media, get album art, obtain theme resources for the UI, and
-invoke app-specific actions.</p>
-
-<p>You don’t have to create a new app for Android Auto: you can extend your existing
-Android app with implementations of the media service interfaces. Your service exposes
-your app’s media content, theme resources, and app-specific actions using the methods and
-data types specified by the media service interfaces. This simplifies the development
-cycle because:</p>
-
-<ul>
-<li>You do not have to maintain a separate project for Android Auto</li>
-<li>You can reuse existing functionality from your Android app</li>
-</ul>
-
-<p>The Android Auto client presents the customized UI to users and invokes the
-functionality from your service as needed. This has two additional advantages:</p>
-
-<ul>
-<li>Your app does not implement a UI for Android Auto</li>
-<li>Your app does not manage user interactions directly</li>
-</ul>
-
-<p>This also means that you do not have to worry about vehicle-specific hardware
-differences such as screen resolutions, software interfaces, knobs and touch
-controls.</p>
-
-
-<h2 id="emulator">Testing Your App on an Android Device</h2>
-
-<p>The Android Auto SDK includes an APK with a media client implementation, which is
-similar to those available in compatible vehicles. To test your app with this
-client:</p>
-
-<ol>
-<li>Get an Android device with a similar form factor to a dashboard screen (like a
-Nexus 7).</li>
-<li>Configure the device for Android development.</li>
-<li>Install the APK for the media client from the Android Auto SDK on the device.</li>
-<li>Install the APK for your app on the device.</li>
-<li>Open the media client app from the Android Auto SDK on the device.</li>
-<li>Select your app from the list of available services.</li>
-</ol>
-
-<p>The customized UI for your app appears on the client. You can navigate the content
-library and play media. If your app provides app-specific actions, these actions appear
-in the UI controls.</p>
-
-
-<h2 id="running">Running Your App on Android Auto</h2>
-
-<p>Media apps are available on the Google Play Store for compatible Android devices.
-When users connect their Android device to a compatible vehicle, the
-Android Auto media client shows a list of all the Android apps installed on the phone
-that implement the media service interfaces.</p>
-
-<p>When users select one of these apps, the Android Auto media client uses the app’s
-service to respond to user input and invoke the methods in the media service interfaces
-to build the UI, navigate the content library, and play media.</p>
-
-<div style="margin-bottom:40px"> </div>
-</div>
diff --git a/docs/html/design/auto/index.jd b/docs/html/design/auto/index.jd
index c970cac..e45bd36 100644
--- a/docs/html/design/auto/index.jd
+++ b/docs/html/design/auto/index.jd
@@ -1,35 +1,177 @@
-page.title=Android Auto
+page.title=Designing for Auto
+page.tags="design","Auto"
 @jd:body
 
-<style>
-.auto-img-container-cols {
-  position:relative;
-  margin-bottom:25px;
-  margin-top:25px;
-}
-.auto-img-frame-cols {
-  z-index:2;
-  position:relative;
-}
-.auto-img-shot-cols {
-  position:absolute;
-  top:5px;
-  left:2px;
-  z-index:1;
-}
-</style>
+<a class="notice-developers" href="{@docRoot}training/auto/index.html">
+  <div>
+    <h3>Developer Docs</h3>
+    <p>Building Apps for Auto</p>
+  </div>
+</a>
 
-<div class="auto-img-container-cols" style="float:right; margin:0 0 40px 40px;width:460px">
-  <img class="auto-img-frame-cols" src="/auto/images/assets/00_frame.png">
-  <img class="auto-img-shot-cols" src="/auto/images/assets/03_a_musict.png">
+<div class="sidebox-wrapper">
+<div class="sidebox">
+  <h2><strong>UI Guidelines</strong></h2>
+  <ul>
+  <li><a href="{@docRoot}shareables/auto/AndroidAuto-media-apps.pdf">
+    <strong>Auto Media Apps (PDF)</strong></a>
+  </li>
+  <li><a href="{@docRoot}shareables/auto/AndroidAuto-messaging-apps.pdf">
+    <strong>Auto Messaging Apps (PDF)</strong></a>
+  </li>
+  <li><a href="{@docRoot}shareables/auto/AndroidAuto-custom-colors.pdf">
+    <strong>Auto Color Customization (PDF)</strong></a>
+  </li>
+ </ul>
+</div>
 </div>
 
-<p>Android Auto is <strong>coming soon</strong> and brings apps to the car,
-integrating with the vehicle's input controls and display.</p>
+<p>Android Auto provide a standardized user interface and user interaction
+model that works across vehicles. As a designer, you do not
+need to worry about vehicle-specific hardware differences. This page
+describes some of the key screens that users will encounter in the
+Auto user interface. To dive deeper into how to design for
+the Auto user interface (UI), see the Auto UI guidelines in the sidebar.</p>
 
-<p>The future design guidelines provide templates that define the user interaction model for all apps and let you hook into a standard UI with touch and voice controls. The templates meet international best practices for reducing driver distraction while still letting you customize and brand them to properly deliver your content.</p>
+<p class="note"><strong>Important:</strong> Google takes driver distraction
+very seriously. There are specific design requirements your app must meet to
+qualify as an Auto app on Google Play. By adhering to these
+requirements, you can reduce the effort for building and testing your app. For
+more information, see <a href="{@docRoot}distribute/essentials/quality/auto.html">Auto App Quality</a>.</p>
 
-<p><a href="{@docRoot}auto/index.html">Learn more about Android Auto</a>.</p>
+<br>
+
+<h2 id="overview-screen">Overview Screen</h2>
+
+<p>When users first connect their Android device to the car, they are presented
+with the Overview screen. This screen displays contextual cards based on the
+user’s location, time of day, and so on. The user can also use this screen to view
+notifications from their messaging apps and select a message to send a response
+by voice input.</p>
+
+<div class="auto-img-container-single">
+  <div class="auto-img-container">
+    <img src="{@docRoot}auto/images/ui/gearhead_overview.png" alt="Overview screen" />
+  </div>
+  <p class="img-caption" style="margin-top:0px">
+    <strong>Figure 1.</strong> The Overview screen may show contextual cards and
+new messages.
+  </p>
+</div>
+
+<h2 id="launchapp">Audio App Launcher</h2>
+
+<p>Tapping on the headphones icon in the Activity Bar lets the
+  user see all audio apps installed on the user’s handheld device and select
+  one of them from a scrollable list.</p>
+
+<div class="auto-img-container-single">
+  <div class="auto-img-container">
+    <img src="{@docRoot}auto/images/ui/gearhead_lens_switching.png" alt="Launcher" />
+  </div>
+  <p class="img-caption" style="margin-top:0px">
+    <strong>Figure 2.</strong> The audio app launcher shows available audio apps.
+  </p>
+</div>
+
+<h2>Primary App UI</h2>
+
+<p>After the user selects an audio app, the display shows the primary app UI.
+Auto presents the app in a standardized UI, but you can customize
+this UI to show your own icons, app name, and background images
+(such as the album art).</p>
+
+<div class="auto-img-container-single">
+  <div class="auto-img-container">
+    <img src="{@docRoot}auto/images/ui/gearhead_generic_UI.png" alt="Generic audio app UI" />
+  </div>
+  <p class="img-caption" style="margin-top:0px">
+    <strong>Figure 3.</strong> Generic audio app UI.
+  </p>
+</div>
+
+<div class="auto-img-container-single">
+  <div class="auto-img-container">
+    <img src="{@docRoot}auto/images/ui/gearhead_custom_UI.png" alt="Customized audio app UI" />
+  </div>
+  <p class="img-caption" style="margin-top:0px">
+    <strong>Figure 4.</strong> Example of the Google Play Music app UI.
+  </p>
+</div>
+
+<h3 id="useractions">User Actions</h3>
+
+<p>The media control card in the primary app UI supports up to four main actions,
+four auxiliary actions on the overflow bar, and the <em>Return</em> action. You can
+use standard controls and customize the actions and icons.</p>
+
+<div class="auto-img-container-single">
+  <div class="auto-img-container">
+    <img src="{@docRoot}auto/images/ui/gearhead_custom_user_actions.png" alt="Customized user actions" />
+  </div>
+  <p class="img-caption" style="margin-top:0px">
+    <strong>Figure 5.</strong> Example of user actions in the Google Play Music app.
+  </p>
+</div>
+
+<h3 id="drawerlist">Drawer List</h3>
+
+<p>For browse actions, the display shows the drawer transition. After the
+transition from the primary app UI to the list UI, the drawer appears in the
+center. The customized list UI shows the media containers and the audio files
+provided by the media service in your app. You can also customize drawers with
+icons for list items.</p>
+
+<div class="auto-img-container-single">
+  <div class="auto-img-container">
+    <img src="{@docRoot}auto/images/ui/gearhead_drawer_generic.png"
+    alt="Generic drawers" style="border:3px solid black" />
+  </div>
+  <p class="img-caption" style="margin-top:0px">
+    <strong>Figure 6.</strong> Example of the drawer layout template with generic list items.
+  </p>
+</div>
+
+<div class="auto-img-container-single">
+  <div class="auto-img-container">
+    <img src="{@docRoot}auto/images/ui/gearhead_drawers_customized.png"
+    alt="Customized drawers" style="border:3px solid black" />
+  </div>
+  <p class="img-caption" style="margin-top:0px">
+    <strong>Figure 7.</strong> Example of the the drawer layout in the Google Play Music app.
+  </p>
+</div>
+
+
+<h2 id="daynighttransitions">Day and Night Transitions</h2>
+
+<p>All the UIs support different color schemes for day and night. The platform
+provides the state (day or night) and makes adjustments automatically.</p>
+
+<div class="auto-img-container-single">
+  <div class="auto-img-container">
+    <img src="{@docRoot}auto/images/ui/gearhead_day.png" alt="Audio app in day mode" />
+  </div>
+  <p class="img-caption" style="margin-top:0px">
+    <strong>Figure 8.</strong> Example of the Google Play Music app in day mode.
+  </p>
+</div>
+
+<div class="auto-img-container-single">
+  <div class="auto-img-container">
+    <img src="{@docRoot}auto/images/ui/gearhead_night.png" alt="Audio app in night mode" />
+  </div>
+  <p class="img-caption" style="margin-top:0px">
+    <strong>Figure 9.</strong> Example of the Google Play Music app in night mode.
+  </p>
+</div>
+
+<h3 class="rel-resources clearfloat">Related resources</h3>
+
+<div class="resource-widget resource-flow-layout col-13" data-query=
+"collection:design/auto/auto_ui_guidelines"
+data-sortorder="-timestamp" data-cardsizes="6x3" data-maxresults="6">
+</div>
 
 
 
diff --git a/docs/html/distribute/essentials/essentials_toc.cs b/docs/html/distribute/essentials/essentials_toc.cs
index a1c9575..985809a 100644
--- a/docs/html/distribute/essentials/essentials_toc.cs
+++ b/docs/html/distribute/essentials/essentials_toc.cs
@@ -22,6 +22,12 @@
           </a>
     </div>
   </li>
+    <li class="nav-section">
+    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/quality/auto.html">
+            <span class="en">Auto App Quality</span>
+          </a>
+    </div>
+  </li>
   <li class="nav-section">
     <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/optimizing-your-app.html">
           <span class="en">Optimize Your App</span>
diff --git a/docs/html/distribute/essentials/quality/auto.jd b/docs/html/distribute/essentials/quality/auto.jd
new file mode 100644
index 0000000..757305e
--- /dev/null
+++ b/docs/html/distribute/essentials/quality/auto.jd
@@ -0,0 +1,411 @@
+
+page.title=Auto App Quality
+page.metaDescription=Auto apps integrate with the vehicle's input controls and display and minimize driver distraction to create a great experience.
+page.image=/distribute/images/gp-auto-quality.png
+@jd:body
+
+<div id="qv-wrapper"><div id="qv">
+<h2>Quality Criteria</h2>
+  <ol>
+    <li><a href="#core">Core App Quality</a></li>
+    <li><a href="#ux">Visual Design and Interaction</a></li>
+    <li><a href="#fn">Functionality</a></li>
+    <li><a href="#faq">Frequently Asked Questions</a></li>
+  </ol>
+
+  <h2>You Should Also Read</h2>
+  <ol>
+    <li><a href="{@docRoot}distribute/essentials/quality/core.html">
+      Core App Quality</a></li>
+    <li><a href="{@docRoot}distribute/essentials/optimizing-your-app.html">
+      Optimize Your App</a></li>
+    <li><a href="{@docRoot}shareables/auto/AndroidAuto-media-apps.pdf">Android Auto UX Guidelines
+      for Media Applications</a></li>
+    <li><a href="{@docRoot}shareables/auto/AndroidAuto-messaging-apps.pdf">Android Auto UX Guidelines
+      for Messaging Applications</a></li>
+  </ol>
+</div>
+</div>
+
+
+  <img src="{@docRoot}distribute/images/gp-auto-quality.png" style="width:480px;">
+
+
+<p>When designing support for Android Auto in your app, avoid driver distraction above all else.
+  Apps that work with the Auto user interface should minimize distractions faced by the driver
+  through best practices such as voice commands and very simple visual design.
+</p>
+
+<p>
+  Great auto experiences are predictive and predictable.  Apps that support Android Auto
+  should show timely information to the driver only when it is relevant, and use
+  simple, predictable patterns for common tasks.
+</p>
+
+<p class="caution">
+  <strong>Important:</strong> The criteria listed in this page apply to your app's user interface 
+  and behavior when running on devices connected to an Android Auto screen. Apps must meet these 
+  criteria to qualify as an Android Auto app on Google Play.
+</p>
+
+
+<div class="headerLine">
+  <h2 id="core">
+  Core App Quality
+  </h2>
+
+<p>
+ In addition to the Auto-specific criteria listed below, Auto apps should meet all relevant core app
+ quality criteria for the Android platform, as detailed in the
+  <a href="{@docRoot}distribute/essentials/quality/core.html">Core App Quality</a> criteria. Test
+  your app against those criteria to ensure that they meet Android standards for navigation and
+  design. Then test your app against all Auto-specific criteria, keeping in mind
+  that, when running on a device connected to Android auto, your app must meet the requirements
+  listed in this page.
+
+
+
+<div class="headerLine">
+  <h2 id="ux">
+  Visual Design and User Interaction
+  </h2>
+
+</div>
+
+<p>
+  These criteria ensure that your app follows critical design and interaction patterns
+  to ensure a consistent, intuitive, and enjoyable user experience on Android Auto. Many elements,
+  such as the navigation drawer, card backgrounds, fonts and icon colors, are set and rendered by
+  the system. Your own app-specific design elements must meet the following criteria.
+</p>
+
+<table>
+
+<tr>
+  <th style="width:2px;">
+    Type
+  </th>
+  <th style="width:54px;">
+    Test
+  </th>
+  <th>
+    Description
+  </th>
+</tr>
+
+<tr>
+  <td rowspan="4" id="safety">
+    Driver Attention
+  </td>
+
+  <td id="AU-MV">
+    AU-MV
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+      App does not display on the Auto screen animated elements such as animated graphics, games, video, or
+      progress bars.
+    </p>
+  </td>
+</tr>
+
+<tr>
+  <td id="AU-VA">
+    AU-VA
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+     App does not display any form of visual or text advertising on the Auto screen.  Only audio
+      ads are acceptable.
+    </p>
+  </td>
+</tr>
+
+<tr>
+  <td id="AU-IM">
+    AU-IM
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+    App elements do not display any images on the Auto screen. Exceptions include: app may display 
+    a single static image for
+    content context in the background of the consumption screen, such as album art, and app may 
+    display icons in the content navigation drawer.
+    </p>
+  </td>
+</tr>
+
+<tr>
+  <td id="AU-DS">
+    AU-DS
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+    App does not include any features that distract the driver.
+    </p>
+  </td>
+</tr>
+
+
+
+<tr>
+  <td rowspan="4" id="layout">
+    Layout
+  </td>
+
+<tr>
+  <td id="AU-SC">
+    AU-SC
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+     App does not display automatically scrolling text.
+    </p>
+  </td>
+</tr>
+
+
+<tr>
+  <td id="AU-FT">
+    AU-FT
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+     App displays all strings using the default Roboto fonts in two approved sizes.
+    </p>
+  </td>
+</tr>
+
+<tr>
+  <td id="AU-ST">
+    AU-ST
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+     App does not display any individual string longer than 120 characters.
+    </p>
+  </td>
+</tr>
+
+<tr>
+  <td id="contrast">
+    Visual Contrast
+  </td>
+
+  <td id="AU-NM">
+    AU-NM
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+     App supports night mode, rendering light text and controls on a dark background.
+    </p>
+  </td>
+</tr>
+
+
+<tr>
+  <td rowspan="2" id="interaction">
+    Interaction
+  </td>
+
+  <td id="AU-VC">
+    AU-VC
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+     App must support voice commands.
+    </p>
+  </td>
+</tr>
+
+<tr>
+  <td id="AU-AB">
+    AU-AB
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+      App-specific buttons respond to user actions with no more than a two-second delay.
+    </p>
+  </td>
+</tr>
+
+</table>
+
+
+<h3 class="rel-resources clearfloat">Related resources</h3>
+
+<div class="resource-widget resource-flow-layout col-13" data-query=
+"collection:distribute/essentials/autoqualityguidelines/visualdesign"
+data-sortorder="-timestamp" data-cardsizes="9x3" data-maxresults="6">
+</div>
+
+
+
+<div class="headerLine">
+  <h2 id="fn">
+  Functionality
+  </h2>
+
+
+</div>
+
+<p>
+  These criteria ensure that your app is configured correctly and provides expected
+  functional behavior.
+</p>
+
+
+<table>
+<tr>
+  <th style="width:2px;">
+    Type
+  </th>
+  <th style="width:54px;">
+    Test
+  </th>
+  <th>
+    Description
+  </th>
+</tr>
+
+<tr>
+  <td rowspan="2" id="general">
+   General
+  </td>
+
+  <td id="AU-RL">
+    AU-RL
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+     When the app is relaunched from the home screen, the app restores the app state as closely as
+     possible to the previous state.
+    </p>
+  </td>
+</tr>
+
+
+</tr>
+  <td id="AU-SS">
+    AU-SS
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+     No tasks in the app take more than six steps to complete.
+    </p>
+  </td>
+</tr>
+
+
+<tr>
+  <td rowspan="2" id="media">
+    Media
+  </td>
+
+
+  <td id="AU-PA">
+    AU-PA
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+     App has no more than four primary actions plus one optional action overflow toggle (or five if
+     no action overflow is used). For more information, see details on the media control card in the
+     <a href="{@docRoot}shareables/auto/AndroidAuto-media-apps.pdf">Android Auto UX Guidelines
+      for Media Applications</a>.
+    </p>
+  </td>
+</tr>
+
+<tr>
+  <td id="AU-SA">
+    AU-SA
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+     App has no more than four optional secondary actions plus one action overflow toggle. For more
+     information, see details on the media control card in the
+     <a href="{@docRoot}shareables/auto/AndroidAuto-media-apps.pdf">Android Auto UX Guidelines
+      for Media Applications</a>.
+    </p>
+  </td>
+</tr>
+
+
+<tr>
+  <td rowspan="2" id="notifications">
+    Notifications
+  </td>
+
+  <td id="AU-NA">
+    AU-NA
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+      App does not present advertisements through notifications.
+    </p>
+  </td>
+</tr>
+
+<tr>
+  <td id="AU-NT">
+    AU-NT
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+     App displays notifications only when relevant to the driver’s needs.
+   </p>
+   <p>
+    Examples:<br />
+    Good: Notifying the user that a new message has arrived.<br />
+    Bad: Notifying the user about a new album release.
+    </p>
+  </td>
+</tr>
+
+</table>
+
+<!--
+<h3 class="rel-resources clearfloat">Related resources</h3>
+
+<div class="resource-widget resource-flow-layout col-13" data-query=
+"collection:distribute/essentials/autoqualityguidelines/functionality"
+data-sortorder="-timestamp" data-cardsizes="9x3" data-maxresults="6">
+</div>
+-->
+
+<div class="headerLine">
+  <h2 id="faq">
+  Frequently Asked Questions
+  </h2>
+</div>
+
+<p style="margin-top:30px;">
+  <strong>After I submit my app, how will find out if my app does not meet all
+    the requirements for Android Auto?</strong>
+</p>
+<p>If you are planning to develop apps for Auto, you are encouraged to begin enabling and testing
+  your apps now. However, Auto-enabled apps cannot be published at this time. Join the
+ <a href="http://g.co/AndroidAutoDev" class="external-link">Auto
+ Developers Google+ community</a> for updates on when you will be able to submit
+ your Auto-enabled apps.</p>
+</p>
+
+
+<p style="margin-top:30px;">
+  <strong>My app targets more than just Android Auto. If my app does not meet the Auto
+  requirements, will my new or updated app still appear on Google Play for phones and
+  tablets?</strong>
+</p>
+<p>
+  No. When Google begins the approval process, your auto app will undergo a driver safety
+  review, and will not be
+  available for distribution until the app is approved. Because this is the same APK as
+  for phones and tablets, your Play Store updates for those devices will not be available until the
+  Auto approval process is complete.  
+</p>
+
+<p class="caution">
+  <strong>Important:</strong> Due to this restriction, you should not use your production APK
+  for Auto support prototyping. 
+</p>
+
diff --git a/docs/html/distribute/images/gp-auto-quality.png b/docs/html/distribute/images/gp-auto-quality.png
new file mode 100644
index 0000000..d322849
--- /dev/null
+++ b/docs/html/distribute/images/gp-auto-quality.png
Binary files differ
diff --git a/docs/html/guide/components/intents-common.jd b/docs/html/guide/components/intents-common.jd
index d4b033a..adba1cd 100644
--- a/docs/html/guide/components/intents-common.jd
+++ b/docs/html/guide/components/intents-common.jd
@@ -2282,6 +2282,14 @@
     <li>"search for cat videos on myvideoapp"</li>
   </ul>
 </div>
+<!-- Video box -->
+<a class="notice-developers-video"
+   href="https://www.youtube.com/watch?v=PS1FbB5qWEI">
+<div>
+    <h3>Video</h3>
+    <p>Voice search in your app</p>
+</div>
+</a>
 
 <p>To support search within the context of your app, declare an intent filter in your app with
 the <code>SEARCH_ACTION</code> action, as shown in the example intent filter below.</p>
diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js
index a38b80b..a843350 100644
--- a/docs/html/jd_collections.js
+++ b/docs/html/jd_collections.js
@@ -68,8 +68,8 @@
       "distribute/essentials/quality/tablets.html",
       "distribute/essentials/quality/tv.html",
       "distribute/essentials/quality/wear.html",
-      "https://developers.google.com/edu/guidelines",
-      "distribute/essentials/optimizing-your-app.html"
+      "distribute/essentials/quality/auto.html",
+      "https://developers.google.com/edu/guidelines"
     ]
   },
   "distribute/users": {
@@ -348,6 +348,13 @@
       "training/wearables/notifications/voice-input.html"
     ]
   },
+    "distribute/essentials/autoqualityguidelines/visualdesign": {
+    "title": "",
+    "resources": [
+      "training/auto/messaging/index.html",
+      "training/auto/start/index.html"
+    ]
+  },
   "distribute/essentials/core/performance": {
     "title": "",
     "resources": [
@@ -787,6 +794,14 @@
       "shareables/distribute/play_dev_guide_secrets_en.pdf"
     ]
   },
+  "design/auto/auto_ui_guidelines": {
+    "title": "",
+    "resources": [
+      "shareables/auto/AndroidAuto-media-apps.pdf",
+      "shareables/auto/AndroidAuto-messaging-apps.pdf",
+      "shareables/auto/AndroidAuto-custom-colors.pdf"
+    ]
+  },
   "distribute/stories/games": {
     "title": "",
     "resources": [
diff --git a/docs/html/jd_extras.js b/docs/html/jd_extras.js
index 36f26e8..a86ffeb 100644
--- a/docs/html/jd_extras.js
+++ b/docs/html/jd_extras.js
@@ -1407,5 +1407,44 @@
     "keywords": ["distribute"],
     "type": "PDF DOWNLOAD (11MB)",
     "titleFriendly": ""
+  },
+  {
+    "lang": "en",
+    "group": "",
+    "tags": [],
+    "url": "shareables/auto/AndroidAuto-media-apps.pdf",
+    "timestamp": null,
+    "image": "auto/images/assets/icons/media_app_playback.png",
+    "title": "Android Auto Media Apps UI Guidelines",
+    "summary": "Guidelines for designing audio apps that work with Auto. ",
+    "keywords": ["design", "Auto", "Automotive"],
+    "type": "PDF DOWNLOAD (1.1MB)",
+    "titleFriendly": ""
+  },
+  {
+    "lang": "en",
+    "group": "",
+    "tags": [],
+    "url": "shareables/auto/AndroidAuto-messaging-apps.pdf",
+    "timestamp": null,
+    "image": "auto/images/assets/icons/messaging_app_notifications.png",
+    "title": "Android Auto Messaging Apps UI Guidelines",
+    "summary": "Guidelines for designing messaging apps that work with Auto. ",
+    "keywords": ["design", "Auto", "Automotive"],
+    "type": "PDF DOWNLOAD (628KB)",
+    "titleFriendly": ""
+  },
+  {
+    "lang": "en",
+    "group": "",
+    "tags": [],
+    "url": "shareables/auto/AndroidAuto-custom-colors.pdf",
+    "timestamp": null,
+    "image": "auto/images/assets/icons/auto_app_in_simulator.png",
+    "title": "Android Auto Color Customization UI Guidelines",
+    "summary": "Guidelines for color-customizing apps that work with Auto. ",
+    "keywords": ["design", "Auto", "Automotive"],
+    "type": "PDF DOWNLOAD (779KB)",
+    "titleFriendly": ""
   }
-]);
+]);
\ No newline at end of file
diff --git a/docs/html/sdk/installing/migrate.jd b/docs/html/sdk/installing/migrate.jd
index db1b5dd..b83f8d3 100644
--- a/docs/html/sdk/installing/migrate.jd
+++ b/docs/html/sdk/installing/migrate.jd
@@ -15,23 +15,7 @@
 </div>
 
 <p>If you've previously developed for Android using Eclipse and would like to migrate
-to Android Studio, you should export your projects from Eclipse in order to generate
-Gradle build files. You can then import your project into Android Studio.</p>
-
-
-<h2 id="Export">Export from Eclipse</h2>
-<ol>
-<li><a href="{@docRoot}tools/help/adt.html#Updating">Update your Eclipse ADT Plugin</a>
-  (you must have version 22.0 or higher).</li>
-<li>In Eclipse, select <strong>File > Export</strong>.</li>
-<li>In the window that appears, open <strong>Android</strong> and select <strong>Generate Gradle
-build files</strong>.</li>
-<li>Select the project you want to export for Android Studio and click
-<strong>Finish</strong>.</li>
-</ol>
-
-<p>Your selected project remains in the same location but now contains a {@code build.gradle}
-file and is ready for Android Studio.</p>
+to Android Studio, you can import your project into Android Studio.</p>
 
 
 <h2 id="Export">Import into Android Studio</h2>
diff --git a/docs/html/training/auto/audio/index.jd b/docs/html/training/auto/audio/index.jd
new file mode 100644
index 0000000..aa25769
--- /dev/null
+++ b/docs/html/training/auto/audio/index.jd
@@ -0,0 +1,475 @@
+page.title=Providing Audio Playback for Auto
+page.tags="auto", "car", "automotive", "audio"
+page.article=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+  <h2>Dependencies and Prerequisites</h2>
+  <ul>
+    <li>Android 5.0 (API level 21) or higher</li>
+  </ul>
+
+    <h2>This class teaches you how to</h2>
+
+    <ol>
+      <li><a href="#overview">Provide Audio Services</a></li>
+      <li><a href="#config_manifest">Configure Your Manifest</a></li>
+      <li><a href="#implement_browser">Build a Browser Service</a></li>
+      <li><a href="#implement_callback">Implement Play Controls</a></li>
+    </ol>
+
+    <h2>Related Samples</h2>
+
+    <ul>
+      <li><a href="{@docRoot}samples/MediaBrowserService/index.html">
+        MediaBrowserService</a></li>
+    </ul>
+
+    <h2>See Also</h2>
+
+    <ul>
+      <li>
+        <a href="{@docRoot}shareables/auto/AndroidAuto-media-apps.pdf">
+              User Experience Guidelines: Media Apps</a>
+      </li>
+      <li><a href="{@docRoot}training/managing-audio/index.html">Managing Audio
+        Playback</a></li>
+      <li><a href="{@docRoot}guide/topics/media/exoplayer.html">ExoPlayer</a>
+      </li>
+    </ul>
+
+</div>
+</div>
+
+<a class="notice-developers-video wide"
+href="https://www.youtube.com/watch?v=Q96Sw6v4ULg">
+<div>
+    <h3>Video</h3>
+    <p>Devbytes: Android Auto Audio</p>
+</div>
+</a>
+
+<p>
+  Drivers want to access their music and other audio content on the road. Audio books, podcasts,
+  sports commentary, and recorded talks can make a long trip educational, inspirational, and
+  enjoyable. The Android framework allows you to extend your audio app so users can listen to their
+  favorite tunes and audio content using a simpler, safer user interface.
+</p>
+
+<p>
+  Apps running on mobile devices with Android 5.0 or higher can provide audio services for
+  dashboard systems running Android Auto. By configuring your app with a few settings and
+  implementing a service for accessing music tracks, you can enable Auto devices to discover your
+  app and provide a browse and playback interface for your app's audio content.
+</p>
+
+<p>
+  This class assumes that you have built an app that plays audio through an Android device's
+  integrated speakers or connected headphones. It describes how to extend your app to allow Auto
+  devices to browse your content listings and play it through a car stereo system.
+</p>
+
+
+<h2 id="overview">Provide Audio Services</h2>
+
+<p>
+  Audio apps do not directly control a car dashboard device that runs Android Auto. When the user
+  connects an Android mobile device into a dashboard system, Android Auto discovers your app through
+  manifest entries that indicate what audio services your app can provide. The dashboard system
+  displays a launcher icon for your app as a music provider and the user can choose to use your
+  app's services. If the user launches your app, the Auto device queries your app to see what
+  content is available, displays your content items to the user, and sends requests to your app to
+  control playback with actions such as play, pause, or skip track.
+</p>
+
+<p>To enable your app to provide audio content for Auto devices, you need to:
+</p>
+
+<ul>
+  <li>Configure your app manifest to do the following:</li>
+    <ul>
+      <li>Declare that your app can provide audio content for Auto devices.</li>
+      <li>Define a service that provides a browsable list of your audio tracks.</li>
+    </ul>
+  </li>
+  <li>Build a service that provides audio track listing information extending
+    {@link android.service.media.MediaBrowserService}.</li>
+  <li>Register a {@link android.media.session.MediaSession} object and implement the
+    {@link android.media.session.MediaSession.Callback} object to enable playback controls.</li>
+</ul>
+
+
+<h2 id="config_manifest">Configure Your Manifest</h2>
+
+<p>
+  When a user plugs an Android mobile device into a dashboard device running Auto, the system
+  requests a list of installed apps that include <a href=
+  "{@docRoot}guide/topics/manifest/manifest-intro.html">app manifest</a> entries to indicate they
+  support services for Auto devices and how to access them. This section describes how to configure
+  your app manifest to indicate your app supports audio services for Auto devices, and allow
+  dashboard system to connect with your app.
+</p>
+
+
+<h3 id="manifest-car-app">Declare Auto audio support</h3>
+
+<p>
+  You indicate that your app supports cars capabilities using the following manifest entry:
+</p>
+
+<pre>
+&lt;application&gt;
+    ...
+    &lt;meta-data android:name="com.google.android.gms.car.application"
+        android:resource="&#64;xml/automotive_app_desc"/&gt;
+    ...
+&lt;application&gt;
+</pre>
+
+<p>
+  This manifest entry refers to a secondary XML file, where you declare what Auto capabilities your
+  app supports. For an app that supports audio for cars, add an XML file to the {@code res/xml/}
+  resources directory as {@code automotive_app_desc.xml}, with the following content:
+</p>
+
+<pre>
+&lt;automotiveApp&gt;
+    &lt;uses name="media"/&gt;
+&lt;/automotiveApp&gt;
+</pre>
+
+<p>
+  For more information about declaring capabilities for Auto devices, see <a href=
+  "{@docRoot}training/auto/start/index.html#auto-metadata">Getting Started with Auto</a>.
+</p>
+
+
+<h3 id="manifest-service">Declare your media browser service</h3>
+
+<p>
+  Auto devices expect to connect to a service in order to browse audio track
+  listings. You declare this service in your manifest to allow the dashboard system to discover
+  this service and connect to your app.
+</p>
+
+<p>The following code example shows how to declare this listing browser service in your manifest:</p>
+
+<pre>
+&lt;application&gt;
+    ...
+    &lt;service android:name="<em>.MyMediaBrowserService</em>"
+                android:exported="true"&gt;
+        &lt;intent-filter&gt;
+            <strong>&lt;action android:name=</strong>
+                <strong>"android.media.browse.MediaBrowserService"/&gt;</strong>
+        &lt;/intent-filter&gt;
+    &lt;/service&gt;
+    ...
+&lt;application&gt;
+</pre>
+
+<p>
+  The service your app provides for browsing audio tracks must extend the
+  {@link android.service.media.MediaBrowserService}. The implementation of this service is discussed
+  in the <a href="#implement_browser">Build a Browser Service</a> section.
+</p>
+
+<p class="note">
+  <strong>Note:</strong> Other clients can also contact your app's browser service aside from Auto
+  devices. These media clients might be other apps on a user's mobile device, or they might be other
+  remote clients.
+</p>
+
+<h3 id="manifest-icon">Specify a notification icon</h3>
+
+<p>
+  The Auto user interface shows notifications about your audio app to the user during the course
+  of operation. For example, if the user has a navigation app running, and one song finishes
+  and a new song starts, the Auto device shows the user a notification to indicate the change with
+  an icon from your app. You can specify an icon that is used to represent your app for these
+  notifications using the following manifest declaration:
+</p>
+
+<pre>
+&lt;application&gt;
+    ...
+    &lt;meta-data android:name="com.google.android.gms.car.notification.SmallIcon"
+        android:resource="&#64;drawable/ic_notification" /&gt;
+    ...
+&lt;application&gt;
+</pre>
+
+<p class="note"><strong>Note:</strong> The icon you provide should have transparency enabled, so the
+icon's background gets filled in with the app's primary color.</p>
+
+
+<h2 id="implement_browser">Build a Browser Service</h2>
+
+<p>Auto devices interact with your app by contacting its implementation of a
+  {@link android.service.media.MediaBrowserService}, which
+you declare in your app manifest. This service allows Auto devices to find out what content your app
+provides. Connected Auto devices can also query your app's media browser service to contact the
+{@link android.media.session.MediaSession} provided by your app, which handles content playback
+commands.</p>
+
+<p>You create a media browser service by extending the
+{@link android.service.media.MediaBrowserService} class.
+Connected Auto devices can contact your service to do the following:</p>
+
+<ul>
+  <li>Browse your app's content hierarchy, in order to present a menu to the
+    user</li>
+  <li>Get the token for your app's {@link android.media.session.MediaSession}
+    object, in order to control audio playback</li>
+</ul>
+
+
+<h3 id="browser_workflow">Media browser service workflow</h3>
+
+<ol>
+
+<li>When your app's audio services are requested by a user through a connected Auto device, the
+dashboard system contacts your app's media browser service.
+In your implementation of the {@link android.service.media.MediaBrowserService#onCreate()
+onCreate()} method, you must create and register a {@link
+android.media.session.MediaSession} object and its callback object.</li>
+
+<li>The Auto device calls the browser service's {@link
+android.service.media.MediaBrowserService#onGetRoot onGetRoot()} method to get the top node of
+your content hierarchy. The node retrieved by this call is not used as a menu item, it is only used
+to retrieve its child nodes, which are subsequently displayed as the top menu items.
+</li>
+
+<li>Auto invokes the {@link android.service.media.MediaBrowserService#onLoadChildren
+onLoadChildren()} method to get the children of the root node, and uses this information to
+present a menu to the user.</li>
+
+<li>If the user selects a submenu, Auto invokes
+{@link android.service.media.MediaBrowserService#onLoadChildren
+onLoadChildren()} again to retrieve the child nodes of the selected menu item.</li>
+
+<li>If the user begins playback, Auto invokes the appropriate media session
+callback method to perform that action. For more information, see the section about how to
+<a href="#implement_callback">Implement Playback Controls</a>. </li>
+
+</ol>
+
+
+<h3 id="build_hierarchy">Building your content hierarchy</h3>
+
+<p>Auto devices acting as audio clients call your app's {@link
+android.service.media.MediaBrowserService} to find out what content you have
+available. You need to implement two methods in your browser service to support
+this: {@link android.service.media.MediaBrowserService#onGetRoot
+onGetRoot()} and {@link
+android.service.media.MediaBrowserService#onLoadChildren
+onLoadChildren()}.</p>
+
+<p>Each node in your content hierarchy is represented by a  {@link
+android.media.browse.MediaBrowser.MediaItem} object. Each of these objects is
+identified by a unique ID string. The client treats these ID strings as
+opaque tokens. When a client wants to browse to a submenu, or play a content
+item, it passes the ID token. Your app is responsible for associating the ID
+token with the appropriate menu node or content item.</p>
+
+<p class="note"><strong>Note:</strong> You should consider providing different content
+hierarchies depending on what client is making the query. In particular, Auto
+applications have strict limits on how large a menu they can display. This is
+intended to prevent distracting the driver, and to make it easy for the driver
+to operate the app via voice commands. For more information on the Auto user
+experience restrictions, see the <a href="{@docRoot}shareables/auto/AndroidAuto-media-apps.pdf">
+Auto Media Apps</a> guidelines.</p>
+
+<p>Your implementation of {@link android.service.media.MediaBrowserService#onGetRoot
+onGetRoot()} returns information about the root node of the menu
+hierarchy. This root node is the parent of the top items your browse hierarchy.
+The method is passed information about the calling client. You can use this
+information to decide if the client should have access to your content at all.
+For example, if you want to limit your app's content to a list of approved
+clients, you can compare the passed {@code clientPackageName} to your whitelist.
+If the caller isn't an approved package, you can return null to deny access to
+your content.</p>
+
+<p>A typical implementation of {@link
+android.service.media.MediaBrowserService#onGetRoot onGetRoot()} might
+look like this:</p>
+
+<pre>
+&#64;Override
+public BrowserRoot onGetRoot(String clientPackageName, int clientUid,
+    Bundle rootHints) {
+
+    // To ensure you are not allowing any arbitrary app to browse your app's
+    // contents, you need to check the origin:
+    if (!PackageValidator.isCallerAllowed(this, clientPackageName, clientUid)) {
+        // If the request comes from an untrusted package, return null.
+        // No further calls will be made to other media browsing methods.
+        LogHelper.w(TAG, "OnGetRoot: IGNORING request from untrusted package "
+                + clientPackageName);
+        return null;
+    }
+    if (ANDROID_AUTO_PACKAGE_NAME.equals(clientPackageName)) {
+        // Optional: if your app needs to adapt ads, music library or anything
+        // else that needs to run differently when connected to the car, this
+        // is where you should handle it.
+    }
+    return new BrowserRoot(MEDIA_ID_ROOT, null);
+}
+</pre>
+
+<p>
+  The Auto device client builds the top-level menu by calling {@link
+  android.service.media.MediaBrowserService#onLoadChildren onLoadChildren()}
+  with the root node object and getting it's children. The client builds
+  submenus by calling the same method with other child nodes. The following
+  example code shows a simple implementation of {@link
+  android.service.media.MediaBrowserService#onLoadChildren onLoadChildren()} method:
+</p>
+
+<pre>
+&#64;Override
+public void onLoadChildren(final String parentMediaId,
+    final Result&lt;List&lt;MediaItem&gt;&gt; result) {
+
+    // Assume for example that the music catalog is already loaded/cached.
+
+    List&lt;MediaBrowser.MediaItem&gt; mediaItems = new ArrayList&lt;&gt;();
+
+    // Check if this is the root menu:
+    if (MEDIA_BROWSER_ROOT.equals(parentMediaId)) {
+
+        // build the MediaItem objects for the top level,
+        // and put them in the &lt;result&gt; list
+    } else {
+
+        // examine the passed parentMediaId to see which submenu we're at,
+        // and put the children of that menu in the &lt;result&gt; list
+    }
+}
+</pre>
+
+
+<h2 id="implement_callback">Enable Playback Control</h2>
+
+<p>
+  Auto devices use {@link android.media.session.MediaSession} objects to pass playback control
+  commands to an app that is providing audio services. Your audio app must create an instance of
+  this object to pass to the dashboard device and implement callback methods to enable remote
+  control of audio playback.
+</p>
+
+<h3 id="registering_mediasession">Register a media session</h3>
+
+<p>An Auto device using your app as audio service needs to obtain a {@link
+android.media.session.MediaSession} object from your app. The Auto device uses the session object
+to send playback commands requested by the Auto user back to your app.</p>
+
+<p>When you initialize your browser service, you register that session object with your {@link
+android.service.media.MediaBrowserService} by calling the {@link
+android.service.media.MediaBrowserService#setSessionToken setSessionToken()} method. This step
+allows clients such as an Auto device to retrieve that object by calling your browser service's
+{@link android.service.media.MediaBrowserService#getSessionToken getSessionToken()} method.</p>
+
+<p>In your browser service's {@link
+android.service.media.MediaBrowserService#onCreate() onCreate()} method,
+create a {@link android.media.session.MediaSession}. You can then query
+the {@link android.media.session.MediaSession} to get its token, and register
+the token with your browser service:</p>
+
+<pre>
+public void onCreate() {
+        super.onCreate();
+
+    ...
+    // Start a new MediaSession
+    MediaSession mSession = new MediaSession(this, "session tag");
+    setSessionToken(mSession.getSessionToken());
+
+    // Set a callback object to handle play control requests, which
+    // implements MediaSession.Callback
+    mSession.setCallback(new MyMediaSessionCallback());
+
+    ...
+</pre>
+
+<p>
+  When you create the media session object, you set a callback object that is used to handle
+  playback control requests. You create this callback object by providing an implementation of the
+  {@link android.media.session.MediaSession.Callback} class for your app. The next section
+  discusses how to implement this object.
+</p>
+
+
+<h3 id="playback-commands">Implement play commands</h3>
+
+<p>When an Auto device requests playback of an audio track from your app, it uses the
+{@link android.media.session.MediaSession.Callback} class from your app's
+{@link android.media.session.MediaSession} object, which it obtained from your app's
+media browse service. When an Auto user wants to play content or control content playback,
+such as pausing play or skipping to the next track, Auto invokes one
+of the callback object's methods.</p>
+
+<p>To handle content playback, your app must extend the abstract {@link
+android.media.session.MediaSession.Callback} class and implement the methods
+that your app supports. The most important callback methods are as follows:</p>
+
+<dl>
+
+<dt>{@link android.media.session.MediaSession.Callback#onPlay onPlay()}</dt>
+<dd>Invoked if the user chooses play without choosing a specific item. Your
+app should play its default content. If playback was paused with
+{@link android.media.session.MediaSession.Callback#onPause onPause()}, your
+app should resume playback.</dd>
+
+<dt>{@link android.media.session.MediaSession.Callback#onPlayFromMediaId
+onPlayFromMediaId()}</dt>
+<dd>Invoked when the user chooses to play a specific item. The method is passed
+the item's media ID, which you assigned to the item in the content
+hierarchy.</dd>
+
+<dt>{@link android.media.session.MediaSession.Callback#onPlayFromSearch
+onPlayFromSearch()}</dt>
+<dd>Invoked when the user chooses to play from a search query. The app should
+make an appropriate choice based on the passed search string.</dd>
+
+<dt>{@link android.media.session.MediaSession.Callback#onPause onPause()}</dt>
+<dd>Pause playback.</dd>
+
+<dt>{@link android.media.session.MediaSession.Callback#onSkipToNext
+onSkipToNext()}</dt>
+<dd>Skip to the next item.</dd>
+
+<dt>{@link android.media.session.MediaSession.Callback#onSkipToPrevious
+onSkipToPrevious()}</dt>
+<dd>Skip to the previous item.</dd>
+
+<dt>{@link android.media.session.MediaSession.Callback#onStop onStop()}</dt>
+<dd>Stop playback.</dd>
+
+</dl>
+
+<p>Your app should override these methods to provide any desired functionality.
+In some cases you might not implement a method if it is not supported by your app.
+For example, if your app plays a live stream (such as a sports
+broadcast), the skip to next function might not make sense. In that case, you
+could simply use the default implementation of
+{@link android.media.session.MediaSession.Callback#onSkipToNext
+onSkipToNext()}.</p>
+
+<p>When your app receives a request to play content, it should play audio the same way it
+would in a non-Auto situation (as if the user was listening through a device speaker
+or connected headphones). The audio content is automatically sent to the dashboard system
+to be played over the car's speakers.</p>
+
+<p>For more information about playing audio content, see
+<a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a>,
+<a href="{@docRoot}training/managing-audio/index.html">Managing Audio Playback</a>, and
+<a href="{@docRoot}guide/topics/media/exoplayer.html">ExoPlayer</a>.
+
+
+(for example, by using a {@link
+android.media.MediaPlayer} or <a
+href="{@docRoot}guide/topics/media/exoplayer.html">ExoPlayer</a>). If the phone
+is connected to an Auto device, .</p>
diff --git a/docs/html/training/auto/index.jd b/docs/html/training/auto/index.jd
new file mode 100644
index 0000000..26eee32
--- /dev/null
+++ b/docs/html/training/auto/index.jd
@@ -0,0 +1,9 @@
+page.title=Building Apps for Auto
+page.trainingcourse=true
+page.metaDescription=Starting point for building apps for Auto, with guidelines, information, and examples.
+page.image=design/tv/images/focus.png
+@jd:body
+
+
+
+<p>These classes teach you how to build and extend apps to work with Auto devices.</p>
\ No newline at end of file
diff --git a/docs/html/training/auto/messaging/index.jd b/docs/html/training/auto/messaging/index.jd
new file mode 100644
index 0000000..c51ad7e
--- /dev/null
+++ b/docs/html/training/auto/messaging/index.jd
@@ -0,0 +1,533 @@
+page.title=Providing Messaging for Auto
+page.tags="auto", "car", "automotive", "messaging"
+page.article=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+  <h2>Dependencies and Prerequisites</h2>
+  <ul>
+    <li>Android 5.0 (API level 21) or higher</li>
+  </ul>
+
+    <h2>This class teaches you to:</h2>
+
+    <ul>
+      <li><a href="#overview">Provide Messaging Services</a></li>
+      <li><a href="#manifest">Configure Your Manifest</a></li>
+      <li><a href="#support-lib">Import Support Library for Messaging</a></li>
+      <li><a href="#messaging">Notify Users of Messages</a></li>
+      <li><a href="#handle_actions">Handle User Actions</a></li>
+    </ul>
+
+    <h2>Related Samples</h2>
+
+    <ul>
+      <li><a href="{@docRoot}samples/MessagingService/index.html">
+        MessagingService</a></li>
+    </ul>
+
+    <h2>See Also</h2>
+
+    <ul>
+      <li><a href="{@docRoot}shareables/auto/AndroidAuto-messaging-apps.pdf">
+        User Experience Guidelines: Messaging Apps</a></li>
+      <li><a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">
+        Notifications</a></li>
+    </ul>
+</div>
+</div>
+
+<a class="notice-developers-video wide"
+    href="https://www.youtube.com/watch?v=gSVLuaOTIPk">
+<div>
+    <h3>Video</h3>
+    <p>DevBytes: Android Auto Messaging</p>
+</div>
+</a>
+
+<p>
+  Staying connected through text messages is important to many drivers. Chat apps can let users
+  know if a child need to be picked up, or if a dinner location has been changed. Apps that provide
+  sports information might tell the user who just won the big game, and let the user ask questions
+  about other games being played. The Android framework enables messaging apps to extend their
+  services into car dashboards using a standard user interface that lets drivers keep their eyes
+  on the road.
+</p>
+
+<p>
+  Apps that support messaging can be extended to pass messaging notifications to Auto
+  dashboard systems, alerting them to new messages and allowing them to respond. You can configure
+  your messaging app to provide these services when an Android mobile device with your app
+  installed is connected to an Auto dashboard. Once connected, your app can provide text
+  information to users and allow them to respond. The Auto dashboard system handles displaying the
+  notification and the interface for replies.
+</p>
+
+<p>
+  This lesson assumes that you have built an app that displays messages to the user and receive the
+  user's replies, such as a chat app. It shows you how to extend your app to hand those messages
+  off to an Auto device for display and replies.
+</p>
+
+
+<h2 id="overview">Provide Messaging Services</h2>
+
+<p>
+  Messaging apps do not run directly on the Android dashboard hardware. They are installed on
+  separate, Android mobile device. When the mobile device is plugged into a dashboard,
+  the installed messaging apps can offer services for viewing and responding to messages
+  through the Auto user interface.
+</p>
+
+<p>To enable your app to provide messaging services for Auto devices:</p>
+
+<ul>
+  <li>Configure your app manifest to indicate that your app provides messaging services which are
+  compatible with Android Auto dashboard devices.
+  </li>
+  <li>Build and send a specific type of <a href=
+  "{@docRoot}guide/topics/ui/notifiers/notifications.html">notification</a> for display on Auto
+  devices.
+  </li>
+  <li>Configure your app to receive {@link android.content.Intent} objects that indicate a user
+    has read or replied to a message.
+</ul>
+
+
+<h2 id="#manifest">Configure Your Manifest</h2>
+
+<p>
+  You configure your app <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">manifest</a>
+  to indicate that it supports messaging services for Auto devices and handle message actions. This
+  section describes what changes to make to your manifest to support messaging for Auto devices.
+</p>
+
+
+<h3 id="manifest-messaging">Declare Auto messaging support</h3>
+
+<p>
+  When a user connects a Android mobile device to a dashboard running Android, the dashboard
+  device looks for apps that declare support for vehicle services, such as messaging. You indicate
+  that your app supports cars capabilities using the following manifest entry:
+</p>
+
+<pre>
+&lt;application&gt;
+    ...
+    &lt;meta-data android:name="com.google.android.gms.car.application"
+        android:resource="@xml/automotive_app_desc" /&gt;
+    ...
+&lt;application&gt;
+</pre>
+
+<p>
+  This manifest entry refers to a secondary xml file, where you declare what Auto capabilities your
+  app supports. For an app that supports messaging for Auto devices, add an xml file to the {@code
+  res/xml/} your app's development project directory as {@code automotive_app_desc.xml}, with the
+  following content:
+</p>
+
+<pre>
+&lt;automotiveApp&gt;
+    &lt;uses name="notification"/&gt;
+&lt;/automotiveApp&gt;
+</pre>
+
+<p>
+  For more information about declaring capabilities for Auto devices, see <a href=
+  "{@docRoot}training/auto/start/index.html#auto-metadata">Getting Started with Auto</a>.
+</p>
+
+
+<h3 id="manifest-intent">Define read and reply intent filters</h3>
+
+<p>
+  Auto devices use {@link android.content.Intent} objects that indicate a user has read or replied
+  to a message provided by your app. Your app defines intent types for reading and replying to
+  messages and adds this information to messaging notifications for Auto devices, so that the
+  dashboard system can notify your app when a user takes one of these actions.
+</p>
+
+<p>
+  You define the read action and reply action intents types for your app and the {@code
+  android.content.BroadcastReceiver} classes that handle them in the manifest. The following code
+  example demonstrates how to declare these intents and thier associated receivers.
+</p>
+
+<pre>
+&lt;application&gt;
+    ...
+    &lt;receiver android:name="<em>.MyMessageReadReceiver</em>"&gt;
+        &lt;intent-filter&gt;
+          &lt;action android:name="<em>com.myapp.messagingservice.ACTION_MESSAGE_HEARD</em>"/&gt;
+        &lt;/intent-filter&gt;
+    &lt;/receiver&gt;
+
+    &lt;receiver android:name="<em>.MyMessageReplyReceiver</em>"&gt;
+        &lt;intent-filter&gt;
+          &lt;action android:name="<em>com.myapp.messagingservice.ACTION_MESSAGE_REPLY</em>"/&gt;
+        &lt;/intent-filter&gt;
+    &lt;/receiver&gt;
+    ...
+&lt;/application&gt;
+</pre>
+
+<p>
+  The definition of the {@code android.content.BroadcastReceiver} classes shown in this example
+  is discussed in <a href="#handle_actions">Handle User Actions</a>.
+</p>
+
+
+<h2 id="support-lib">Import Support Library for Messaging</h3>
+
+<p>
+  Building notifications for use with Auto devices requires classes from the
+  <a href="{@docRoot}tools/support-library/features.html#v4">v4 support library</a>. Use the
+  <a href="{@docRoot}tools/help/sdk-manager.html">Android SDK Manager</a> to update the
+  <em>Extras > Android Support Repository</em> to version 9 or higher and the
+  <em>Extras > Android Support Library</em> to version 21.1.0 or higher.
+</p>
+
+<p>
+  After you have updated the support libraries, import them into your Android Studio development
+  project by adding this dependency to your
+  <a href="{@docRoot}sdk/installing/studio-build.html#configBuild">build.gradle</a> file:
+</p>
+
+<pre>
+dependencies {
+    ...
+    compile 'com.android.support:support-v4:21.1.+'
+}
+</pre>
+
+<p>
+  For information about importing the support library into development projects for other
+  development environments, see <a href="{@docRoot}tools/support-library/setup.html">Support
+  Library Setup</a>.
+</p>
+
+
+
+<h2 id="messaging">Notify Users of Messages</h2>
+
+<p>
+  A messaging app provides messages to a connected Auto dashboard using the <a href=
+  "{@docRoot}guide/topics/ui/notifiers/notifications.html">notifications</a> framework. When your
+  messaging app has a message for a user, you build a specially configured notification that is
+  received by the dashboard system and presented to the user. The Auto device manages the
+  presentation on the dashboard screen and may play the message via text-to-speech. The dashboard
+  system also handles voice interaction if the user replies to a message using verbal input.
+</p>
+
+<p>
+  The messaging user interface for Auto presents users with two levels of information about
+  messages. The first level of notification tells users what <em>conversations</em> are
+  available, and who they are with, but not the content of the messages. Typically, a
+  conversation is one or more messages from another user to the Auto user.
+</p>
+
+<p>
+  The second level of the notification is the actual content of messages in the conversation. If a
+  user indicates they want to hear the messages in a conversation, the Auto user interface plays
+  the messages using text-to-speech.
+</p>
+
+<p>
+  This section describes how to notify Auto users that conversations are available and
+  provide the content of messages in those conversations.
+</p>
+
+
+<h3 id="build_conversation">Build message conversations</h4>
+
+<p>
+  Messaging notifications for Auto organize messages into conversations using the {@code
+  NotificationCompat.CarExtender.UnreadConversation} class, that represents an unread or new
+  portion of a conversation from a particular sender. It contains a list of messages from the
+  sender.
+</p>
+
+<p>
+  Use the {@code UnreadConversation.Builder} class to create an unread conversation object,
+  as shown in the following example code:
+</p>
+
+<pre>
+// Build a RemoteInput for receiving voice input in a Car Notification
+RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
+        .setLabel(getApplicationContext().getString(R.string.notification_reply))
+        .build();
+
+// Create an unread conversation object to organize a group of messages
+// from a particular sender.
+UnreadConversation.Builder unreadConvBuilder =
+    new UnreadConversation.Builder(participantName)
+        .setReadPendingIntent(msgHeardPendingIntent)
+        .setReplyAction(replyPendingIntent, remoteInput);
+</pre>
+
+<p>
+  This conversation object includes a {@link android.app.PendingIntent}, which allows the Auto
+  device to signal your app that the conversation has been read by the Auto user. The construction
+  of this intent is discussed in the <a href="#conversation-intents">Creating conversation read and
+  reply intents</a> section.
+</p>
+
+<p>
+  If your app supports replying to a conversation, you must call the {@code setReplyAction()}
+  method and provide a pending intent to pass that user action back to your app. The {@code
+  UnreadConversation} object you create must also include a {@link
+  android.support.v4.app.RemoteInput} object. This object is required because the Auto user
+  receiving this conversation speaks a reply, a the remote input objects lets your app get a text
+  version of the voice reply.
+</p>
+
+
+<h4 id="conversation-messages">Associate messages with conversations</h4>
+
+<p>
+  Messages provided for Auto must be associated with a conversation using the {@code
+  NotificationCompat.CarExtender.UnreadConversation} class. The following code example shows how
+  to associate individual messages with a conversation object.
+</p>
+
+<pre>
+// Note: Add messages from oldest to newest to the UnreadConversation.Builder
+for (Iterator&lt;String&gt; messages = conversation.getMessages().iterator();
+     messages.hasNext(); ) {
+    String message = messages.next();
+    unreadConvBuilder.addMessage(message);
+}
+</pre>
+
+<p>
+  When a new message arrives in a particular conversation, your app should check if there is
+  already a conversation object for that particular conversation. If there is, associate the new
+  message with the existing conversation instead of building a new one.
+</p>
+
+
+<h4 id="conversation-intents">Create conversation read and reply intents</h4>
+
+<p>
+  Unread conversation objects contain intents for reading and replying to a conversation. You
+  create a {@link android.app.PendingIntent} object for each of these actions, so the Auto device
+  can notify your app of action taken by the Auto user on a particular conversation.
+</p>
+
+<p>
+  The following example code demonstrates how to define a {@link android.app.PendingIntent} to let
+  your app know if a conversation was listened to by the Auto user:
+</p>
+
+<pre>
+Intent msgHeardIntent = new Intent()
+    .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
+    .setAction(<em>com.myapp.messagingservice.ACTION_MESSAGE_HEARD</em>)
+    .putExtra("conversation_id", conversationId);
+
+PendingIntent msgHeardPendingIntent =
+    PendingIntent.getBroadcast(getApplicationContext(),
+        conversationId,
+        msgHeardIntent,
+        PendingIntent.FLAG_UPDATE_CURRENT);
+</pre>
+
+<p>
+  In this example, {@code conversationId} is an integer that identifies the current conversation.
+  The value of {@code setAction()} is an intent filter identifier for heard messages which is
+  defined in your app manifest, as shown in <a href="#manifest-intent">Define read and reply intent
+  filters</a>.
+</p>
+
+<p>
+  If your app supports replying to conversations, you also create a {@link
+  android.app.PendingIntent} for each conversation to notify your app that the user has replied.
+  The following code example shows you how to build this intent for use with a particular
+  conversation:
+</p>
+
+<pre>
+Intent msgReplyIntent = new Intent()
+    .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
+    .setAction(<em>com.myapp.messagingservice.ACTION_MESSAGE_REPLY</em>)
+    .putExtra("conversation_id", <em>conversationId</em>);
+
+PendingIntent msgReplyPendingIntent = PendingIntent.getBroadcast(
+    getApplicationContext(),
+    <em>conversationId</em>,
+    msgReplyIntent,
+    PendingIntent.FLAG_UPDATE_CURRENT);
+</pre>
+
+<p>
+  Once again, {@code conversationId} is an integer that uniquely identifies this conversation. The
+  value of {@code setAction()} is an intent filter identifier for replies which is defined in your
+  app manifest, as shown in <a href="#manifest-intent">Define read and reply intent filters</a>.
+</p>
+
+
+<h3 id="sending_messages">Sending Messages</h4>
+
+<p>
+  When a message arrives for a conversation, you take the following steps to dispatch it as a
+  notification to Auto.
+</p>
+
+<p>First, add the message to the <code>UnreadConversation.Builder</code> for
+this conversation, and update its timestamp:</p>
+
+<pre>
+unreadConvBuilder.addMessage(<em>messageString</em>)
+    .setLatestTimestamp(<em>currentTimestamp</em>);
+</pre>
+
+<p>Then create a {@link android.support.v4.app.NotificationCompat.Builder}
+object that you'll use to build the actual notification. You'll need to use the
+pending intents you created in the previous step.</p>
+
+<pre>
+NotificationCompat.Builder notificationBuilder =
+    new NotificationCompat.Builder(getApplicationContext())
+        .setSmallIcon(R.drawable.<em>notification_icon</em>)
+        .setLargeIcon(<em>icon_bitmap</em>)
+        .setContentText(<em>messageString</em>)
+        .setWhen(<em>currentTimestamp</em>)
+        .setContentTitle(<em>participant_name</em>)
+        .setContentIntent(msgHeardPendingIntent);
+
+</pre>
+
+<p>You'll also need to extend the  {@link
+android.support.v4.app.NotificationCompat.Builder} with the
+<code>CarExtender</code>. This is where you actually create the
+<code>UnreadConversation</code> object using the builder you just
+created, and attach it to the <code>CarExtender</code>:</p>
+
+<pre>
+notificationBuilder.extend(new CarExtender()
+    .setUnreadConversation(unreadConvBuilder.build());
+</pre>
+
+<p>Once you've done all this, you use your app's {@link
+android.support.v4.app.NotificationManagerCompat} to send the notification:</p>
+
+<pre>
+mNotificationManager = NotificationManagerCompat.from(context);
+mNotificationManager.notify(<em>notificationId</em>, notificationBuilder.build());
+</pre>
+
+<p>In this example, <em>msgNotificationManager</em> is a
+{@link android.support.v4.app.NotificationManagerCompat} you created for your app.</p>
+
+
+<h2 id="handle_actions">Handle User Actions</h2>
+
+<p>
+  When your create and dispatch a notification for messaging, you specify intents to be triggered
+  when the Auto user hears the message and when the user dictates a reply. Your app indicates to
+  the Android framework that it handles these intends by registering them through it's manifest, as
+  discussed in <a href="#manifest-intent">Define read and reply intent filters</a>.
+</p>
+
+<p>
+  In addition to registering these intent filters, your app must provide code to handle these
+  actions. Your app can do this by providing a service or {@link android.content.BroadcastReceiver}
+  objects that handle these intents.</p>
+
+<p>
+  For more information about intents, see <a href=
+  "{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>.
+</p>
+
+
+<h3 id="handling_msg_heard">Handling a message heard action</h3>
+
+<p>
+  When a user listens to a messaging conversation through the Auto user interface, the dashboard
+  device sends a read intent based on how your app defined the messaging notification. Your app
+  catches that intent and invokes the broadcast receiver class associated with it, or the service
+  method set up to handle that action.
+</p>
+
+<p>
+  The following code example shows how to define a {@link android.content.BroadcastReceiver} class
+  to handle a received message heard intent:
+</p>
+
+<pre>
+public class MessageHeardReceiver extends BroadcastReceiver {
+
+    &#64;Override
+    public void onReceive(Context context, Intent intent) {
+
+        // If you set up the intent as described in
+        // "Create conversation read and reply intents",
+        // you can get the conversation ID by calling:
+        int conversationId = intent.getIntExtra("conversation_id", -1);
+
+        // Remove the notification to indicate it has been read
+        // and update the list of unread conversations in your app.
+    }
+}
+</pre>
+
+<p>
+  Once a notification is read, your app can remove it by calling
+  {@link android.support.v4.app.NotificationManagerCompat#cancel} with the notification ID.
+  Within your app, you should mark the messages provided in the notification as read.
+</p>
+
+
+<p class="note">
+  <strong>Note:</strong> An alternative to this implementation is to use a service in a
+  {@link android.app.PendingIntent}.
+</p>
+
+
+<h3 id="handling_reply">Handling a reply action</h3>
+
+<p>
+  When a user replies to a messaging conversation through the Auto user interface, the dashboard
+  system sends a reply intent based on how your app defined the messaging notification. Your app
+  catches that intent and invokes the broadcast receiver class associated with it, or the service
+  method set up to handle that action.
+</p>
+
+<p>
+  The following code example shows how to define a {@link android.content.BroadcastReceiver} class
+  to handle a received message reply intent:
+</p>
+
+<pre>
+  public class MessageReplyReceiver extends BroadcastReceiver {
+
+
+    &#64;Override
+    public void onReceive(Context context, Intent intent) {
+        // If you set up the intent as described in
+        // "Create conversation read and reply intents",
+        // you can get the conversation ID by calling:
+        int conversationId = intent.getIntExtra("conversation_id", -1).
+
+    }
+
+    /**
+     * Get the message text from the intent.
+     * Note that you should call
+     * RemoteInput.getResultsFromIntent() to process
+     * the RemoteInput.
+     */
+    private CharSequence getMessageText(Intent intent) {
+        Bundle remoteInput =
+            RemoteInput.getResultsFromIntent(intent);
+        if (remoteInput != null) {
+            return remoteInput.getCharSequence("extra_voice_reply");
+        }
+        return null;
+    }
+
+}</pre>
diff --git a/docs/html/training/auto/start/index.jd b/docs/html/training/auto/start/index.jd
new file mode 100644
index 0000000..b955cef
--- /dev/null
+++ b/docs/html/training/auto/start/index.jd
@@ -0,0 +1,210 @@
+page.title=Getting Started with Auto
+page.tags="auto", "car", "automotive"
+page.article=true
+page.image=auto/images/assets/icons/auto_app_in_simulator.png
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+  <h2>Dependencies and Prerequisites</h2>
+  <ul>
+    <li>Android 5.0 (API level 21) or higher</li>
+  </ul>
+
+  <h2>This class teaches you how to</h2>
+  <ol>
+    <li><a href="#dev-project">Set Up an Auto Project</a></li>
+    <li><a href="#build-it">Build Auto Apps</a></li>
+    <li><a href="#test-it">Run and Test Auto Apps</a></li>
+  </ol>
+
+ <h2>You should also read</h2>
+ <ul>
+   <li><a href="{@docRoot}design/auto/index.html">Designing for Auto</a></li>
+   <li><a href="{@docRoot}training/auto/audio/index.html">Providing Audio Playback with Auto</a></li>
+   <li><a href="{@docRoot}training/auto/messaging/index.html">Providing Messaging for Auto</a></li>
+ </ul>
+</div>
+</div>
+
+<p>Android Auto extends the Android platform into the car. When users connect
+their handheld devices running Android 5.0 or higher to a compatible vehicle,
+the Auto user interface provides a car-optimized Android experience on the
+vehicle's screen. Users interact with compatible apps and services through
+voice actions and the vehicle's input controls (like a touchscreen or dashboard
+buttons).</p>
+
+<p>Auto currently supports two types of apps:</p>
+
+<ul>
+<li><em>Audio apps</em> that allow users to browse and play music and spoken
+audio content in the car.</li>
+<li><em>Messaging apps</em> that receive incoming notifications, read messages
+  aloud via text-to-speech, and send replies via voice input in the car.</li>
+</ul>
+
+<p>You can enable your existing audio and messaging apps developed for
+phones and tablets to work in the car, without having to worry about
+vehicle-specific hardware differences. To enable your app for Auto, your
+app must target Android 5.0 (API level 21) or higher. Your app’s manifest must
+also declare the car capabilities that it uses, such as audio playback or
+messaging services. </p>
+
+<p>This lesson describes how to start building apps for Auto, including
+setting up your development environment and meeting the the minimum requirements
+to enable an app to communicate with Auto.</p>
+
+<p class="note"><strong>Important:</strong> If you are planning to develop
+apps for Auto, you are encouraged to begin enabling and testing your
+apps now. However, Auto-enabled apps cannot be published at this time.
+Join the
+<a href="http://g.co/AndroidAutoDev" class="external-link">Auto
+Developers Google+ community</a> for updates on when you will be able to submit
+your Auto-enabled apps.</p>
+
+<h2 id="dev-project">Set Up an Auto Project</h2>
+<p>This section describes how to create a new app or modify an existing app to
+communicate with Auto.</p>
+
+<h3 id="prerequisites">Prerequisites</h3>
+<p>Before you begin building apps for Auto, you must:</p>
+
+<ul>
+<li><strong><a href="{@docRoot}sdk/installing/create-project.html">Create or
+update your app project</a></strong> - Android 5.0 (API level 21) provides new
+APIs for implementing audio playback and messaging that is compatible with Auto.
+To access the new APIs, create a project or modify an existing project to target
+Android 5.0 (API level 21) or higher. This means you must set the manifest
+<a href="{@docRoot}topics/manifest/uses-sdk-element.html">{@code targetSdkVersion}</a>
+to 21 or higher.
+</li>
+<li><strong><a href="{@docRoot}tools/support-library/setup.html">Install the
+support library</a></strong> - If you are building messaging apps for Auto, you
+need the {@code NotificationCompat.CarExtender} class contained in the
+<a href="{@docRoot}tools/support-library/features.html#v4">v4 support library</a>.
+This class allows you to create notifications that are compatible with Auto
+devices.</li>
+</ul>
+
+<h3 id="auto-metadata">Declare Auto capabilities</h3>
+<p>The Auto features that your app can access are controlled
+by the settings in your app manifest and a separate XML configuration file.
+Before adding Auto features to your app, you must first define the Auto
+XML configuration file and add a manifest entry referencing your XML file.</p>
+
+<h4 id="auto_xml">Define the Auto XML configuration file</h4>
+<p>Specify the car capabilities that your app uses in an XML file that you
+place in your project’s resources directory ({@code res/xml/}). For example, to
+extend an audio application for Auto, create a file called
+{@code automotive_app_desc.xml} and store it under your projects’s
+{@code res/xml/} folder. The {@code automotive_app_desc.xml} file contains the
+following metadata:</p>
+<pre>
+&lt;automotiveApp&gt;
+   &lt;uses name="media" /&gt;
+&lt;/automotiveApp&gt;
+</pre>
+<p>The {@code &lt;uses&gt;} element declares the Auto capability your app
+intends to use. Multiple {@code &lt;uses&gt;} tags can be added if your
+application uses multiple car capabilities. The {@code name} attribute indicates
+the specific capability your app uses. The values supported are:</p>
+<ul>
+<li>{@code media} - The app uses the Android framework APIs to play music in
+a vehicle. Set this value if you are enabling an audio app for Auto.</li>
+<li>{@code notification} - The app displays message notifications in the car’s
+Overview screen, allows users select a message to be read aloud, and lets them
+respond through voice input. Set this value if you are enabling a messaging
+app for Auto.
+</ul>
+
+<h4 id="auto_xml">Add a manifest entry</h4>
+<p>In your app’s manifest ({@code AndroidManifest.xml}), provide a reference to
+the Auto XML configuration file you created in the previous section. Add a
+{@code "com.google.android.gms.car.application"} metadata entry under the
+<a href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
+element that references your Auto XML configuration file. Omit the {@code .xml}
+file extension when specifying the configuration filename.</p>
+<p>The following code snippet shows how to include this reference in your
+manifest.</p>
+<pre>
+&lt;application&gt;
+
+    ...
+    &lt;meta-data android:name="com.google.android.gms.car.application"
+     android:resource="@xml/automotive_app_desc"/&gt;
+
+&lt;/application&gt;
+</pre>
+
+<h2 id="build-it">Add Auto Features to Your Apps</h2>
+<p>After you have completed the steps described above, you're ready to add Auto
+features to your apps. See these additional topics to help you build apps for
+Auto:</p>
+
+<ul>
+<li><a href="{@docRoot}training/auto/audio/index.html">Providing Audio Playback for Auto</a>
+- Create apps that let users browse and play music in the car.</li>
+<li><a href="{@docRoot}training/auto/messaging/index.html">Providing Messaging for Auto</a>
+- Enable users to receive and reply to messages in the car.</li>
+</ul>
+
+<p class="caution"><strong>Important:</strong> Google takes driver distraction
+very seriously. There are specific design requirements your app must meet to
+qualify as an Auto app on Google Play. By adhering to these
+requirements, you can reduce the effort for building and testing your app. For
+more information, see
+<a href="{@docRoot}distribute/essentials/quality/auto.html">Auto App Quality</a>.</p>
+
+<h2 id="test-it">Run and Test Auto Apps</h2>
+
+<p>As you prepare to publish your app, make sure that your app looks correct
+when projected on the Auto user interface. Use the Android Media Browser
+simulator and Android Messaging simulators to view and test your audio or
+messaging apps in a screen that looks similar to what is projected on Auto.</p>
+
+<p>To get the simulators, open the
+<a href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a> and download
+them from <strong>Extras &gt; Android Auto API Simulators</strong>.</p>
+
+<p>Before you begin testing, compile your app in your development environment.
+Install your app and the Android simulator for the features you want to test
+(that is, audio or messaging) on a physical or virtual device running Android
+5.0 (API level 21) or higher. To check the version of Android on the device, go
+to <strong>Settings &gt; About &gt; Android Version</strong>.</p>
+
+<h3 id="testing-audio-apps">Testing audio apps</h3>
+<p>To run and test audio apps:</p>
+
+<ol>
+<li>Install the Android Media Browser simulator
+({@code media-browser-simulator.apk}) on the test device. You can do this using
+the <a href="{@docRoot}tools/help/adb.html#move">adb</a> command line tool.</li>
+<li>Enable <a href="{@docRoot}tools/device.html#device-developer-options">
+developer options</a> on the test device.</li>
+<li>Install your app on the test device.</li>
+<li>Launch the Android Media Browser simulator to see how your audio app
+appears in Auto. If your app does not appear, stop the simulator from
+<strong>Settings &gt; Apps</strong> then restart it.</li>
+</ol>
+
+<h3 id="testing-messaging-apps">Testing messaging apps</h3>
+<p>To run and test messaging apps:</p>
+
+<ol>
+<li>Install the Android Messaging simulator ({@code messaging-simulator.apk})
+on the test device. You can do this using the
+<a href="{@docRoot}tools/help/adb.html#move">adb</a> command line tool.</li>
+<li>Enable the simulator to read notifications posted on the system:
+<ol type="a">
+	<li>Enable <a href="{@docRoot}tools/device.html#device-developer-options">
+developer options</a> on the test device.</li>
+	<li>Click <strong>Settings &gt; Sounds &amp; Notifications &gt; Notification
+	Access</strong> and check the box labeled
+	<strong>Messaging Simulator</strong>.</li>
+</ol>
+<li>Install your app on the test device.</li>
+<li>Launch the Android Messaging Simulator to see how your messaging app appears
+in Auto. If your app does not appear, stop the simulator from
+<strong>Settings &gt; Apps</strong> then restart it.</li>
+</ol>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 9f06666..61a5e3c 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -939,6 +939,36 @@
   <!-- End: Building for TV -->
 
 
+  <!-- Start: Building for Auto -->
+  <li class="nav-section">
+    <div class="nav-section-header">
+      <a href="<?cs var:toroot ?>training/auto/index.html">
+      <span class="small">Building Apps for</span><br/>
+              Auto
+      </a>
+    </div>
+    <ul>
+      <li>
+        <a href="<?cs var:toroot ?>training/auto/start/index.html"
+             description="How to start building or extending apps that work
+             with Auto devices.">
+             Getting Started with Auto</a>
+      </li>
+      <li>
+        <a href="<?cs var:toroot ?>training/auto/audio/index.html"
+             description="How to extend audio apps to play content on Auto devices.">
+             Playing Audio for Auto</a>
+      </li>
+      <li>
+        <a href="<?cs var:toroot ?>training/auto/messaging/index.html"
+             description="How to extend text messaging apps to work with Auto devices.">
+             Messaging for Auto</a>
+      </li>
+    </ul>
+  </li>
+  <!-- End: Building for Auto -->
+
+
   <li class="nav-section">
     <div class="nav-section-header">
       <a href="<?cs var:toroot ?>training/best-ux.html">
diff --git a/graphics/java/android/graphics/ColorMatrix.java b/graphics/java/android/graphics/ColorMatrix.java
index 1242eb5..64f0c05 100644
--- a/graphics/java/android/graphics/ColorMatrix.java
+++ b/graphics/java/android/graphics/ColorMatrix.java
@@ -21,23 +21,43 @@
 import java.util.Arrays;
 
 /**
- *  4x5 matrix for transforming the color+alpha components of a Bitmap.
- *  The matrix is stored in a single array, and its treated as follows:
+ * 4x5 matrix for transforming the color and alpha components of a Bitmap.
+ * The matrix can be passed as single array, and is treated as follows:
+ *
  * <pre>
  *  [ a, b, c, d, e,
  *    f, g, h, i, j,
  *    k, l, m, n, o,
- *    p, q, r, s, t ]
- * </pre>
+ *    p, q, r, s, t ]</pre>
  *
- * When applied to a color <code>[r, g, b, a]</code>, the resulting color
- * is computed as (after clamping):
+ * <p>
+ * When applied to a color <code>[R, G, B, A]</code>, the resulting color
+ * is computed as:
+ * </p>
+ *
  * <pre>
- *   R' = a*R + b*G + c*B + d*A + e;
- *   G' = f*R + g*G + h*B + i*A + j;
- *   B' = k*R + l*G + m*B + n*A + o;
- *   A' = p*R + q*G + r*B + s*A + t;
- * </pre>
+ *   R&rsquo; = a*R + b*G + c*B + d*A + e;
+ *   G&rsquo; = f*R + g*G + h*B + i*A + j;
+ *   B&rsquo; = k*R + l*G + m*B + n*A + o;
+ *   A&rsquo; = p*R + q*G + r*B + s*A + t;</pre>
+ *
+ * <p>
+ * That resulting color <code>[R&rsquo;, G&rsquo;, B&rsquo;, A&rsquo;]</code>
+ * then has each channel clamped to the <code>0</code> to <code>255</code>
+ * range.
+ * </p>
+ *
+ * <p>
+ * The sample ColorMatrix below inverts incoming colors by scaling each
+ * channel by <code>-1</code>, and then shifting the result up by
+ * <code>255</code> to remain in the standard color space.
+ * </p>
+ *
+ * <pre>
+ *   [ -1, 0, 0, 0, 255,
+ *     0, -1, 0, 0, 255,
+ *     0, 0, -1, 0, 255,
+ *     0, 0, 0, 1, 0 ]</pre>
  */
 @SuppressWarnings({ "MismatchedReadAndWriteOfArray", "PointlessArithmeticExpression" })
 public class ColorMatrix {
@@ -52,24 +72,24 @@
     }
 
     /**
-        * Create a new colormatrix initialized with the specified array of values.
+     * Create a new colormatrix initialized with the specified array of values.
      */
     public ColorMatrix(float[] src) {
         System.arraycopy(src, 0, mArray, 0, 20);
     }
-    
+
     /**
      * Create a new colormatrix initialized with the specified colormatrix.
      */
     public ColorMatrix(ColorMatrix src) {
         System.arraycopy(src.mArray, 0, mArray, 0, 20);
     }
-    
+
     /**
      * Return the array of floats representing this colormatrix.
      */
     public final float[] getArray() { return mArray; }
-    
+
     /**
      * Set this colormatrix to identity:
      * <pre>
@@ -84,7 +104,7 @@
         Arrays.fill(a, 0);
         a[0] = a[6] = a[12] = a[18] = 1;
     }
-    
+
     /**
      * Assign the src colormatrix into this matrix, copying all of its values.
      */
@@ -98,7 +118,7 @@
     public void set(float[] src) {
         System.arraycopy(src, 0, mArray, 0, 20);
     }
-    
+
     /**
      * Set this colormatrix to scale by the specified values.
      */
@@ -114,12 +134,14 @@
         a[12] = bScale;
         a[18] = aScale;
     }
-    
+
     /**
      * Set the rotation on a color axis by the specified values.
+     * <p>
      * <code>axis=0</code> correspond to a rotation around the RED color
      * <code>axis=1</code> correspond to a rotation around the GREEN color
      * <code>axis=2</code> correspond to a rotation around the BLUE color
+     * </p>
      */
     public void setRotate(int axis, float degrees) {
         reset();
@@ -153,8 +175,10 @@
     /**
      * Set this colormatrix to the concatenation of the two specified
      * colormatrices, such that the resulting colormatrix has the same effect
-     * as applying matB and then applying matA. It is legal for either matA or
-     * matB to be the same colormatrix as this.
+     * as applying matB and then applying matA.
+     * <p>
+     * It is legal for either matA or matB to be the same colormatrix as this.
+     * </p>
      */
     public void setConcat(ColorMatrix matA, ColorMatrix matB) {
         float[] tmp;
@@ -163,7 +187,7 @@
         } else {
             tmp = mArray;
         }
-        
+
         final float[] a = matA.mArray;
         final float[] b = matB.mArray;
         int index = 0;
@@ -176,38 +200,43 @@
                            a[j + 2] * b[14] + a[j + 3] * b[19] +
                            a[j + 4];
         }
-        
+
         if (tmp != mArray) {
             System.arraycopy(tmp, 0, mArray, 0, 20);
         }
     }
 
     /**
-     * Concat this colormatrix with the specified prematrix. This is logically
-     * the same as calling setConcat(this, prematrix);
+     * Concat this colormatrix with the specified prematrix.
+     * <p>
+     * This is logically the same as calling setConcat(this, prematrix);
+     * </p>
      */
     public void preConcat(ColorMatrix prematrix) {
         setConcat(this, prematrix);
     }
 
     /**
-     * Concat this colormatrix with the specified postmatrix. This is logically
-     * the same as calling setConcat(postmatrix, this);
+     * Concat this colormatrix with the specified postmatrix.
+     * <p>
+     * This is logically the same as calling setConcat(postmatrix, this);
+     * </p>
      */
     public void postConcat(ColorMatrix postmatrix) {
         setConcat(postmatrix, this);
     }
 
     ///////////////////////////////////////////////////////////////////////////
-    
+
     /**
-     * Set the matrix to affect the saturation of colors. A value of 0 maps the
-     * color to gray-scale. 1 is identity.
+     * Set the matrix to affect the saturation of colors.
+     *
+     * @param sat A value of 0 maps the color to gray-scale. 1 is identity.
      */
     public void setSaturation(float sat) {
         reset();
         float[] m = mArray;
-        
+
         final float invSat = 1 - sat;
         final float R = 0.213f * invSat;
         final float G = 0.715f * invSat;
@@ -217,7 +246,7 @@
         m[5] = R;       m[6] = G + sat; m[7] = B;
         m[10] = R;      m[11] = G;      m[12] = B + sat;
     }
-    
+
     /**
      * Set the matrix to convert RGB to YUV
      */
@@ -229,7 +258,7 @@
         m[5]  = -0.16874f; m[6]  = -0.33126f; m[7]  = 0.5f;
         m[10] = 0.5f;      m[11] = -0.41869f; m[12] = -0.08131f;
     }
-    
+
     /**
      * Set the matrix to convert from YUV to RGB
      */
@@ -242,4 +271,3 @@
         m[10] = 1;  m[11] = 1.772f;     m[12] = 0;
     }
 }
-
diff --git a/include/androidfw/AttributeFinder.h b/include/androidfw/AttributeFinder.h
new file mode 100644
index 0000000..a0ffeb3
--- /dev/null
+++ b/include/androidfw/AttributeFinder.h
@@ -0,0 +1,201 @@
+/*
+ * 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.
+ */
+
+#ifndef H_ATTRIBUTE_FINDER
+#define H_ATTRIBUTE_FINDER
+
+#include <stdint.h>
+#include <utils/KeyedVector.h>
+
+namespace android {
+
+static inline uint32_t getPackage(uint32_t attr) {
+    return attr >> 24;
+}
+
+/**
+ * A helper class to search linearly for the requested
+ * attribute, maintaining it's position and optimizing for
+ * the case that subsequent searches will involve an attribute with
+ * a higher attribute ID.
+ *
+ * In the case that a subsequent attribute has a different package ID,
+ * its resource ID may not be larger than the preceding search, so
+ * back tracking is supported for this case. This
+ * back tracking requirement is mainly for shared library
+ * resources, whose package IDs get assigned at runtime
+ * and thus attributes from a shared library may
+ * be out of order.
+ *
+ * We make two assumptions about the order of attributes:
+ * 1) The input has the same sorting rules applied to it as
+ *    the attribute data contained by this class.
+ * 2) Attributes are grouped by package ID.
+ * 3) Among attributes with the same package ID, the attributes are
+ *    sorted by increasing resource ID.
+ *
+ * Ex: 02010000, 02010001, 010100f4, 010100f5, 0x7f010001, 07f010003
+ *
+ * The total order of attributes (including package ID) can not be linear
+ * as shared libraries get assigned dynamic package IDs at runtime, which
+ * may break the sort order established at build time.
+ */
+template <typename Derived, typename Iterator>
+class BackTrackingAttributeFinder {
+public:
+    BackTrackingAttributeFinder(const Iterator& begin, const Iterator& end);
+
+    Iterator find(uint32_t attr);
+
+private:
+    void jumpToClosestAttribute(uint32_t packageId);
+    void markCurrentPackageId(uint32_t packageId);
+
+    Iterator mBegin;
+    Iterator mEnd;
+    Iterator mCurrent;
+    Iterator mLargest;
+    uint32_t mLastPackageId;
+    uint32_t mCurrentAttr;
+
+    // Package Offsets (best-case, fast look-up).
+    Iterator mFrameworkStart;
+    Iterator mAppStart;
+
+    // Worst case, we have shared-library resources.
+    KeyedVector<uint32_t, Iterator> mPackageOffsets;
+};
+
+template <typename Derived, typename Iterator> inline
+BackTrackingAttributeFinder<Derived, Iterator>::BackTrackingAttributeFinder(const Iterator& begin, const Iterator& end)
+    : mBegin(begin)
+    , mEnd(end)
+    , mCurrent(begin)
+    , mLargest(begin)
+    , mLastPackageId(0)
+    , mCurrentAttr(0)
+    , mFrameworkStart(end)
+    , mAppStart(end) {
+}
+
+template <typename Derived, typename Iterator>
+void BackTrackingAttributeFinder<Derived, Iterator>::jumpToClosestAttribute(const uint32_t packageId) {
+    switch (packageId) {
+        case 0x01:
+            mCurrent = mFrameworkStart;
+            break;
+        case 0x7f:
+            mCurrent = mAppStart;
+            break;
+        default: {
+            ssize_t idx = mPackageOffsets.indexOfKey(packageId);
+            if (idx >= 0) {
+                // We have seen this package ID before, so jump to the first
+                // attribute with this package ID.
+                mCurrent = mPackageOffsets[idx];
+            } else {
+                mCurrent = mEnd;
+            }
+            break;
+        }
+    }
+
+    // We have never seen this package ID yet, so jump to the
+    // latest/largest index we have processed so far.
+    if (mCurrent == mEnd) {
+        mCurrent = mLargest;
+    }
+
+    if (mCurrent != mEnd) {
+        mCurrentAttr = static_cast<const Derived*>(this)->getAttribute(mCurrent);
+    }
+}
+
+template <typename Derived, typename Iterator>
+void BackTrackingAttributeFinder<Derived, Iterator>::markCurrentPackageId(const uint32_t packageId) {
+    switch (packageId) {
+        case 0x01:
+            mFrameworkStart = mCurrent;
+            break;
+        case 0x7f:
+            mAppStart = mCurrent;
+            break;
+        default:
+            mPackageOffsets.add(packageId, mCurrent);
+            break;
+    }
+}
+
+template <typename Derived, typename Iterator>
+Iterator BackTrackingAttributeFinder<Derived, Iterator>::find(uint32_t attr) {
+    if (!(mBegin < mEnd)) {
+        return mEnd;
+    }
+
+    if (mCurrentAttr == 0) {
+        // One-time initialization.
+        mCurrentAttr = static_cast<const Derived*>(this)->getAttribute(mBegin);
+        mLastPackageId = getPackage(mCurrentAttr);
+        markCurrentPackageId(mLastPackageId);
+    }
+
+    // Looking for the needle (attribute we're looking for)
+    // in the haystack (the attributes we're searching through)
+    const uint32_t needlePackageId = getPackage(attr);
+    if (mLastPackageId != needlePackageId) {
+        jumpToClosestAttribute(needlePackageId);
+        mLastPackageId = needlePackageId;
+    }
+
+    // Walk through the xml attributes looking for the requested attribute.
+    while (mCurrent != mEnd) {
+        const uint32_t haystackPackageId = getPackage(mCurrentAttr);
+        if (needlePackageId == haystackPackageId && attr < mCurrentAttr) {
+            // The attribute we are looking was not found.
+            break;
+        }
+        const uint32_t prevAttr = mCurrentAttr;
+
+        // Move to the next attribute in the XML.
+        ++mCurrent;
+        if (mCurrent != mEnd) {
+            mCurrentAttr = static_cast<const Derived*>(this)->getAttribute(mCurrent);
+            const uint32_t newHaystackPackageId = getPackage(mCurrentAttr);
+            if (haystackPackageId != newHaystackPackageId) {
+                // We've moved to the next group of attributes
+                // with a new package ID, so we should record
+                // the offset of this new package ID.
+                markCurrentPackageId(newHaystackPackageId);
+            }
+        }
+
+        if (mCurrent > mLargest) {
+            // We've moved past the latest attribute we've
+            // seen.
+            mLargest = mCurrent;
+        }
+
+        if (attr == prevAttr) {
+            // We found the attribute we were looking for.
+            return mCurrent - 1;
+        }
+    }
+    return mEnd;
+}
+
+} // namespace android
+
+#endif // H_ATTRIBUTE_FINDER
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 3cf1021..6dfb4dc 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -1185,7 +1185,11 @@
 {
     int32_t id = getAttributeNameID(idx);
     if (id >= 0 && (size_t)id < mTree.mNumResIds) {
-        return dtohl(mTree.mResIds[id]);
+        uint32_t resId = dtohl(mTree.mResIds[id]);
+        if (mTree.mDynamicRefTable != NULL) {
+            mTree.mDynamicRefTable->lookupResourceId(&resId);
+        }
+        return resId;
     }
     return 0;
 }
@@ -5977,11 +5981,11 @@
     // Do a proper lookup.
     uint8_t translatedId = mLookupTable[packageId];
     if (translatedId == 0) {
-        ALOGE("DynamicRefTable(0x%02x): No mapping for build-time package ID 0x%02x.",
+        ALOGV("DynamicRefTable(0x%02x): No mapping for build-time package ID 0x%02x.",
                 (uint8_t)mAssignedPackageId, (uint8_t)packageId);
         for (size_t i = 0; i < 256; i++) {
             if (mLookupTable[i] != 0) {
-                ALOGE("e[0x%02x] -> 0x%02x", (uint8_t)i, mLookupTable[i]);
+                ALOGV("e[0x%02x] -> 0x%02x", (uint8_t)i, mLookupTable[i]);
             }
         }
         return UNKNOWN_ERROR;
diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk
index 2d7906f..c1014be 100644
--- a/libs/androidfw/tests/Android.mk
+++ b/libs/androidfw/tests/Android.mk
@@ -20,6 +20,7 @@
 # ==========================================================
 LOCAL_PATH:= $(call my-dir)
 testFiles := \
+    AttributeFinder_test.cpp \
     ByteBucketArray_test.cpp \
     Config_test.cpp \
     ConfigLocale_test.cpp \
diff --git a/libs/androidfw/tests/AttributeFinder_test.cpp b/libs/androidfw/tests/AttributeFinder_test.cpp
new file mode 100644
index 0000000..664709c
--- /dev/null
+++ b/libs/androidfw/tests/AttributeFinder_test.cpp
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+#include <androidfw/AttributeFinder.h>
+
+#include <gtest/gtest.h>
+
+using android::BackTrackingAttributeFinder;
+
+class MockAttributeFinder : public BackTrackingAttributeFinder<MockAttributeFinder, int> {
+public:
+    MockAttributeFinder(const uint32_t* attrs, int len)
+        : BackTrackingAttributeFinder(0, len) {
+        mAttrs = new uint32_t[len];
+        memcpy(mAttrs, attrs, sizeof(*attrs) * len);
+    }
+
+    ~MockAttributeFinder() {
+        delete mAttrs;
+    }
+
+    inline uint32_t getAttribute(const int index) const {
+        return mAttrs[index];
+    }
+
+private:
+    uint32_t* mAttrs;
+};
+
+static const uint32_t sortedAttributes[] = {
+        0x01010000, 0x01010001, 0x01010002, 0x01010004,
+        0x02010001, 0x02010010, 0x7f010001
+};
+
+static const uint32_t packageUnsortedAttributes[] = {
+        0x02010001, 0x02010010, 0x01010000, 0x01010001,
+        0x01010002, 0x01010004, 0x7f010001
+};
+
+TEST(AttributeFinderTest, IteratesSequentially) {
+    const int end = sizeof(sortedAttributes) / sizeof(*sortedAttributes);
+    MockAttributeFinder finder(sortedAttributes, end);
+
+    EXPECT_EQ(0, finder.find(0x01010000));
+    EXPECT_EQ(1, finder.find(0x01010001));
+    EXPECT_EQ(2, finder.find(0x01010002));
+    EXPECT_EQ(3, finder.find(0x01010004));
+    EXPECT_EQ(4, finder.find(0x02010001));
+    EXPECT_EQ(5, finder.find(0x02010010));
+    EXPECT_EQ(6, finder.find(0x7f010001));
+    EXPECT_EQ(end, finder.find(0x7f010002));
+}
+
+TEST(AttributeFinderTest, PackagesAreOutOfOrder) {
+    const int end = sizeof(sortedAttributes) / sizeof(*sortedAttributes);
+    MockAttributeFinder finder(sortedAttributes, end);
+
+    EXPECT_EQ(6, finder.find(0x7f010001));
+    EXPECT_EQ(end, finder.find(0x7f010002));
+    EXPECT_EQ(4, finder.find(0x02010001));
+    EXPECT_EQ(5, finder.find(0x02010010));
+    EXPECT_EQ(0, finder.find(0x01010000));
+    EXPECT_EQ(1, finder.find(0x01010001));
+    EXPECT_EQ(2, finder.find(0x01010002));
+    EXPECT_EQ(3, finder.find(0x01010004));
+}
+
+TEST(AttributeFinderTest, SomeAttributesAreNotFound) {
+    const int end = sizeof(sortedAttributes) / sizeof(*sortedAttributes);
+    MockAttributeFinder finder(sortedAttributes, end);
+
+    EXPECT_EQ(0, finder.find(0x01010000));
+    EXPECT_EQ(1, finder.find(0x01010001));
+    EXPECT_EQ(2, finder.find(0x01010002));
+    EXPECT_EQ(end, finder.find(0x01010003));
+    EXPECT_EQ(3, finder.find(0x01010004));
+    EXPECT_EQ(end, finder.find(0x01010005));
+    EXPECT_EQ(end, finder.find(0x01010006));
+    EXPECT_EQ(4, finder.find(0x02010001));
+    EXPECT_EQ(end, finder.find(0x02010002));
+}
+
+TEST(AttributeFinderTest, FindAttributesInPackageUnsortedAttributeList) {
+    const int end = sizeof(packageUnsortedAttributes) / sizeof(*packageUnsortedAttributes);
+    MockAttributeFinder finder(packageUnsortedAttributes, end);
+
+    EXPECT_EQ(2, finder.find(0x01010000));
+    EXPECT_EQ(3, finder.find(0x01010001));
+    EXPECT_EQ(4, finder.find(0x01010002));
+    EXPECT_EQ(end, finder.find(0x01010003));
+    EXPECT_EQ(5, finder.find(0x01010004));
+    EXPECT_EQ(end, finder.find(0x01010005));
+    EXPECT_EQ(end, finder.find(0x01010006));
+    EXPECT_EQ(0, finder.find(0x02010001));
+    EXPECT_EQ(end, finder.find(0x02010002));
+    EXPECT_EQ(1, finder.find(0x02010010));
+    EXPECT_EQ(6, finder.find(0x7f010001));
+}
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index fc86e4f..e5a93bd 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -33,6 +33,8 @@
         return;
     }
 
+    ATRACE_NAME("AssetAtlas::init");
+
     mImage = new Image(buffer);
 
     if (mImage->getTexture()) {
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 952f739..6453206 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -66,6 +66,8 @@
 bool Caches::init() {
     if (mInitialized) return false;
 
+    ATRACE_NAME("Caches::init");
+
     glGenBuffers(1, &meshBuffer);
     glBindBuffer(GL_ARRAY_BUFFER, meshBuffer);
     glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW);
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index b95636b..9aa29ca 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -20,11 +20,18 @@
 
 #include "Caches.h"
 #include "DeferredDisplayList.h"
-#include "RenderState.h"
 #include "Layer.h"
 #include "LayerRenderer.h"
 #include "OpenGLRenderer.h"
 #include "RenderNode.h"
+#include "RenderState.h"
+#include "utils/TraceUtils.h"
+
+#define ATRACE_LAYER_WORK(label) \
+    ATRACE_FORMAT("%s HW Layer DisplayList %s %ux%u", \
+            label, \
+            (renderNode.get() != NULL) ? renderNode->getName() : "", \
+            getWidth(), getHeight())
 
 namespace android {
 namespace uirenderer {
@@ -223,6 +230,8 @@
 }
 
 void Layer::defer(const OpenGLRenderer& rootRenderer) {
+    ATRACE_LAYER_WORK("Optimize");
+
     updateLightPosFromRenderer(rootRenderer);
     const float width = layer.getWidth();
     const float height = layer.getHeight();
@@ -260,6 +269,9 @@
 void Layer::flush() {
     // renderer is checked as layer may be destroyed/put in layer cache with flush scheduled
     if (deferredList && renderer) {
+        ATRACE_LAYER_WORK("Issue");
+        renderer->startMark((renderNode.get() != NULL) ? renderNode->getName() : "Layer");
+
         renderer->setViewport(layer.getWidth(), layer.getHeight());
         renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom,
                 !isBlend());
@@ -270,10 +282,14 @@
 
         dirtyRect.setEmpty();
         renderNode = NULL;
+
+        renderer->endMark();
     }
 }
 
 void Layer::render(const OpenGLRenderer& rootRenderer) {
+    ATRACE_LAYER_WORK("Direct-Issue");
+
     updateLightPosFromRenderer(rootRenderer);
     renderer->setViewport(layer.getWidth(), layer.getHeight());
     renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom,
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 394c647..83f9c6a 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -27,6 +27,7 @@
 #include "Matrix.h"
 #include "Properties.h"
 #include "Rect.h"
+#include "utils/TraceUtils.h"
 
 namespace android {
 namespace uirenderer {
@@ -185,7 +186,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 Layer* LayerRenderer::createRenderLayer(RenderState& renderState, uint32_t width, uint32_t height) {
-    ATRACE_CALL();
+    ATRACE_FORMAT("Allocate %ux%u HW Layer", width, height);
     LAYER_RENDERER_LOGD("Requesting new render layer %dx%d", width, height);
 
     Caches& caches = Caches::getInstance();
@@ -310,7 +311,7 @@
 
 void LayerRenderer::destroyLayer(Layer* layer) {
     if (layer) {
-        ATRACE_CALL();
+        ATRACE_FORMAT("Destroy %ux%u HW Layer", layer->getWidth(), layer->getHeight());
         LAYER_RENDERER_LOGD("Recycling layer, %dx%d fbo = %d",
                 layer->getWidth(), layer->getHeight(), layer->getFbo());
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index d570b0d..80b4c2a 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -42,6 +42,7 @@
 #include "ShadowTessellator.h"
 #include "SkiaShader.h"
 #include "utils/GLUtils.h"
+#include "utils/TraceUtils.h"
 #include "Vector.h"
 #include "VertexBuffer.h"
 
@@ -51,21 +52,6 @@
     #define EVENT_LOGD(...)
 #endif
 
-static void atraceFormatBegin(const char* fmt, ...) {
-    const int BUFFER_SIZE = 256;
-    va_list ap;
-    char buf[BUFFER_SIZE];
-
-    va_start(ap, fmt);
-    vsnprintf(buf, BUFFER_SIZE, fmt, ap);
-    va_end(ap);
-
-    ATRACE_BEGIN(buf);
-}
-
-#define ATRACE_FORMAT_BEGIN(fmt, ...) \
-    if (CC_UNLIKELY(ATRACE_ENABLED())) atraceFormatBegin(fmt, ##__VA_ARGS__)
-
 namespace android {
 namespace uirenderer {
 
@@ -466,8 +452,6 @@
 bool OpenGLRenderer::updateLayer(Layer* layer, bool inFrame) {
     if (layer->deferredUpdateScheduled && layer->renderer
             && layer->renderNode.get() && layer->renderNode->isRenderable()) {
-        ATRACE_CALL();
-
         Rect& dirty = layer->dirtyRect;
 
         if (inFrame) {
@@ -525,20 +509,10 @@
     int count = mLayerUpdates.size();
     if (count > 0) {
         startMark("Apply Layer Updates");
-        char layerName[12];
 
         // Note: it is very important to update the layers in order
         for (int i = 0; i < count; i++) {
-            Layer* layer = mLayerUpdates.itemAt(i).get();
-
-            sprintf(layerName, "Layer #%d", i);
-            startMark(layerName);
-            ATRACE_FORMAT_BEGIN("flushLayer %ux%u", layer->getWidth(), layer->getHeight());
-
-            layer->flush();
-
-            ATRACE_END();
-            endMark();
+            mLayerUpdates.itemAt(i)->flush();
         }
 
         mLayerUpdates.clear();
@@ -575,7 +549,7 @@
 }
 
 void OpenGLRenderer::flushLayerUpdates() {
-    ATRACE_CALL();
+    ATRACE_NAME("Update HW Layers");
     syncState();
     updateLayers();
     flushLayers();
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 9ba8854..6f48e4d 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -255,7 +255,7 @@
 
 PathTexture* PathCache::addTexture(const PathDescription& entry, const SkPath *path,
         const SkPaint* paint) {
-    ATRACE_CALL();
+    ATRACE_NAME("Generate Path Texture");
 
     float left, top, offset;
     uint32_t width, height;
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp
index 0dad0dc..e6fd2dc 100644
--- a/libs/hwui/Program.cpp
+++ b/libs/hwui/Program.cpp
@@ -132,7 +132,7 @@
 }
 
 GLuint Program::buildShader(const char* source, GLenum type) {
-    ATRACE_CALL();
+    ATRACE_NAME("Build GL Shader");
 
     GLuint shader = glCreateShader(type);
     glShaderSource(shader, 1, &source, 0);
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 13c5499..eb0948f 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -25,7 +25,6 @@
 #include <SkCanvas.h>
 #include <algorithm>
 
-#include <utils/Trace.h>
 
 #include "DamageAccumulator.h"
 #include "Debug.h"
@@ -34,6 +33,7 @@
 #include "LayerRenderer.h"
 #include "OpenGLRenderer.h"
 #include "utils/MathUtils.h"
+#include "utils/TraceUtils.h"
 #include "renderthread/CanvasContext.h"
 
 namespace android {
@@ -426,6 +426,10 @@
                 clipFlags = 0; // all clipping done by saveLayer
             }
 
+            ATRACE_FORMAT("%s alpha caused %ssaveLayer %ux%u",
+                    getName(), clipFlags ? "" : "unclipped ",
+                    layerBounds.getWidth(), layerBounds.getHeight());
+
             SaveLayerOp* op = new (handler.allocator()) SaveLayerOp(
                     layerBounds.left, layerBounds.top, layerBounds.right, layerBounds.bottom,
                     properties().getAlpha() * 255, saveFlags);
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 3b8a9a4..5fcb194 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -26,6 +26,7 @@
 #include "Caches.h"
 #include "TextureCache.h"
 #include "Properties.h"
+#include "utils/TraceUtils.h"
 
 namespace android {
 namespace uirenderer {
@@ -266,7 +267,7 @@
         return;
     }
 
-    ATRACE_CALL();
+    ATRACE_FORMAT("Upload %ux%u Texture", bitmap->width(), bitmap->height());
 
     // We could also enable mipmapping if both bitmap dimensions are powers
     // of 2 but we'd have to deal with size changes. Let's keep this simple
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index ba878bac..af39f16 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -363,7 +363,7 @@
 }
 
 void Font::precache(const SkPaint* paint, const char* text, int numGlyphs) {
-    ATRACE_NAME("precacheText");
+    ATRACE_NAME("Precache Glyphs");
 
     if (numGlyphs == 0 || text == NULL) {
         return;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 6c3637d..39528be 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -71,6 +71,8 @@
 }
 
 void CanvasContext::setSurface(ANativeWindow* window) {
+    ATRACE_CALL();
+
     mNativeWindow = window;
 
     if (mEglSurface != EGL_NO_SURFACE) {
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 9bd6f41..378cf61 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -82,6 +82,8 @@
 void EglManager::initialize() {
     if (hasEglContext()) return;
 
+    ATRACE_NAME("Creating EGLContext");
+
     mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY,
             "Failed to get EGL_DEFAULT_DISPLAY! err=%s", egl_error_str());
diff --git a/libs/hwui/utils/TraceUtils.h b/libs/hwui/utils/TraceUtils.h
new file mode 100644
index 0000000..ff8ccb8
--- /dev/null
+++ b/libs/hwui/utils/TraceUtils.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+#ifndef TRACE_UTILS_H
+#define TRACE_UTILS_H
+
+#include <utils/Trace.h>
+
+#define ATRACE_FORMAT(fmt, ...) \
+    TraceUtils::TraceEnder __traceEnder = (TraceUtils::atraceFormatBegin(fmt, ##__VA_ARGS__), TraceUtils::TraceEnder())
+
+#define ATRACE_FORMAT_BEGIN(fmt, ...) \
+    TraceUtils::atraceFormatBegin(fmt, ##__VA_ARGS__)
+
+namespace android {
+namespace uirenderer {
+
+class TraceUtils {
+public:
+    class TraceEnder {
+    public:
+        ~TraceEnder() { ATRACE_END(); }
+    };
+
+    static void atraceFormatBegin(const char* fmt, ...) {
+        if (CC_UNLIKELY(!ATRACE_ENABLED())) return;
+
+        const int BUFFER_SIZE = 256;
+        va_list ap;
+        char buf[BUFFER_SIZE];
+
+        va_start(ap, fmt);
+        vsnprintf(buf, BUFFER_SIZE, fmt, ap);
+        va_end(ap);
+
+        ATRACE_BEGIN(buf);
+    }
+
+}; // class TraceUtils
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* TRACE_UTILS_H */
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index 58ed4f8..9a0266d 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -128,6 +128,29 @@
 
     /**
      * @hide
+     * Return the input channel mask corresponding to an output channel mask.
+     * This can be used for submix rerouting for the mask of the recorder to map to that of the mix.
+     * @param outMask a combination of the CHANNEL_OUT_* definitions, but not CHANNEL_OUT_DEFAULT
+     * @return a combination of CHANNEL_IN_* definitions matching an output channel mask
+     * @throws IllegalArgumentException
+     */
+    public static int inChannelMaskFromOutChannelMask(int outMask) throws IllegalArgumentException {
+        if (outMask == CHANNEL_OUT_DEFAULT) {
+            throw new IllegalArgumentException(
+                    "Illegal CHANNEL_OUT_DEFAULT channel mask for input.");
+        }
+        switch (channelCountFromOutChannelMask(outMask)) {
+            case 1:
+                return CHANNEL_IN_MONO;
+            case 2:
+                return CHANNEL_IN_STEREO;
+            default:
+                throw new IllegalArgumentException("Unsupported channel configuration for input.");
+        }
+    }
+
+    /**
+     * @hide
      * Return the number of channels from an input channel mask
      * @param mask a combination of the CHANNEL_IN_* definitions, even CHANNEL_IN_DEFAULT
      * @return number of channels for the mask
diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
index 7c0d758..a6cc493 100644
--- a/media/java/android/media/AudioManagerInternal.java
+++ b/media/java/android/media/AudioManagerInternal.java
@@ -35,4 +35,7 @@
 
     public abstract void setStreamVolumeForUid(int streamType, int direction, int flags,
             String callingPackage, int uid);
+
+    public abstract void adjustMasterVolumeForUid(int steps, int flags, String callingPackage,
+            int uid);
 }
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index a80b356..c70ac55 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -50,7 +50,6 @@
 import android.media.MediaPlayer.OnErrorListener;
 import android.media.audiopolicy.AudioMix;
 import android.media.audiopolicy.AudioPolicyConfig;
-import android.media.session.MediaSessionLegacyHelper;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Environment;
@@ -61,7 +60,6 @@
 import android.os.PowerManager;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -75,12 +73,11 @@
 import android.util.MathUtils;
 import android.util.Slog;
 import android.view.KeyEvent;
+import android.view.OrientationEventListener;
 import android.view.Surface;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
-import android.view.OrientationEventListener;
 
-import com.android.internal.telephony.ITelephony;
 import com.android.internal.util.XmlUtils;
 import com.android.server.LocalServices;
 
@@ -91,8 +88,6 @@
 import java.io.PrintWriter;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -100,6 +95,7 @@
 import java.util.NoSuchElementException;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * The implementation of the volume manager service.
@@ -1152,6 +1148,10 @@
 
     /** @see AudioManager#adjustMasterVolume(int, int) */
     public void adjustMasterVolume(int steps, int flags, String callingPackage) {
+        adjustMasterVolume(steps, flags, callingPackage, Binder.getCallingUid());
+    }
+
+    public void adjustMasterVolume(int steps, int flags, String callingPackage, int uid) {
         if (mUseFixedVolume) {
             return;
         }
@@ -1166,7 +1166,7 @@
         }
 
         //Log.d(TAG, "adjustMasterVolume volume: " + volume + " steps: " + steps);
-        setMasterVolume(volume, flags, callingPackage);
+        setMasterVolume(volume, flags, callingPackage, uid);
     }
 
     // StreamVolumeCommand contains the information needed to defer the process of
@@ -1679,18 +1679,24 @@
         }
     }
 
+    @Override
     public int getMasterVolume() {
         if (isMasterMute()) return 0;
         return getLastAudibleMasterVolume();
     }
 
+    @Override
     public void setMasterVolume(int volume, int flags, String callingPackage) {
+        setMasterVolume(volume, flags, callingPackage, Binder.getCallingUid());
+    }
+
+    public void setMasterVolume(int volume, int flags, String callingPackage, int uid) {
         if (mUseFixedVolume) {
             return;
         }
 
-        if (mAppOps.noteOp(AppOpsManager.OP_AUDIO_MASTER_VOLUME, Binder.getCallingUid(),
-                callingPackage) != AppOpsManager.MODE_ALLOWED) {
+        if (mAppOps.noteOp(AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage)
+                != AppOpsManager.MODE_ALLOWED) {
             return;
         }
 
@@ -1827,8 +1833,8 @@
                 if (!isStreamAffectedByRingerMode(streamType) ||
                     ringerMode == AudioManager.RINGER_MODE_NORMAL) {
                     // ring and notifications volume should never be 0 when not silenced
-                    // on voice capable devices
-                    if (isPlatformVoice() &&
+                    // on voice capable devices or devices that support vibration
+                    if ((isPlatformVoice() || mHasVibrator) &&
                             mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) {
                         synchronized (VolumeStreamState.class) {
                             Set set = mStreamStates[streamType].mIndex.entrySet();
@@ -5667,6 +5673,12 @@
                 String callingPackage, int uid) {
             setStreamVolume(streamType, direction, flags, callingPackage, uid);
         }
+
+        @Override
+        public void adjustMasterVolumeForUid(int steps, int flags, String callingPackage,
+                int uid) {
+            adjustMasterVolume(steps, flags, callingPackage, uid);
+        }
     }
 
     //==========================================================================================
diff --git a/media/java/android/media/MediaMetadata.java b/media/java/android/media/MediaMetadata.java
index 924078c..754da0e 100644
--- a/media/java/android/media/MediaMetadata.java
+++ b/media/java/android/media/MediaMetadata.java
@@ -16,8 +16,6 @@
 package android.media;
 
 import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -25,16 +23,14 @@
 import android.media.session.MediaController;
 import android.net.Uri;
 import android.os.Bundle;
-import android.os.CancellationSignal;
-import android.os.OperationCanceledException;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
-import android.util.Size;
 import android.util.SparseArray;
 
+import java.util.ArrayList;
 import java.util.Set;
 
 /**
@@ -569,6 +565,29 @@
         }
 
         /**
+         * Create a Builder using a {@link MediaMetadata} instance to set
+         * initial values, but replace bitmaps with a scaled down copy if they
+         * are larger than maxBitmapSize.
+         *
+         * @param source The original metadata to copy.
+         * @param maxBitmapSize The maximum height/width for bitmaps contained
+         *            in the metadata.
+         * @hide
+         */
+        public Builder(MediaMetadata source, int maxBitmapSize) {
+            this(source);
+            for (String key : mBundle.keySet()) {
+                Object value = mBundle.get(key);
+                if (value != null && value instanceof Bitmap) {
+                    Bitmap bmp = (Bitmap) value;
+                    if (bmp.getHeight() > maxBitmapSize || bmp.getWidth() > maxBitmapSize) {
+                        putBitmap(key, scaleBitmap(bmp, maxBitmapSize));
+                    }
+                }
+            }
+        }
+
+        /**
          * Put a CharSequence value into the metadata. Custom keys may be used,
          * but if the METADATA_KEYs defined in this class are used they may only
          * be one of the following:
@@ -707,6 +726,10 @@
          * <li>{@link #METADATA_KEY_ALBUM_ART}</li>
          * <li>{@link #METADATA_KEY_DISPLAY_ICON}</li>
          * </ul>
+         * <p>
+         * Large bitmaps may be scaled down by the system. To pass full
+         * resolution images {@link Uri Uris} should be used with
+         * {@link #putString}.
          *
          * @param key The key for referencing this value
          * @param value The Bitmap to store
@@ -731,5 +754,15 @@
         public MediaMetadata build() {
             return new MediaMetadata(mBundle);
         }
+
+        private Bitmap scaleBitmap(Bitmap bmp, int maxSize) {
+            float maxSizeF = maxSize;
+            float widthScale = maxSizeF / bmp.getWidth();
+            float heightScale = maxSizeF / bmp.getHeight();
+            float scale = Math.min(widthScale, heightScale);
+            int height = (int) (bmp.getHeight() * scale);
+            int width = (int) (bmp.getWidth() * scale);
+            return Bitmap.createScaledBitmap(bmp, width, height, true);
+        }
     }
 }
diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java
index 255d828..e9dc3af 100644
--- a/media/java/android/media/audiopolicy/AudioPolicy.java
+++ b/media/java/android/media/audiopolicy/AudioPolicy.java
@@ -155,6 +155,7 @@
         {
             throw new IllegalArgumentException("Invalid AudioMix: not defined for loop back");
         }
+        // TODO also check mix is defined for playback or recording, and matches forTrack argument
     }
 
     /**
@@ -175,13 +176,19 @@
             return null;
         }
         checkMixReadyToUse(mix, false/*not for an AudioTrack*/);
+        // create an AudioFormat from the mix format compatible with recording, as the mix
+        // was defined for playback
+        AudioFormat mixFormat = new AudioFormat.Builder(mix.getFormat())
+                .setChannelMask(AudioFormat.inChannelMaskFromOutChannelMask(
+                        mix.getFormat().getChannelMask()))
+                .build();
         // create the AudioRecord, configured for loop back, using the same format as the mix
         AudioRecord ar = new AudioRecord(
                 new AudioAttributes.Builder()
                         .setInternalCapturePreset(MediaRecorder.AudioSource.REMOTE_SUBMIX)
                         .addTag(mix.getRegistration())
                         .build(),
-                mix.getFormat(),
+                mixFormat,
                 AudioRecord.getMinBufferSize(mix.getFormat().getSampleRate(),
                         // using stereo for buffer size to avoid the current poor support for masks
                         AudioFormat.CHANNEL_IN_STEREO, mix.getFormat().getEncoding()),
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 973527f..e13f008 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -104,6 +104,7 @@
     public @interface SessionFlags { }
 
     private final Object mLock = new Object();
+    private final int mMaxBitmapSize;
 
     private final MediaSession.Token mSessionToken;
     private final MediaController mController;
@@ -147,6 +148,8 @@
         if (TextUtils.isEmpty(tag)) {
             throw new IllegalArgumentException("tag cannot be null or empty");
         }
+        mMaxBitmapSize = context.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.config_mediaMetadataBitmapMaxSize);
         mCbStub = new CallbackStub(this);
         MediaSessionManager manager = (MediaSessionManager) context
                 .getSystemService(Context.MEDIA_SESSION_SERVICE);
@@ -409,6 +412,7 @@
      * @param metadata The new metadata
      */
     public void setMetadata(@Nullable MediaMetadata metadata) {
+        metadata = (new MediaMetadata.Builder(metadata, mMaxBitmapSize)).build();
         try {
             mBinder.setMetadata(metadata);
         } catch (RemoteException e) {
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index 1ac80c1..da6f3fc 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -42,6 +42,7 @@
     private static final String TAG = "TvInputSessionWrapper";
 
     private static final int MESSAGE_HANDLING_DURATION_THRESHOLD_MILLIS = 50;
+    private static final int MESSAGE_TUNE_DURATION_THRESHOLD_MILLIS = 1000;
 
     private static final int DO_RELEASE = 1;
     private static final int DO_SET_MAIN = 2;
@@ -161,6 +162,11 @@
         if (duration > MESSAGE_HANDLING_DURATION_THRESHOLD_MILLIS) {
             Log.w(TAG, "Handling message (" + msg.what + ") took too long time (duration="
                     + duration + "ms)");
+            if (msg.what == DO_TUNE && duration > MESSAGE_TUNE_DURATION_THRESHOLD_MILLIS) {
+                throw new RuntimeException("Too much time to handle tune request. (" + duration
+                        + "ms > " + MESSAGE_TUNE_DURATION_THRESHOLD_MILLIS + "ms) "
+                        + "Consider handling the tune request in a separate thread.");
+            }
         }
     }
 
@@ -193,6 +199,8 @@
 
     @Override
     public void tune(Uri channelUri, Bundle params) {
+        // Clear the pending tune requests.
+        mCaller.removeMessages(DO_TUNE);
         mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_TUNE, channelUri, params));
     }
 
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 51bd205..de9d54f 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -1012,6 +1012,12 @@
     /**
      * Returns the TvStreamConfig list of the given TV input.
      *
+     * If you are using {@link Hardware} object from {@link
+     * #acquireTvInputHardware}, you should get the list of available streams
+     * from {@link HardwareCallback#onStreamConfigChanged} method, not from
+     * here. This method is designed to be used with {@link #captureFrame} in
+     * capture scenarios specifically and not suitable for any other use.
+     *
      * @param inputId the id of the TV input.
      * @return List of {@link TvStreamConfig} which is available for capturing
      *   of the given TV input.
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index f9d84c1..6fc1b82 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -18,7 +18,10 @@
 
 import android.annotation.SystemApi;
 import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.media.tv.TvInputManager.Session;
 import android.media.tv.TvInputManager.Session.FinishedInputEventCallback;
 import android.media.tv.TvInputManager.SessionCallback;
@@ -593,6 +596,42 @@
     }
 
     @Override
+    public boolean gatherTransparentRegion(Region region) {
+        if (mWindowZOrder != ZORDER_ON_TOP) {
+            if (region != null) {
+                int width = getWidth();
+                int height = getHeight();
+                if (width > 0 && height > 0) {
+                    int location[] = new int[2];
+                    getLocationInWindow(location);
+                    int left = location[0];
+                    int top = location[1];
+                    region.op(left, top, left + width, top + height, Region.Op.UNION);
+                }
+            }
+        }
+        return super.gatherTransparentRegion(region);
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        if (mWindowZOrder != ZORDER_ON_TOP) {
+            // Punch a hole so that the underlying overlay view and surface can be shown.
+            canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+        }
+        super.draw(canvas);
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        if (mWindowZOrder != ZORDER_ON_TOP) {
+            // Punch a hole so that the underlying overlay view and surface can be shown.
+            canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+        }
+        super.dispatchDraw(canvas);
+    }
+
+    @Override
     protected void onVisibilityChanged(View changedView, int visibility) {
         super.onVisibilityChanged(changedView, visibility);
         mSurfaceView.setVisibility(visibility);
diff --git a/packages/Keyguard/test/SampleTrustAgent/res/layout/sample_trust_agent_settings.xml b/packages/Keyguard/test/SampleTrustAgent/res/layout/sample_trust_agent_settings.xml
index 63694a8..00193ed8 100644
--- a/packages/Keyguard/test/SampleTrustAgent/res/layout/sample_trust_agent_settings.xml
+++ b/packages/Keyguard/test/SampleTrustAgent/res/layout/sample_trust_agent_settings.xml
@@ -44,15 +44,21 @@
             android:paddingTop="8dp"
             android:paddingBottom="8dp"
             android:text="Report unlock attempts" />
+    <CheckBox android:id="@+id/report_device_locked"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="8dp"
+            android:paddingBottom="8dp"
+            android:text="Report device locked or unlocked" />
 
     <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content">
-        <Button android:id="@+id/check_trusted"
+        <Button android:id="@+id/check_device_locked"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:text="Keyguard in trusted state?" />
-        <TextView android:id="@+id/check_trusted_result"
+                android:text="Device locked?" />
+        <TextView android:id="@+id/check_device_locked_result"
                 android:layout_width="0dp"
                 android:layout_height="wrap_content"
                 android:layout_weight="1" />
diff --git a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java
index f28d0e4..e6a0dd7 100644
--- a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java
+++ b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java
@@ -56,6 +56,7 @@
             = "preference.report_unlock_attempts";
     private static final String PREFERENCE_MANAGING_TRUST
             = "preference.managing_trust";
+    private static final String PREFERENCE_REPORT_DEVICE_LOCKED = "preference.report_device_locked";
 
     private static final String TAG = "SampleTrustAgent";
 
@@ -80,17 +81,37 @@
     @Override
     public void onTrustTimeout() {
         super.onTrustTimeout();
-        Toast.makeText(this, "onTrustTimeout(): timeout expired", Toast.LENGTH_SHORT).show();
+        logAndShowToast("onTrustTimeout(): timeout expired");
+    }
+
+    @Override
+    public void onDeviceLocked() {
+        super.onDeviceLocked();
+        if (getReportDeviceLocked(this)) {
+            logAndShowToast("onDeviceLocked(): device is now locked");
+        }
+    }
+
+    @Override
+    public void onDeviceUnlocked() {
+        super.onDeviceUnlocked();
+        if (getReportDeviceLocked(this)) {
+            logAndShowToast("onDeviceUnlocked(): device is now unlocked");
+        }
     }
 
     @Override
     public void onUnlockAttempt(boolean successful) {
         if (getReportUnlockAttempts(this)) {
-            Toast.makeText(this, "onUnlockAttempt(successful=" + successful + ")",
-                    Toast.LENGTH_SHORT).show();
+            logAndShowToast("onUnlockAttempt(successful=" + successful + ")");
         }
     }
 
+    private void logAndShowToast(String text) {
+        Log.i(TAG, text);
+        Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
+    }
+
     @Override
     public boolean onConfigure(List<PersistableBundle> options) {
         if (options != null) {
@@ -125,8 +146,7 @@
                             intent.getLongExtra(EXTRA_DURATION, 0),
                             intent.getBooleanExtra(EXTRA_INITIATED_BY_USER, false));
                 } catch (IllegalStateException e) {
-                    Toast.makeText(context,
-                            "IllegalStateException: " + e.getMessage(), Toast.LENGTH_SHORT).show();
+                    logAndShowToast("IllegalStateException: " + e.getMessage());
                 }
             } else if (ACTION_REVOKE_TRUST.equals(action)) {
                 revokeTrust();
@@ -160,6 +180,18 @@
         return sharedPreferences.getBoolean(PREFERENCE_REPORT_UNLOCK_ATTEMPTS, false);
     }
 
+    public static void setReportDeviceLocked(Context context, boolean enabled) {
+        SharedPreferences sharedPreferences = PreferenceManager
+                .getDefaultSharedPreferences(context);
+        sharedPreferences.edit().putBoolean(PREFERENCE_REPORT_DEVICE_LOCKED, enabled).apply();
+    }
+
+    public static boolean getReportDeviceLocked(Context context) {
+        SharedPreferences sharedPreferences = PreferenceManager
+                .getDefaultSharedPreferences(context);
+        return sharedPreferences.getBoolean(PREFERENCE_REPORT_DEVICE_LOCKED, false);
+    }
+
     public static void setIsManagingTrust(Context context, boolean enabled) {
         SharedPreferences sharedPreferences = PreferenceManager
                 .getDefaultSharedPreferences(context);
diff --git a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java
index 39a599e..29b15cb 100644
--- a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java
+++ b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java
@@ -31,8 +31,9 @@
     private static final int TRUST_DURATION_MS = 30 * 1000;
 
     private CheckBox mReportUnlockAttempts;
+    private CheckBox mReportDeviceLocked;
     private CheckBox mManagingTrust;
-    private TextView mCheckTrustedStateResult;
+    private TextView mCheckDeviceLockedResult;
 
     private KeyguardManager mKeyguardManager;
 
@@ -48,15 +49,18 @@
         findViewById(R.id.enable_trust).setOnClickListener(this);
         findViewById(R.id.revoke_trust).setOnClickListener(this);
         findViewById(R.id.crash).setOnClickListener(this);
-        findViewById(R.id.check_trusted).setOnClickListener(this);
+        findViewById(R.id.check_device_locked).setOnClickListener(this);
 
         mReportUnlockAttempts = (CheckBox) findViewById(R.id.report_unlock_attempts);
         mReportUnlockAttempts.setOnCheckedChangeListener(this);
 
+        mReportDeviceLocked = (CheckBox) findViewById(R.id.report_device_locked);
+        mReportDeviceLocked.setOnCheckedChangeListener(this);
+
         mManagingTrust = (CheckBox) findViewById(R.id.managing_trust);
         mManagingTrust.setOnCheckedChangeListener(this);
 
-        mCheckTrustedStateResult = (TextView) findViewById(R.id.check_trusted_result);
+        mCheckDeviceLockedResult = (TextView) findViewById(R.id.check_device_locked_result);
     }
 
     @Override
@@ -77,7 +81,7 @@
             SampleTrustAgent.sendRevokeTrust(this);
         } else if (id == R.id.crash) {
             throw new RuntimeException("crash");
-        } else if (id == R.id.check_trusted) {
+        } else if (id == R.id.check_device_locked) {
             updateTrustedState();
         }
     }
@@ -88,11 +92,13 @@
             SampleTrustAgent.setReportUnlockAttempts(this, isChecked);
         } else if (buttonView == mManagingTrust) {
             SampleTrustAgent.setIsManagingTrust(this, isChecked);
+        } else if (buttonView == mReportDeviceLocked) {
+            SampleTrustAgent.setReportDeviceLocked(this, isChecked);
         }
     }
 
     private void updateTrustedState() {
-        mCheckTrustedStateResult.setText(Boolean.toString(
-                mKeyguardManager.isKeyguardInTrustedState()));
+        mCheckDeviceLockedResult.setText(Boolean.toString(
+                mKeyguardManager.isDeviceLocked()));
     }
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 1771eac..175b424 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2620,8 +2620,7 @@
             // Set the preferred network mode to target desired value or Default
             // value defined in RILConstants
             int type;
-            type = SystemProperties.getInt("ro.telephony.default_network",
-                        RILConstants.PREFERRED_NETWORK_MODE);
+            type = RILConstants.PREFERRED_NETWORK_MODE;
             loadSetting(stmt, Settings.Global.PREFERRED_NETWORK_MODE, type);
 
             // Set the preferred cdma subscription source to target desired value or default
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index b3e60d1..0cbbf875 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -55,6 +55,7 @@
     <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
     <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
     <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
+    <uses-permission android:name="android.permission.CONTROL_VPN" />
 
     <!-- Physical hardware -->
     <uses-permission android:name="android.permission.MANAGE_USB" />
@@ -210,7 +211,7 @@
         <activity android:name=".usb.UsbConfirmActivity"
             android:exported="true"
             android:permission="android.permission.MANAGE_USB"
-            android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert"
+            android:theme="@style/Theme.SystemUI.Dialog.Alert"
             android:finishOnCloseSystemDialogs="true"
             android:excludeFromRecents="true">
         </activity>
@@ -219,7 +220,7 @@
         <activity android:name=".usb.UsbPermissionActivity"
             android:exported="true"
             android:permission="android.permission.MANAGE_USB"
-            android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert"
+            android:theme="@style/Theme.SystemUI.Dialog.Alert"
             android:finishOnCloseSystemDialogs="true"
             android:excludeFromRecents="true">
         </activity>
@@ -228,7 +229,7 @@
         <activity android:name=".usb.UsbResolverActivity"
             android:exported="true"
             android:permission="android.permission.MANAGE_USB"
-            android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert"
+            android:theme="@style/Theme.SystemUI.Dialog.Alert"
             android:finishOnCloseSystemDialogs="true"
             android:excludeFromRecents="true">
         </activity>
@@ -237,7 +238,7 @@
         <activity android:name=".usb.UsbAccessoryUriActivity"
             android:exported="true"
             android:permission="android.permission.MANAGE_USB"
-            android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert"
+            android:theme="@style/Theme.SystemUI.Dialog.Alert"
             android:finishOnCloseSystemDialogs="true"
             android:excludeFromRecents="true">
         </activity>
@@ -245,7 +246,7 @@
         <!-- started from UsbDebuggingManager -->
         <activity android:name=".usb.UsbDebuggingActivity"
             android:permission="android.permission.MANAGE_USB"
-            android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert"
+            android:theme="@style/Theme.SystemUI.Dialog.Alert"
             android:finishOnCloseSystemDialogs="true"
             android:excludeFromRecents="true">
         </activity>
@@ -265,7 +266,7 @@
         <activity
             android:name=".media.MediaProjectionPermissionActivity"
             android:exported="true"
-            android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert"
+            android:theme="@style/Theme.SystemUI.Dialog.Alert"
             android:finishOnCloseSystemDialogs="true"
             android:launchMode="singleTop"
             android:excludeFromRecents="true" />
diff --git a/packages/SystemUI/res/anim/recents_from_app_enter.xml b/packages/SystemUI/res/anim/recents_from_app_enter.xml
index 6abe8b3..10ddce6 100644
--- a/packages/SystemUI/res/anim/recents_from_app_enter.xml
+++ b/packages/SystemUI/res/anim/recents_from_app_enter.xml
@@ -16,7 +16,7 @@
 ** limitations under the License.
 */
 -->
-
+<!-- Recents Activity -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
      android:shareInterpolator="false"
      android:zAdjustment="top">
diff --git a/packages/SystemUI/res/anim/recents_from_app_exit.xml b/packages/SystemUI/res/anim/recents_from_app_exit.xml
index 1447a5a..c98ecf4 100644
--- a/packages/SystemUI/res/anim/recents_from_app_exit.xml
+++ b/packages/SystemUI/res/anim/recents_from_app_exit.xml
@@ -16,7 +16,7 @@
 ** limitations under the License.
 */
 -->
-
+<!-- Incoming Activity -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
      android:shareInterpolator="false"
      android:zAdjustment="normal">
diff --git a/packages/SystemUI/res/anim/recents_from_search_launcher_enter.xml b/packages/SystemUI/res/anim/recents_from_search_launcher_enter.xml
index 20e7764..7de4460 100644
--- a/packages/SystemUI/res/anim/recents_from_search_launcher_enter.xml
+++ b/packages/SystemUI/res/anim/recents_from_search_launcher_enter.xml
@@ -16,13 +16,13 @@
 ** limitations under the License.
 */
 -->
-
+<!-- Recents Activity -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
      android:shareInterpolator="false"
      android:zAdjustment="normal">
-  <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+  <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
          android:fillEnabled="true"
          android:fillBefore="true" android:fillAfter="true"
          android:interpolator="@android:interpolator/linear"
-         android:duration="50"/>
+         android:duration="1"/>
 </set>
diff --git a/packages/SystemUI/res/anim/recents_from_search_launcher_exit.xml b/packages/SystemUI/res/anim/recents_from_search_launcher_exit.xml
index 92a8882..e0e2fc8 100644
--- a/packages/SystemUI/res/anim/recents_from_search_launcher_exit.xml
+++ b/packages/SystemUI/res/anim/recents_from_search_launcher_exit.xml
@@ -16,14 +16,13 @@
 ** limitations under the License.
 */
 -->
-
+<!-- Launcher Activity -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
      android:shareInterpolator="false"
      android:zAdjustment="top">
   <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
-  		 android:startOffset="50"
          android:fillEnabled="true"
          android:fillBefore="true" android:fillAfter="true"
          android:interpolator="@android:interpolator/linear_out_slow_in"
-         android:duration="100"/>
+         android:duration="@integer/recents_enter_from_home_transition_duration"/>
 </set>
diff --git a/packages/SystemUI/res/anim/recents_to_search_launcher_enter.xml b/packages/SystemUI/res/anim/recents_to_search_launcher_enter.xml
index 4e1d66d..ea82835 100644
--- a/packages/SystemUI/res/anim/recents_to_search_launcher_enter.xml
+++ b/packages/SystemUI/res/anim/recents_to_search_launcher_enter.xml
@@ -16,7 +16,7 @@
 ** limitations under the License.
 */
 -->
-
+<!-- Launcher Activity -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
      android:shareInterpolator="false"
      android:zAdjustment="normal">
diff --git a/packages/SystemUI/res/anim/recents_to_search_launcher_exit.xml b/packages/SystemUI/res/anim/recents_to_search_launcher_exit.xml
index d7a12a4..a8bdc8e 100644
--- a/packages/SystemUI/res/anim/recents_to_search_launcher_exit.xml
+++ b/packages/SystemUI/res/anim/recents_to_search_launcher_exit.xml
@@ -16,14 +16,13 @@
 ** limitations under the License.
 */
 -->
-
+<!-- Recents Activity -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
      android:shareInterpolator="false"
      android:zAdjustment="top">
-  <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
-  		 android:startOffset="100"
+  <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
          android:fillEnabled="true"
          android:fillBefore="true" android:fillAfter="true"
          android:interpolator="@android:interpolator/linear"
-         android:duration="50"/>
+         android:duration="100"/>
 </set>
diff --git a/packages/SystemUI/res/drawable-hdpi/btn_fab_recents.png b/packages/SystemUI/res/drawable-hdpi/btn_fab_recents.png
deleted file mode 100644
index b95fde5..0000000
--- a/packages/SystemUI/res/drawable-hdpi/btn_fab_recents.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
index 5be74ec..d2760bb 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
index 305c9fb..5cbf418 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
index 3e676ab..d6e2065 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
index d3e1f7a..df43e21b 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
index d632600..6be4161 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png
index 1233fca..552a3d1 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_small.png
index 6768c1f..6016ac4 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_small.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
index 8984a49d..72b2b21 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
index 2e8f8f0..bcb203e 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
index ec499d4..6fab1d6 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
index 13e8a4f..b031273 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
index c697da7..2fcfdde 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
index 94404df..2f4dbbe 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
index 9d0014d..48708a5 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
index 9a8b0e9..d04d84f 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
deleted file mode 100644
index 80d60af..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
deleted file mode 100644
index 2dfe964..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
deleted file mode 100644
index fd1cc27..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
deleted file mode 100644
index 183aa0d..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
deleted file mode 100644
index 6f763a4..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
deleted file mode 100644
index 3dc75a3..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png
deleted file mode 100644
index 83040fd..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png
deleted file mode 100644
index 9917be4..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
index c116bbe..3d73184 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
index 1446850..1500ae5 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
index 83040fd..786935d 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
index 9917be4..a7fec49 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/btn_fab_recents.png b/packages/SystemUI/res/drawable-mdpi/btn_fab_recents.png
deleted file mode 100644
index 6bbed06..0000000
--- a/packages/SystemUI/res/drawable-mdpi/btn_fab_recents.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
index 447c655..1d8c3af 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
index d5ca622..47c6ebd 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
index 47985de..12ceb90 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
index 7b5fe8b..66de0ec 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
index 9fcb705..dc8809e 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png
index 4d9c21c..48b96d8 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_small.png
index 9f0570a..9bdc305 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_small.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
index 23c24ba..35e7af4 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
index 41c1acb..94c9743 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
index 11a92f0..30c65f5 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
index 7fb14a8..5178ac5 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
deleted file mode 100644
index eaac305..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
deleted file mode 100644
index b5d3739..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
deleted file mode 100644
index 9915260..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
deleted file mode 100644
index 4a349e2..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
deleted file mode 100644
index d14da80..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png
index 11e3b65..23ec6db 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_small.png
index afcc487..91a4d2d 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_small.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
deleted file mode 100644
index 4f5e723..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
deleted file mode 100644
index 05b9b44..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
deleted file mode 100644
index 2035323..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index 69b541b..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
deleted file mode 100644
index 3f2b8b4..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
deleted file mode 100644
index 23e5e8f..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
deleted file mode 100644
index 4b7f3ac..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
deleted file mode 100644
index 41054f6..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
deleted file mode 100644
index e4a7181..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png
index 24442343..e450058 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_small.png
index a3e32f4c..edd53aa 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_small.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
deleted file mode 100644
index be678e0..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
deleted file mode 100644
index 24d37e0..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
deleted file mode 100644
index 9443656..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index c3c64f4..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
deleted file mode 100644
index 0ab43ce..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
deleted file mode 100644
index 3c58211..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
deleted file mode 100644
index 14ff6d3..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
deleted file mode 100644
index eb74d0d..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
deleted file mode 100644
index e29c9d0..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png
index 298b62f..d18e419 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_small.png
index 41f4b42..cb54780 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_small.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
deleted file mode 100644
index cfecdcf..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
deleted file mode 100644
index d98208a..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 71cc61b..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index bdecf06..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png
deleted file mode 100644
index 01edd86..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png
deleted file mode 100644
index 52bd6e8..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png
deleted file mode 100644
index b0dd0f0..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png
deleted file mode 100644
index b5c189d..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png
deleted file mode 100644
index 42e9e31..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_large.png
index 5ef7798..00a751c 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_large.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_small.png
index 4a98e31..dfc8f96 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_small.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png
deleted file mode 100644
index 669d8ba..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png
deleted file mode 100644
index 0fbf1f6..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 023b94c..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index 5884492..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/btn_fab_recents.png b/packages/SystemUI/res/drawable-xhdpi/btn_fab_recents.png
deleted file mode 100644
index 4cdd0aa..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/btn_fab_recents.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
index 4956aad..a356285 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
index e9a6223..42893ff 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
index e9767a1..98be526 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
index acaf32d..ba2d0b2 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
index 20cb101..eed3f54 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_large.png
index e62dece..e49db34 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_large.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_small.png
index 958b2fe0..0b75558 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_small.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
index cc620a2..69a018d 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
index aa8a60e..8a7ac4f 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
index 88d6a41..94a74b1 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
index 8acdd3c..22ae09d 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/btn_fab_recents.png b/packages/SystemUI/res/drawable-xxhdpi/btn_fab_recents.png
deleted file mode 100644
index 2220d60..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/btn_fab_recents.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
index 01edd86..29da099 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
index 52bd6e8..ada2879 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
index b0dd0f0..c819545 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
index b5c189d..59b32f2 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
index 42e9e31..6075caf 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_large.png
index 55a266f..b91704a 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_large.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_small.png
index 97d1fbc..d83d285 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_small.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
index 669d8ba..a37ca5d 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
index 0fbf1f6..62f44e8 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
index 023b94c..ba66d27 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
index 5884492..bccda1b 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/recents_lock_to_task_button_bg.xml b/packages/SystemUI/res/drawable/recents_lock_to_task_button_bg.xml
index 6424a65..8a8164a 100644
--- a/packages/SystemUI/res/drawable/recents_lock_to_task_button_bg.xml
+++ b/packages/SystemUI/res/drawable/recents_lock_to_task_button_bg.xml
@@ -16,5 +16,11 @@
 
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
      android:color="#ff9cdfd9">
-    <item android:drawable="@drawable/btn_fab_recents" />
+     <item>
+          <shape android:shape="oval">
+               <solid android:color="#9cc8c4" />
+               <size android:width="@dimen/recents_lock_to_app_size"
+                     android:height="@dimen/recents_lock_to_app_size" />
+          </shape>
+     </item>
 </ripple>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
index 0c0be29..b5d2f86 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
@@ -20,7 +20,7 @@
 
 <com.android.systemui.recent.RecentsPanelView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+    xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/recents_root"
     android:layout_height="match_parent"
     android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml b/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml
index c2733fb..456d2f9 100644
--- a/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml
+++ b/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml
@@ -19,7 +19,7 @@
 <!--  navigation bar for sw600dp (small tablets) -->
 <com.android.systemui.statusbar.phone.NavigationBarView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+    xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_height="match_parent"
     android:layout_width="match_parent"
     android:background="@drawable/system_bar_background"
@@ -57,6 +57,7 @@
                 android:layout_width="128dp" android:paddingStart="25dp" android:paddingEnd="25dp"
                 android:layout_height="match_parent"
                 android:src="@drawable/ic_sysbar_back"
+                android:scaleType="centerInside"
                 systemui:keyCode="4"
                 android:layout_weight="0"
                 android:contentDescription="@string/accessibility_back"
@@ -65,6 +66,7 @@
                 android:layout_width="128dp" android:paddingStart="25dp" android:paddingEnd="25dp"
                 android:layout_height="match_parent"
                 android:src="@drawable/ic_sysbar_home"
+                android:scaleType="centerInside"
                 systemui:keyCode="3"
                 systemui:keyRepeat="true"
                 android:layout_weight="0"
@@ -74,6 +76,7 @@
                 android:layout_width="128dp" android:paddingStart="25dp" android:paddingEnd="25dp"
                 android:layout_height="match_parent"
                 android:src="@drawable/ic_sysbar_recent"
+                android:scaleType="centerInside"
                 android:layout_weight="0"
                 android:contentDescription="@string/accessibility_recent"
                 />
@@ -91,6 +94,7 @@
                     android:layout_width="@dimen/navigation_extra_key_width"
                     android:layout_height="match_parent"
                     android:src="@drawable/ic_sysbar_menu"
+                    android:scaleType="centerInside"
                     android:layout_marginEnd="2dp"
                     systemui:keyCode="82"
                     android:visibility="invisible"
@@ -198,6 +202,7 @@
                 android:layout_width="162dp" android:paddingStart="42dp" android:paddingEnd="42dp"
                 android:layout_height="match_parent"
                 android:src="@drawable/ic_sysbar_back"
+                android:scaleType="centerInside"
                 systemui:keyCode="4"
                 android:layout_weight="0"
                 android:contentDescription="@string/accessibility_back"
@@ -206,6 +211,7 @@
                 android:layout_width="162dp" android:paddingStart="42dp" android:paddingEnd="42dp"
                 android:layout_height="match_parent"
                 android:src="@drawable/ic_sysbar_home"
+                android:scaleType="centerInside"
                 systemui:keyCode="3"
                 systemui:keyRepeat="true"
                 android:layout_weight="0"
@@ -215,6 +221,7 @@
                 android:layout_width="162dp" android:paddingStart="42dp" android:paddingEnd="42dp"
                 android:layout_height="match_parent"
                 android:src="@drawable/ic_sysbar_recent"
+                android:scaleType="centerInside"
                 android:layout_weight="0"
                 android:contentDescription="@string/accessibility_recent"
                 />
@@ -233,6 +240,7 @@
                     android:layout_height="match_parent"
                     android:layout_marginEnd="2dp"
                     android:src="@drawable/ic_sysbar_menu"
+                    android:scaleType="centerInside"
                     systemui:keyCode="82"
                     android:visibility="invisible"
                     android:contentDescription="@string/accessibility_menu" />
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index 2e38b20..898389d 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -20,7 +20,7 @@
 
 <com.android.systemui.statusbar.phone.NavigationBarView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+    xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_height="match_parent"
     android:layout_width="match_parent"
     android:background="@drawable/system_bar_background"
@@ -98,6 +98,7 @@
                     android:contentDescription="@string/accessibility_menu"
                     android:src="@drawable/ic_sysbar_menu"
                     android:visibility="invisible"
+                    android:scaleType="centerInside"
                     android:layout_gravity="end"
                     systemui:keyCode="82" />
 
@@ -210,6 +211,7 @@
                     android:layout_height="40dp"
                     android:contentDescription="@string/accessibility_menu"
                     android:src="@drawable/ic_sysbar_menu_land"
+                    android:scaleType="centerInside"
                     android:layout_gravity="top"
                     android:visibility="invisible"
                     systemui:keyCode="82" />
diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
index f776a87..a996260 100644
--- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
+++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+    xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:paddingLeft="16dp"
     android:paddingRight="16dp"
     style="@style/BrightnessDialogContainer">
diff --git a/packages/SystemUI/res/layout/recents_task_view.xml b/packages/SystemUI/res/layout/recents_task_view.xml
index d1d3828..9c6f67c 100644
--- a/packages/SystemUI/res/layout/recents_task_view.xml
+++ b/packages/SystemUI/res/layout/recents_task_view.xml
@@ -29,8 +29,8 @@
         <include layout="@layout/recents_task_view_header" />
         <FrameLayout
             android:id="@+id/lock_to_app_fab"
-            android:layout_width="48dp"
-            android:layout_height="48dp"
+            android:layout_width="@dimen/recents_lock_to_app_size"
+            android:layout_height="@dimen/recents_lock_to_app_size"
             android:layout_gravity="bottom|right"
             android:layout_marginRight="15dp"
             android:layout_marginBottom="15dp"
@@ -38,8 +38,8 @@
             android:contentDescription="@string/recents_lock_to_app_button_label"
             android:background="@drawable/recents_lock_to_task_button_bg">
             <ImageView
-                android:layout_width="24dp"
-                android:layout_height="24dp"
+                android:layout_width="@dimen/recents_lock_to_app_icon_size"
+                android:layout_height="@dimen/recents_lock_to_app_icon_size"
                 android:layout_gravity="center"
                 android:src="@drawable/recents_lock_to_app_pin" />
         </FrameLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index 9912e89c..2fb7cdbf 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -18,7 +18,7 @@
 <!-- Extends RelativeLayout -->
 <com.android.systemui.statusbar.phone.StatusBarHeaderView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+    xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/header"
     android:layout_width="@dimen/notification_panel_width"
     android:layout_height="@dimen/status_bar_header_height"
diff --git a/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml b/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml
index ef85847..4526af5 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml
@@ -32,6 +32,7 @@
         />
 
     <LinearLayout
+        android:id="@+id/content"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
         <TextView
diff --git a/packages/SystemUI/res/layout/status_bar_recent_panel.xml b/packages/SystemUI/res/layout/status_bar_recent_panel.xml
index 2f3968d..588873a 100644
--- a/packages/SystemUI/res/layout/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout/status_bar_recent_panel.xml
@@ -20,7 +20,7 @@
 
 <com.android.systemui.recent.RecentsPanelView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+    xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/recents_root"
     android:layout_height="match_parent"
     android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index d319dc4..3df06f3 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -353,20 +353,12 @@
     <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>
-    <!-- no translation found for screen_pinning_title (3273740381976175811) -->
-    <skip />
-    <!-- no translation found for screen_pinning_description (1346522416878235405) -->
-    <skip />
-    <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
-    <skip />
-    <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
-    <skip />
-    <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
-    <skip />
-    <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
-    <skip />
-    <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
-    <skip />
-    <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
-    <skip />
+    <string name="screen_pinning_title" msgid="3273740381976175811">"තීරය අමුණන ලදි"</string>
+    <string name="screen_pinning_description" msgid="1346522416878235405">"ඔබ ගලවන තෙක් එය දර්ශනය තුළ මෙය තබයි. ගැලවීමට ආපසු සහ දළ විශ්ලේෂණය එකම වේලාවක ස්පර්ෂ කර අල්ලා සිටින්න."</string>
+    <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"ඔබ ගලවන තෙක් එය දර්ශනය තුළ මෙය තබයි. ගැලවීමට දළ විශ්ලේෂණය ස්පර්ෂ කර අල්ලා සිටින්න."</string>
+    <string name="screen_pinning_positive" msgid="3783985798366751226">"හරි, තේරුණා"</string>
+    <string name="screen_pinning_negative" msgid="3741602308343880268">"එපා ස්තූතියි"</string>
+    <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> සඟවන්නද?"</string>
+    <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"ඊළඟ අවස්ථාවේ සැකසීම් තුළ ඔබ එය සක්‍රිය කළ විට එය නැවත දිසිවේ."</string>
+    <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"සඟවන්න"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-television/styles.xml b/packages/SystemUI/res/values-television/styles.xml
new file mode 100644
index 0000000..53dc4aa
--- /dev/null
+++ b/packages/SystemUI/res/values-television/styles.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <style name="Theme.SystemUI.Dialog.Alert" parent="@*android:style/Theme.DeviceDefault.Dialog.Alert" />
+</resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 72041c5..64b6f84 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -354,8 +354,8 @@
     <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="screen_pinning_title" msgid="3273740381976175811">"اسکرین پن کردہ ہے"</string>
-    <string name="screen_pinning_description" msgid="1346522416878235405">"یہ اس کو اس وقت تک منظر میں رکھتا ہے جب تک آپ اس سے پن نہیں ہٹا دیتے۔ پن ہٹانے کیلئے واپس اور عام جائزہ کو ایک ساتھ ٹچ کریں اور پکڑ کر رکھیں۔"</string>
-    <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"یہ اس کو اس وقت تک منظر میں رکھتا ہے جب تک آپ اس سے پن نہیں ہٹا دیتے۔ پن ہٹانے کیلئے عام جائزہ کو ٹچ کریں اور پکڑ کر رکھیں۔"</string>
+    <string name="screen_pinning_description" msgid="1346522416878235405">"یہ اس کو اس وقت تک منظر میں رکھتا ہے جب تک آپ اس سے پن نہیں ہٹا دیتے۔ پن ہٹانے کیلئے واپس اور عمومی جائزہ کو ایک ساتھ ٹچ کریں اور پکڑ کر رکھیں۔"</string>
+    <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"یہ اس کو اس وقت تک منظر میں رکھتا ہے جب تک آپ اس سے پن نہیں ہٹا دیتے۔ پن ہٹانے کیلئے عمومی جائزہ کو ٹچ کریں اور پکڑ کر رکھیں۔"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"سمجھ آ گئی"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"نہیں شکریہ"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> کو چھپائیں؟"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 7f34a75..6ae57f3 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -360,7 +360,7 @@
     <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"这将会固定显示此屏幕,直到您取消固定为止。触摸并按住“概览”即可取消固定屏幕。"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"知道了"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"不用了"</string>
-    <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"要隐藏<xliff:g id="TILE_LABEL">%1$s</xliff:g>吗?"</string>
-    <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"下次在设置中开启此图块后,它便会重新显示。"</string>
+    <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"要隐藏“<xliff:g id="TILE_LABEL">%1$s</xliff:g>”吗?"</string>
+    <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"下次在设置中将其开启后,此快捷设置条目将会重新显示。"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"隐藏"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index ae3de7a..2e36010 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -164,7 +164,7 @@
     <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"正在啟動「<xliff:g id="APP">%s</xliff:g>」。"</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_quick_settings" msgid="6186378411582437046">"快捷設定。"</string>
     <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"螢幕鎖定。"</string>
     <string name="accessibility_desc_settings" msgid="3417884241751434521">"設定"</string>
     <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"總覽。"</string>
@@ -356,11 +356,11 @@
     <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="screen_pinning_title" msgid="3273740381976175811">"螢幕已固定"</string>
-    <string name="screen_pinning_description" msgid="1346522416878235405">"這會讓螢幕畫面持續顯示,直到取消固定為止。同時輕觸並按住返回按鈕和總覽按鈕即可取消固定。"</string>
-    <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"這會讓螢幕畫面持續顯示,直到取消固定為止。輕觸並按住總覽按鈕即可取消固定。"</string>
+    <string name="screen_pinning_description" msgid="1346522416878235405">"這會讓目前的螢幕畫面保持顯示狀態,直到取消固定為止。同時按住返回按鈕和總覽按鈕即可取消固定。"</string>
+    <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"這會讓目前的螢幕畫面保持顯示狀態,直到取消固定為止。按住總覽按鈕即可取消固定。"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"知道了"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"不用了,謝謝"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"隱藏<xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
-    <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"當您下次在設定中將其開啟時,這項設定就會重新顯示。"</string>
+    <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"只要在設定頁面中重新啟用,就能再次看到快捷設定選項。"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"隱藏"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 3cd72fc..1152eea 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -144,44 +144,65 @@
 
     <!-- The duration in seconds to wait before the dismiss buttons are shown. -->
     <integer name="recents_task_bar_dismiss_delay_seconds">1</integer>
+
     <!-- The min animation duration for animating views that are currently visible. -->
     <integer name="recents_filter_animate_current_views_duration">250</integer>
+
     <!-- The min animation duration for animating views that are newly visible. -->
     <integer name="recents_filter_animate_new_views_duration">250</integer>
-    <!-- The min animation duration for animating the task bar in. -->
-    <integer name="recents_animate_task_bar_enter_duration">225</integer>
-    <!-- The animation delay for animating the first task in. This should roughly be the animation
-     duration of the transition in to recents. -->
-    <integer name="recents_animate_task_bar_enter_delay">275</integer>
-    <!-- The min animation duration for animating the task bar out. -->
-    <integer name="recents_animate_task_exit_to_home_duration">225</integer>
-    <!-- The min animation duration for animating the task bar out. -->
-    <integer name="recents_animate_task_bar_exit_duration">125</integer>
-    <!-- The animation delay for animating the first task in. This should roughly be the animation
-     duration of the transition in to recents from home. -->
-    <integer name="recents_animate_task_enter_from_home_delay">150</integer>
-    <!-- The min animation duration for animating the task in when transitioning from home. -->
-    <integer name="recents_animate_task_enter_from_home_duration">250</integer>
-    <!-- The animation stagger to apply to each task animation when transitioning from home. -->
-    <integer name="recents_animate_task_enter_from_home_stagger_delay">12</integer>
-    <!-- The short duration when animating in/out the lock to app button. -->
-    <integer name="recents_animate_lock_to_app_button_short_duration">150</integer>
-    <!-- The long duration when animating in/out the lock to app button. -->
-    <integer name="recents_animate_lock_to_app_button_long_duration">300</integer>
+
+    <!-- The duration of the window transition when coming to Recents from an app.
+         In order to defer the in-app animations until after the transition is complete,
+         we also need to use this value as the starting delay when animating the first
+         task decorations in. -->
+    <integer name="recents_enter_from_app_transition_duration">325</integer>
+
+    <!-- The duration for animating the task decorations in after transitioning from an app. -->
+    <integer name="recents_task_enter_from_app_duration">200</integer>
+
+    <!-- The duration for animating the task decorations out before transitioning to an app. -->
+    <integer name="recents_task_exit_to_app_duration">125</integer>
+
+    <!-- The duration of the window transition when coming to Recents from the Launcher.
+         In order to defer the in-app animations until after the transition is complete,
+         we also need to use this value as the starting delay when animating the task views
+         in from the bottom of the screen. -->
+    <integer name="recents_enter_from_home_transition_duration">100</integer>
+
+    <!-- The duration for animating the task from the bottom of the screen when transitioning
+     from home. -->
+    <integer name="recents_task_enter_from_home_duration">225</integer>
+
+    <!-- The stagger for each task when animating the task from the bottom of the screen when 
+     transitioning from home. -->
+    <integer name="recents_task_enter_from_home_stagger_delay">12</integer>
+
+    <!-- The duration of the animation of the tasks to the bottom of the screen when leaving
+     Recents to go back to the Launcher. -->
+    <integer name="recents_task_exit_to_home_duration">225</integer>
+
     <!-- The min animation duration for animating the nav bar scrim in. -->
     <integer name="recents_nav_bar_scrim_enter_duration">400</integer>
+
     <!-- The animation duration for animating the removal of a task view. -->
     <integer name="recents_animate_task_view_remove_duration">250</integer>
+
     <!-- The animation duration for scrolling the stack to a particular item. -->
     <integer name="recents_animate_task_stack_scroll_duration">225</integer>
+
     <!-- The minimum alpha for the dim applied to cards that go deeper into the stack. -->
     <integer name="recents_max_task_stack_view_dim">96</integer>
+
     <!-- The delay to enforce between each alt-tab key press. -->
     <integer name="recents_alt_tab_key_delay">200</integer>
+
     <!-- Transposes the search bar layout in landscape. -->
     <bool name="recents_has_transposed_search_bar">true</bool>
+
     <!-- Transposes the nav bar in landscape (only used for purposes of layout). -->
     <bool name="recents_has_transposed_nav_bar">true</bool>
+    <!-- Svelte specific logic, see RecentsConfiguration.SVELTE_* constants. -->
+    <integer name="recents_svelte_level">0</integer>
 
     <!-- Whether to enable KeyguardService or not -->
     <bool name="config_enableKeyguardService">true</bool>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 3d9f723..1143553 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -226,9 +226,6 @@
     <!-- The amount of highlight to make on each task view. -->
     <dimen name="recents_task_view_highlight">1.5dp</dimen>
 
-    <!-- The height of the lock-to-app button. -->
-    <dimen name="recents_task_view_lock_to_app_button_height">48dp</dimen>
-
     <!-- The amount to offset when animating into an affiliate group. -->
     <dimen name="recents_task_view_affiliate_group_enter_offset">64dp</dimen>
 
@@ -257,6 +254,12 @@
     <!-- The min alpha to apply to a task affiliation group color. -->
     <item name="recents_task_affiliation_color_min_alpha_percentage" format="float" type="dimen">0.6</item>
 
+    <!-- The size of the lock-to-app button. -->
+    <dimen name="recents_lock_to_app_size">56dp</dimen>
+
+    <!-- The size of the lock-to-app button icon. -->
+    <dimen name="recents_lock_to_app_icon_size">28dp</dimen>
+
     <!-- Space reserved for the cards behind the top card in the top stack -->
     <dimen name="top_stack_peek_amount">12dp</dimen>
 
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 7649340..8d1e9671 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -228,6 +228,8 @@
         <item name="android:colorControlActivated">@color/system_accent_color</item>
     </style>
 
+    <style name="Theme.SystemUI.Dialog.Alert" parent="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert" />
+
     <style name="QSBorderlessButton">
         <item name="android:padding">12dp</item>
         <item name="android:background">@drawable/btn_borderless_rect</item>
diff --git a/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java b/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java
new file mode 100644
index 0000000..2ff8f8a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java
@@ -0,0 +1,101 @@
+/*
+ * 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.systemui;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Paint;
+import android.view.View;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+
+import com.android.systemui.statusbar.phone.NotificationPanelView;
+
+/**
+ * Helper to invert the colors of views and fade between the states.
+ */
+public class ViewInvertHelper {
+
+    private final Paint mDarkPaint = new Paint();
+    private final Interpolator mLinearOutSlowInInterpolator;
+    private final View mTarget;
+    private final ColorMatrix mMatrix = new ColorMatrix();
+    private final ColorMatrix mGrayscaleMatrix = new ColorMatrix();
+    private final long mFadeDuration;
+
+    public ViewInvertHelper(View target, long fadeDuration) {
+        mTarget = target;
+        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(mTarget.getContext(),
+                android.R.interpolator.linear_out_slow_in);
+        mFadeDuration = fadeDuration;
+    }
+
+    public void fade(final boolean invert, long delay) {
+        float startIntensity = invert ? 0f : 1f;
+        float endIntensity = invert ? 1f : 0f;
+        ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity);
+        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                updateInvertPaint((Float) animation.getAnimatedValue());
+                mTarget.setLayerType(View.LAYER_TYPE_HARDWARE, mDarkPaint);
+            }
+        });
+        animator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                if (!invert) {
+                    mTarget.setLayerType(View.LAYER_TYPE_NONE, null);
+                }
+            }
+        });
+        animator.setDuration(mFadeDuration);
+        animator.setInterpolator(mLinearOutSlowInInterpolator);
+        animator.setStartDelay(delay);
+        animator.start();
+    }
+
+    public void update(boolean invert) {
+        if (invert) {
+            updateInvertPaint(1f);
+            mTarget.setLayerType(View.LAYER_TYPE_HARDWARE, mDarkPaint);
+        } else {
+            mTarget.setLayerType(View.LAYER_TYPE_NONE, null);
+        }
+    }
+
+    public View getTarget() {
+        return mTarget;
+    }
+
+    private void updateInvertPaint(float intensity) {
+        float components = 1 - 2 * intensity;
+        final float[] invert = {
+                components, 0f,         0f,         0f, 255f * intensity,
+                0f,         components, 0f,         0f, 255f * intensity,
+                0f,         0f,         components, 0f, 255f * intensity,
+                0f,         0f,         0f,         1f, 0f
+        };
+        mMatrix.set(invert);
+        mGrayscaleMatrix.setSaturation(1 - intensity);
+        mMatrix.preConcat(mGrayscaleMatrix);
+        mDarkPaint.setColorFilter(new ColorMatrixColorFilter(mMatrix));
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index ee699d2..98d4112 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -22,6 +22,7 @@
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.IBinder;
+import android.os.Process;
 import android.util.Log;
 import android.view.MotionEvent;
 
@@ -52,6 +53,10 @@
     }
 
     void checkPermission() {
+        // Avoid deadlock by avoiding calling back into the system process.
+        if (Binder.getCallingUid() == Process.SYSTEM_UID) return;
+
+        // Otherwise,explicitly check for caller permission ...
         if (getBaseContext().checkCallingOrSelfPermission(PERMISSION) != PERMISSION_GRANTED) {
             Log.w(TAG, "Caller needs permission '" + PERMISSION + "' to call " + Debug.getCaller());
             throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 20e418c..5f92dc6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -23,6 +23,7 @@
 import android.app.PendingIntent;
 import android.app.SearchManager;
 import android.app.StatusBarManager;
+import android.app.trust.TrustManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -187,8 +188,9 @@
     /** High level access to the window manager for dismissing keyguard animation */
     private IWindowManager mWM;
 
-    /** UserManager for querying number of users */
-    private UserManager mUserManager;
+
+    /** TrustManager for letting it know when we change visibility */
+    private TrustManager mTrustManager;
 
     /** SearchManager for determining whether or not search assistant is available */
     private SearchManager mSearchManager;
@@ -484,7 +486,8 @@
     private void setup() {
         mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mWM = WindowManagerGlobal.getWindowManagerService();
-        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        mTrustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
+
         mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
         mShowKeyguardWakeLock.setReferenceCounted(false);
 
@@ -501,6 +504,7 @@
 
         // Assume keyguard is showing (unless it's disabled) until we know for sure...
         mShowing = !shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled();
+        mTrustManager.reportKeyguardShowingChanged();
 
         mStatusBarKeyguardViewManager = new StatusBarKeyguardViewManager(mContext,
                 mViewMediatorCallback, mLockPatternUtils);
@@ -931,7 +935,7 @@
         if (mLockPatternUtils.checkVoldPassword()) {
             if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
             // Without this, settings is not enabled until the lock screen first appears
-            mShowing = false;
+            setShowing(false);
             hideLocked();
             return;
         }
@@ -1249,7 +1253,7 @@
 
             mStatusBarKeyguardViewManager.show(options);
             mHiding = false;
-            mShowing = true;
+            setShowing(true);
             resetKeyguardDonePendingLocked();
             mHideAnimationRun = false;
             updateActivityLockScreenState();
@@ -1328,7 +1332,7 @@
             }
 
             mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration);
-            mShowing = false;
+            setShowing(false);
             resetKeyguardDonePendingLocked();
             mHideAnimationRun = false;
             updateActivityLockScreenState();
@@ -1389,7 +1393,7 @@
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleVerifyUnlock");
             mStatusBarKeyguardViewManager.verifyUnlock();
-            mShowing = true;
+            setShowing(true);
             updateActivityLockScreenState();
         }
     }
@@ -1471,4 +1475,12 @@
             this.fadeoutDuration = fadeoutDuration;
         }
     }
+
+    private void setShowing(boolean showing) {
+        boolean changed = (showing != mShowing);
+        mShowing = showing;
+        if (changed) {
+            mTrustManager.reportKeyguardShowingChanged();
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SecureSetting.java b/packages/SystemUI/src/com/android/systemui/qs/SecureSetting.java
index 0ab6626..4f812bc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SecureSetting.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SecureSetting.java
@@ -26,24 +26,26 @@
 
 /** Helper for managing a secure setting. **/
 public abstract class SecureSetting extends ContentObserver implements Listenable {
+    private static final int DEFAULT = 0;
+
     private final Context mContext;
     private final String mSettingName;
 
     private boolean mListening;
     private int mUserId;
+    private int mObservedValue = DEFAULT;
 
-    protected abstract void handleValueChanged(int value);
+    protected abstract void handleValueChanged(int value, boolean observedChange);
 
     public SecureSetting(Context context, Handler handler, String settingName) {
         super(handler);
         mContext = context;
         mSettingName = settingName;
         mUserId = ActivityManager.getCurrentUser();
-        setListening(true);
     }
 
     public int getValue() {
-        return Secure.getIntForUser(mContext.getContentResolver(), mSettingName, 0, mUserId);
+        return Secure.getIntForUser(mContext.getContentResolver(), mSettingName, DEFAULT, mUserId);
     }
 
     public void setValue(int value) {
@@ -52,18 +54,23 @@
 
     @Override
     public void setListening(boolean listening) {
+        if (listening == mListening) return;
         mListening = listening;
         if (listening) {
+            mObservedValue = getValue();
             mContext.getContentResolver().registerContentObserver(
                     Secure.getUriFor(mSettingName), false, this, mUserId);
         } else {
             mContext.getContentResolver().unregisterContentObserver(this);
+            mObservedValue = DEFAULT;
         }
     }
 
     @Override
     public void onChange(boolean selfChange) {
-        handleValueChanged(getValue());
+        final int value = getValue();
+        handleValueChanged(value, value != mObservedValue);
+        mObservedValue = value;
     }
 
     public void setUserId(int userId) {
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 4d77348..1bc1d77 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -77,6 +77,10 @@
 
     @Override
     protected void handleSecondaryClick() {
+        if (!mState.value) {
+            mState.value = true;
+            mController.setBluetoothEnabled(true);
+        }
         showDetail(true);
     }
 
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 178590b..80ddd4a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -29,7 +29,8 @@
 import com.android.systemui.qs.QSTileView;
 import com.android.systemui.qs.SignalTileView;
 import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkController.DataUsageInfo;
+import com.android.systemui.statusbar.policy.NetworkController.MobileDataController;
+import com.android.systemui.statusbar.policy.NetworkController.MobileDataController.DataUsageInfo;
 import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
 
 /** Quick settings tile: Cellular **/
@@ -38,11 +39,13 @@
             "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity"));
 
     private final NetworkController mController;
+    private final MobileDataController mDataController;
     private final CellularDetailAdapter mDetailAdapter;
 
     public CellularTile(Host host) {
         super(host);
         mController = host.getNetworkController();
+        mDataController = mController.getMobileDataController();
         mDetailAdapter = new CellularDetailAdapter();
     }
 
@@ -72,7 +75,7 @@
 
     @Override
     protected void handleClick() {
-        if (mController.isMobileDataSupported()) {
+        if (mDataController.isMobileDataSupported()) {
             showDetail(true);
         } else {
             mHost.startSettingsActivity(CELLULAR_SETTINGS);
@@ -199,7 +202,8 @@
 
         @Override
         public Boolean getToggleState() {
-            return mController.isMobileDataSupported() ? mController.isMobileDataEnabled() : null;
+            return mDataController.isMobileDataSupported()
+                    ? mDataController.isMobileDataEnabled() : null;
         }
 
         @Override
@@ -209,7 +213,7 @@
 
         @Override
         public void setToggleState(boolean state) {
-            mController.setMobileDataEnabled(state);
+            mDataController.setMobileDataEnabled(state);
         }
 
         @Override
@@ -217,7 +221,7 @@
             final DataUsageDetailView v = (DataUsageDetailView) (convertView != null
                     ? convertView
                     : LayoutInflater.from(mContext).inflate(R.layout.data_usage, parent, false));
-            final DataUsageInfo info = mController.getDataUsageInfo();
+            final DataUsageInfo info = mDataController.getDataUsageInfo();
             if (info == null) return v;
             v.bind(info);
             return v;
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 b565afa..5963a45e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -41,8 +41,10 @@
         mSetting = new SecureSetting(mContext, mHandler,
                 Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) {
             @Override
-            protected void handleValueChanged(int value) {
-                mUsageTracker.trackUsage();
+            protected void handleValueChanged(int value, boolean observedChange) {
+                if (value != 0 || observedChange) {
+                    mUsageTracker.trackUsage();
+                }
                 if (mListening) {
                     handleRefreshState(value);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java
index 7bdb58f..eb816b7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java
@@ -20,7 +20,6 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.util.AttributeSet;
-import android.util.TypedValue;
 import android.view.View;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -61,7 +60,7 @@
                 R.dimen.qs_data_usage_text_size);
     }
 
-    public void bind(NetworkController.DataUsageInfo info) {
+    public void bind(NetworkController.MobileDataController.DataUsageInfo info) {
         final Resources res = mContext.getResources();
         final int titleId;
         final long bytes;
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 7aa884e..4fb1189 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -31,7 +31,8 @@
 import com.android.systemui.qs.QSTileView;
 import com.android.systemui.qs.SignalTileView;
 import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkController.AccessPoint;
+import com.android.systemui.statusbar.policy.NetworkController.AccessPointController;
+import com.android.systemui.statusbar.policy.NetworkController.AccessPointController.AccessPoint;
 import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
 
 /** Quick settings tile: Wifi **/
@@ -39,12 +40,14 @@
     private static final Intent WIFI_SETTINGS = new Intent(Settings.ACTION_WIFI_SETTINGS);
 
     private final NetworkController mController;
+    private final AccessPointController mWifiController;
     private final WifiDetailAdapter mDetailAdapter;
     private final QSTile.SignalState mStateBeforeClick = newTileState();
 
     public WifiTile(Host host) {
         super(host);
         mController = host.getNetworkController();
+        mWifiController = mController.getAccessPointController();
         mDetailAdapter = new WifiDetailAdapter();
     }
 
@@ -62,10 +65,10 @@
     public void setListening(boolean listening) {
         if (listening) {
             mController.addNetworkSignalChangedCallback(mCallback);
-            mController.addAccessPointCallback(mDetailAdapter);
+            mWifiController.addAccessPointCallback(mDetailAdapter);
         } else {
             mController.removeNetworkSignalChangedCallback(mCallback);
-            mController.removeAccessPointCallback(mDetailAdapter);
+            mWifiController.removeAccessPointCallback(mDetailAdapter);
         }
     }
 
@@ -87,7 +90,7 @@
 
     @Override
     protected void handleSecondaryClick() {
-        if (!mController.canConfigWifi()) {
+        if (!mWifiController.canConfigWifi()) {
             mHost.startSettingsActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
             return;
         }
@@ -231,7 +234,7 @@
     };
 
     private final class WifiDetailAdapter implements DetailAdapter,
-            NetworkController.AccessPointCallback, QSDetailItems.Callback {
+            NetworkController.AccessPointController.AccessPointCallback, QSDetailItems.Callback {
 
         private QSDetailItems mItems;
         private AccessPoint[] mAccessPoints;
@@ -261,7 +264,7 @@
         public View createDetailView(Context context, View convertView, ViewGroup parent) {
             if (DEBUG) Log.d(TAG, "createDetailView convertView=" + (convertView != null));
             mAccessPoints = null;
-            mController.scanForAccessPoints();
+            mWifiController.scanForAccessPoints();
             fireScanStateChanged(true);
             mItems = QSDetailItems.convertOrInflate(context, convertView, parent);
             mItems.setTagSuffix("Wifi");
@@ -287,7 +290,7 @@
             if (item == null || item.tag == null) return;
             final AccessPoint ap = (AccessPoint) item.tag;
             if (!ap.isConnected) {
-                if (mController.connect(ap)) {
+                if (mWifiController.connect(ap)) {
                     mHost.collapsePanels();
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index bb9a105..38ce467 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -32,6 +32,7 @@
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.os.Handler;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.Pair;
 import android.view.LayoutInflater;
@@ -361,8 +362,7 @@
         // If the user has toggled it too quickly, then just eat up the event here (it's better than
         // showing a janky screenshot).
         // NOTE: Ideally, the screenshot mechanism would take the window transform into account
-        long currentTime = System.currentTimeMillis();
-        if ((currentTime > mLastToggleTime) && (currentTime - mLastToggleTime) < sMinToggleDelay) {
+        if ((SystemClock.elapsedRealtime() - mLastToggleTime) < sMinToggleDelay) {
             return;
         }
 
@@ -377,7 +377,7 @@
             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
                     Intent.FLAG_RECEIVER_FOREGROUND);
             mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
-            mLastToggleTime = System.currentTimeMillis();
+            mLastToggleTime = SystemClock.elapsedRealtime();
             return;
         } else {
             // Otherwise, start the recents activity
@@ -559,7 +559,7 @@
                 startAlternateRecentsActivity(topTask, opts, EXTRA_FROM_HOME, stackVr);
             }
         }
-        mLastToggleTime = System.currentTimeMillis();
+        mLastToggleTime = SystemClock.elapsedRealtime();
     }
 
     /** Starts the recents activity */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index d1eadd8..6dc2edb 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -28,6 +28,7 @@
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
 import android.os.Bundle;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.Pair;
 import android.view.KeyEvent;
@@ -431,8 +432,6 @@
         // Update if we are getting a configuration change
         if (savedInstanceState != null) {
             // Update RecentsConfiguration
-            mConfig = RecentsConfiguration.reinitialize(this,
-                    RecentsTaskLoader.getInstance().getSystemServicesProxy());
             mConfig.updateOnConfigurationChange();
             // Trigger the enter animation
             onEnterAnimationTriggered();
@@ -566,13 +565,13 @@
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         switch (keyCode) {
             case KeyEvent.KEYCODE_TAB: {
-                boolean hasRepKeyTimeElapsed = (System.currentTimeMillis() -
+                boolean hasRepKeyTimeElapsed = (SystemClock.elapsedRealtime() -
                         mLastTabKeyEventTime) > mConfig.altTabKeyDelay;
                 if (event.getRepeatCount() <= 0 || hasRepKeyTimeElapsed) {
                     // Focus the next task in the stack
                     final boolean backward = event.isShiftPressed();
                     mRecentsView.focusNextTask(!backward);
-                    mLastTabKeyEventTime = System.currentTimeMillis();
+                    mLastTabKeyEventTime = SystemClock.elapsedRealtime();
                 }
                 return true;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index e0c76b1..2b33d14 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -38,6 +38,18 @@
     static RecentsConfiguration sInstance;
     static int sPrevConfigurationHashCode;
 
+    /** Levels of svelte in increasing severity/austerity. */
+    // No svelting.
+    public static final int SVELTE_NONE = 0;
+    // Limit thumbnail cache to number of visible thumbnails when Recents was loaded, disable
+    // caching thumbnails as you scroll.
+    public static final int SVELTE_LIMIT_CACHE = 1;
+    // Disable the thumbnail cache, load thumbnails asynchronously when the activity loads and
+    // evict all thumbnails when hidden.
+    public static final int SVELTE_DISABLE_CACHE = 2;
+    // Disable all thumbnail loading.
+    public static final int SVELTE_DISABLE_LOADING = 3;
+
     /** Animations */
     public float animationPxMovementPerSecond;
 
@@ -74,11 +86,15 @@
     public float taskStackWidthPaddingPct;
     public float taskStackOverscrollPct;
 
+    /** Transitions */
+    public int transitionEnterFromAppDelay;
+    public int transitionEnterFromHomeDelay;
+
     /** Task view animation and styles */
-    public int taskViewEnterFromHomeDelay;
+    public int taskViewEnterFromAppDuration;
     public int taskViewEnterFromHomeDuration;
     public int taskViewEnterFromHomeStaggerDelay;
-    public int taskViewEnterFromHomeStaggerDuration;
+    public int taskViewExitToAppDuration;
     public int taskViewExitToHomeDuration;
     public int taskViewRemoveAnimDuration;
     public int taskViewRemoveAnimTranslationXPx;
@@ -98,16 +114,8 @@
 
     /** Task bar size & animations */
     public int taskBarHeight;
-    public int taskBarEnterAnimDuration;
-    public int taskBarEnterAnimDelay;
-    public int taskBarExitAnimDuration;
     public int taskBarDismissDozeDelaySeconds;
 
-    /** Lock to app */
-    public int taskViewLockToAppButtonHeight;
-    public int taskViewLockToAppShortAnimDuration;
-    public int taskViewLockToAppLongAnimDuration;
-
     /** Nav bar scrim */
     public int navBarScrimEnterDuration;
 
@@ -128,6 +136,7 @@
     public boolean lockToAppEnabled;
     public boolean developerOptionsEnabled;
     public boolean debugModeEnabled;
+    public int svelteLevel;
 
     /** Private constructor */
     private RecentsConfiguration(Context context) {
@@ -213,15 +222,23 @@
         taskStackMaxDim = res.getInteger(R.integer.recents_max_task_stack_view_dim);
         taskStackTopPaddingPx = res.getDimensionPixelSize(R.dimen.recents_stack_top_padding);
 
+        // Transition
+        transitionEnterFromAppDelay =
+                res.getInteger(R.integer.recents_enter_from_app_transition_duration);
+        transitionEnterFromHomeDelay =
+                res.getInteger(R.integer.recents_enter_from_home_transition_duration);
+
         // Task view animation and styles
-        taskViewEnterFromHomeDelay =
-                res.getInteger(R.integer.recents_animate_task_enter_from_home_delay);
+        taskViewEnterFromAppDuration =
+                res.getInteger(R.integer.recents_task_enter_from_app_duration);
         taskViewEnterFromHomeDuration =
-                res.getInteger(R.integer.recents_animate_task_enter_from_home_duration);
+                res.getInteger(R.integer.recents_task_enter_from_home_duration);
         taskViewEnterFromHomeStaggerDelay =
-                res.getInteger(R.integer.recents_animate_task_enter_from_home_stagger_delay);
+                res.getInteger(R.integer.recents_task_enter_from_home_stagger_delay);
+        taskViewExitToAppDuration =
+                res.getInteger(R.integer.recents_task_exit_to_app_duration);
         taskViewExitToHomeDuration =
-                res.getInteger(R.integer.recents_animate_task_exit_to_home_duration);
+                res.getInteger(R.integer.recents_task_exit_to_home_duration);
         taskViewRemoveAnimDuration =
                 res.getInteger(R.integer.recents_animate_task_view_remove_duration);
         taskViewRemoveAnimTranslationXPx =
@@ -252,23 +269,9 @@
 
         // Task bar size & animations
         taskBarHeight = res.getDimensionPixelSize(R.dimen.recents_task_bar_height);
-        taskBarEnterAnimDuration =
-                res.getInteger(R.integer.recents_animate_task_bar_enter_duration);
-        taskBarEnterAnimDelay =
-                res.getInteger(R.integer.recents_animate_task_bar_enter_delay);
-        taskBarExitAnimDuration =
-                res.getInteger(R.integer.recents_animate_task_bar_exit_duration);
         taskBarDismissDozeDelaySeconds =
                 res.getInteger(R.integer.recents_task_bar_dismiss_delay_seconds);
 
-        // Lock to app
-        taskViewLockToAppButtonHeight =
-                res.getDimensionPixelSize(R.dimen.recents_task_view_lock_to_app_button_height);
-        taskViewLockToAppShortAnimDuration =
-                res.getInteger(R.integer.recents_animate_lock_to_app_button_short_duration);
-        taskViewLockToAppLongAnimDuration =
-                res.getInteger(R.integer.recents_animate_lock_to_app_button_long_duration);
-
         // Nav bar scrim
         navBarScrimEnterDuration =
                 res.getInteger(R.integer.recents_nav_bar_scrim_enter_duration);
@@ -277,6 +280,7 @@
         useHardwareLayers = res.getBoolean(R.bool.config_recents_use_hardware_layers);
         altTabKeyDelay = res.getInteger(R.integer.recents_alt_tab_key_delay);
         fakeShadows = res.getBoolean(R.bool.config_recents_fake_shadows);
+        svelteLevel = res.getInteger(R.integer.recents_svelte_level);
     }
 
     /** Updates the system insets */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index 33c4b05..0011811 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -155,7 +155,8 @@
     /**
      * Called to apply the actual loading based on the specified conditions.
      */
-    synchronized void executePlan(Options opts, RecentsTaskLoader loader) {
+    synchronized void executePlan(Options opts, RecentsTaskLoader loader,
+            TaskResourceLoadQueue loadQueue) {
         if (DEBUG) Log.d(TAG, "executePlan, # tasks: " + opts.numVisibleTasks +
                 ", # thumbnails: " + opts.numVisibleTaskThumbnails +
                 ", running task id: " + opts.runningTaskId);
@@ -195,8 +196,12 @@
             if (opts.loadThumbnails && (isRunningTask || isVisibleThumbnail)) {
                 if (task.thumbnail == null) {
                     if (DEBUG) Log.d(TAG, "\tLoading thumbnail: " + taskKey);
-                    task.thumbnail = loader.getAndUpdateThumbnail(taskKey, mSystemServicesProxy,
-                            true);
+                    if (mConfig.svelteLevel <= RecentsConfiguration.SVELTE_LIMIT_CACHE) {
+                        task.thumbnail = loader.getAndUpdateThumbnail(taskKey, mSystemServicesProxy,
+                                true);
+                    } else if (mConfig.svelteLevel == RecentsConfiguration.SVELTE_DISABLE_CACHE) {
+                        loadQueue.addTask(task);
+                    }
                 }
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index 599d3ce..ba2903a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -94,6 +94,9 @@
 
 /* Task resource loader */
 class TaskResourceLoader implements Runnable {
+    static String TAG = "TaskResourceLoader";
+    static boolean DEBUG = false;
+
     Context mContext;
     HandlerThread mLoadThread;
     Handler mLoadThreadHandler;
@@ -165,57 +168,67 @@
                     }
                 }
             } else {
+                RecentsConfiguration config = RecentsConfiguration.getInstance();
                 SystemServicesProxy ssp = mSystemServicesProxy;
-                // If we've stopped the loader, then fall thorugh to the above logic to wait on
+                // If we've stopped the loader, then fall through to the above logic to wait on
                 // the load thread
-                if (ssp == null) continue;
+                if (ssp != null) {
+                    // Load the next item from the queue
+                    final Task t = mLoadQueue.nextTask();
+                    if (t != null) {
+                        Drawable cachedIcon = mApplicationIconCache.get(t.key);
+                        Bitmap cachedThumbnail = mThumbnailCache.get(t.key);
 
-                // Load the next item from the queue
-                final Task t = mLoadQueue.nextTask();
-                if (t != null) {
-                    Drawable cachedIcon = mApplicationIconCache.get(t.key);
-                    Bitmap cachedThumbnail = mThumbnailCache.get(t.key);
-
-                    // Load the application icon if it is stale or we haven't cached one yet
-                    if (cachedIcon == null) {
-                        cachedIcon = getTaskDescriptionIcon(t.key, t.icon, t.iconFilename, ssp,
-                                mContext.getResources());
-
+                        // Load the application icon if it is stale or we haven't cached one yet
                         if (cachedIcon == null) {
-                            ActivityInfo info = ssp.getActivityInfo(t.key.baseIntent.getComponent(),
-                                    t.key.userId);
-                            if (info != null) {
-                                cachedIcon = ssp.getActivityIcon(info, t.key.userId);
+                            cachedIcon = getTaskDescriptionIcon(t.key, t.icon, t.iconFilename, ssp,
+                                    mContext.getResources());
+
+                            if (cachedIcon == null) {
+                                ActivityInfo info = ssp.getActivityInfo(
+                                        t.key.baseIntent.getComponent(), t.key.userId);
+                                if (info != null) {
+                                    if (DEBUG) Log.d(TAG, "Loading icon: " + t.key);
+                                    cachedIcon = ssp.getActivityIcon(info, t.key.userId);
+                                }
                             }
-                        }
 
-                        if (cachedIcon == null) {
-                            cachedIcon = mDefaultApplicationIcon;
-                        }
+                            if (cachedIcon == null) {
+                                cachedIcon = mDefaultApplicationIcon;
+                            }
 
-                        // At this point, even if we can't load the icon, we will set the default
-                        // icon.
-                        mApplicationIconCache.put(t.key, cachedIcon);
-                    }
-                    // Load the thumbnail if it is stale or we haven't cached one yet
-                    if (cachedThumbnail == null) {
-                        cachedThumbnail = ssp.getTaskThumbnail(t.key.id);
+                            // At this point, even if we can't load the icon, we will set the
+                            // default icon.
+                            mApplicationIconCache.put(t.key, cachedIcon);
+                        }
+                        // Load the thumbnail if it is stale or we haven't cached one yet
                         if (cachedThumbnail == null) {
-                            cachedThumbnail = mDefaultThumbnail;
-                        }
-                        mThumbnailCache.put(t.key, cachedThumbnail);
-                    }
-                    if (!mCancelled) {
-                        // Notify that the task data has changed
-                        final Drawable newIcon = cachedIcon;
-                        final Bitmap newThumbnail = cachedThumbnail == mDefaultThumbnail
-                                ? null : cachedThumbnail;
-                        mMainThreadHandler.post(new Runnable() {
-                            @Override
-                            public void run() {
-                                t.notifyTaskDataLoaded(newThumbnail, newIcon);
+                            if (config.svelteLevel < RecentsConfiguration.SVELTE_DISABLE_LOADING) {
+                                if (DEBUG) Log.d(TAG, "Loading thumbnail: " + t.key);
+                                cachedThumbnail = ssp.getTaskThumbnail(t.key.id);
                             }
-                        });
+                            if (cachedThumbnail == null) {
+                                cachedThumbnail = mDefaultThumbnail;
+                            }
+                            // When svelte, we trim the memory to just the visible thumbnails when
+                            // leaving, so don't thrash the cache as the user scrolls (just load
+                            // them from scratch each time)
+                            if (config.svelteLevel < RecentsConfiguration.SVELTE_LIMIT_CACHE) {
+                                mThumbnailCache.put(t.key, cachedThumbnail);
+                            }
+                        }
+                        if (!mCancelled) {
+                            // Notify that the task data has changed
+                            final Drawable newIcon = cachedIcon;
+                            final Bitmap newThumbnail = cachedThumbnail == mDefaultThumbnail
+                                    ? null : cachedThumbnail;
+                            mMainThreadHandler.post(new Runnable() {
+                                @Override
+                                public void run() {
+                                    t.notifyTaskDataLoaded(newThumbnail, newIcon);
+                                }
+                            });
+                        }
                     }
                 }
 
@@ -267,6 +280,7 @@
     int mMaxThumbnailCacheSize;
     int mMaxIconCacheSize;
     int mNumVisibleTasksLoaded;
+    int mNumVisibleThumbnailsLoaded;
 
     BitmapDrawable mDefaultApplicationIcon;
     Bitmap mDefaultThumbnail;
@@ -392,7 +406,8 @@
             return thumbnail;
         }
 
-        if (loadIfNotCached) {
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
+        if (config.svelteLevel < RecentsConfiguration.SVELTE_DISABLE_LOADING && loadIfNotCached) {
             // Load the thumbnail from the system
             thumbnail = ssp.getTaskThumbnail(taskKey.id);
             if (thumbnail != null) {
@@ -441,9 +456,10 @@
         if (opts == null) {
             throw new RuntimeException("Requires load options");
         }
-        plan.executePlan(opts, this);
+        plan.executePlan(opts, this, mLoadQueue);
         if (!opts.onlyLoadForCache) {
             mNumVisibleTasksLoaded = opts.numVisibleTasks;
+            mNumVisibleThumbnailsLoaded = opts.numVisibleTaskThumbnails;
 
             // Start the loader
             mLoader.start(context);
@@ -503,12 +519,19 @@
      * out of memory.
      */
     public void onTrimMemory(int level) {
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
         switch (level) {
             case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
                 // Stop the loader immediately when the UI is no longer visible
                 stopLoader();
-                mThumbnailCache.trimToSize(Math.max(mNumVisibleTasksLoaded,
-                        mMaxThumbnailCacheSize / 2));
+                if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) {
+                    mThumbnailCache.trimToSize(Math.max(mNumVisibleTasksLoaded,
+                            mMaxThumbnailCacheSize / 2));
+                } else if (config.svelteLevel == RecentsConfiguration.SVELTE_LIMIT_CACHE) {
+                    mThumbnailCache.trimToSize(mNumVisibleThumbnailsLoaded);
+                } else if (config.svelteLevel >= RecentsConfiguration.SVELTE_DISABLE_CACHE) {
+                    mThumbnailCache.evictAll();
+                }
                 mApplicationIconCache.trimToSize(Math.max(mNumVisibleTasksLoaded,
                         mMaxIconCacheSize / 2));
                 break;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
index 5f8f3f2..fb05c01 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.recents.views;
 
-import android.animation.ObjectAnimator;
 import android.graphics.Outline;
 import android.graphics.Rect;
 import android.view.View;
@@ -35,8 +34,6 @@
     float mAlpha = 1f;
     final float mMinAlpha = 0.25f;
 
-    ObjectAnimator mClipBottomAnimator;
-
     public AnimateableViewBounds(TaskView source, int cornerRadius) {
         mConfig = RecentsConfiguration.getInstance();
         mSourceView = source;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
index 162897e..1086160 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
@@ -64,7 +64,9 @@
             mStatusBarScrimView.setTranslationY(-mStatusBarScrimView.getMeasuredHeight());
             mStatusBarScrimView.animate()
                     .translationY(0)
-                    .setStartDelay(mConfig.taskBarEnterAnimDelay)
+                    .setStartDelay(mConfig.launchedFromHome ?
+                            mConfig.transitionEnterFromHomeDelay :
+                            mConfig.transitionEnterFromAppDelay)
                     .setDuration(mConfig.navBarScrimEnterDuration)
                     .setInterpolator(mConfig.quintOutInterpolator)
                     .withStartAction(new Runnable() {
@@ -79,7 +81,9 @@
             mNavBarScrimView.setTranslationY(mNavBarScrimView.getMeasuredHeight());
             mNavBarScrimView.animate()
                     .translationY(0)
-                    .setStartDelay(mConfig.taskBarEnterAnimDelay)
+                    .setStartDelay(mConfig.launchedFromHome ?
+                            mConfig.transitionEnterFromHomeDelay :
+                            mConfig.transitionEnterFromAppDelay)
                     .setDuration(mConfig.navBarScrimEnterDuration)
                     .setInterpolator(mConfig.quintOutInterpolator)
                     .withStartAction(new Runnable() {
@@ -101,7 +105,7 @@
             mStatusBarScrimView.animate()
                     .translationY(-mStatusBarScrimView.getMeasuredHeight())
                     .setStartDelay(0)
-                    .setDuration(mConfig.taskBarExitAnimDuration)
+                    .setDuration(mConfig.taskViewExitToAppDuration)
                     .setInterpolator(mConfig.fastOutSlowInInterpolator)
                     .start();
         }
@@ -109,7 +113,7 @@
             mNavBarScrimView.animate()
                     .translationY(mNavBarScrimView.getMeasuredHeight())
                     .setStartDelay(0)
-                    .setDuration(mConfig.taskBarExitAnimDuration)
+                    .setDuration(mConfig.taskViewExitToAppDuration)
                     .setInterpolator(mConfig.fastOutSlowInInterpolator)
                     .start();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 49fd792..5732879 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -186,6 +186,7 @@
             mUIDozeTrigger.stopDozing();
             mUIDozeTrigger.resetTrigger();
         }
+        mStackScroller.reset();
     }
 
     /** Requests that the views be synchronized with the model */
@@ -554,7 +555,8 @@
 
     /** Resets the focused task. */
     void resetFocusedTask() {
-        if (mFocusedTaskIndex > -1) {
+        if ((mStack != null) && (0 <= mFocusedTaskIndex) &&
+                (mFocusedTaskIndex < mStack.getTaskCount())) {
             Task t = mStack.getTasks().get(mFocusedTaskIndex);
             TaskView tv = getChildViewForTask(t);
             tv.unsetFocusedTask();
@@ -658,9 +660,10 @@
         // If this is the first layout, then scroll to the front of the stack and synchronize the
         // stack views immediately to load all the views
         if (mAwaitingFirstLayout) {
-            mStackScroller.setStackScrollToInitialState();
-            requestSynchronizeStackViewsWithModel();
-            synchronizeStackViewsWithModel();
+            if (mStackScroller.setStackScrollToInitialState()) {
+                requestSynchronizeStackViewsWithModel();
+                synchronizeStackViewsWithModel();
+            }
         }
 
         // Measure each of the TaskViews
@@ -914,7 +917,7 @@
             TaskView frontTv = getChildViewForTask(newFrontMostTask);
             if (frontTv != null) {
                 frontTv.onTaskBound(newFrontMostTask);
-                frontTv.fadeInActionButton(false);
+                frontTv.fadeInActionButton(0, mConfig.taskViewEnterFromAppDuration);
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
index 04f7c6f..f7067be 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
@@ -48,6 +48,11 @@
         setStackScroll(getStackScroll());
     }
 
+    /** Resets the task scroller. */
+    void reset() {
+        mStackScrollP = 0f;
+    }
+
     /** Sets the callbacks */
     void setCallbacks(TaskStackViewScrollerCallbacks cb) {
         mCb = cb;
@@ -71,9 +76,14 @@
         mStackScrollP = s;
     }
 
-    /** Sets the current stack scroll to the initial state when you first enter recents */
-    public void setStackScrollToInitialState() {
+    /**
+     * Sets the current stack scroll to the initial state when you first enter recents.
+     * @return whether the stack progress changed.
+     */
+    public boolean setStackScrollToInitialState() {
+        float prevStackScrollP = mStackScrollP;
         setStackScroll(getBoundedStackScroll(mLayoutAlgorithm.mInitialScrollP));
+        return Float.compare(prevStackScrollP, mStackScrollP) != 0;
     }
 
     /** Bounds the current scroll if necessary */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 219108e..d42fa15 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -24,7 +24,6 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewOutlineProvider;
-import android.view.ViewPropertyAnimator;
 import android.view.animation.AccelerateInterpolator;
 import android.widget.FrameLayout;
 import com.android.systemui.R;
@@ -271,24 +270,25 @@
                 if (Constants.DebugFlags.App.EnableThumbnailAlphaOnFrontmost) {
                     // Animate the thumbnail alpha before the dim animation (to prevent updating the
                     // hardware layer)
-                    mThumbnailView.startEnterRecentsAnimation(mConfig.taskBarEnterAnimDelay,
+                    mThumbnailView.startEnterRecentsAnimation(mConfig.transitionEnterFromAppDelay,
                             new Runnable() {
                                 @Override
                                 public void run() {
-                                    animateDimToProgress(0, mConfig.taskBarEnterAnimDuration,
+                                    animateDimToProgress(0, mConfig.taskViewEnterFromAppDuration,
                                             ctx.postAnimationTrigger.decrementOnAnimationEnd());
                                 }
                             });
                 } else {
                     // Immediately start the dim animation
-                    animateDimToProgress(mConfig.taskBarEnterAnimDelay,
-                            mConfig.taskBarEnterAnimDuration,
+                    animateDimToProgress(mConfig.transitionEnterFromAppDelay,
+                            mConfig.taskViewEnterFromAppDuration,
                             ctx.postAnimationTrigger.decrementOnAnimationEnd());
                 }
                 ctx.postAnimationTrigger.increment();
 
                 // Animate the action button in
-                fadeInActionButton(true);
+                fadeInActionButton(mConfig.transitionEnterFromAppDelay,
+                        mConfig.taskViewEnterFromAppDuration);
             } else {
                 // Animate the task up if it was occluding the launch target
                 if (ctx.currentTaskOccludesLaunchTarget) {
@@ -296,7 +296,7 @@
                     setAlpha(0f);
                     animate().alpha(1f)
                             .translationY(transform.translationY)
-                            .setStartDelay(mConfig.taskBarEnterAnimDelay)
+                            .setStartDelay(mConfig.transitionEnterFromAppDelay)
                             .setUpdateListener(null)
                             .setInterpolator(mConfig.fastOutSlowInInterpolator)
                             .setDuration(mConfig.taskViewEnterFromHomeDuration)
@@ -311,12 +311,12 @@
                     ctx.postAnimationTrigger.increment();
                 }
             }
-            startDelay = mConfig.taskBarEnterAnimDelay;
+            startDelay = mConfig.transitionEnterFromAppDelay;
 
         } else if (mConfig.launchedFromHome) {
             // Animate the tasks up
             int frontIndex = (ctx.currentStackViewCount - ctx.currentStackViewIndex - 1);
-            int delay = mConfig.taskViewEnterFromHomeDelay +
+            int delay = mConfig.transitionEnterFromHomeDelay +
                     frontIndex * mConfig.taskViewEnterFromHomeStaggerDelay;
 
             setScaleX(transform.scale);
@@ -353,19 +353,17 @@
         }, (startDelay / 2));
     }
 
-    public void fadeInActionButton(boolean withDelay) {
+    public void fadeInActionButton(int delay, int duration) {
         // Hide the action button
         mActionButtonView.setAlpha(0f);
 
         // Animate the action button in
-        ViewPropertyAnimator animator = mActionButtonView.animate().alpha(1f)
-                .setDuration(mConfig.taskBarEnterAnimDuration)
+        mActionButtonView.animate().alpha(1f)
+                .setStartDelay(delay)
+                .setDuration(duration)
                 .setInterpolator(PhoneStatusBar.ALPHA_IN)
-                .withLayer();
-        if (withDelay) {
-            animator.setStartDelay(mConfig.taskBarEnterAnimDelay);
-        }
-        animator.start();
+                .withLayer()
+                .start();
     }
 
     /** Animates this task view as it leaves recents by pressing home. */
@@ -391,7 +389,7 @@
             // Animate the dim
             if (mDimAlpha > 0) {
                 ObjectAnimator anim = ObjectAnimator.ofInt(this, "dim", 0);
-                anim.setDuration(mConfig.taskBarExitAnimDuration);
+                anim.setDuration(mConfig.taskViewExitToAppDuration);
                 anim.setInterpolator(mConfig.fastOutLinearInInterpolator);
                 anim.start();
             }
@@ -406,7 +404,7 @@
             mActionButtonView.animate()
                     .alpha(0f)
                     .setStartDelay(0)
-                    .setDuration(mConfig.taskBarExitAnimDuration)
+                    .setDuration(mConfig.taskViewExitToAppDuration)
                     .setInterpolator(mConfig.fastOutLinearInInterpolator)
                     .withLayer()
                     .start();
@@ -421,7 +419,7 @@
                     .setStartDelay(0)
                     .setUpdateListener(null)
                     .setInterpolator(mConfig.fastOutLinearInInterpolator)
-                    .setDuration(mConfig.taskBarExitAnimDuration)
+                    .setDuration(mConfig.taskViewExitToAppDuration)
                     .start();
             }
         }
@@ -477,7 +475,9 @@
         startDeleteTaskAnimation(new Runnable() {
             @Override
             public void run() {
-                mCb.onTaskViewDismissed(tv);
+                if (mCb != null) {
+                    mCb.onTaskViewDismissed(tv);
+                }
             }
         });
     }
@@ -494,7 +494,9 @@
     void setClipViewInStack(boolean clip) {
         if (clip != mClipViewInStack) {
             mClipViewInStack = clip;
-            mCb.onTaskViewClipStateChanged(this);
+            if (mCb != null) {
+                mCb.onTaskViewClipStateChanged(this);
+            }
         }
     }
 
@@ -578,7 +580,9 @@
         // Update the thumbnail alpha with the focus
         mThumbnailView.onFocusChanged(true);
         // Call the callback
-        mCb.onTaskViewFocusChanged(this, true);
+        if (mCb != null) {
+            mCb.onTaskViewFocusChanged(this, true);
+        }
         // Workaround, we don't always want it focusable in touch mode, but we want the first task
         // to be focused after the enter-recents animation, which can be triggered from either touch
         // or keyboard
@@ -601,7 +605,9 @@
         // Update the thumbnail alpha with the focus
         mThumbnailView.onFocusChanged(false);
         // Call the callback
-        mCb.onTaskViewFocusChanged(this, false);
+        if (mCb != null) {
+            mCb.onTaskViewFocusChanged(this, false);
+        }
         invalidate();
     }
 
@@ -702,7 +708,9 @@
                 @Override
                 public void run() {
                     if (Constants.DebugFlags.App.EnableTaskFiltering && v == mHeaderView.mApplicationIcon) {
-                        mCb.onTaskViewAppIconClicked(tv);
+                        if (mCb != null) {
+                            mCb.onTaskViewAppIconClicked(tv);
+                        }
                     } else if (v == mHeaderView.mDismissButton) {
                         dismissTask();
                     }
@@ -713,7 +721,9 @@
                 // Reset the translation of the action button before we animate it out
                 mActionButtonView.setTranslationZ(0f);
             }
-            mCb.onTaskViewClicked(tv, tv.getTask(), (v == mActionButtonView));
+            if (mCb != null) {
+                mCb.onTaskViewClicked(tv, tv.getTask(), (v == mActionButtonView));
+            }
         }
     }
 
@@ -722,8 +732,10 @@
     @Override
     public boolean onLongClick(View v) {
         if (v == mHeaderView.mApplicationIcon) {
-            mCb.onTaskViewAppInfoClicked(this);
-            return true;
+            if (mCb != null) {
+                mCb.onTaskViewAppInfoClicked(this);
+                return true;
+            }
         }
         return false;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index 5de84bd..1e5d9fc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -235,7 +235,7 @@
                     .alpha(0f)
                     .setStartDelay(0)
                     .setInterpolator(mConfig.fastOutSlowInInterpolator)
-                    .setDuration(mConfig.taskBarExitAnimDuration)
+                    .setDuration(mConfig.taskViewExitToAppDuration)
                     .withLayer()
                     .start();
         }
@@ -249,7 +249,7 @@
                 .alpha(1f)
                 .setStartDelay(0)
                 .setInterpolator(mConfig.fastOutLinearInInterpolator)
-                .setDuration(mConfig.taskBarEnterAnimDuration)
+                .setDuration(mConfig.taskViewEnterFromAppDuration)
                 .withLayer()
                 .start();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
index c83248e..117a7d3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
@@ -237,12 +237,12 @@
     /** Animates this task thumbnail as it enters Recents. */
     void startEnterRecentsAnimation(int delay, Runnable postAnimRunnable) {
         startFadeAnimation(mConfig.taskViewThumbnailAlpha, delay,
-                mConfig.taskBarEnterAnimDuration, postAnimRunnable);
+                mConfig.taskViewEnterFromAppDuration, postAnimRunnable);
     }
 
     /** Animates this task thumbnail as it exits Recents. */
     void startLaunchTaskAnimation(Runnable postAnimRunnable) {
-        startFadeAnimation(1f, 0, mConfig.taskBarExitAnimDuration, postAnimRunnable);
+        startFadeAnimation(1f, 0, mConfig.taskViewExitToAppDuration, postAnimRunnable);
     }
 
     /** Starts a new thumbnail alpha animation. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 02b9378..7b60307 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -43,6 +43,7 @@
 import android.view.animation.PathInterpolator;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 /**
  * Base class for both {@link ExpandableNotificationRow} and {@link NotificationOverflowContainer}
@@ -53,6 +54,7 @@
     private static final long DOUBLETAP_TIMEOUT_MS = 1200;
     private static final int BACKGROUND_ANIMATION_LENGTH_MS = 220;
     private static final int ACTIVATE_ANIMATION_LENGTH = 220;
+    private static final int DARK_ANIMATION_LENGTH = 170;
 
     /**
      * The amount of width, which is kept in the end when performing a disappear animation (also
@@ -84,6 +86,11 @@
      */
     private static final float VERTICAL_ANIMATION_START = 1.0f;
 
+    /**
+     * Scale for the background to animate from when exiting dark mode.
+     */
+    private static final float DARK_EXIT_SCALE_START = 0.93f;
+
     private static final Interpolator ACTIVATE_INVERSE_INTERPOLATOR
             = new PathInterpolator(0.6f, 0, 0.5f, 1);
     private static final Interpolator ACTIVATE_INVERSE_ALPHA_INTERPOLATOR
@@ -94,7 +101,6 @@
 
     private boolean mDimmed;
     private boolean mDark;
-    private final Paint mDarkPaint = createDarkPaint();
 
     private int mBgTint = 0;
     private final int mRoundedRectCornerRadius;
@@ -332,40 +338,32 @@
         if (mDimmed != dimmed) {
             mDimmed = dimmed;
             if (fade) {
-                fadeBackground();
+                fadeDimmedBackground();
             } else {
                 updateBackground();
             }
         }
     }
 
-    public void setDark(boolean dark, boolean fade) {
-        // TODO implement fade
-        if (mDark != dark) {
-            mDark = dark;
-            if (mDark) {
-                setLayerType(View.LAYER_TYPE_HARDWARE, mDarkPaint);
-            } else {
-                setLayerType(View.LAYER_TYPE_NONE, null);
-            }
+    public void setDark(boolean dark, boolean fade, long delay) {
+        super.setDark(dark, fade, delay);
+        if (mDark == dark) {
+            return;
         }
-    }
-
-    private static Paint createDarkPaint() {
-        final Paint p = new Paint();
-        final float[] invert = {
-            -1f,  0f,  0f, 1f, 1f,
-             0f, -1f,  0f, 1f, 1f,
-             0f,  0f, -1f, 1f, 1f,
-             0f,  0f,  0f, 1f, 0f
-        };
-        final ColorMatrix m = new ColorMatrix(invert);
-        final ColorMatrix grayscale = new ColorMatrix();
-        grayscale.setSaturation(0);
-        m.preConcat(grayscale);
-        p.setColorFilter(new ColorMatrixColorFilter(m));
-        return p;
-    }
+        mDark = dark;
+        if (!dark && fade) {
+            if (mActivated) {
+                mBackgroundDimmed.setVisibility(View.VISIBLE);
+                mBackgroundNormal.setVisibility(View.VISIBLE);
+            } else {
+                mBackgroundDimmed.setVisibility(View.VISIBLE);
+                mBackgroundNormal.setVisibility(View.INVISIBLE);
+            }
+            fadeDarkToDimmed(delay);
+        } else {
+            updateBackground();
+        }
+     }
 
     public void setShowingLegacyBackground(boolean showing) {
         mShowingLegacyBackground = showing;
@@ -402,7 +400,39 @@
         mBackgroundNormal.setRippleColor(rippleColor);
     }
 
-    private void fadeBackground() {
+    /**
+     * Fades the dimmed background when exiting dark mode.
+     */
+    private void fadeDarkToDimmed(long delay) {
+        mBackgroundDimmed.setAlpha(0f);
+        mBackgroundDimmed.setPivotX(mBackgroundDimmed.getWidth() / 2f);
+        mBackgroundDimmed.setPivotY(getActualHeight() / 2f);
+        mBackgroundDimmed.setScaleX(DARK_EXIT_SCALE_START);
+        mBackgroundDimmed.setScaleY(DARK_EXIT_SCALE_START);
+        mBackgroundDimmed.animate()
+                .alpha(1f)
+                .scaleX(1f)
+                .scaleY(1f)
+                .setDuration(DARK_ANIMATION_LENGTH)
+                .setStartDelay(delay)
+                .setInterpolator(mLinearOutSlowInInterpolator)
+                .setListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationCancel(Animator animation) {
+                        // Jump state if we are cancelled
+                        mBackgroundDimmed.setScaleX(1f);
+                        mBackgroundDimmed.setScaleY(1f);
+                        mBackgroundDimmed.setAlpha(1f);
+                    }
+                })
+                .start();
+    }
+
+    /**
+     * Fades the background when the dimmed state changes.
+     */
+    private void fadeDimmedBackground() {
+        mBackgroundDimmed.animate().cancel();
         mBackgroundNormal.animate().cancel();
         if (mDimmed) {
             mBackgroundDimmed.setVisibility(View.VISIBLE);
@@ -443,11 +473,14 @@
     }
 
     private void updateBackground() {
-        if (mDimmed) {
+        cancelFadeAnimations();
+        if (mDark) {
+            mBackgroundDimmed.setVisibility(View.INVISIBLE);
+            mBackgroundNormal.setVisibility(View.INVISIBLE);
+        } else if (mDimmed) {
             mBackgroundDimmed.setVisibility(View.VISIBLE);
             mBackgroundNormal.setVisibility(View.INVISIBLE);
         } else {
-            cancelFadeAnimations();
             mBackgroundDimmed.setVisibility(View.INVISIBLE);
             mBackgroundNormal.setVisibility(View.VISIBLE);
             mBackgroundNormal.setAlpha(1f);
@@ -459,6 +492,7 @@
         if (mBackgroundAnimator != null) {
             mBackgroundAnimator.cancel();
         }
+        mBackgroundDimmed.animate().cancel();
         mBackgroundNormal.animate().cancel();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 7345440..8ad8406 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -207,11 +207,11 @@
     }
 
     @Override
-    public void setDark(boolean dark, boolean fade) {
-        super.setDark(dark, fade);
+    public void setDark(boolean dark, boolean fade, long delay) {
+        super.setDark(dark, fade, delay);
         final NotificationContentView showing = getShowingLayout();
         if (showing != null) {
-            showing.setDark(dark, fade);
+            showing.setDark(dark, fade, delay);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index bf1e78e..ebc663c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -39,6 +39,7 @@
     private int mActualHeight;
     protected int mClipTopAmount;
     private boolean mActualHeightInitialized;
+    private boolean mDark;
     private ArrayList<View> mMatchParentViews = new ArrayList<View>();
 
     public ExpandableView(Context context, AttributeSet attrs) {
@@ -185,8 +186,14 @@
      *
      * @param dark Whether the notification should be dark.
      * @param fade Whether an animation should be played to change the state.
+     * @param delay If fading, the delay of the animation.
      */
-    public void setDark(boolean dark, boolean fade) {
+    public void setDark(boolean dark, boolean fade, long delay) {
+        mDark = dark;
+    }
+
+    public boolean isDark() {
+        return mDark;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 99214a0..27da6fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -42,14 +42,14 @@
 public class NotificationContentView extends FrameLayout {
 
     private static final long ANIMATION_DURATION_LENGTH = 170;
-    private static final Paint INVERT_PAINT = createInvertPaint();
-    private static final ColorFilter NO_COLOR_FILTER = new ColorFilter();
 
     private final Rect mClipBounds = new Rect();
 
     private View mContractedChild;
     private View mExpandedChild;
 
+    private NotificationViewWrapper mContractedWrapper;
+
     private int mSmallHeight;
     private int mClipTopAmount;
     private int mActualHeight;
@@ -84,8 +84,8 @@
     }
 
     @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
         updateVisibility();
     }
 
@@ -122,6 +122,7 @@
         sanitizeContractedLayoutParams(child);
         addView(child);
         mContractedChild = child;
+        mContractedWrapper = NotificationViewWrapper.wrap(getContext(), child);
         selectLayout(false /* animate */, true /* force */);
     }
 
@@ -249,38 +250,10 @@
         return mExpandedChild != null;
     }
 
-    public void setDark(boolean dark, boolean fade) {
+    public void setDark(boolean dark, boolean fade, long delay) {
         if (mDark == dark || mContractedChild == null) return;
         mDark = dark;
-        setImageViewDark(dark, fade, com.android.internal.R.id.right_icon);
-        setImageViewDark(dark, fade, com.android.internal.R.id.icon);
-    }
-
-    private void setImageViewDark(boolean dark, boolean fade, int imageViewId) {
-        // TODO: implement fade
-        final ImageView v = (ImageView) mContractedChild.findViewById(imageViewId);
-        if (v == null) return;
-        final Drawable d = v.getBackground();
-        if (dark) {
-            v.setLayerType(LAYER_TYPE_HARDWARE, INVERT_PAINT);
-            if (d != null) {
-                v.setTag(R.id.doze_saved_filter_tag, d.getColorFilter() != null ? d.getColorFilter()
-                        : NO_COLOR_FILTER);
-                d.setColorFilter(getResources().getColor(R.color.doze_small_icon_background_color),
-                        PorterDuff.Mode.SRC_ATOP);
-                v.setImageAlpha(getResources().getInteger(R.integer.doze_small_icon_alpha));
-            }
-        } else {
-            v.setLayerType(LAYER_TYPE_NONE, null);
-            if (d != null)  {
-                final ColorFilter filter = (ColorFilter) v.getTag(R.id.doze_saved_filter_tag);
-                if (filter != null) {
-                    d.setColorFilter(filter == NO_COLOR_FILTER ? null : filter);
-                    v.setTag(R.id.doze_saved_filter_tag, null);
-                }
-                v.setImageAlpha(0xff);
-            }
-        }
+        mContractedWrapper.setDark(dark, fade, delay);
     }
 
     @Override
@@ -290,16 +263,4 @@
         // layout, and saves us some layers.
         return false;
     }
-
-    private static Paint createInvertPaint() {
-        final Paint p = new Paint();
-        final float[] invert = {
-            -1f,  0f,  0f, 1f, 1f,
-             0f, -1f,  0f, 1f, 1f,
-             0f,  0f, -1f, 1f, 1f,
-             0f,  0f,  0f, 1f, 0f
-        };
-        p.setColorFilter(new ColorMatrixColorFilter(new ColorMatrix(invert)));
-        return p;
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationCustomViewWrapper.java
new file mode 100644
index 0000000..045be3e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationCustomViewWrapper.java
@@ -0,0 +1,48 @@
+/*
+ * 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.systemui.statusbar;
+
+import android.view.View;
+
+import com.android.systemui.ViewInvertHelper;
+import com.android.systemui.statusbar.phone.NotificationPanelView;
+
+/**
+ * Wraps a notification containing a custom view.
+ */
+public class NotificationCustomViewWrapper extends NotificationViewWrapper {
+
+    private final ViewInvertHelper mInvertHelper;
+    private boolean mDark;
+
+    protected NotificationCustomViewWrapper(View view) {
+        super(view);
+        mInvertHelper = new ViewInvertHelper(view, NotificationPanelView.DOZE_ANIMATION_DURATION);
+    }
+
+    @Override
+    public void setDark(boolean dark, boolean fade, long delay) {
+        if (mDark != dark) {
+            mDark = dark;
+            if (fade) {
+                mInvertHelper.fade(dark, delay);
+            } else {
+                mInvertHelper.update(dark);
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaViewWrapper.java
new file mode 100644
index 0000000..8f63a79
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaViewWrapper.java
@@ -0,0 +1,42 @@
+/*
+ * 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.systemui.statusbar;
+
+import android.content.Context;
+import android.view.View;
+
+/**
+ * Wraps a media notification.
+ */
+public class NotificationMediaViewWrapper extends NotificationTemplateViewWrapper {
+
+    private boolean mDark;
+
+    protected NotificationMediaViewWrapper(Context ctx, View view) {
+        super(ctx, view);
+    }
+
+    @Override
+    public void setDark(boolean dark, boolean fade, long delay) {
+        if (mDark != dark) {
+            mDark = dark;
+
+            // Only update the large icon, because the rest is already inverted.
+            setPictureGrayscale(dark, fade, delay);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java
index edfd205..bfa3aa5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java
@@ -21,6 +21,8 @@
 import android.widget.TextView;
 
 import com.android.systemui.R;
+import com.android.systemui.ViewInvertHelper;
+import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 /**
  * Container view for overflowing notification icons on Keyguard.
@@ -28,6 +30,8 @@
 public class NotificationOverflowContainer extends ActivatableNotificationView {
 
     private NotificationOverflowIconsView mIconsView;
+    private ViewInvertHelper mViewInvertHelper;
+    private boolean mDark;
 
     public NotificationOverflowContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -39,6 +43,20 @@
         mIconsView = (NotificationOverflowIconsView) findViewById(R.id.overflow_icons_view);
         mIconsView.setMoreText((TextView) findViewById(R.id.more_text));
         mIconsView.setOverflowIndicator(findViewById(R.id.more_icon_overflow));
+        mViewInvertHelper = new ViewInvertHelper(findViewById(R.id.content),
+                NotificationPanelView.DOZE_ANIMATION_DURATION);
+    }
+
+    @Override
+    public void setDark(boolean dark, boolean fade, long delay) {
+        super.setDark(dark, fade, delay);
+        if (mDark == dark) return;
+        mDark = dark;
+        if (fade) {
+            mViewInvertHelper.fade(dark, delay);
+        } else {
+            mViewInvertHelper.update(dark);
+        }
     }
 
     public NotificationOverflowIconsView getIconsView() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java
new file mode 100644
index 0000000..8dc14b0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java
@@ -0,0 +1,223 @@
+/*
+ * 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.systemui.statusbar;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.view.View;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+import android.widget.ImageView;
+
+import com.android.systemui.R;
+import com.android.systemui.ViewInvertHelper;
+import com.android.systemui.statusbar.phone.NotificationPanelView;
+
+/**
+ * Wraps a notification view inflated from a template.
+ */
+public class NotificationTemplateViewWrapper extends NotificationViewWrapper {
+
+    private final ViewInvertHelper mInvertHelper;
+    private final ImageView mIcon;
+    protected final ImageView mPicture;
+    private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix();
+    private final PorterDuffColorFilter mIconColorFilter = new PorterDuffColorFilter(
+            0, PorterDuff.Mode.SRC_ATOP);
+    private final int mIconDarkAlpha;
+    private final int mIconBackgroundColor;
+    private final int mIconBackgroundDarkColor;
+    private final Interpolator mLinearOutSlowInInterpolator;
+
+    private boolean mDark;
+
+    protected NotificationTemplateViewWrapper(Context ctx, View view) {
+        super(view);
+        mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha);
+        mIconBackgroundDarkColor =
+                ctx.getResources().getColor(R.color.doze_small_icon_background_color);
+        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(ctx,
+                android.R.interpolator.linear_out_slow_in);
+        View mainColumn = view.findViewById(com.android.internal.R.id.notification_main_column);
+        mInvertHelper = mainColumn != null
+                ? new ViewInvertHelper(mainColumn, NotificationPanelView.DOZE_ANIMATION_DURATION)
+                : null;
+        ImageView largeIcon = (ImageView) view.findViewById(com.android.internal.R.id.icon);
+        ImageView rightIcon = (ImageView) view.findViewById(com.android.internal.R.id.right_icon);
+        mIcon = resolveIcon(largeIcon, rightIcon);
+        mPicture = resolvePicture(largeIcon);
+        mIconBackgroundColor = resolveBackgroundColor(mIcon);
+    }
+
+    private ImageView resolveIcon(ImageView largeIcon, ImageView rightIcon) {
+        return largeIcon != null && largeIcon.getBackground() != null ? largeIcon
+                : rightIcon != null && rightIcon.getBackground() != null ? rightIcon
+                : null;
+    }
+
+    private ImageView resolvePicture(ImageView largeIcon) {
+        return largeIcon != null && largeIcon.getBackground() == null
+                ? largeIcon
+                : null;
+    }
+
+    private int resolveBackgroundColor(ImageView icon) {
+        if (icon != null && icon.getBackground() != null) {
+            ColorFilter filter = icon.getBackground().getColorFilter();
+            if (filter instanceof PorterDuffColorFilter) {
+                return ((PorterDuffColorFilter) filter).getColor();
+            }
+        }
+        return 0;
+    }
+
+    @Override
+    public void setDark(boolean dark, boolean fade, long delay) {
+        if (mDark != dark) {
+            mDark = dark;
+            if (mInvertHelper != null) {
+                if (fade) {
+                    mInvertHelper.fade(dark, delay);
+                } else {
+                    mInvertHelper.update(dark);
+                }
+            }
+            if (mIcon != null) {
+                if (fade) {
+                    fadeIconColorFilter(mIcon, dark, delay);
+                    fadeIconAlpha(mIcon, dark, delay);
+                } else {
+                    updateIconColorFilter(mIcon, dark);
+                    updateIconAlpha(mIcon, dark);
+                }
+            }
+            setPictureGrayscale(dark, fade, delay);
+        }
+    }
+
+    protected void setPictureGrayscale(boolean grayscale, boolean fade, long delay) {
+        if (mPicture != null) {
+            if (fade) {
+                fadeGrayscale(mPicture, grayscale, delay);
+            } else {
+                updateGrayscale(mPicture, grayscale);
+            }
+        }
+    }
+
+    private void startIntensityAnimation(ValueAnimator.AnimatorUpdateListener updateListener,
+            boolean dark, long delay, Animator.AnimatorListener listener) {
+        float startIntensity = dark ? 0f : 1f;
+        float endIntensity = dark ? 1f : 0f;
+        ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity);
+        animator.addUpdateListener(updateListener);
+        animator.setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION);
+        animator.setInterpolator(mLinearOutSlowInInterpolator);
+        animator.setStartDelay(delay);
+        if (listener != null) {
+            animator.addListener(listener);
+        }
+        animator.start();
+    }
+
+    private void fadeIconColorFilter(final ImageView target, boolean dark, long delay) {
+        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                updateIconColorFilter(target, (Float) animation.getAnimatedValue());
+            }
+        }, dark, delay, null /* listener */);
+    }
+
+    private void fadeIconAlpha(final ImageView target, boolean dark, long delay) {
+        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                float t = (float) animation.getAnimatedValue();
+                target.setImageAlpha((int) (255 * (1f - t) + mIconDarkAlpha * t));
+            }
+        }, dark, delay, null /* listener */);
+    }
+
+    protected void fadeGrayscale(final ImageView target, final boolean dark, long delay) {
+        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                updateGrayscaleMatrix((float) animation.getAnimatedValue());
+                target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
+            }
+        }, dark, delay, new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                if (!dark) {
+                    target.setColorFilter(null);
+                }
+            }
+        });
+    }
+
+    private void updateIconColorFilter(ImageView target, boolean dark) {
+        updateIconColorFilter(target, dark ? 1f : 0f);
+    }
+
+    private void updateIconColorFilter(ImageView target, float intensity) {
+        int color = interpolateColor(mIconBackgroundColor, mIconBackgroundDarkColor, intensity);
+        mIconColorFilter.setColor(color);
+        target.getBackground().mutate().setColorFilter(mIconColorFilter);
+    }
+
+    private void updateIconAlpha(ImageView target, boolean dark) {
+        target.setImageAlpha(dark ? mIconDarkAlpha : 255);
+    }
+
+    protected void updateGrayscale(ImageView target, boolean dark) {
+        if (dark) {
+            updateGrayscaleMatrix(1f);
+            target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
+        } else {
+            target.setColorFilter(null);
+        }
+    }
+
+    private void updateGrayscaleMatrix(float intensity) {
+        mGrayscaleColorMatrix.setSaturation(1 - intensity);
+    }
+
+    private static int interpolateColor(int source, int target, float t) {
+        int aSource = Color.alpha(source);
+        int rSource = Color.red(source);
+        int gSource = Color.green(source);
+        int bSource = Color.blue(source);
+        int aTarget = Color.alpha(target);
+        int rTarget = Color.red(target);
+        int gTarget = Color.green(target);
+        int bTarget = Color.blue(target);
+        return Color.argb(
+                (int) (aSource * (1f - t) + aTarget * t),
+                (int) (rSource * (1f - t) + rTarget * t),
+                (int) (gSource * (1f - t) + gTarget * t),
+                (int) (bSource * (1f - t) + bTarget * t));
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java
new file mode 100644
index 0000000..0a02573
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java
@@ -0,0 +1,56 @@
+/*
+ * 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.systemui.statusbar;
+
+import android.content.Context;
+import android.view.View;
+
+import com.android.internal.R;
+
+/**
+ * Wraps the actual notification content view; used to implement behaviors which are different for
+ * the individual templates and custom views.
+ */
+public abstract class NotificationViewWrapper {
+
+    protected final View mView;
+
+    public static NotificationViewWrapper wrap(Context ctx, View v) {
+
+        // TODO: Figure out a better way to find out which template the view is.
+        if (v.findViewById(com.android.internal.R.id.media_actions) != null) {
+            return new NotificationMediaViewWrapper(ctx, v);
+        } else if (v.getId() == com.android.internal.R.id.status_bar_latest_event_content) {
+            return new NotificationTemplateViewWrapper(ctx, v);
+        } else {
+            return new NotificationCustomViewWrapper(v);
+        }
+    }
+
+    protected NotificationViewWrapper(View view) {
+        mView = view;
+    }
+
+    /**
+     * In dark mode, we draw as little as possible, assuming a black background.
+     *
+     * @param dark whether we should display ourselves in dark mode
+     * @param fade whether to animate the transition if the mode changes
+     * @param delay if fading, the delay of the animation
+     */
+    public abstract void setDark(boolean dark, boolean fade, long delay);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 9154a48..418c57f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -48,6 +48,7 @@
     private int mMobileStrengthId = 0, mMobileTypeId = 0;
     private boolean mIsAirplaneMode = false;
     private int mAirplaneIconId = 0;
+    private int mAirplaneContentDescription;
     private String mWifiDescription, mMobileDescription, mMobileTypeDescription;
     private boolean mIsMobileTypeIconWide;
 
@@ -160,9 +161,10 @@
     }
 
     @Override
-    public void setIsAirplaneMode(boolean is, int airplaneIconId) {
+    public void setIsAirplaneMode(boolean is, int airplaneIconId, int contentDescription) {
         mIsAirplaneMode = is;
         mAirplaneIconId = airplaneIconId;
+        mAirplaneContentDescription = contentDescription;
 
         apply();
     }
@@ -236,6 +238,8 @@
 
         if (mIsAirplaneMode) {
             mAirplane.setImageResource(mAirplaneIconId);
+            mAirplane.setContentDescription(mAirplaneContentDescription != 0 ?
+                    mContext.getString(mAirplaneContentDescription) : "");
             mAirplane.setVisibility(View.VISIBLE);
         } else {
             mAirplane.setVisibility(View.GONE);
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 47ce603..a044743 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -98,6 +98,7 @@
     private boolean mCollapseAfterPeek;
     private boolean mExpanding;
     private boolean mGestureWaitForTouchSlop;
+    private boolean mDozingOnDown;
     private Runnable mPeekRunnable = new Runnable() {
         @Override
         public void run() {
@@ -244,6 +245,7 @@
                 mUpdateFlingOnLayout = false;
                 mPeekTouching = mPanelClosedOnDown;
                 mTouchAboveFalsingThreshold = false;
+                mDozingOnDown = isDozing();
                 if (mVelocityTracker == null) {
                     initVelocityTracker();
                 }
@@ -418,6 +420,7 @@
                 mHasLayoutedSinceDown = false;
                 mUpdateFlingOnLayout = false;
                 mTouchAboveFalsingThreshold = false;
+                mDozingOnDown = isDozing();
                 initVelocityTracker();
                 trackMovement(event);
                 break;
@@ -937,7 +940,7 @@
     private boolean onMiddleClicked() {
         switch (mStatusBar.getBarState()) {
             case StatusBarState.KEYGUARD:
-                if (!isDozing()) {
+                if (!mDozingOnDown) {
                     startUnlockHintAnimation();
                 }
                 return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index f5c994a..3fca56d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -79,6 +79,7 @@
 import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
+import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
@@ -821,7 +822,12 @@
         signalClusterQs.setNetworkController(mNetworkController);
         final boolean isAPhone = mNetworkController.hasVoiceCallingFeature();
         if (isAPhone) {
-            mNetworkController.addEmergencyLabelView(mHeader);
+            mNetworkController.addEmergencyListener(new NetworkControllerImpl.EmergencyListener() {
+                @Override
+                public void setEmergencyCallsOnly(boolean emergencyOnly) {
+                    mHeader.setShowEmergencyCallsOnly(emergencyOnly);
+                }
+            });
         }
 
         mCarrierLabel = (TextView)mStatusBarWindow.findViewById(R.id.carrier_label);
@@ -830,13 +836,19 @@
         if (mShowCarrierInPanel) {
             mCarrierLabel.setVisibility(mCarrierLabelVisible ? View.VISIBLE : View.INVISIBLE);
 
-            // for mobile devices, we always show mobile connection info here (SPN/PLMN)
-            // for other devices, we show whatever network is connected
-            if (mNetworkController.hasMobileDataFeature()) {
-                mNetworkController.addMobileLabelView(mCarrierLabel);
-            } else {
-                mNetworkController.addCombinedLabelView(mCarrierLabel);
-            }
+            mNetworkController.addCarrierLabel(new NetworkControllerImpl.CarrierLabelListener() {
+                @Override
+                public void setCarrierLabel(String label) {
+                    mCarrierLabel.setText(label);
+                    if (mNetworkController.hasMobileDataFeature()) {
+                        if (TextUtils.isEmpty(label)) {
+                            mCarrierLabel.setVisibility(View.GONE);
+                        } else {
+                            mCarrierLabel.setVisibility(View.VISIBLE);
+                        }
+                    }
+                }
+            });
 
             // set up the dynamic hide/show of the label
             // TODO: uncomment, handle this for the Stack scroller aswell
@@ -2669,6 +2681,7 @@
 
     @Override
     public void setInteracting(int barWindow, boolean interacting) {
+        final boolean changing = ((mInteractingWindows & barWindow) != 0) != interacting;
         mInteractingWindows = interacting
                 ? (mInteractingWindows | barWindow)
                 : (mInteractingWindows & ~barWindow);
@@ -2677,6 +2690,12 @@
         } else {
             resumeSuspendedAutohide();
         }
+        // manually dismiss the volume panel when interacting with the nav bar
+        if (changing && interacting && barWindow == StatusBarManager.WINDOW_NAVIGATION_BAR) {
+            if (mVolumeComponent != null) {
+                mVolumeComponent.dismissNow();
+            }
+        }
         checkBarModes();
     }
 
@@ -3689,14 +3708,11 @@
         if (mState != StatusBarState.KEYGUARD && !mNotificationPanel.isDozing()) {
             return;
         }
-        mNotificationPanel.setDozing(mDozing, mDozeScrimController.isPulsing() /*animate*/);
-        if (mDozing) {
-            mStackScroller.setDark(true, false /*animate*/);
-        } else {
-            mStackScroller.setDark(false, false /*animate*/);
-        }
+        boolean animate = !mDozing && mDozeScrimController.isPulsing();
+        mNotificationPanel.setDozing(mDozing, animate);
+        mStackScroller.setDark(mDozing, animate);
         mScrimController.setDozing(mDozing);
-        mDozeScrimController.setDozing(mDozing, mDozeScrimController.isPulsing() /* animate */);
+        mDozeScrimController.setDozing(mDozing, animate);
     }
 
     public void updateStackScrollerState(boolean goingToFullShade) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index 45a1386..8ce608c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -122,7 +122,7 @@
                     tile.userSwitch(newUserId);
                 }
                 mSecurity.onUserSwitched(newUserId);
-                mNetwork.onUserSwitched(newUserId);
+                mNetwork.getAccessPointController().onUserSwitched(newUserId);
                 mObserver.register();
             }
         };
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointController.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java
index 0a385d7..6fec97e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java
@@ -36,15 +36,13 @@
 import android.util.Log;
 
 import com.android.systemui.R;
-import com.android.systemui.statusbar.policy.NetworkController.AccessPoint;
-import com.android.systemui.statusbar.policy.NetworkController.AccessPointCallback;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 
-public class AccessPointController {
+public class AccessPointControllerImpl implements NetworkController.AccessPointController {
     private static final String TAG = "AccessPointController";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
@@ -69,7 +67,7 @@
     private boolean mScanning;
     private int mCurrentUser;
 
-    public AccessPointController(Context context) {
+    public AccessPointControllerImpl(Context context) {
         mContext = context;
         mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
@@ -81,25 +79,28 @@
                 new UserHandle(mCurrentUser));
     }
 
-    void onUserSwitched(int newUserId) {
+    public void onUserSwitched(int newUserId) {
         mCurrentUser = newUserId;
     }
 
-    public void addCallback(AccessPointCallback callback) {
+    @Override
+    public void addAccessPointCallback(AccessPointCallback callback) {
         if (callback == null || mCallbacks.contains(callback)) return;
         if (DEBUG) Log.d(TAG, "addCallback " + callback);
         mCallbacks.add(callback);
         mReceiver.setListening(!mCallbacks.isEmpty());
     }
 
-    public void removeCallback(AccessPointCallback callback) {
+    @Override
+    public void removeAccessPointCallback(AccessPointCallback callback) {
         if (callback == null) return;
         if (DEBUG) Log.d(TAG, "removeCallback " + callback);
         mCallbacks.remove(callback);
         mReceiver.setListening(!mCallbacks.isEmpty());
     }
 
-    public void scan() {
+    @Override
+    public void scanForAccessPoints() {
         if (mScanning) return;
         if (DEBUG) Log.d(TAG, "scan!");
         mScanning = mWifiManager.startScan();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityContentDescriptions.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityContentDescriptions.java
index 7ac2a98..b7c74e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityContentDescriptions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityContentDescriptions.java
@@ -33,11 +33,5 @@
         R.string.accessibility_wifi_three_bars,
         R.string.accessibility_wifi_signal_full
     };
-    static final int[] WIMAX_CONNECTION_STRENGTH = {
-        R.string.accessibility_no_wimax,
-        R.string.accessibility_wimax_one_bar,
-        R.string.accessibility_wimax_two_bars,
-        R.string.accessibility_wimax_three_bars,
-        R.string.accessibility_wimax_signal_full
-    };
+    static final int WIFI_NO_CONNECTION = R.string.accessibility_no_wifi;
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataControllerImpl.java
similarity index 94%
rename from packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataController.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataControllerImpl.java
index 33d68bf..20f0a83 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataControllerImpl.java
@@ -38,12 +38,10 @@
 import android.text.format.Time;
 import android.util.Log;
 
-import com.android.systemui.statusbar.policy.NetworkController.DataUsageInfo;
-
 import java.util.Date;
 import java.util.Locale;
 
-public class MobileDataController {
+public class MobileDataControllerImpl implements NetworkController.MobileDataController {
     private static final String TAG = "MobileDataController";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
@@ -61,8 +59,9 @@
 
     private INetworkStatsSession mSession;
     private Callback mCallback;
+    private NetworkControllerImpl mNetworkController;
 
-    public MobileDataController(Context context) {
+    public MobileDataControllerImpl(Context context) {
         mContext = context;
         mTelephonyManager = TelephonyManager.from(context);
         mConnectivityManager = ConnectivityManager.from(context);
@@ -71,6 +70,10 @@
         mPolicyManager = NetworkPolicyManager.from(mContext);
     }
 
+    public void setNetworkController(NetworkControllerImpl networkController) {
+        mNetworkController = networkController;
+    }
+
     private INetworkStatsSession getSession() {
         if (mSession == null) {
             try {
@@ -155,6 +158,9 @@
             } else {
                 usage.warningLevel = DEFAULT_WARNING_LEVEL;
             }
+            if (usage != null) {
+                usage.carrier = mNetworkController.getMobileNetworkName();
+            }
             return usage;
         } catch (RemoteException e) {
             return warn("remote call failed");
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 bb29d01..b024f58 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -22,6 +22,8 @@
     void addNetworkSignalChangedCallback(NetworkSignalChangedCallback cb);
     void removeNetworkSignalChangedCallback(NetworkSignalChangedCallback cb);
     void setWifiEnabled(boolean enabled);
+    AccessPointController getAccessPointController();
+    MobileDataController getMobileDataController();
 
     public interface NetworkSignalChangedCallback {
         void onWifiSignalChanged(boolean enabled, boolean connected, int wifiSignalIconId,
@@ -36,38 +38,50 @@
         void onMobileDataEnabled(boolean enabled);
     }
 
-    void addAccessPointCallback(AccessPointCallback callback);
-    void removeAccessPointCallback(AccessPointCallback callback);
-    void scanForAccessPoints();
-    boolean connect(AccessPoint ap);
-    boolean isMobileDataSupported();
-    boolean isMobileDataEnabled();
-    void setMobileDataEnabled(boolean enabled);
-    DataUsageInfo getDataUsageInfo();
-    boolean canConfigWifi();
-    void onUserSwitched(int newUserId);
+    /**
+     * Tracks changes in access points.  Allows listening for changes, scanning for new APs,
+     * and connecting to new ones.
+     */
+    public interface AccessPointController {
+        void addAccessPointCallback(AccessPointCallback callback);
+        void removeAccessPointCallback(AccessPointCallback callback);
+        void scanForAccessPoints();
+        boolean connect(AccessPoint ap);
+        boolean canConfigWifi();
+        void onUserSwitched(int newUserId);
 
-    public interface AccessPointCallback {
-        void onAccessPointsChanged(AccessPoint[] accessPoints);
+        public interface AccessPointCallback {
+            void onAccessPointsChanged(AccessPoint[] accessPoints);
+        }
+
+        public static class AccessPoint {
+            public static final int NO_NETWORK = -1;  // see WifiManager
+
+            public int networkId;
+            public int iconId;
+            public String ssid;
+            public boolean isConnected;
+            public boolean isConfigured;
+            public boolean hasSecurity;
+            public int level;  // 0 - 5
+        }
     }
 
-    public static class AccessPoint {
-        public static final int NO_NETWORK = -1;  // see WifiManager
+    /**
+     * Tracks mobile data support and usage.
+     */
+    public interface MobileDataController {
+        boolean isMobileDataSupported();
+        boolean isMobileDataEnabled();
+        void setMobileDataEnabled(boolean enabled);
+        DataUsageInfo getDataUsageInfo();
 
-        public int networkId;
-        public int iconId;
-        public String ssid;
-        public boolean isConnected;
-        public boolean isConfigured;
-        public boolean hasSecurity;
-        public int level;  // 0 - 5
-    }
-
-    public static class DataUsageInfo {
-        public String carrier;
-        public String period;
-        public long limitLevel;
-        public long warningLevel;
-        public long usageLevel;
+        public static class DataUsageInfo {
+            public String carrier;
+            public String period;
+            public long limitLevel;
+            public long warningLevel;
+            public long usageLevel;
+        }
     }
 }
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 0caded5..5a97c75 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -26,7 +26,6 @@
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
-import android.net.wimax.WimaxManagerConstants;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
@@ -37,9 +36,8 @@
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
+import android.text.format.DateFormat;
 import android.util.Log;
-import android.view.View;
-import android.widget.TextView;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.IccCardConstants;
@@ -48,130 +46,66 @@
 import com.android.internal.util.AsyncChannel;
 import com.android.systemui.DemoMode;
 import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.StatusBarHeaderView;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
 
 /** Platform implementation of the network controller. **/
 public class NetworkControllerImpl extends BroadcastReceiver
         implements NetworkController, DemoMode {
     // debug
-    static final String TAG = "StatusBar.NetworkController";
-    static final boolean DEBUG = false;
-    static final boolean CHATTY = false; // additional diagnostics, but not logspew
+    static final String TAG = "NetworkController";
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    // additional diagnostics, but not logspew
+    static final boolean CHATTY =  Log.isLoggable(TAG + ".Chat", Log.DEBUG);
+    // Save the previous states of all SignalController state info.
+    static final boolean RECORD_HISTORY = true;
+    // How many to save, must be a power of 2.
+    static final int HISTORY_SIZE = 16;
 
-    // telephony
-    boolean mHspaDataDistinguishable;
-    final TelephonyManager mPhone;
-    boolean mDataConnected;
-    IccCardConstants.State mSimState = IccCardConstants.State.READY;
-    int mPhoneState = TelephonyManager.CALL_STATE_IDLE;
-    int mDataNetType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
-    int mDataState = TelephonyManager.DATA_DISCONNECTED;
-    int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
-    ServiceState mServiceState;
-    SignalStrength mSignalStrength;
-    int[] mDataIconList = TelephonyIcons.DATA_G[0];
-    String mNetworkName;
-    String mNetworkNameDefault;
-    String mNetworkNameSeparator;
-    int mPhoneSignalIconId;
-    int mQSPhoneSignalIconId;
-    int mDataDirectionIconId; // data + data direction on phones
-    int mDataSignalIconId;
-    int mDataTypeIconId;
-    int mQSDataTypeIconId;
-    int mAirplaneIconId;
-    boolean mDataActive;
-    boolean mNoSim;
-    int mLastSignalLevel;
-    boolean mShowPhoneRSSIForData = false;
-    boolean mShowAtLeastThreeGees = false;
-    boolean mAlwaysShowCdmaRssi = false;
+    private static final int INET_CONDITION_THRESHOLD = 50;
 
-    String mContentDescriptionPhoneSignal;
-    String mContentDescriptionWifi;
-    String mContentDescriptionWimax;
-    String mContentDescriptionCombinedSignal;
-    String mContentDescriptionDataType;
+    private final Context mContext;
+    private final TelephonyManager mPhone;
+    private final WifiManager mWifiManager;
+    private final ConnectivityManager mConnectivityManager;
+    private final boolean mHasMobileDataFeature;
 
-    // wifi
-    final WifiManager mWifiManager;
-    AsyncChannel mWifiChannel;
-    boolean mWifiEnabled, mWifiConnected;
-    int mWifiRssi, mWifiLevel;
-    String mWifiSsid;
-    int mWifiIconId = 0;
-    int mQSWifiIconId = 0;
-    int mWifiActivity = WifiManager.DATA_ACTIVITY_NONE;
+    // Subcontrollers.
+    @VisibleForTesting
+    final WifiSignalController mWifiSignalController;
+    @VisibleForTesting
+    final MobileSignalController mMobileSignalController;
+    private final AccessPointController mAccessPoints;
+    private final MobileDataControllerImpl mMobileDataController;
 
     // bluetooth
     private boolean mBluetoothTethered = false;
-    private int mBluetoothTetherIconId =
-        com.android.internal.R.drawable.stat_sys_tether_bluetooth;
-
-    //wimax
-    private boolean mWimaxSupported = false;
-    private boolean mIsWimaxEnabled = false;
-    private boolean mWimaxConnected = false;
-    private boolean mWimaxIdle = false;
-    private int mWimaxIconId = 0;
-    private int mWimaxSignal = 0;
-    private int mWimaxState = 0;
-    private int mWimaxExtraState = 0;
 
     // data connectivity (regardless of state, can we access the internet?)
     // state of inet connection - 0 not connected, 100 connected
     private boolean mConnected = false;
     private int mConnectedNetworkType = ConnectivityManager.TYPE_NONE;
     private String mConnectedNetworkTypeName;
-    private int mLastConnectedNetworkType = ConnectivityManager.TYPE_NONE;
+    private boolean mInetCondition; // Used for Logging and demo.
 
-    private int mInetCondition = 0;
-    private int mLastInetCondition = 0;
-    private static final int INET_CONDITION_THRESHOLD = 50;
-
+    // States that don't belong to a subcontroller.
     private boolean mAirplaneMode = false;
-    private boolean mLastAirplaneMode = true;
-
     private Locale mLocale = null;
-    private Locale mLastLocale = null;
 
-    // our ui
-    Context mContext;
-    ArrayList<TextView> mCombinedLabelViews = new ArrayList<TextView>();
-    ArrayList<TextView> mMobileLabelViews = new ArrayList<TextView>();
-    ArrayList<TextView> mWifiLabelViews = new ArrayList<TextView>();
-    ArrayList<StatusBarHeaderView> mEmergencyViews = new ArrayList<>();
-    ArrayList<SignalCluster> mSignalClusters = new ArrayList<SignalCluster>();
-    ArrayList<NetworkSignalChangedCallback> mSignalsChangedCallbacks =
+    // All the callbacks.
+    private ArrayList<EmergencyListener> mEmergencyListeners = new ArrayList<EmergencyListener>();
+    private ArrayList<CarrierLabelListener> mCarrierListeners =
+            new ArrayList<CarrierLabelListener>();
+    private ArrayList<SignalCluster> mSignalClusters = new ArrayList<SignalCluster>();
+    private ArrayList<NetworkSignalChangedCallback> mSignalsChangedCallbacks =
             new ArrayList<NetworkSignalChangedCallback>();
-    int mLastPhoneSignalIconId = -1;
-    int mLastDataDirectionIconId = -1;
-    int mLastWifiIconId = -1;
-    int mLastWimaxIconId = -1;
-    int mLastCombinedSignalIconId = -1;
-    int mLastDataTypeIconId = -1;
-    String mLastCombinedLabel = "";
-
-    private boolean mHasMobileDataFeature;
-
-    boolean mDataAndWifiStacked = false;
-
-    public interface SignalCluster {
-        void setWifiIndicators(boolean visible, int strengthIcon, String contentDescription);
-        void setMobileDataIndicators(boolean visible, int strengthIcon, int typeIcon,
-                String contentDescription, String typeContentDescription, boolean isTypeIconWide);
-        void setIsAirplaneMode(boolean is, int airplaneIcon);
-    }
-
-    private final AccessPointController mAccessPoints;
-    private final MobileDataController mMobileDataController;
-    private final ConnectivityManager mConnectivityManager;
 
     /**
      * Construct this controller object and register for updates.
@@ -179,68 +113,51 @@
     public NetworkControllerImpl(Context context) {
         this(context, (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE),
                 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE),
-                (WifiManager) context.getSystemService(Context.WIFI_SERVICE));
+                (WifiManager) context.getSystemService(Context.WIFI_SERVICE),
+                Config.readConfig(context), new AccessPointControllerImpl(context),
+                new MobileDataControllerImpl(context));
         registerListeners();
     }
 
     @VisibleForTesting
     NetworkControllerImpl(Context context, ConnectivityManager connectivityManager,
-            TelephonyManager telephonyManager, WifiManager wifiManager) {
+            TelephonyManager telephonyManager, WifiManager wifiManager, Config config,
+            AccessPointControllerImpl accessPointController,
+            MobileDataControllerImpl mobileDataController) {
         mContext = context;
-        final Resources res = context.getResources();
 
         mConnectivityManager = connectivityManager;
         mHasMobileDataFeature =
                 mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
 
-        mShowPhoneRSSIForData = res.getBoolean(R.bool.config_showPhoneRSSIForData);
-        mShowAtLeastThreeGees = res.getBoolean(R.bool.config_showMin3G);
-        mAlwaysShowCdmaRssi = res.getBoolean(
-                com.android.internal.R.bool.config_alwaysUseCdmaRssi);
-
-        // set up the default wifi icon, used when no radios have ever appeared
-        updateWifiIcons();
-        updateWimaxIcons();
-
         // telephony
         mPhone = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
-        mHspaDataDistinguishable = mContext.getResources().getBoolean(
-                R.bool.config_hspa_data_distinguishable);
-        mNetworkNameSeparator = mContext.getString(R.string.status_bar_network_name_separator);
-        mNetworkNameDefault = mContext.getString(
-                com.android.internal.R.string.lockscreen_carrier_default);
-        mNetworkName = mNetworkNameDefault;
 
         // wifi
         mWifiManager = wifiManager;
-        Handler handler = new WifiHandler();
-        mWifiChannel = new AsyncChannel();
-        Messenger wifiMessenger = mWifiManager.getWifiServiceMessenger();
-        if (wifiMessenger != null) {
-            mWifiChannel.connect(mContext, handler, wifiMessenger);
-        }
 
-        // AIRPLANE_MODE_CHANGED is sent at boot; we've probably already missed it
-        updateAirplaneMode();
-
-        mLastLocale = mContext.getResources().getConfiguration().locale;
-        mAccessPoints = new AccessPointController(mContext);
-        mMobileDataController = new MobileDataController(mContext);
-        mMobileDataController.setCallback(new MobileDataController.Callback() {
+        mLocale = mContext.getResources().getConfiguration().locale;
+        mAccessPoints = accessPointController;
+        mMobileDataController = mobileDataController;
+        mMobileDataController.setNetworkController(this);
+        // TODO: Find a way to move this into MobileDataController.
+        mMobileDataController.setCallback(new MobileDataControllerImpl.Callback() {
             @Override
             public void onMobileDataEnabled(boolean enabled) {
                 notifyMobileDataEnabled(enabled);
             }
         });
+        mWifiSignalController = new WifiSignalController(mContext, mHasMobileDataFeature,
+                mSignalsChangedCallbacks, mSignalClusters, this);
+        mMobileSignalController = new MobileSignalController(mContext, config,
+                mHasMobileDataFeature, mPhone, mSignalsChangedCallbacks, mSignalClusters, this);
+
+        // AIRPLANE_MODE_CHANGED is sent at boot; we've probably already missed it
+        updateAirplaneMode(true);
     }
 
     private void registerListeners() {
-        mPhone.listen(mPhoneStateListener,
-                          PhoneStateListener.LISTEN_SERVICE_STATE
-                        | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
-                        | PhoneStateListener.LISTEN_CALL_STATE
-                        | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
-                        | PhoneStateListener.LISTEN_DATA_ACTIVITY);
+        mMobileSignalController.registerListener();
 
         // broadcasts
         IntentFilter filter = new IntentFilter();
@@ -253,29 +170,38 @@
         filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
         filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        mWimaxSupported = mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_wimaxEnabled);
-        if(mWimaxSupported) {
-            filter.addAction(WimaxManagerConstants.WIMAX_NETWORK_STATE_CHANGED_ACTION);
-            filter.addAction(WimaxManagerConstants.SIGNAL_LEVEL_CHANGED_ACTION);
-            filter.addAction(WimaxManagerConstants.NET_4G_STATE_CHANGED_ACTION);
-        }
         mContext.registerReceiver(this, filter);
     }
 
-    @Override
-    public boolean canConfigWifi() {
-        return mAccessPoints.canConfigWifi();
+    private void unregisterListeners() {
+        mMobileSignalController.unregisterListener();
+        mContext.unregisterReceiver(this);
     }
 
     @Override
-    public void onUserSwitched(int newUserId) {
-        mAccessPoints.onUserSwitched(newUserId);
+    public AccessPointController getAccessPointController() {
+        return mAccessPoints;
+    }
+
+    @Override
+    public MobileDataController getMobileDataController() {
+        return mMobileDataController;
+    }
+
+    public void addEmergencyListener(EmergencyListener listener) {
+        mEmergencyListeners.add(listener);
+        refreshCarrierLabel();
+    }
+
+    public void addCarrierLabel(CarrierLabelListener listener) {
+        mCarrierListeners.add(listener);
+        refreshCarrierLabel();
     }
 
     private void notifyMobileDataEnabled(boolean enabled) {
-        for (NetworkSignalChangedCallback cb : mSignalsChangedCallbacks) {
-            cb.onMobileDataEnabled(enabled);
+        int length = mSignalsChangedCallbacks.size();
+        for (int i = 0; i < length; i++) {
+            mSignalsChangedCallbacks.get(i).onMobileDataEnabled(enabled);
         }
     }
 
@@ -287,34 +213,40 @@
         return mPhone.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE;
     }
 
+    public String getMobileNetworkName() {
+        return mMobileSignalController.mCurrentState.networkName;
+    }
+
     public boolean isEmergencyOnly() {
-        return (mServiceState != null && mServiceState.isEmergencyOnly());
+        return mMobileSignalController.isEmergencyOnly();
     }
 
-    public void addCombinedLabelView(TextView v) {
-        mCombinedLabelViews.add(v);
-    }
+    /**
+     * Emergency status may have changed (triggered by MobileSignalController),
+     * so we should recheck and send out the state to listeners.
+     */
+    void recalculateEmergency() {
+        final boolean emergencyOnly = isEmergencyOnly();
 
-    public void addMobileLabelView(TextView v) {
-        mMobileLabelViews.add(v);
-    }
-
-    public void addWifiLabelView(TextView v) {
-        mWifiLabelViews.add(v);
-    }
-
-    public void addEmergencyLabelView(StatusBarHeaderView v) {
-        mEmergencyViews.add(v);
+        int length = mEmergencyListeners.size();
+        for (int i = 0; i < length; i++) {
+            mEmergencyListeners.get(i).setEmergencyCallsOnly(emergencyOnly);
+        }
     }
 
     public void addSignalCluster(SignalCluster cluster) {
         mSignalClusters.add(cluster);
-        refreshSignalCluster(cluster);
+        cluster.setIsAirplaneMode(mAirplaneMode, TelephonyIcons.FLIGHT_MODE_ICON,
+                R.string.accessibility_airplane_mode);
+        mWifiSignalController.notifyListeners();
+        mMobileSignalController.notifyListeners();
     }
 
     public void addNetworkSignalChangedCallback(NetworkSignalChangedCallback cb) {
         mSignalsChangedCallbacks.add(cb);
-        notifySignalsChangedCallbacks(cb);
+        cb.onAirplaneModeChanged(mAirplaneMode);
+        mWifiSignalController.notifyListeners();
+        mMobileSignalController.notifyListeners();
     }
 
     public void removeNetworkSignalChangedCallback(NetworkSignalChangedCallback cb) {
@@ -322,26 +254,6 @@
     }
 
     @Override
-    public void addAccessPointCallback(AccessPointCallback callback) {
-        mAccessPoints.addCallback(callback);
-    }
-
-    @Override
-    public void removeAccessPointCallback(AccessPointCallback callback) {
-        mAccessPoints.removeCallback(callback);
-    }
-
-    @Override
-    public void scanForAccessPoints() {
-        mAccessPoints.scan();
-    }
-
-    @Override
-    public boolean connect(AccessPoint ap) {
-        return mAccessPoints.connect(ap);
-    }
-
-    @Override
     public void setWifiEnabled(final boolean enabled) {
         new AsyncTask<Void, Void, Void>() {
             @Override
@@ -349,7 +261,7 @@
                 // Disable tethering if enabling Wifi
                 final int wifiApState = mWifiManager.getWifiApState();
                 if (enabled && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
-                               (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
+                        (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
                     mWifiManager.setWifiApEnabled(null, false);
                 }
 
@@ -360,732 +272,79 @@
     }
 
     @Override
-    public DataUsageInfo getDataUsageInfo() {
-        final DataUsageInfo info =  mMobileDataController.getDataUsageInfo();
-        if (info != null) {
-            info.carrier = mNetworkName;
-        }
-        return info;
-    }
-
-    @Override
-    public boolean isMobileDataSupported() {
-        return mMobileDataController.isMobileDataSupported();
-    }
-
-    @Override
-    public boolean isMobileDataEnabled() {
-        return mMobileDataController.isMobileDataEnabled();
-    }
-
-    @Override
-    public void setMobileDataEnabled(boolean enabled) {
-        mMobileDataController.setMobileDataEnabled(enabled);
-    }
-
-    private boolean isTypeIconWide(int iconId) {
-        return TelephonyIcons.ICON_LTE == iconId || TelephonyIcons.ICON_1X == iconId
-                || TelephonyIcons.ICON_3G == iconId || TelephonyIcons.ICON_4G == iconId;
-    }
-
-    private boolean isQsTypeIconWide(int iconId) {
-        return TelephonyIcons.QS_ICON_LTE == iconId || TelephonyIcons.QS_ICON_1X == iconId
-                || TelephonyIcons.QS_ICON_3G == iconId || TelephonyIcons.QS_ICON_4G == iconId;
-    }
-
-    public void refreshSignalCluster(SignalCluster cluster) {
-        if (mDemoMode) return;
-        cluster.setWifiIndicators(
-                // only show wifi in the cluster if connected or if wifi-only
-                mWifiEnabled && (mWifiConnected || !mHasMobileDataFeature),
-                mWifiIconId,
-                mContentDescriptionWifi);
-
-        if (mIsWimaxEnabled && mWimaxConnected) {
-            // wimax is special
-            cluster.setMobileDataIndicators(
-                    true,
-                    mAlwaysShowCdmaRssi ? mPhoneSignalIconId : mWimaxIconId,
-                    mDataTypeIconId,
-                    mContentDescriptionWimax,
-                    mContentDescriptionDataType,
-                    false /* isTypeIconWide */ );
-        } else {
-            // normal mobile data
-            cluster.setMobileDataIndicators(
-                    mHasMobileDataFeature,
-                    mShowPhoneRSSIForData ? mPhoneSignalIconId : mDataSignalIconId,
-                    mDataTypeIconId,
-                    mContentDescriptionPhoneSignal,
-                    mContentDescriptionDataType,
-                    isTypeIconWide(mDataTypeIconId));
-        }
-        cluster.setIsAirplaneMode(mAirplaneMode, mAirplaneIconId);
-    }
-
-    void notifySignalsChangedCallbacks(NetworkSignalChangedCallback cb) {
-        // only show wifi in the cluster if connected or if wifi-only
-        boolean wifiEnabled = mWifiEnabled && (mWifiConnected || !mHasMobileDataFeature);
-        String wifiDesc = wifiEnabled ?
-                mWifiSsid : null;
-        boolean wifiIn = wifiEnabled && mWifiSsid != null
-                && (mWifiActivity == WifiManager.DATA_ACTIVITY_INOUT
-                || mWifiActivity == WifiManager.DATA_ACTIVITY_IN);
-        boolean wifiOut = wifiEnabled && mWifiSsid != null
-                && (mWifiActivity == WifiManager.DATA_ACTIVITY_INOUT
-                || mWifiActivity == WifiManager.DATA_ACTIVITY_OUT);
-        cb.onWifiSignalChanged(mWifiEnabled, mWifiConnected, mQSWifiIconId, wifiIn, wifiOut,
-                mContentDescriptionWifi, wifiDesc);
-
-        boolean mobileIn = mDataConnected && (mDataActivity == TelephonyManager.DATA_ACTIVITY_INOUT
-                || mDataActivity == TelephonyManager.DATA_ACTIVITY_IN);
-        boolean mobileOut = mDataConnected && (mDataActivity == TelephonyManager.DATA_ACTIVITY_INOUT
-                || mDataActivity == TelephonyManager.DATA_ACTIVITY_OUT);
-        if (isEmergencyOnly()) {
-            cb.onMobileDataSignalChanged(false, mQSPhoneSignalIconId,
-                    mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
-                    mContentDescriptionDataType, null, mNoSim, isQsTypeIconWide(mQSDataTypeIconId));
-        } else {
-            if (mIsWimaxEnabled && mWimaxConnected) {
-                // Wimax is special
-                cb.onMobileDataSignalChanged(true, mQSPhoneSignalIconId,
-                        mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
-                        mContentDescriptionDataType, mNetworkName, mNoSim,
-                        isQsTypeIconWide(mQSDataTypeIconId));
-            } else {
-                // Normal mobile data
-                cb.onMobileDataSignalChanged(mHasMobileDataFeature, mQSPhoneSignalIconId,
-                        mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
-                        mContentDescriptionDataType, mNetworkName, mNoSim,
-                        isQsTypeIconWide(mQSDataTypeIconId));
-            }
-        }
-        cb.onAirplaneModeChanged(mAirplaneMode);
-    }
-
-    public void setStackedMode(boolean stacked) {
-        mDataAndWifiStacked = true;
-    }
-
-    @Override
     public void onReceive(Context context, Intent intent) {
+        if (CHATTY) {
+            Log.d(TAG, "onReceive: intent=" + intent);
+        }
         final String action = intent.getAction();
-        if (action.equals(WifiManager.RSSI_CHANGED_ACTION)
-                || action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)
-                || action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
-            updateWifiState(intent);
-            refreshViews();
-        } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
-            updateSimState(intent);
-            updateDataIcon();
-            refreshViews();
-        } else if (action.equals(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION)) {
-            updateNetworkName(intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false),
-                        intent.getStringExtra(TelephonyIntents.EXTRA_SPN),
-                        intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false),
-                        intent.getStringExtra(TelephonyIntents.EXTRA_PLMN));
-            refreshViews();
-        } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE) ||
-                 action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
+        if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE) ||
+                action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
             updateConnectivity(intent);
-            refreshViews();
+            refreshCarrierLabel();
         } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
             refreshLocale();
-            refreshViews();
+            refreshCarrierLabel();
         } else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
             refreshLocale();
-            updateAirplaneMode();
-            refreshViews();
-        } else if (action.equals(WimaxManagerConstants.NET_4G_STATE_CHANGED_ACTION) ||
-                action.equals(WimaxManagerConstants.SIGNAL_LEVEL_CHANGED_ACTION) ||
-                action.equals(WimaxManagerConstants.WIMAX_NETWORK_STATE_CHANGED_ACTION)) {
-            updateWimaxState(intent);
-            refreshViews();
+            updateAirplaneMode(false);
+            refreshCarrierLabel();
         }
+        mWifiSignalController.handleBroadcast(intent);
+        mMobileSignalController.handleBroadcast(intent);
     }
 
-
-    // ===== Telephony ==============================================================
-
-    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
-        @Override
-        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
-            if (DEBUG) {
-                Log.d(TAG, "onSignalStrengthsChanged signalStrength=" + signalStrength +
-                    ((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel())));
-            }
-            mSignalStrength = signalStrength;
-            updateTelephonySignalStrength();
-            refreshViews();
+    private void updateAirplaneMode(boolean force) {
+        boolean airplaneMode = (Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.AIRPLANE_MODE_ON, 0) == 1);
+        if (airplaneMode != mAirplaneMode || force) {
+            mAirplaneMode = airplaneMode;
+            mMobileSignalController.setAirplaneMode(mAirplaneMode);
+            notifyAirplaneCallbacks();
+            refreshCarrierLabel();
         }
-
-        @Override
-        public void onServiceStateChanged(ServiceState state) {
-            if (DEBUG) {
-                Log.d(TAG, "onServiceStateChanged voiceState=" + state.getVoiceRegState()
-                        + " dataState=" + state.getDataRegState());
-            }
-            mServiceState = state;
-            updateTelephonySignalStrength();
-            updateDataNetType();
-            updateDataIcon();
-            refreshViews();
-        }
-
-        @Override
-        public void onCallStateChanged(int state, String incomingNumber) {
-            if (DEBUG) {
-                Log.d(TAG, "onCallStateChanged state=" + state);
-            }
-            // In cdma, if a voice call is made, RSSI should switch to 1x.
-            if (isCdma()) {
-                updateTelephonySignalStrength();
-                refreshViews();
-            }
-        }
-
-        @Override
-        public void onDataConnectionStateChanged(int state, int networkType) {
-            if (DEBUG) {
-                Log.d(TAG, "onDataConnectionStateChanged: state=" + state
-                        + " type=" + networkType);
-            }
-            mDataState = state;
-            mDataNetType = networkType;
-            updateDataNetType();
-            updateDataIcon();
-            refreshViews();
-        }
-
-        @Override
-        public void onDataActivity(int direction) {
-            if (DEBUG) {
-                Log.d(TAG, "onDataActivity: direction=" + direction);
-            }
-            mDataActivity = direction;
-            updateDataIcon();
-            refreshViews();
-        }
-    };
-
-    private final void updateSimState(Intent intent) {
-        String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
-        if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
-            mSimState = IccCardConstants.State.ABSENT;
-        }
-        else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
-            mSimState = IccCardConstants.State.READY;
-        }
-        else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
-            final String lockedReason =
-                    intent.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
-            if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
-                mSimState = IccCardConstants.State.PIN_REQUIRED;
-            }
-            else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
-                mSimState = IccCardConstants.State.PUK_REQUIRED;
-            }
-            else {
-                mSimState = IccCardConstants.State.NETWORK_LOCKED;
-            }
-        } else {
-            mSimState = IccCardConstants.State.UNKNOWN;
-        }
-        if (DEBUG) Log.d(TAG, "updateSimState: mSimState=" + mSimState);
-    }
-
-    private boolean isCdma() {
-        return (mSignalStrength != null) && !mSignalStrength.isGsm();
-    }
-
-    private boolean hasService() {
-        boolean retVal;
-        if (mServiceState != null) {
-            // Consider the device to be in service if either voice or data service is available.
-            // Some SIM cards are marketed as data-only and do not support voice service, and on
-            // these SIM cards, we want to show signal bars for data service as well as the "no
-            // service" or "emergency calls only" text that indicates that voice is not available.
-            switch(mServiceState.getVoiceRegState()) {
-                case ServiceState.STATE_POWER_OFF:
-                    retVal = false;
-                    break;
-                case ServiceState.STATE_OUT_OF_SERVICE:
-                case ServiceState.STATE_EMERGENCY_ONLY:
-                    retVal = mServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE;
-                    break;
-                default:
-                    retVal = true;
-            }
-        } else {
-            retVal = false;
-        }
-        if (DEBUG) Log.d(TAG, "hasService: mServiceState=" + mServiceState + " retVal=" + retVal);
-        return retVal;
-    }
-
-    private void updateAirplaneMode() {
-        mAirplaneMode = (Settings.Global.getInt(mContext.getContentResolver(),
-            Settings.Global.AIRPLANE_MODE_ON, 0) == 1);
     }
 
     private void refreshLocale() {
-        mLocale = mContext.getResources().getConfiguration().locale;
-    }
-
-    private final void updateTelephonySignalStrength() {
-        if (DEBUG) {
-            Log.d(TAG, "updateTelephonySignalStrength: hasService=" + hasService()
-                    + " ss=" + mSignalStrength);
-        }
-        if (!hasService()) {
-            if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: !hasService()");
-            mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
-            mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal;
-            mDataSignalIconId = R.drawable.stat_sys_signal_null;
-            mContentDescriptionPhoneSignal = mContext.getString(
-                    AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0]);
-        } else {
-            if (mSignalStrength == null) {
-                if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: mSignalStrength == null");
-                mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
-                mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal;
-                mDataSignalIconId = R.drawable.stat_sys_signal_null;
-                mContentDescriptionPhoneSignal = mContext.getString(
-                        AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0]);
-            } else {
-                int iconLevel;
-                int[] iconList;
-                if (isCdma() && mAlwaysShowCdmaRssi) {
-                    mLastSignalLevel = iconLevel = mSignalStrength.getCdmaLevel();
-                    if (DEBUG) {
-                        Log.d(TAG, "updateTelephonySignalStrength:"
-                            + " mAlwaysShowCdmaRssi=" + mAlwaysShowCdmaRssi
-                            + " set to cdmaLevel=" + mSignalStrength.getCdmaLevel()
-                            + " instead of level=" + mSignalStrength.getLevel());
-                    }
-                } else {
-                    mLastSignalLevel = iconLevel = mSignalStrength.getLevel();
-                }
-
-                if (isRoaming()) {
-                    iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition];
-                } else {
-                    iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition];
-                }
-                mPhoneSignalIconId = iconList[iconLevel];
-                mQSPhoneSignalIconId =
-                        TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[mInetCondition][iconLevel];
-                mContentDescriptionPhoneSignal = mContext.getString(
-                        AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[iconLevel]);
-                mDataSignalIconId = TelephonyIcons.DATA_SIGNAL_STRENGTH[mInetCondition][iconLevel];
-                if (DEBUG) Log.d(TAG, "updateTelephonySignalStrength: iconLevel=" + iconLevel);
-            }
+        Locale current = mContext.getResources().getConfiguration().locale;
+        if (current.equals(mLocale)) {
+            mLocale = current;
+            notifyAllListeners();
         }
     }
 
-    private int inetConditionForNetwork(int networkType) {
-        return (mInetCondition == 1 && mConnectedNetworkType == networkType) ? 1 : 0;
+    /**
+     * Turns inet condition into a boolean indexing for a specific network.
+     * returns 0 for bad connectivity on this network.
+     * returns 1 for good connectivity on this network.
+     */
+    private int inetConditionForNetwork(int networkType, boolean inetCondition) {
+        return (inetCondition && mConnectedNetworkType == networkType) ? 1 : 0;
     }
 
-    private final void updateDataNetType() {
-        int inetCondition;
-        mDataTypeIconId = mQSDataTypeIconId = 0;
-        if (mIsWimaxEnabled && mWimaxConnected) {
-            // wimax is a special 4g network not handled by telephony
-            inetCondition = inetConditionForNetwork(ConnectivityManager.TYPE_WIMAX);
-            mDataIconList = TelephonyIcons.DATA_4G[inetCondition];
-            mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_4g;
-            mQSDataTypeIconId = TelephonyIcons.QS_DATA_4G[inetCondition];
-            mContentDescriptionDataType = mContext.getString(
-                    R.string.accessibility_data_connection_4g);
-        } else {
-            inetCondition = inetConditionForNetwork(ConnectivityManager.TYPE_MOBILE);
-            final boolean showDataTypeIcon = (inetCondition > 0);
-            switch (mDataNetType) {
-                case TelephonyManager.NETWORK_TYPE_UNKNOWN:
-                    if (!mShowAtLeastThreeGees) {
-                        mDataIconList = TelephonyIcons.DATA_G[inetCondition];
-                        mContentDescriptionDataType = "";
-                        break;
-                    } else {
-                        // fall through
-                    }
-                case TelephonyManager.NETWORK_TYPE_EDGE:
-                    if (!mShowAtLeastThreeGees) {
-                        mDataIconList = TelephonyIcons.DATA_E[inetCondition];
-                        mDataTypeIconId = showDataTypeIcon ?
-                                R.drawable.stat_sys_data_fully_connected_e : 0;
-                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_E[inetCondition];
-                        mContentDescriptionDataType = mContext.getString(
-                                R.string.accessibility_data_connection_edge);
-                        break;
-                    } else {
-                        // fall through
-                    }
-                case TelephonyManager.NETWORK_TYPE_UMTS:
-                    mDataIconList = TelephonyIcons.DATA_3G[inetCondition];
-                    mDataTypeIconId = showDataTypeIcon ?
-                                R.drawable.stat_sys_data_fully_connected_3g : 0;
-                    mQSDataTypeIconId = TelephonyIcons.QS_DATA_3G[inetCondition];
-                    mContentDescriptionDataType = mContext.getString(
-                            R.string.accessibility_data_connection_3g);
-                    break;
-                case TelephonyManager.NETWORK_TYPE_HSDPA:
-                case TelephonyManager.NETWORK_TYPE_HSUPA:
-                case TelephonyManager.NETWORK_TYPE_HSPA:
-                case TelephonyManager.NETWORK_TYPE_HSPAP:
-                    if (mHspaDataDistinguishable) {
-                        mDataIconList = TelephonyIcons.DATA_H[inetCondition];
-                        mDataTypeIconId = showDataTypeIcon ?
-                                R.drawable.stat_sys_data_fully_connected_h : 0;
-                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_H[inetCondition];
-                        mContentDescriptionDataType = mContext.getString(
-                                R.string.accessibility_data_connection_3_5g);
-                    } else {
-                        mDataIconList = TelephonyIcons.DATA_3G[inetCondition];
-                        mDataTypeIconId = showDataTypeIcon ?
-                                R.drawable.stat_sys_data_fully_connected_3g : 0;
-                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_3G[inetCondition];
-                        mContentDescriptionDataType = mContext.getString(
-                                R.string.accessibility_data_connection_3g);
-                    }
-                    break;
-                case TelephonyManager.NETWORK_TYPE_CDMA:
-                    if (!mShowAtLeastThreeGees) {
-                        // display 1xRTT for IS95A/B
-                        mDataIconList = TelephonyIcons.DATA_1X[inetCondition];
-                        mDataTypeIconId = showDataTypeIcon ?
-                                R.drawable.stat_sys_data_fully_connected_1x : 0;
-                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_1X[inetCondition];
-                        mContentDescriptionDataType = mContext.getString(
-                                R.string.accessibility_data_connection_cdma);
-                        break;
-                    } else {
-                        // fall through
-                    }
-                case TelephonyManager.NETWORK_TYPE_1xRTT:
-                    if (!mShowAtLeastThreeGees) {
-                        mDataIconList = TelephonyIcons.DATA_1X[inetCondition];
-                        mDataTypeIconId = showDataTypeIcon ?
-                                R.drawable.stat_sys_data_fully_connected_1x : 0;
-                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_1X[inetCondition];
-                        mContentDescriptionDataType = mContext.getString(
-                                R.string.accessibility_data_connection_cdma);
-                        break;
-                    } else {
-                        // fall through
-                    }
-                case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through
-                case TelephonyManager.NETWORK_TYPE_EVDO_A:
-                case TelephonyManager.NETWORK_TYPE_EVDO_B:
-                case TelephonyManager.NETWORK_TYPE_EHRPD:
-                    mDataIconList = TelephonyIcons.DATA_3G[inetCondition];
-                    mDataTypeIconId = showDataTypeIcon ?
-                                R.drawable.stat_sys_data_fully_connected_3g : 0;
-                    mQSDataTypeIconId = TelephonyIcons.QS_DATA_3G[inetCondition];
-                    mContentDescriptionDataType = mContext.getString(
-                            R.string.accessibility_data_connection_3g);
-                    break;
-                case TelephonyManager.NETWORK_TYPE_LTE:
-                    boolean show4GforLTE = mContext.getResources().getBoolean(R.bool.config_show4GForLTE);
-                    if (show4GforLTE) {
-                        mDataIconList = TelephonyIcons.DATA_4G[inetCondition];
-                        mDataTypeIconId = showDataTypeIcon ?
-                                R.drawable.stat_sys_data_fully_connected_4g : 0;
-                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_4G[inetCondition];
-                        mContentDescriptionDataType = mContext.getString(
-                                R.string.accessibility_data_connection_4g);
-                    } else {
-                        mDataIconList = TelephonyIcons.DATA_LTE[inetCondition];
-                        mDataTypeIconId = showDataTypeIcon ? TelephonyIcons.ICON_LTE : 0;
-                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_LTE[inetCondition];
-                        mContentDescriptionDataType = mContext.getString(
-                                R.string.accessibility_data_connection_lte);
-                    }
-                    break;
-                default:
-                    if (!mShowAtLeastThreeGees) {
-                        mDataIconList = TelephonyIcons.DATA_G[inetCondition];
-                        mDataTypeIconId = showDataTypeIcon ?
-                                R.drawable.stat_sys_data_fully_connected_g : 0;
-                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_G[inetCondition];
-                        mContentDescriptionDataType = mContext.getString(
-                                R.string.accessibility_data_connection_gprs);
-                    } else {
-                        mDataIconList = TelephonyIcons.DATA_3G[inetCondition];
-                        mDataTypeIconId = showDataTypeIcon ?
-                                R.drawable.stat_sys_data_fully_connected_3g : 0;
-                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_3G[inetCondition];
-                        mContentDescriptionDataType = mContext.getString(
-                                R.string.accessibility_data_connection_3g);
-                    }
-                    break;
-            }
-        }
+    private void notifyAllListeners() {
+        // Something changed, trigger everything!
+        notifyAirplaneCallbacks();
+        mMobileSignalController.notifyListeners();
+        mWifiSignalController.notifyListeners();
+    }
 
-        if (isRoaming()) {
-            mDataTypeIconId = TelephonyIcons.ROAMING_ICON;
-            mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition];
+    private void notifyAirplaneCallbacks() {
+        int length = mSignalClusters.size();
+        for (int i = 0; i < length; i++) {
+            mSignalClusters.get(i).setIsAirplaneMode(mAirplaneMode, TelephonyIcons.FLIGHT_MODE_ICON,
+                    R.string.accessibility_airplane_mode);
+        }
+        // update QS
+        int signalsChangedLength = mSignalsChangedCallbacks.size();
+        for (int i = 0; i < signalsChangedLength; i++) {
+            mSignalsChangedCallbacks.get(i).onAirplaneModeChanged(mAirplaneMode);
         }
     }
 
-    boolean isCdmaEri() {
-        if (mServiceState != null) {
-            final int iconIndex = mServiceState.getCdmaEriIconIndex();
-            if (iconIndex != EriInfo.ROAMING_INDICATOR_OFF) {
-                final int iconMode = mServiceState.getCdmaEriIconMode();
-                if (iconMode == EriInfo.ROAMING_ICON_MODE_NORMAL
-                        || iconMode == EriInfo.ROAMING_ICON_MODE_FLASH) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    private boolean isRoaming() {
-        if (isCdma()) {
-            return isCdmaEri();
-        } else {
-            return mServiceState != null && mServiceState.getRoaming();
-        }
-    }
-
-    private final void updateDataIcon() {
-        int iconId;
-        boolean visible = true;
-
-        if (!isCdma()) {
-            // GSM case, we have to check also the sim state
-            if (mSimState == IccCardConstants.State.READY ||
-                    mSimState == IccCardConstants.State.UNKNOWN) {
-                mNoSim = false;
-                if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
-                    switch (mDataActivity) {
-                        case TelephonyManager.DATA_ACTIVITY_IN:
-                            iconId = mDataIconList[1];
-                            break;
-                        case TelephonyManager.DATA_ACTIVITY_OUT:
-                            iconId = mDataIconList[2];
-                            break;
-                        case TelephonyManager.DATA_ACTIVITY_INOUT:
-                            iconId = mDataIconList[3];
-                            break;
-                        default:
-                            iconId = mDataIconList[0];
-                            break;
-                    }
-                    mDataDirectionIconId = iconId;
-                } else {
-                    iconId = 0;
-                    visible = false;
-                }
-            } else {
-                iconId = 0;
-                mNoSim = true;
-                visible = false; // no SIM? no data
-            }
-        } else {
-            // CDMA case, mDataActivity can be also DATA_ACTIVITY_DORMANT
-            if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
-                switch (mDataActivity) {
-                    case TelephonyManager.DATA_ACTIVITY_IN:
-                        iconId = mDataIconList[1];
-                        break;
-                    case TelephonyManager.DATA_ACTIVITY_OUT:
-                        iconId = mDataIconList[2];
-                        break;
-                    case TelephonyManager.DATA_ACTIVITY_INOUT:
-                        iconId = mDataIconList[3];
-                        break;
-                    case TelephonyManager.DATA_ACTIVITY_DORMANT:
-                    default:
-                        iconId = mDataIconList[0];
-                        break;
-                }
-            } else {
-                iconId = 0;
-                visible = false;
-            }
-        }
-
-        mDataDirectionIconId = iconId;
-        mDataConnected = visible;
-    }
-
-    void updateNetworkName(boolean showSpn, String spn, boolean showPlmn, String plmn) {
-        if (false) {
-            Log.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn
-                    + " showPlmn=" + showPlmn + " plmn=" + plmn);
-        }
-        StringBuilder str = new StringBuilder();
-        boolean something = false;
-        if (showPlmn && plmn != null) {
-            str.append(plmn);
-            something = true;
-        }
-        if (showSpn && spn != null) {
-            if (something) {
-                str.append(mNetworkNameSeparator);
-            }
-            str.append(spn);
-            something = true;
-        }
-        if (something) {
-            mNetworkName = str.toString();
-        } else {
-            mNetworkName = mNetworkNameDefault;
-        }
-    }
-
-    // ===== Wifi ===================================================================
-
-    class WifiHandler extends Handler {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
-                    if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
-                        mWifiChannel.sendMessage(Message.obtain(this,
-                                AsyncChannel.CMD_CHANNEL_FULL_CONNECTION));
-                    } else {
-                        Log.e(TAG, "Failed to connect to wifi");
-                    }
-                    break;
-                case WifiManager.DATA_ACTIVITY_NOTIFICATION:
-                    if (msg.arg1 != mWifiActivity) {
-                        mWifiActivity = msg.arg1;
-                        refreshViews();
-                    }
-                    break;
-                default:
-                    //Ignore
-                    break;
-            }
-        }
-    }
-
-    private void updateWifiState(Intent intent) {
-        final String action = intent.getAction();
-        if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
-            mWifiEnabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
-                    WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
-
-        } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
-            final NetworkInfo networkInfo = (NetworkInfo)
-                    intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
-            boolean wasConnected = mWifiConnected;
-            mWifiConnected = networkInfo != null && networkInfo.isConnected();
-            // If Connected grab the signal strength and ssid
-            if (mWifiConnected) {
-                // try getting it out of the intent first
-                WifiInfo info = (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
-                if (info == null) {
-                    info = mWifiManager.getConnectionInfo();
-                }
-                if (info != null) {
-                    mWifiSsid = huntForSsid(info);
-                } else {
-                    mWifiSsid = null;
-                }
-            } else if (!mWifiConnected) {
-                mWifiSsid = null;
-            }
-        } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
-            mWifiRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
-            mWifiLevel = WifiManager.calculateSignalLevel(
-                    mWifiRssi, WifiIcons.WIFI_LEVEL_COUNT);
-        }
-
-        updateWifiIcons();
-    }
-
-    private void updateWifiIcons() {
-        int inetCondition = inetConditionForNetwork(ConnectivityManager.TYPE_WIFI);
-        if (mWifiConnected) {
-            mWifiIconId = WifiIcons.WIFI_SIGNAL_STRENGTH[inetCondition][mWifiLevel];
-            mQSWifiIconId = WifiIcons.QS_WIFI_SIGNAL_STRENGTH[inetCondition][mWifiLevel];
-            mContentDescriptionWifi = mContext.getString(
-                    AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH[mWifiLevel]);
-        } else {
-            if (mDataAndWifiStacked) {
-                mWifiIconId = 0;
-                mQSWifiIconId = 0;
-            } else {
-                mWifiIconId = mWifiEnabled ? R.drawable.stat_sys_wifi_signal_null : 0;
-                mQSWifiIconId = mWifiEnabled ? R.drawable.ic_qs_wifi_no_network : 0;
-            }
-            mContentDescriptionWifi = mContext.getString(R.string.accessibility_no_wifi);
-        }
-    }
-
-    private String huntForSsid(WifiInfo info) {
-        String ssid = info.getSSID();
-        if (ssid != null) {
-            return ssid;
-        }
-        // OK, it's not in the connectionInfo; we have to go hunting for it
-        List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks();
-        for (WifiConfiguration net : networks) {
-            if (net.networkId == info.getNetworkId()) {
-                return net.SSID;
-            }
-        }
-        return null;
-    }
-
-
-    // ===== Wimax ===================================================================
-    private final void updateWimaxState(Intent intent) {
-        final String action = intent.getAction();
-        boolean wasConnected = mWimaxConnected;
-        if (action.equals(WimaxManagerConstants.NET_4G_STATE_CHANGED_ACTION)) {
-            int wimaxStatus = intent.getIntExtra(WimaxManagerConstants.EXTRA_4G_STATE,
-                    WimaxManagerConstants.NET_4G_STATE_UNKNOWN);
-            mIsWimaxEnabled = (wimaxStatus ==
-                    WimaxManagerConstants.NET_4G_STATE_ENABLED);
-        } else if (action.equals(WimaxManagerConstants.SIGNAL_LEVEL_CHANGED_ACTION)) {
-            mWimaxSignal = intent.getIntExtra(WimaxManagerConstants.EXTRA_NEW_SIGNAL_LEVEL, 0);
-        } else if (action.equals(WimaxManagerConstants.WIMAX_NETWORK_STATE_CHANGED_ACTION)) {
-            mWimaxState = intent.getIntExtra(WimaxManagerConstants.EXTRA_WIMAX_STATE,
-                    WimaxManagerConstants.NET_4G_STATE_UNKNOWN);
-            mWimaxExtraState = intent.getIntExtra(
-                    WimaxManagerConstants.EXTRA_WIMAX_STATE_DETAIL,
-                    WimaxManagerConstants.NET_4G_STATE_UNKNOWN);
-            mWimaxConnected = (mWimaxState ==
-                    WimaxManagerConstants.WIMAX_STATE_CONNECTED);
-            mWimaxIdle = (mWimaxExtraState == WimaxManagerConstants.WIMAX_IDLE);
-        }
-        updateDataNetType();
-        updateWimaxIcons();
-    }
-
-    private void updateWimaxIcons() {
-        if (mIsWimaxEnabled) {
-            if (mWimaxConnected) {
-                int inetCondition = inetConditionForNetwork(ConnectivityManager.TYPE_WIMAX);
-                if (mWimaxIdle)
-                    mWimaxIconId = WimaxIcons.WIMAX_IDLE;
-                else
-                    mWimaxIconId = WimaxIcons.WIMAX_SIGNAL_STRENGTH[inetCondition][mWimaxSignal];
-                mContentDescriptionWimax = mContext.getString(
-                        AccessibilityContentDescriptions.WIMAX_CONNECTION_STRENGTH[mWimaxSignal]);
-            } else {
-                mWimaxIconId = WimaxIcons.WIMAX_DISCONNECTED;
-                mContentDescriptionWimax = mContext.getString(R.string.accessibility_no_wimax);
-            }
-        } else {
-            mWimaxIconId = 0;
-        }
-    }
-
-    // ===== Full or limited Internet connectivity ==================================
-
+    /**
+     * Update the Inet conditions and what network we are connected to.
+     */
     private void updateConnectivity(Intent intent) {
-        if (CHATTY) {
-            Log.d(TAG, "updateConnectivity: intent=" + intent);
-        }
-
         final NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
 
         // Are we connected at all, by any interface?
@@ -1105,7 +364,7 @@
             Log.d(TAG, "updateConnectivity: connectionStatus=" + connectionStatus);
         }
 
-        mInetCondition = (connectionStatus > INET_CONDITION_THRESHOLD ? 1 : 0);
+        mInetCondition = connectionStatus > INET_CONDITION_THRESHOLD;
 
         if (info != null && info.getType() == ConnectivityManager.TYPE_BLUETOOTH) {
             mBluetoothTethered = info.isConnected();
@@ -1114,376 +373,68 @@
         }
 
         // We want to update all the icons, all at once, for any condition change
-        updateDataNetType();
-        updateWimaxIcons();
-        updateDataIcon();
-        updateTelephonySignalStrength();
-        updateWifiIcons();
+        mMobileSignalController.setInetCondition(mInetCondition ? 1 : 0,
+                inetConditionForNetwork(mMobileSignalController.getNetworkType(), mInetCondition));
+        mWifiSignalController.setInetCondition(
+                inetConditionForNetwork(mWifiSignalController.getNetworkType(), mInetCondition));
     }
 
-
-    // ===== Update the views =======================================================
-
-    void refreshViews() {
+    /**
+     * Recalculate and update the carrier label.
+     */
+    void refreshCarrierLabel() {
         Context context = mContext;
 
-        int combinedSignalIconId = 0;
-        String combinedLabel = "";
-        String wifiLabel = "";
-        String mobileLabel = "";
-        int N;
-        final boolean emergencyOnly = isEmergencyOnly();
+        WifiSignalController.WifiState wifiState = mWifiSignalController.getState();
+        MobileSignalController.MobileState mobileState = mMobileSignalController.getState();
+        String label = mMobileSignalController.getLabel("", mConnected, mHasMobileDataFeature);
 
-        if (!mHasMobileDataFeature) {
-            mDataSignalIconId = mPhoneSignalIconId = 0;
-            mQSPhoneSignalIconId = 0;
-            mobileLabel = "";
-        } else {
-            // We want to show the carrier name if in service and either:
-            //   - We are connected to mobile data, or
-            //   - We are not connected to mobile data, as long as the *reason* packets are not
-            //     being routed over that link is that we have better connectivity via wifi.
-            // If data is disconnected for some other reason but wifi (or ethernet/bluetooth)
-            // is connected, we show nothing.
-            // Otherwise (nothing connected) we show "No internet connection".
-
-            if (mDataConnected) {
-                mobileLabel = mNetworkName;
-            } else if (mConnected || emergencyOnly) {
-                if (hasService() || emergencyOnly) {
-                    // The isEmergencyOnly test covers the case of a phone with no SIM
-                    mobileLabel = mNetworkName;
-                } else {
-                    // Tablets, basically
-                    mobileLabel = "";
-                }
-            } else {
-                mobileLabel
-                    = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
-            }
-
-            // Now for things that should only be shown when actually using mobile data.
-            if (mDataConnected) {
-                combinedSignalIconId = mDataSignalIconId;
-
-                combinedLabel = mobileLabel;
-                combinedSignalIconId = mDataSignalIconId; // set by updateDataIcon()
-                mContentDescriptionCombinedSignal = mContentDescriptionDataType;
-            }
+        // TODO Simplify this ugliness, some of the flows below shouldn't be possible anymore
+        // but stay for the sake of history.
+        if (mBluetoothTethered && !mHasMobileDataFeature) {
+            label = mContext.getString(R.string.bluetooth_tethered);
         }
 
-        if (mWifiConnected) {
-            if (mWifiSsid == null) {
-                wifiLabel = context.getString(R.string.status_bar_settings_signal_meter_wifi_nossid);
-            } else {
-                wifiLabel = mWifiSsid;
-                if (DEBUG) {
-                    wifiLabel += "xxxxXXXXxxxxXXXX";
-                }
-            }
-
-            combinedLabel = wifiLabel;
-            combinedSignalIconId = mWifiIconId; // set by updateWifiIcons()
-            mContentDescriptionCombinedSignal = mContentDescriptionWifi;
-        } else {
-            if (mHasMobileDataFeature) {
-                wifiLabel = "";
-            } else {
-                wifiLabel = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
-            }
+        final boolean ethernetConnected =
+                (mConnectedNetworkType == ConnectivityManager.TYPE_ETHERNET);
+        if (ethernetConnected && !mHasMobileDataFeature) {
+            label = context.getString(R.string.ethernet_label);
         }
 
-        if (mBluetoothTethered) {
-            combinedLabel = mContext.getString(R.string.bluetooth_tethered);
-            combinedSignalIconId = mBluetoothTetherIconId;
-            mContentDescriptionCombinedSignal = mContext.getString(
-                    R.string.accessibility_bluetooth_tether);
-        }
-
-        final boolean ethernetConnected = (mConnectedNetworkType == ConnectivityManager.TYPE_ETHERNET);
-        if (ethernetConnected) {
-            combinedLabel = context.getString(R.string.ethernet_label);
-        }
-
-        if (mAirplaneMode &&
-                (mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly()))) {
-            // Only display the flight-mode icon if not in "emergency calls only" mode.
-
-            // look again; your radios are now airplanes
-            mContentDescriptionPhoneSignal = mContext.getString(
-                    R.string.accessibility_airplane_mode);
-            mAirplaneIconId = TelephonyIcons.FLIGHT_MODE_ICON;
-            mPhoneSignalIconId = mDataSignalIconId = mDataTypeIconId = mQSDataTypeIconId = 0;
-            mQSPhoneSignalIconId = 0;
-
+        if (mAirplaneMode && (!mobileState.connected && !mobileState.isEmergency)) {
             // combined values from connected wifi take precedence over airplane mode
-            if (mWifiConnected) {
+            if (wifiState.connected && mHasMobileDataFeature) {
                 // Suppress "No internet connection." from mobile if wifi connected.
-                mobileLabel = "";
+                label = "";
             } else {
-                if (mHasMobileDataFeature) {
-                    // let the mobile icon show "No internet connection."
-                    wifiLabel = "";
-                } else {
-                    wifiLabel = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
-                    combinedLabel = wifiLabel;
-                }
-                mContentDescriptionCombinedSignal = mContentDescriptionPhoneSignal;
-                combinedSignalIconId = mDataSignalIconId;
+                 if (!mHasMobileDataFeature) {
+                      label = context.getString(
+                              R.string.status_bar_settings_signal_meter_disconnected);
+                 }
             }
-        }
-        else if (!mDataConnected && !mWifiConnected && !mBluetoothTethered && !mWimaxConnected && !ethernetConnected) {
-            // pretty much totally disconnected
-
-            combinedLabel = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
-            // On devices without mobile radios, we want to show the wifi icon
-            combinedSignalIconId =
-                mHasMobileDataFeature ? mDataSignalIconId : mWifiIconId;
-            mContentDescriptionCombinedSignal = mHasMobileDataFeature
-                ? mContentDescriptionDataType : mContentDescriptionWifi;
-
-            int inetCondition = inetConditionForNetwork(ConnectivityManager.TYPE_MOBILE);
-
-            mDataTypeIconId = 0;
-            mQSDataTypeIconId = 0;
-            if (isRoaming()) {
-                mDataTypeIconId = TelephonyIcons.ROAMING_ICON;
-                mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition];
-            }
+        } else if (!mobileState.dataConnected && !wifiState.connected && !mBluetoothTethered &&
+                 !ethernetConnected && !mHasMobileDataFeature) {
+            // Pretty much no connection.
+            label = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
         }
 
-        if (mDemoMode) {
-            mQSWifiIconId = mDemoWifiLevel < 0 ? R.drawable.ic_qs_wifi_no_network
-                    : WifiIcons.QS_WIFI_SIGNAL_STRENGTH[mDemoInetCondition][mDemoWifiLevel];
-            mQSPhoneSignalIconId = mDemoMobileLevel < 0 ? R.drawable.ic_qs_signal_no_signal :
-                    TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[mDemoInetCondition][mDemoMobileLevel];
-            mQSDataTypeIconId = mDemoQSDataTypeIconId;
-        }
-
-        if (DEBUG) {
-            Log.d(TAG, "refreshViews connected={"
-                    + (mWifiConnected?" wifi":"")
-                    + (mDataConnected?" data":"")
-                    + " } level="
-                    + ((mSignalStrength == null)?"??":Integer.toString(mSignalStrength.getLevel()))
-                    + " combinedSignalIconId=0x"
-                    + Integer.toHexString(combinedSignalIconId)
-                    + "/" + getResourceName(combinedSignalIconId)
-                    + " mobileLabel=" + mobileLabel
-                    + " wifiLabel=" + wifiLabel
-                    + " emergencyOnly=" + emergencyOnly
-                    + " combinedLabel=" + combinedLabel
-                    + " mAirplaneMode=" + mAirplaneMode
-                    + " mDataActivity=" + mDataActivity
-                    + " mPhoneSignalIconId=0x" + Integer.toHexString(mPhoneSignalIconId)
-                    + " mQSPhoneSignalIconId=0x" + Integer.toHexString(mQSPhoneSignalIconId)
-                    + " mDataDirectionIconId=0x" + Integer.toHexString(mDataDirectionIconId)
-                    + " mDataSignalIconId=0x" + Integer.toHexString(mDataSignalIconId)
-                    + " mDataTypeIconId=0x" + Integer.toHexString(mDataTypeIconId)
-                    + " mQSDataTypeIconId=0x" + Integer.toHexString(mQSDataTypeIconId)
-                    + " mWifiIconId=0x" + Integer.toHexString(mWifiIconId)
-                    + " mQSWifiIconId=0x" + Integer.toHexString(mQSWifiIconId)
-                    + " mBluetoothTetherIconId=0x" + Integer.toHexString(mBluetoothTetherIconId));
-        }
-
-        // update QS
-        for (NetworkSignalChangedCallback cb : mSignalsChangedCallbacks) {
-            notifySignalsChangedCallbacks(cb);
-        }
-
-        if (mLastPhoneSignalIconId          != mPhoneSignalIconId
-         || mLastWifiIconId                 != mWifiIconId
-         || mLastInetCondition              != mInetCondition
-         || mLastWimaxIconId                != mWimaxIconId
-         || mLastDataTypeIconId             != mDataTypeIconId
-         || mLastAirplaneMode               != mAirplaneMode
-         || mLastLocale                     != mLocale
-         || mLastConnectedNetworkType       != mConnectedNetworkType)
-        {
-            // NB: the mLast*s will be updated later
-            for (SignalCluster cluster : mSignalClusters) {
-                refreshSignalCluster(cluster);
-            }
-        }
-
-        if (mLastAirplaneMode != mAirplaneMode) {
-            mLastAirplaneMode = mAirplaneMode;
-        }
-
-        if (mLastLocale != mLocale) {
-            mLastLocale = mLocale;
-        }
-
-        // the phone icon on phones
-        if (mLastPhoneSignalIconId != mPhoneSignalIconId) {
-            mLastPhoneSignalIconId = mPhoneSignalIconId;
-        }
-
-        // the data icon on phones
-        if (mLastDataDirectionIconId != mDataDirectionIconId) {
-            mLastDataDirectionIconId = mDataDirectionIconId;
-        }
-
-        // the wifi icon on phones
-        if (mLastWifiIconId != mWifiIconId) {
-            mLastWifiIconId = mWifiIconId;
-        }
-
-        if (mLastInetCondition != mInetCondition) {
-            mLastInetCondition = mInetCondition;
-        }
-
-        if (mLastConnectedNetworkType != mConnectedNetworkType) {
-            mLastConnectedNetworkType = mConnectedNetworkType;
-        }
-
-        // the wimax icon on phones
-        if (mLastWimaxIconId != mWimaxIconId) {
-            mLastWimaxIconId = mWimaxIconId;
-        }
-        // the combined data signal icon
-        if (mLastCombinedSignalIconId != combinedSignalIconId) {
-            mLastCombinedSignalIconId = combinedSignalIconId;
-        }
-
-        // the data network type overlay
-        if (mLastDataTypeIconId != mDataTypeIconId) {
-            mLastDataTypeIconId = mDataTypeIconId;
-        }
-
-        // the combinedLabel in the notification panel
-        if (!mLastCombinedLabel.equals(combinedLabel)) {
-            mLastCombinedLabel = combinedLabel;
-            N = mCombinedLabelViews.size();
-            for (int i=0; i<N; i++) {
-                TextView v = mCombinedLabelViews.get(i);
-                v.setText(combinedLabel);
-            }
-        }
-
-        // wifi label
-        N = mWifiLabelViews.size();
-        for (int i=0; i<N; i++) {
-            TextView v = mWifiLabelViews.get(i);
-            v.setText(wifiLabel);
-            if ("".equals(wifiLabel)) {
-                v.setVisibility(View.GONE);
-            } else {
-                v.setVisibility(View.VISIBLE);
-            }
-        }
-
-        // mobile label
-        N = mMobileLabelViews.size();
-        for (int i=0; i<N; i++) {
-            TextView v = mMobileLabelViews.get(i);
-            v.setText(mobileLabel);
-            if ("".equals(mobileLabel)) {
-                v.setVisibility(View.GONE);
-            } else {
-                v.setVisibility(View.VISIBLE);
-            }
-        }
-
-        // e-call label
-        N = mEmergencyViews.size();
-        for (int i=0; i<N; i++) {
-            StatusBarHeaderView v = mEmergencyViews.get(i);
-            v.setShowEmergencyCallsOnly(emergencyOnly);
+        // for mobile devices, we always show mobile connection info here (SPN/PLMN)
+        // for other devices, we show whatever network is connected
+        // This is determined above by references to mHasMobileDataFeature.
+        int length = mCarrierListeners.size();
+        for (int i = 0; i < length; i++) {
+            mCarrierListeners.get(i).setCarrierLabel(label);
         }
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("NetworkController state:");
         pw.println(String.format("  %s network type %d (%s)",
-                mConnected?"CONNECTED":"DISCONNECTED",
+                mConnected ? "CONNECTED" : "DISCONNECTED",
                 mConnectedNetworkType, mConnectedNetworkTypeName));
         pw.println("  - telephony ------");
         pw.print("  hasVoiceCallingFeature()=");
         pw.println(hasVoiceCallingFeature());
-        pw.print("  hasService()=");
-        pw.println(hasService());
-        pw.print("  mHspaDataDistinguishable=");
-        pw.println(mHspaDataDistinguishable);
-        pw.print("  mDataConnected=");
-        pw.println(mDataConnected);
-        pw.print("  mSimState=");
-        pw.println(mSimState);
-        pw.print("  mPhoneState=");
-        pw.println(mPhoneState);
-        pw.print("  mDataState=");
-        pw.println(mDataState);
-        pw.print("  mDataActivity=");
-        pw.println(mDataActivity);
-        pw.print("  mDataNetType=");
-        pw.print(mDataNetType);
-        pw.print("/");
-        pw.println(TelephonyManager.getNetworkTypeName(mDataNetType));
-        pw.print("  mServiceState=");
-        pw.println(mServiceState);
-        pw.print("  mSignalStrength=");
-        pw.println(mSignalStrength);
-        pw.print("  mLastSignalLevel=");
-        pw.println(mLastSignalLevel);
-        pw.print("  mNetworkName=");
-        pw.println(mNetworkName);
-        pw.print("  mNetworkNameDefault=");
-        pw.println(mNetworkNameDefault);
-        pw.print("  mNetworkNameSeparator=");
-        pw.println(mNetworkNameSeparator.replace("\n","\\n"));
-        pw.print("  mPhoneSignalIconId=0x");
-        pw.print(Integer.toHexString(mPhoneSignalIconId));
-        pw.print("/");
-        pw.print("  mQSPhoneSignalIconId=0x");
-        pw.print(Integer.toHexString(mQSPhoneSignalIconId));
-        pw.print("/");
-        pw.println(getResourceName(mPhoneSignalIconId));
-        pw.print("  mDataDirectionIconId=");
-        pw.print(Integer.toHexString(mDataDirectionIconId));
-        pw.print("/");
-        pw.println(getResourceName(mDataDirectionIconId));
-        pw.print("  mDataSignalIconId=");
-        pw.print(Integer.toHexString(mDataSignalIconId));
-        pw.print("/");
-        pw.println(getResourceName(mDataSignalIconId));
-        pw.print("  mDataTypeIconId=");
-        pw.print(Integer.toHexString(mDataTypeIconId));
-        pw.print("/");
-        pw.println(getResourceName(mDataTypeIconId));
-        pw.print("  mQSDataTypeIconId=");
-        pw.print(Integer.toHexString(mQSDataTypeIconId));
-        pw.print("/");
-        pw.println(getResourceName(mQSDataTypeIconId));
-
-        pw.println("  - wifi ------");
-        pw.print("  mWifiEnabled=");
-        pw.println(mWifiEnabled);
-        pw.print("  mWifiConnected=");
-        pw.println(mWifiConnected);
-        pw.print("  mWifiRssi=");
-        pw.println(mWifiRssi);
-        pw.print("  mWifiLevel=");
-        pw.println(mWifiLevel);
-        pw.print("  mWifiSsid=");
-        pw.println(mWifiSsid);
-        pw.println(String.format("  mWifiIconId=0x%08x/%s",
-                    mWifiIconId, getResourceName(mWifiIconId)));
-        pw.println(String.format("  mQSWifiIconId=0x%08x/%s",
-                    mQSWifiIconId, getResourceName(mQSWifiIconId)));
-        pw.print("  mWifiActivity=");
-        pw.println(mWifiActivity);
-
-        if (mWimaxSupported) {
-            pw.println("  - wimax ------");
-            pw.print("  mIsWimaxEnabled="); pw.println(mIsWimaxEnabled);
-            pw.print("  mWimaxConnected="); pw.println(mWimaxConnected);
-            pw.print("  mWimaxIdle="); pw.println(mWimaxIdle);
-            pw.println(String.format("  mWimaxIconId=0x%08x/%s",
-                        mWimaxIconId, getResourceName(mWimaxIconId)));
-            pw.println(String.format("  mWimaxSignal=%d", mWimaxSignal));
-            pw.println(String.format("  mWimaxState=%d", mWimaxState));
-            pw.println(String.format("  mWimaxExtraState=%d", mWimaxExtraState));
-        }
 
         pw.println("  - Bluetooth ----");
         pw.print("  mBtReverseTethered=");
@@ -1492,143 +443,1079 @@
         pw.println("  - connectivity ------");
         pw.print("  mInetCondition=");
         pw.println(mInetCondition);
+        pw.print("  mAirplaneMode=");
+        pw.println(mAirplaneMode);
+        pw.print("  mLocale=");
+        pw.println(mLocale);
 
-        pw.println("  - icons ------");
-        pw.print("  mLastPhoneSignalIconId=0x");
-        pw.print(Integer.toHexString(mLastPhoneSignalIconId));
-        pw.print("/");
-        pw.println(getResourceName(mLastPhoneSignalIconId));
-        pw.print("  mLastDataDirectionIconId=0x");
-        pw.print(Integer.toHexString(mLastDataDirectionIconId));
-        pw.print("/");
-        pw.println(getResourceName(mLastDataDirectionIconId));
-        pw.print("  mLastWifiIconId=0x");
-        pw.print(Integer.toHexString(mLastWifiIconId));
-        pw.print("/");
-        pw.println(getResourceName(mLastWifiIconId));
-        pw.print("  mLastCombinedSignalIconId=0x");
-        pw.print(Integer.toHexString(mLastCombinedSignalIconId));
-        pw.print("/");
-        pw.println(getResourceName(mLastCombinedSignalIconId));
-        pw.print("  mLastDataTypeIconId=0x");
-        pw.print(Integer.toHexString(mLastDataTypeIconId));
-        pw.print("/");
-        pw.println(getResourceName(mLastDataTypeIconId));
-        pw.print("  mLastCombinedLabel=");
-        pw.print(mLastCombinedLabel);
-        pw.println("");
-    }
-
-    private String getResourceName(int resId) {
-        if (resId != 0) {
-            final Resources res = mContext.getResources();
-            try {
-                return res.getResourceName(resId);
-            } catch (android.content.res.Resources.NotFoundException ex) {
-                return "(unknown)";
-            }
-        } else {
-            return "(null)";
-        }
+        mMobileSignalController.dump(pw);
+        mWifiSignalController.dump(pw);
     }
 
     private boolean mDemoMode;
     private int mDemoInetCondition;
-    private int mDemoWifiLevel;
-    private int mDemoDataTypeIconId;
-    private int mDemoQSDataTypeIconId;
-    private int mDemoMobileLevel;
+    private WifiSignalController.WifiState mDemoWifiState;
+    private MobileSignalController.MobileState mDemoMobileState;
 
     @Override
     public void dispatchDemoCommand(String command, Bundle args) {
         if (!mDemoMode && command.equals(COMMAND_ENTER)) {
+            if (DEBUG) Log.d(TAG, "Entering demo mode");
+            unregisterListeners();
             mDemoMode = true;
-            mDemoWifiLevel = mWifiLevel;
-            mDemoInetCondition = mInetCondition;
-            mDemoDataTypeIconId = mDataTypeIconId;
-            mDemoQSDataTypeIconId = mQSDataTypeIconId;
-            mDemoMobileLevel = mLastSignalLevel;
+            mDemoInetCondition = mInetCondition ? 1 : 0;
+            mDemoWifiState = mWifiSignalController.getState();
+            mDemoMobileState = mMobileSignalController.getState();
         } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
+            if (DEBUG) Log.d(TAG, "Exiting demo mode");
             mDemoMode = false;
-            for (SignalCluster cluster : mSignalClusters) {
-                refreshSignalCluster(cluster);
-            }
-            refreshViews();
+            mWifiSignalController.resetLastState();
+            mMobileSignalController.resetLastState();
+            registerListeners();
+            notifyAllListeners();
+            refreshCarrierLabel();
         } else if (mDemoMode && command.equals(COMMAND_NETWORK)) {
             String airplane = args.getString("airplane");
             if (airplane != null) {
                 boolean show = airplane.equals("show");
-                for (SignalCluster cluster : mSignalClusters) {
-                    cluster.setIsAirplaneMode(show, TelephonyIcons.FLIGHT_MODE_ICON);
+                int length = mSignalClusters.size();
+                for (int i = 0; i < length; i++) {
+                    mSignalClusters.get(i).setIsAirplaneMode(show, TelephonyIcons.FLIGHT_MODE_ICON,
+                            R.string.accessibility_airplane_mode);
                 }
             }
             String fully = args.getString("fully");
             if (fully != null) {
                 mDemoInetCondition = Boolean.parseBoolean(fully) ? 1 : 0;
+                mWifiSignalController.setInetCondition(mDemoInetCondition);
+                mMobileSignalController.setInetCondition(mDemoInetCondition, mDemoInetCondition);
             }
             String wifi = args.getString("wifi");
             if (wifi != null) {
                 boolean show = wifi.equals("show");
                 String level = args.getString("level");
                 if (level != null) {
-                    mDemoWifiLevel = level.equals("null") ? -1
+                    mDemoWifiState.level = level.equals("null") ? -1
                             : Math.min(Integer.parseInt(level), WifiIcons.WIFI_LEVEL_COUNT - 1);
+                    mDemoWifiState.connected = mDemoWifiState.level >= 0;
                 }
-                int iconId = mDemoWifiLevel < 0 ? R.drawable.stat_sys_wifi_signal_null
-                        : WifiIcons.WIFI_SIGNAL_STRENGTH[mDemoInetCondition][mDemoWifiLevel];
-                for (SignalCluster cluster : mSignalClusters) {
-                    cluster.setWifiIndicators(
-                            show,
-                            iconId,
-                            "Demo");
-                }
-                refreshViews();
+                mDemoWifiState.enabled = show;
+                mWifiSignalController.notifyListeners();
             }
             String mobile = args.getString("mobile");
             if (mobile != null) {
                 boolean show = mobile.equals("show");
                 String datatype = args.getString("datatype");
                 if (datatype != null) {
-                    mDemoDataTypeIconId =
-                            datatype.equals("1x") ? TelephonyIcons.ICON_1X :
-                            datatype.equals("3g") ? TelephonyIcons.ICON_3G :
-                            datatype.equals("4g") ? TelephonyIcons.ICON_4G :
-                            datatype.equals("e") ? R.drawable.stat_sys_data_fully_connected_e :
-                            datatype.equals("g") ? R.drawable.stat_sys_data_fully_connected_g :
-                            datatype.equals("h") ? R.drawable.stat_sys_data_fully_connected_h :
-                            datatype.equals("lte") ? TelephonyIcons.ICON_LTE :
-                            datatype.equals("roam") ? TelephonyIcons.ROAMING_ICON :
-                            0;
-                    mDemoQSDataTypeIconId =
-                            datatype.equals("1x") ? TelephonyIcons.QS_ICON_1X :
-                            datatype.equals("3g") ? TelephonyIcons.QS_ICON_3G :
-                            datatype.equals("4g") ? TelephonyIcons.QS_ICON_4G :
-                            datatype.equals("e") ? R.drawable.ic_qs_signal_e :
-                            datatype.equals("g") ? R.drawable.ic_qs_signal_g :
-                            datatype.equals("h") ? R.drawable.ic_qs_signal_h :
-                            datatype.equals("lte") ? TelephonyIcons.QS_ICON_LTE :
-                            datatype.equals("roam") ? R.drawable.ic_qs_signal_r :
-                            0;
+                    mDemoMobileState.iconGroup =
+                            datatype.equals("1x") ? TelephonyIcons.ONE_X :
+                            datatype.equals("3g") ? TelephonyIcons.THREE_G :
+                            datatype.equals("4g") ? TelephonyIcons.FOUR_G :
+                            datatype.equals("e") ? TelephonyIcons.E :
+                            datatype.equals("g") ? TelephonyIcons.G :
+                            datatype.equals("h") ? TelephonyIcons.H :
+                            datatype.equals("lte") ? TelephonyIcons.LTE :
+                            datatype.equals("roam") ? TelephonyIcons.ROAMING :
+                            TelephonyIcons.UNKNOWN;
                 }
                 int[][] icons = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH;
                 String level = args.getString("level");
                 if (level != null) {
-                    mDemoMobileLevel = level.equals("null") ? -1
+                    mDemoMobileState.level = level.equals("null") ? -1
                             : Math.min(Integer.parseInt(level), icons[0].length - 1);
+                    mDemoMobileState.connected = mDemoMobileState.level >= 0;
                 }
-                int iconId = mDemoMobileLevel < 0 ? R.drawable.stat_sys_signal_null :
-                        icons[mDemoInetCondition][mDemoMobileLevel];
-                for (SignalCluster cluster : mSignalClusters) {
-                    cluster.setMobileDataIndicators(
-                            show,
-                            iconId,
-                            mDemoDataTypeIconId,
-                            "Demo",
-                            "Demo",
-                            isTypeIconWide(mDemoDataTypeIconId));
-                }
-                refreshViews();
+                mDemoMobileState.enabled = show;
+                mMobileSignalController.notifyListeners();
             }
+            refreshCarrierLabel();
+        }
+    }
+
+    static class WifiSignalController extends
+            SignalController<WifiSignalController.WifiState, SignalController.IconGroup> {
+        private final WifiManager mWifiManager;
+        private final AsyncChannel mWifiChannel;
+        private final boolean mHasMobileData;
+
+        public WifiSignalController(Context context, boolean hasMobileData,
+                List<NetworkSignalChangedCallback> signalCallbacks,
+                List<SignalCluster> signalClusters, NetworkControllerImpl networkController) {
+            super("WifiSignalController", context, ConnectivityManager.TYPE_WIFI, signalCallbacks,
+                    signalClusters, networkController);
+            mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+            mHasMobileData = hasMobileData;
+            Handler handler = new WifiHandler();
+            mWifiChannel = new AsyncChannel();
+            Messenger wifiMessenger = mWifiManager.getWifiServiceMessenger();
+            if (wifiMessenger != null) {
+                mWifiChannel.connect(context, handler, wifiMessenger);
+            }
+            // WiFi only has one state.
+            mCurrentState.iconGroup = mLastState.iconGroup = new IconGroup(
+                    "Wi-Fi Icons",
+                    WifiIcons.WIFI_SIGNAL_STRENGTH,
+                    WifiIcons.QS_WIFI_SIGNAL_STRENGTH,
+                    AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH,
+                    WifiIcons.WIFI_NO_NETWORK,
+                    WifiIcons.QS_WIFI_NO_NETWORK,
+                    WifiIcons.WIFI_NO_NETWORK,
+                    WifiIcons.QS_WIFI_NO_NETWORK,
+                    AccessibilityContentDescriptions.WIFI_NO_CONNECTION
+                    );
+        }
+
+        @Override
+        public WifiState cleanState() {
+            return new WifiState();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void notifyListeners() {
+            // only show wifi in the cluster if connected or if wifi-only
+            boolean wifiEnabled = mCurrentState.enabled
+                    && (mCurrentState.connected || !mHasMobileData);
+            String wifiDesc = wifiEnabled ? mCurrentState.ssid : null;
+            boolean ssidPresent = wifiEnabled && mCurrentState.ssid != null;
+            String contentDescription = getStringIfExists(getContentDescription());
+            int length = mSignalsChangedCallbacks.size();
+            for (int i = 0; i < length; i++) {
+                mSignalsChangedCallbacks.get(i).onWifiSignalChanged(mCurrentState.enabled,
+                        mCurrentState.connected, getQsCurrentIconId(),
+                        ssidPresent && mCurrentState.activityIn,
+                        ssidPresent && mCurrentState.activityOut, contentDescription, wifiDesc);
+            }
+
+            int signalClustersLength = mSignalClusters.size();
+            for (int i = 0; i < signalClustersLength; i++) {
+                mSignalClusters.get(i).setWifiIndicators(
+                        // only show wifi in the cluster if connected or if wifi-only
+                        mCurrentState.enabled && (mCurrentState.connected || !mHasMobileData),
+                        getCurrentIconId(), contentDescription);
+            }
+        }
+
+        /**
+         * Extract wifi state directly from broadcasts about changes in wifi state.
+         */
+        public void handleBroadcast(Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
+                mCurrentState.enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+                        WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
+            } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
+                final NetworkInfo networkInfo = (NetworkInfo)
+                        intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+                mCurrentState.connected = networkInfo != null && networkInfo.isConnected();
+                // If Connected grab the signal strength and ssid.
+                if (mCurrentState.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) {
+                        mCurrentState.ssid = huntForSsid(info);
+                    } else {
+                        mCurrentState.ssid = null;
+                    }
+                } else if (!mCurrentState.connected) {
+                    mCurrentState.ssid = null;
+                }
+            } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
+                mCurrentState.rssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
+                mCurrentState.level = WifiManager.calculateSignalLevel(
+                        mCurrentState.rssi, WifiIcons.WIFI_LEVEL_COUNT);
+            }
+
+            notifyListenersIfNecessary();
+        }
+
+        private String huntForSsid(WifiInfo info) {
+            String ssid = info.getSSID();
+            if (ssid != null) {
+                return ssid;
+            }
+            // OK, it's not in the connectionInfo; we have to go hunting for it
+            List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks();
+            int length = networks.size();
+            for (int i = 0; i < length; i++) {
+                if (networks.get(i).networkId == info.getNetworkId()) {
+                    return networks.get(i).SSID;
+                }
+            }
+            return null;
+        }
+
+        @VisibleForTesting
+        void setActivity(int wifiActivity) {
+            mCurrentState.activityIn = wifiActivity == WifiManager.DATA_ACTIVITY_INOUT
+                    || wifiActivity == WifiManager.DATA_ACTIVITY_IN;
+            mCurrentState.activityOut = wifiActivity == WifiManager.DATA_ACTIVITY_INOUT
+                    || wifiActivity == WifiManager.DATA_ACTIVITY_OUT;
+            notifyListenersIfNecessary();
+        }
+
+        /**
+         * Handler to receive the data activity on wifi.
+         */
+        class WifiHandler extends Handler {
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+                        if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
+                            mWifiChannel.sendMessage(Message.obtain(this,
+                                    AsyncChannel.CMD_CHANNEL_FULL_CONNECTION));
+                        } else {
+                            Log.e(mTag, "Failed to connect to wifi");
+                        }
+                        break;
+                    case WifiManager.DATA_ACTIVITY_NOTIFICATION:
+                        setActivity(msg.arg1);
+                        break;
+                    default:
+                        // Ignore
+                        break;
+                }
+            }
+        }
+
+        static class WifiState extends SignalController.State {
+            String ssid;
+
+            @Override
+            public void copyFrom(State s) {
+                WifiState state = (WifiState) s;
+                ssid = state.ssid;
+                super.copyFrom(s);
+            }
+
+            @Override
+            protected void toString(StringBuilder builder) {
+                builder.append("ssid=").append(ssid).append(',');
+                super.toString(builder);
+            }
+
+            @Override
+            public boolean equals(Object o) {
+                return super.equals(o)
+                        && Objects.equals(((WifiState) o).ssid, ssid);
+            }
+        }
+    }
+
+    static class MobileSignalController extends SignalController<MobileSignalController.MobileState,
+            MobileSignalController.MobileIconGroup> {
+        private final Config mConfig;
+        private final TelephonyManager mPhone;
+        private final String mNetworkNameDefault;
+        private final String mNetworkNameSeparator;
+
+        // @VisibleForDemoMode
+        Map<Integer, MobileIconGroup> mNetworkToIconLookup;
+
+        // Since some pieces of the phone state are interdependent we store it locally,
+        // this could potentially become part of MobileState for simplification/complication
+        // of code.
+        private IccCardConstants.State mSimState = IccCardConstants.State.READY;
+        private int mDataNetType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
+        private int mDataState = TelephonyManager.DATA_DISCONNECTED;
+        private ServiceState mServiceState;
+        private SignalStrength mSignalStrength;
+        private MobileIconGroup mDefaultIcons;
+
+        // TODO: Reduce number of vars passed in, if we have the NetworkController, probably don't
+        // need listener lists anymore.
+        public MobileSignalController(Context context, Config config, boolean hasMobileData,
+                TelephonyManager phone, List<NetworkSignalChangedCallback> signalCallbacks,
+                List<SignalCluster> signalClusters, NetworkControllerImpl networkController) {
+            super("MobileSignalController", context, ConnectivityManager.TYPE_MOBILE,
+                    signalCallbacks, signalClusters, networkController);
+            mConfig = config;
+            mPhone = phone;
+            mNetworkNameSeparator = getStringIfExists(R.string.status_bar_network_name_separator);
+            mNetworkNameDefault = getStringIfExists(
+                    com.android.internal.R.string.lockscreen_carrier_default);
+
+            mapIconSets();
+
+            mLastState.networkName = mCurrentState.networkName = mNetworkNameDefault;
+            mLastState.enabled = mCurrentState.enabled = hasMobileData;
+            mLastState.iconGroup = mCurrentState.iconGroup = mDefaultIcons;
+        }
+
+        /**
+         * Get (the mobile parts of) the carrier string.
+         *
+         * @param currentLabel can be used for concatenation, currently just empty
+         * @param connected whether the device has connection to the internet at all
+         * @param isMobileLabel whether to always return the network or just when data is connected
+         */
+        public String getLabel(String currentLabel, boolean connected, boolean isMobileLabel) {
+            if (!mCurrentState.enabled) {
+                return "";
+            } else {
+                String mobileLabel = "";
+                // We want to show the carrier name if in service and either:
+                // - We are connected to mobile data, or
+                // - We are not connected to mobile data, as long as the *reason* packets are not
+                //   being routed over that link is that we have better connectivity via wifi.
+                // If data is disconnected for some other reason but wifi (or ethernet/bluetooth)
+                // is connected, we show nothing.
+                // Otherwise (nothing connected) we show "No internet connection".
+                if (mCurrentState.dataConnected) {
+                    mobileLabel = mCurrentState.networkName;
+                } else if (connected || mCurrentState.isEmergency) {
+                    if (mCurrentState.connected || mCurrentState.isEmergency) {
+                        // The isEmergencyOnly test covers the case of a phone with no SIM
+                        mobileLabel = mCurrentState.networkName;
+                    }
+                } else {
+                    mobileLabel = mContext
+                            .getString(R.string.status_bar_settings_signal_meter_disconnected);
+                }
+
+                // Now for things that should only be shown when actually using mobile data.
+                if (isMobileLabel) {
+                    return mobileLabel;
+                } else {
+                    return mCurrentState.dataConnected ? mobileLabel : currentLabel;
+                }
+            }
+        }
+
+        public int getDataContentDescription() {
+            return getIcons().mDataContentDescription;
+        }
+
+        public void setAirplaneMode(boolean airplaneMode) {
+            mCurrentState.airplaneMode = airplaneMode;
+            notifyListenersIfNecessary();
+        }
+
+        public void setInetCondition(int inetCondition, int inetConditionForNetwork) {
+            // For mobile data, use general inet condition for phone signal indexing,
+            // and network specific for data indexing (I think this might be a bug, but
+            // keeping for now).
+            // TODO: Update with explanation of why.
+            mCurrentState.inetForNetwork = inetConditionForNetwork;
+            setInetCondition(inetCondition);
+        }
+
+        /**
+         * Start listening for phone state changes.
+         */
+        public void registerListener() {
+            mPhone.listen(mPhoneStateListener,
+                    PhoneStateListener.LISTEN_SERVICE_STATE
+                            | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
+                            | PhoneStateListener.LISTEN_CALL_STATE
+                            | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
+                            | PhoneStateListener.LISTEN_DATA_ACTIVITY);
+        }
+
+        /**
+         * Stop listening for phone state changes.
+         */
+        public void unregisterListener() {
+            mPhone.listen(mPhoneStateListener, 0);
+        }
+
+        /**
+         * Produce a mapping of data network types to icon groups for simple and quick use in
+         * updateTelephony.
+         *
+         * TODO: See if config can change with locale, this may need to be regenerated on Locale
+         * change.
+         */
+        private void mapIconSets() {
+            mNetworkToIconLookup = new HashMap<Integer, MobileIconGroup>();
+
+            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyIcons.THREE_G);
+            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyIcons.THREE_G);
+            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_B, TelephonyIcons.THREE_G);
+            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EHRPD, TelephonyIcons.THREE_G);
+            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UMTS, TelephonyIcons.THREE_G);
+
+            if (!mConfig.showAtLeastThreeGees) {
+                mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UNKNOWN,
+                        TelephonyIcons.UNKNOWN);
+                mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EDGE, TelephonyIcons.E);
+                mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_CDMA, TelephonyIcons.ONE_X);
+                mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_1xRTT, TelephonyIcons.ONE_X);
+
+                mDefaultIcons = TelephonyIcons.G;
+            } else {
+                mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UNKNOWN,
+                        TelephonyIcons.THREE_G);
+                mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EDGE,
+                        TelephonyIcons.THREE_G);
+                mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_CDMA,
+                        TelephonyIcons.THREE_G);
+                mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_1xRTT,
+                        TelephonyIcons.THREE_G);
+                mDefaultIcons = TelephonyIcons.THREE_G;
+            }
+
+            MobileIconGroup hGroup = TelephonyIcons.THREE_G;
+            if (mConfig.hspaDataDistinguishable) {
+                hGroup = TelephonyIcons.H;
+            }
+            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSDPA, hGroup);
+            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSUPA, hGroup);
+            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSPA, hGroup);
+            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSPAP, hGroup);
+
+            if (mConfig.show4gForLte) {
+                mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE, TelephonyIcons.FOUR_G);
+            } else {
+                mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE, TelephonyIcons.LTE);
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void notifyListeners() {
+            MobileIconGroup icons = getIcons();
+
+            String contentDescription = getStringIfExists(getContentDescription());
+            String dataContentDescription = getStringIfExists(icons.mDataContentDescription);
+            int qsTypeIcon = icons.mQsDataType[mCurrentState.inetForNetwork];
+            int length = mSignalsChangedCallbacks.size();
+            for (int i = 0; i < length; i++) {
+                mSignalsChangedCallbacks.get(i).onMobileDataSignalChanged(mCurrentState.enabled
+                        && !mCurrentState.isEmergency && !mCurrentState.airplaneMode,
+                        getQsCurrentIconId(), contentDescription,
+                        qsTypeIcon,
+                        mCurrentState.dataConnected && mCurrentState.activityIn,
+                        mCurrentState.dataConnected && mCurrentState.activityOut,
+                        dataContentDescription,
+                        mCurrentState.isEmergency ? null : mCurrentState.networkName,
+                        mCurrentState.noSim,
+                        // Only wide if actually showing something.
+                        icons.mIsWide && qsTypeIcon != 0);
+            }
+            boolean showDataIcon = mCurrentState.inetForNetwork != 0
+                    || mCurrentState.iconGroup == TelephonyIcons.ROAMING;
+            int typeIcon = showDataIcon ? icons.mDataType : 0;
+            int signalClustersLength = mSignalClusters.size();
+            for (int i = 0; i < signalClustersLength; i++) {
+                mSignalClusters.get(i).setMobileDataIndicators(
+                        mCurrentState.enabled && !mCurrentState.airplaneMode,
+                        getCurrentIconId(),
+                        typeIcon,
+                        contentDescription,
+                        dataContentDescription,
+                        // Only wide if actually showing something.
+                        icons.mIsWide && typeIcon != 0);
+            }
+        }
+
+        @Override
+        public MobileState cleanState() {
+            return new MobileState();
+        }
+
+        private boolean hasService() {
+            if (mServiceState != null) {
+                // Consider the device to be in service if either voice or data
+                // service is available. Some SIM cards are marketed as data-only
+                // and do not support voice service, and on these SIM cards, we
+                // want to show signal bars for data service as well as the "no
+                // service" or "emergency calls only" text that indicates that voice
+                // is not available.
+                switch (mServiceState.getVoiceRegState()) {
+                    case ServiceState.STATE_POWER_OFF:
+                        return false;
+                    case ServiceState.STATE_OUT_OF_SERVICE:
+                    case ServiceState.STATE_EMERGENCY_ONLY:
+                        return mServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE;
+                    default:
+                        return true;
+                }
+            } else {
+                return false;
+            }
+        }
+
+        private boolean isCdma() {
+            return (mSignalStrength != null) && !mSignalStrength.isGsm();
+        }
+
+        public boolean isEmergencyOnly() {
+            return (mServiceState != null && mServiceState.isEmergencyOnly());
+        }
+
+        private boolean isRoaming() {
+            if (isCdma()) {
+                final int iconMode = mServiceState.getCdmaEriIconMode();
+                return mServiceState.getCdmaEriIconIndex() != EriInfo.ROAMING_INDICATOR_OFF
+                        && (iconMode == EriInfo.ROAMING_ICON_MODE_NORMAL
+                            || iconMode == EriInfo.ROAMING_ICON_MODE_FLASH);
+            } else {
+                return mServiceState != null && mServiceState.getRoaming();
+            }
+        }
+
+        public void handleBroadcast(Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
+                String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
+                final String lockedReason =
+                        intent.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
+                updateSimState(stateExtra, lockedReason);
+                updateTelephony();
+            } else if (action.equals(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION)) {
+                updateNetworkName(intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false),
+                        intent.getStringExtra(TelephonyIntents.EXTRA_SPN),
+                        intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false),
+                        intent.getStringExtra(TelephonyIntents.EXTRA_PLMN));
+                notifyListenersIfNecessary();
+            }
+        }
+
+        /**
+         * Determines the current sim state, based on a TelephonyIntents.ACTION_SIM_STATE_CHANGED
+         * broadcast.
+         */
+        private final void updateSimState(String stateExtra, String lockedReason) {
+            if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
+                mSimState = IccCardConstants.State.ABSENT;
+            } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
+                mSimState = IccCardConstants.State.READY;
+            } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
+                if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
+                    mSimState = IccCardConstants.State.PIN_REQUIRED;
+                } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
+                    mSimState = IccCardConstants.State.PUK_REQUIRED;
+                } else {
+                    mSimState = IccCardConstants.State.NETWORK_LOCKED;
+                }
+            } else {
+                mSimState = IccCardConstants.State.UNKNOWN;
+            }
+            if (DEBUG) Log.d(TAG, "updateSimState: mSimState=" + mSimState);
+        }
+
+        /**
+         * Updates the network's name based on incoming spn and plmn.
+         */
+        void updateNetworkName(boolean showSpn, String spn, boolean showPlmn, String plmn) {
+            if (CHATTY) {
+                Log.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn
+                        + " showPlmn=" + showPlmn + " plmn=" + plmn);
+            }
+            StringBuilder str = new StringBuilder();
+            if (showPlmn && plmn != null) {
+                str.append(plmn);
+            }
+            if (showSpn && spn != null) {
+                if (str.length() != 0) {
+                    str.append(mNetworkNameSeparator);
+                }
+                str.append(spn);
+            }
+            if (str.length() != 0) {
+                mCurrentState.networkName = str.toString();
+            } else {
+                mCurrentState.networkName = mNetworkNameDefault;
+            }
+        }
+
+        /**
+         * Updates the current state based on mServiceState, mSignalStrength, mDataNetType,
+         * mDataState, and mSimState.  It should be called any time one of these is updated.
+         * This will call listeners if necessary.
+         */
+        private final void updateTelephony() {
+            if (DEBUG) {
+                Log.d(TAG, "updateTelephonySignalStrength: hasService=" + hasService()
+                        + " ss=" + mSignalStrength);
+            }
+            mCurrentState.connected = hasService() && mSignalStrength != null;
+            if (mCurrentState.connected) {
+                if (!mSignalStrength.isGsm() && mConfig.alwaysShowCdmaRssi) {
+                    mCurrentState.level = mSignalStrength.getCdmaLevel();
+                } else {
+                    mCurrentState.level = mSignalStrength.getLevel();
+                }
+            }
+            if (mNetworkToIconLookup.containsKey(mDataNetType)) {
+                mCurrentState.iconGroup = mNetworkToIconLookup.get(mDataNetType);
+            } else {
+                mCurrentState.iconGroup = mDefaultIcons;
+            }
+            mCurrentState.dataConnected = mCurrentState.connected
+                    && mDataState == TelephonyManager.DATA_CONNECTED;
+            if (!isCdma()) {
+                if (mSimState == IccCardConstants.State.READY ||
+                        mSimState == IccCardConstants.State.UNKNOWN) {
+                    mCurrentState.noSim = false;
+                } else {
+                    mCurrentState.noSim = true;
+                    // No sim, no data.
+                    mCurrentState.dataConnected = false;
+                }
+            }
+
+            if (isRoaming()) {
+                mCurrentState.iconGroup = TelephonyIcons.ROAMING;
+            }
+            if (isEmergencyOnly() != mCurrentState.isEmergency) {
+                mCurrentState.isEmergency = isEmergencyOnly();
+                mNetworkController.recalculateEmergency();
+            }
+            notifyListenersIfNecessary();
+        }
+
+        @VisibleForTesting
+        void setActivity(int activity) {
+            mCurrentState.activityIn = activity == TelephonyManager.DATA_ACTIVITY_INOUT
+                    || activity == TelephonyManager.DATA_ACTIVITY_IN;
+            mCurrentState.activityOut = activity == TelephonyManager.DATA_ACTIVITY_INOUT
+                    || activity == TelephonyManager.DATA_ACTIVITY_OUT;
+            notifyListenersIfNecessary();
+        }
+
+        @Override
+        public void dump(PrintWriter pw) {
+            super.dump(pw);
+            pw.println("  mServiceState=" + mServiceState + ",");
+            pw.println("  mSignalStrength=" + mSignalStrength + ",");
+            pw.println("  mDataState=" + mDataState + ",");
+            pw.println("  mDataNetType=" + mDataNetType + ",");
+        }
+
+        PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+            @Override
+            public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+                if (DEBUG) {
+                    Log.d(TAG, "onSignalStrengthsChanged signalStrength=" + signalStrength +
+                            ((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel())));
+                }
+                mSignalStrength = signalStrength;
+                updateTelephony();
+            }
+
+            @Override
+            public void onServiceStateChanged(ServiceState state) {
+                if (DEBUG) {
+                    Log.d(TAG, "onServiceStateChanged voiceState=" + state.getVoiceRegState()
+                            + " dataState=" + state.getDataRegState());
+                }
+                mServiceState = state;
+                updateTelephony();
+            }
+
+            @Override
+            public void onDataConnectionStateChanged(int state, int networkType) {
+                if (DEBUG) {
+                    Log.d(TAG, "onDataConnectionStateChanged: state=" + state
+                            + " type=" + networkType);
+                }
+                mDataState = state;
+                mDataNetType = networkType;
+                updateTelephony();
+            }
+
+            @Override
+            public void onDataActivity(int direction) {
+                if (DEBUG) {
+                    Log.d(TAG, "onDataActivity: direction=" + direction);
+                }
+                setActivity(direction);
+            }
+        };
+
+        static class MobileIconGroup extends SignalController.IconGroup {
+            final int mDataContentDescription; // mContentDescriptionDataType
+            final int mDataType;
+            final boolean mIsWide;
+            final int[] mQsDataType;
+
+            public MobileIconGroup(String name, int[][] sbIcons, int[][] qsIcons, int[] contentDesc,
+                    int sbNullState, int qsNullState, int sbDiscState, int qsDiscState,
+                    int discContentDesc, int dataContentDesc, int dataType, boolean isWide,
+                    int[] qsDataType) {
+                super(name, sbIcons, qsIcons, contentDesc, sbNullState, qsNullState, sbDiscState,
+                        qsDiscState, discContentDesc);
+                mDataContentDescription = dataContentDesc;
+                mDataType = dataType;
+                mIsWide = isWide;
+                mQsDataType = qsDataType;
+            }
+        }
+
+        static class MobileState extends SignalController.State {
+            String networkName;
+            boolean noSim;
+            boolean dataConnected;
+            boolean isEmergency;
+            boolean airplaneMode;
+            int inetForNetwork;
+
+            @Override
+            public void copyFrom(State s) {
+                MobileState state = (MobileState) s;
+                noSim = state.noSim;
+                networkName = state.networkName;
+                dataConnected = state.dataConnected;
+                inetForNetwork = state.inetForNetwork;
+                isEmergency = state.isEmergency;
+                airplaneMode = state.airplaneMode;
+                super.copyFrom(s);
+            }
+
+            @Override
+            protected void toString(StringBuilder builder) {
+                builder.append("noSim=").append(noSim).append(',');
+                builder.append("networkName=").append(networkName).append(',');
+                builder.append("dataConnected=").append(dataConnected).append(',');
+                builder.append("inetForNetwork=").append(inetForNetwork).append(',');
+                builder.append("isEmergency=").append(isEmergency).append(',');
+                builder.append("airplaneMode=").append(airplaneMode).append(',');
+                super.toString(builder);
+            }
+
+            @Override
+            public boolean equals(Object o) {
+                return super.equals(o)
+                        && Objects.equals(((MobileState) o).networkName, networkName)
+                        && ((MobileState) o).noSim == noSim
+                        && ((MobileState) o).dataConnected == dataConnected
+                        && ((MobileState) o).isEmergency == isEmergency
+                        && ((MobileState) o).airplaneMode == airplaneMode
+                        && ((MobileState) o).inetForNetwork == inetForNetwork;
+            }
+        }
+    }
+
+    /**
+     * Common base class for handling signal for both wifi and mobile data.
+     */
+    static abstract class SignalController<T extends SignalController.State,
+            I extends SignalController.IconGroup> {
+        protected final String mTag;
+        protected final T mCurrentState;
+        protected final T mLastState;
+        protected final int mNetworkType;
+        protected final Context mContext;
+        // The owner of the SignalController (i.e. NetworkController will maintain the following
+        // lists and call notifyListeners whenever the list has changed to ensure everyone
+        // is aware of current state.
+        protected final List<NetworkSignalChangedCallback> mSignalsChangedCallbacks;
+        protected final List<SignalCluster> mSignalClusters;
+        protected final NetworkControllerImpl mNetworkController;
+
+        // Save the previous HISTORY_SIZE states for logging.
+        private final State[] mHistory;
+        // Where to copy the next state into.
+        private int mHistoryIndex;
+
+        public SignalController(String tag, Context context, int type,
+                List<NetworkSignalChangedCallback> signalCallbacks,
+                List<SignalCluster> signalClusters, NetworkControllerImpl networkController) {
+            mTag = TAG + "::" + tag;
+            mNetworkController = networkController;
+            mNetworkType = type;
+            mContext = context;
+            mSignalsChangedCallbacks = signalCallbacks;
+            mSignalClusters = signalClusters;
+            mCurrentState = cleanState();
+            mLastState = cleanState();
+            if (RECORD_HISTORY) {
+                mHistory = new State[HISTORY_SIZE];
+                for (int i = 0; i < HISTORY_SIZE; i++) {
+                    mHistory[i] = cleanState();
+                }
+            }
+        }
+
+        public T getState() {
+            return mCurrentState;
+        }
+
+        public int getNetworkType() {
+            return mNetworkType;
+        }
+
+        public void setInetCondition(int inetCondition) {
+            mCurrentState.inetCondition = inetCondition;
+            notifyListenersIfNecessary();
+        }
+
+        // @VisibleForDemoMode
+        /**
+         * Used at the end of demo mode to clear out any ugly state that it has created.
+         * Since we haven't had any callbacks, then isDirty will not have been triggered,
+         * so we can just take the last good state directly from there.
+         */
+        void resetLastState() {
+            mCurrentState.copyFrom(mLastState);
+        }
+
+        /**
+         * Determines if the state of this signal controller has changed and
+         * needs to trigger callbacks related to it.
+         */
+        public boolean isDirty() {
+            if (!mLastState.equals(mCurrentState)) {
+                if (DEBUG) {
+                    Log.d(mTag, "Change in state from: " + mLastState + "\n"
+                            + "\tto: " + mCurrentState);
+                }
+                return true;
+            }
+            return false;
+        }
+
+        public void saveLastState() {
+            if (RECORD_HISTORY) {
+                recordLast();
+            }
+            // Updates the current time.
+            mCurrentState.time = System.currentTimeMillis();
+            mLastState.copyFrom(mCurrentState);
+        }
+
+        /**
+         * Gets the signal icon for QS based on current state of connected, enabled, and level.
+         */
+        public int getQsCurrentIconId() {
+            if (mCurrentState.connected) {
+                return getIcons().mQsIcons[mCurrentState.inetCondition][mCurrentState.level];
+            } else if (mCurrentState.enabled) {
+                return getIcons().mQsDiscState;
+            } else {
+                return getIcons().mQsNullState;
+            }
+        }
+
+        /**
+         * Gets the signal icon for SB based on current state of connected, enabled, and level.
+         */
+        public int getCurrentIconId() {
+            if (mCurrentState.connected) {
+                return getIcons().mSbIcons[mCurrentState.inetCondition][mCurrentState.level];
+            } else if (mCurrentState.enabled) {
+                return getIcons().mSbDiscState;
+            } else {
+                return getIcons().mSbNullState;
+            }
+        }
+
+        /**
+         * Gets the content description for the signal based on current state of connected and
+         * level.
+         */
+        public int getContentDescription() {
+            if (mCurrentState.connected) {
+                return getIcons().mContentDesc[mCurrentState.level];
+            } else {
+                return getIcons().mDiscContentDesc;
+            }
+        }
+
+        protected void notifyListenersIfNecessary() {
+            if (isDirty()) {
+                saveLastState();
+                notifyListeners();
+                mNetworkController.refreshCarrierLabel();
+            }
+        }
+
+        /**
+         * Returns the resource if resId is not 0, and an empty string otherwise.
+         */
+        protected String getStringIfExists(int resId) {
+            return resId != 0 ? mContext.getString(resId) : "";
+        }
+
+        protected I getIcons() {
+            return (I) mCurrentState.iconGroup;
+        }
+
+        /**
+         * Saves the last state of any changes, so we can log the current
+         * and last value of any state data.
+         */
+        protected void recordLast() {
+            mHistory[mHistoryIndex++ & (HISTORY_SIZE - 1)].copyFrom(mLastState);
+        }
+
+        public void dump(PrintWriter pw) {
+            pw.println("  - " + mTag + " -----");
+            pw.println("  Current State: " + mCurrentState);
+            if (RECORD_HISTORY) {
+                // Count up the states that actually contain time stamps, and only display those.
+                int size = 0;
+                for (int i = 0; i < HISTORY_SIZE; i++) {
+                    if (mHistory[i].time != 0) size++;
+                }
+                // Print out the previous states in ordered number.
+                for (int i = mHistoryIndex + HISTORY_SIZE - 1;
+                        i >= mHistoryIndex + HISTORY_SIZE - size; i--) {
+                    pw.println("  Previous State(" + (mHistoryIndex + HISTORY_SIZE - i) + ": "
+                            + mHistory[i & (HISTORY_SIZE - 1)]);
+                }
+            }
+        }
+
+        /**
+         * Trigger callbacks based on current state.  The callbacks should be completely
+         * based on current state, and only need to be called in the scenario where
+         * mCurrentState != mLastState.
+         */
+        public abstract void notifyListeners();
+
+        /**
+         * Generate a blank T.
+         */
+        public abstract T cleanState();
+
+        /*
+         * Holds icons for a given state. Arrays are generally indexed as inet
+         * state (full connectivity or not) first, and second dimension as
+         * signal strength.
+         */
+        static class IconGroup {
+            final int[][] mSbIcons;
+            final int[][] mQsIcons;
+            final int[] mContentDesc;
+            final int mSbNullState;
+            final int mQsNullState;
+            final int mSbDiscState;
+            final int mQsDiscState;
+            final int mDiscContentDesc;
+            // For logging.
+            final String mName;
+
+            public IconGroup(String name, int[][] sbIcons, int[][] qsIcons, int[] contentDesc,
+                    int sbNullState, int qsNullState, int sbDiscState, int qsDiscState,
+                    int discContentDesc) {
+                mName = name;
+                mSbIcons = sbIcons;
+                mQsIcons = qsIcons;
+                mContentDesc = contentDesc;
+                mSbNullState = sbNullState;
+                mQsNullState = qsNullState;
+                mSbDiscState = sbDiscState;
+                mQsDiscState = qsDiscState;
+                mDiscContentDesc = discContentDesc;
+            }
+
+            @Override
+            public String toString() {
+                return "IconGroup(" + mName + ")";
+            }
+        }
+
+        static class State {
+            boolean connected;
+            boolean enabled;
+            boolean activityIn;
+            boolean activityOut;
+            int level;
+            IconGroup iconGroup;
+            int inetCondition;
+            int rssi; // Only for logging.
+
+            // Not used for comparison, just used for logging.
+            long time;
+
+            public void copyFrom(State state) {
+                connected = state.connected;
+                enabled = state.enabled;
+                level = state.level;
+                iconGroup = state.iconGroup;
+                inetCondition = state.inetCondition;
+                activityIn = state.activityIn;
+                activityOut = state.activityOut;
+                rssi = state.rssi;
+                time = state.time;
+            }
+
+            @Override
+            public String toString() {
+                if (time != 0) {
+                    StringBuilder builder = new StringBuilder();
+                    toString(builder);
+                    return builder.toString();
+                } else {
+                    return "Empty " + getClass().getSimpleName();
+                }
+            }
+
+            protected void toString(StringBuilder builder) {
+                builder.append("connected=").append(connected).append(',')
+                        .append("enabled=").append(enabled).append(',')
+                        .append("level=").append(level).append(',')
+                        .append("inetCondition=").append(inetCondition).append(',')
+                        .append("iconGroup=").append(iconGroup).append(',')
+                        .append("activityIn=").append(activityIn).append(',')
+                        .append("activityOut=").append(activityOut).append(',')
+                        .append("rssi=").append(rssi).append(',')
+                        .append("lastModified=").append(DateFormat.format("MM-dd hh:mm:ss", time));
+            }
+
+            @Override
+            public boolean equals(Object o) {
+                if (!o.getClass().equals(getClass())) {
+                    return false;
+                }
+                State other = (State) o;
+                return other.connected == connected
+                        && other.enabled == enabled
+                        && other.level == level
+                        && other.inetCondition == inetCondition
+                        && other.iconGroup == iconGroup
+                        && other.activityIn == activityIn
+                        && other.activityOut == activityOut
+                        && other.rssi == rssi;
+            }
+        }
+    }
+
+    public interface SignalCluster {
+        void setWifiIndicators(boolean visible, int strengthIcon, String contentDescription);
+
+        void setMobileDataIndicators(boolean visible, int strengthIcon, int typeIcon,
+                String contentDescription, String typeContentDescription, boolean isTypeIconWide);
+
+        void setIsAirplaneMode(boolean is, int airplaneIcon, int contentDescription);
+    }
+
+    public interface EmergencyListener {
+        void setEmergencyCallsOnly(boolean emergencyOnly);
+    }
+
+    public interface CarrierLabelListener {
+        void setCarrierLabel(String label);
+    }
+
+    @VisibleForTesting
+    static class Config {
+        boolean showAtLeastThreeGees = false;
+        boolean alwaysShowCdmaRssi = false;
+        boolean show4gForLte = false;
+        boolean hspaDataDistinguishable;
+
+        static Config readConfig(Context context) {
+            Config config = new Config();
+            Resources res = context.getResources();
+
+            config.showAtLeastThreeGees = res.getBoolean(R.bool.config_showMin3G);
+            config.alwaysShowCdmaRssi =
+                    res.getBoolean(com.android.internal.R.bool.config_alwaysUseCdmaRssi);
+            config.show4gForLte = res.getBoolean(R.bool.config_show4GForLTE);
+            config.hspaDataDistinguishable =
+                    res.getBoolean(R.bool.config_hspa_data_distinguishable);
+            return config;
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
index 1f2b918..4091619 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
@@ -17,11 +17,16 @@
 package com.android.systemui.statusbar.policy;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.NetworkControllerImpl.MobileSignalController.MobileIconGroup;
 
 class TelephonyIcons {
     //***** Signal strength icons
 
+    static final int TELEPHONY_NUM_LEVELS = 5;
+
     //GSM/UMTS
+    static final int TELEPHONY_NO_NETWORK = R.drawable.stat_sys_signal_null;
+
     static final int[][] TELEPHONY_SIGNAL_STRENGTH = {
         { R.drawable.stat_sys_signal_0,
           R.drawable.stat_sys_signal_1,
@@ -35,6 +40,8 @@
           R.drawable.stat_sys_signal_4_fully }
     };
 
+    static final int QS_TELEPHONY_NO_NETWORK = R.drawable.ic_qs_signal_no_signal;
+
     static final int[][] QS_TELEPHONY_SIGNAL_STRENGTH = {
         { R.drawable.ic_qs_signal_0,
           R.drawable.ic_qs_signal_1,
@@ -66,8 +73,6 @@
         R.drawable.ic_qs_signal_r
     };
 
-    static final int[][] DATA_SIGNAL_STRENGTH = TELEPHONY_SIGNAL_STRENGTH;
-
     //***** Data connection icons
 
     //GSM/UMTS
@@ -191,6 +196,9 @@
     static final int FLIGHT_MODE_ICON = R.drawable.stat_sys_airplane_mode;
     static final int ROAMING_ICON = R.drawable.stat_sys_data_fully_connected_roam;
     static final int ICON_LTE = R.drawable.stat_sys_data_fully_connected_lte;
+    static final int ICON_G = R.drawable.stat_sys_data_fully_connected_g;
+    static final int ICON_E = R.drawable.stat_sys_data_fully_connected_e;
+    static final int ICON_H = R.drawable.stat_sys_data_fully_connected_h;
     static final int ICON_3G = R.drawable.stat_sys_data_fully_connected_3g;
     static final int ICON_4G = R.drawable.stat_sys_data_fully_connected_4g;
     static final int ICON_1X = R.drawable.stat_sys_data_fully_connected_1x;
@@ -199,5 +207,137 @@
     static final int QS_ICON_3G = R.drawable.ic_qs_signal_3g;
     static final int QS_ICON_4G = R.drawable.ic_qs_signal_4g;
     static final int QS_ICON_1X = R.drawable.ic_qs_signal_1x;
+
+    static final MobileIconGroup THREE_G = new MobileIconGroup(
+            "3G",
+            TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH,
+            TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
+            0, 0,
+            TelephonyIcons.TELEPHONY_NO_NETWORK,
+            TelephonyIcons.QS_TELEPHONY_NO_NETWORK,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
+            R.string.accessibility_data_connection_3g,
+            TelephonyIcons.ICON_3G,
+            true,
+            TelephonyIcons.QS_DATA_3G
+            );
+
+    static final MobileIconGroup UNKNOWN = new MobileIconGroup(
+            "Unknown",
+            TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH,
+            TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
+            0, 0,
+            TelephonyIcons.TELEPHONY_NO_NETWORK,
+            TelephonyIcons.QS_TELEPHONY_NO_NETWORK,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
+            0, 0, false, new int[2]
+            );
+
+    static final MobileIconGroup E = new MobileIconGroup(
+            "E",
+            TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH,
+            TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
+            0, 0,
+            TelephonyIcons.TELEPHONY_NO_NETWORK,
+            TelephonyIcons.QS_TELEPHONY_NO_NETWORK,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
+            R.string.accessibility_data_connection_edge,
+            TelephonyIcons.ICON_E,
+            false,
+            TelephonyIcons.QS_DATA_E
+            );
+
+    static final MobileIconGroup ONE_X = new MobileIconGroup(
+            "1X",
+            TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH,
+            TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
+            0, 0,
+            TelephonyIcons.TELEPHONY_NO_NETWORK,
+            TelephonyIcons.QS_TELEPHONY_NO_NETWORK,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
+            R.string.accessibility_data_connection_cdma,
+            TelephonyIcons.ICON_1X,
+            true,
+            TelephonyIcons.QS_DATA_1X
+            );
+
+    static final MobileIconGroup G = new MobileIconGroup(
+            "G",
+            TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH,
+            TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
+            0, 0,
+            TelephonyIcons.TELEPHONY_NO_NETWORK,
+            TelephonyIcons.QS_TELEPHONY_NO_NETWORK,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
+            R.string.accessibility_data_connection_gprs,
+            TelephonyIcons.ICON_G,
+            false,
+            TelephonyIcons.QS_DATA_G
+            );
+
+    static final MobileIconGroup H = new MobileIconGroup(
+            "H",
+            TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH,
+            TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
+            0, 0,
+            TelephonyIcons.TELEPHONY_NO_NETWORK,
+            TelephonyIcons.QS_TELEPHONY_NO_NETWORK,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
+            R.string.accessibility_data_connection_3_5g,
+            TelephonyIcons.ICON_H,
+            false,
+            TelephonyIcons.QS_DATA_H
+            );
+
+    static final MobileIconGroup FOUR_G = new MobileIconGroup(
+            "4G",
+            TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH,
+            TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
+            0, 0,
+            TelephonyIcons.TELEPHONY_NO_NETWORK,
+            TelephonyIcons.QS_TELEPHONY_NO_NETWORK,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
+            R.string.accessibility_data_connection_4g,
+            TelephonyIcons.ICON_4G,
+            true,
+            TelephonyIcons.QS_DATA_4G
+            );
+
+    static final MobileIconGroup LTE = new MobileIconGroup(
+            "LTE",
+            TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH,
+            TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
+            0, 0,
+            TelephonyIcons.TELEPHONY_NO_NETWORK,
+            TelephonyIcons.QS_TELEPHONY_NO_NETWORK,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
+            R.string.accessibility_data_connection_lte,
+            TelephonyIcons.ICON_LTE,
+            true,
+            TelephonyIcons.QS_DATA_LTE
+            );
+
+    static final MobileIconGroup ROAMING = new MobileIconGroup(
+            "Roaming",
+            TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING,
+            TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
+            0, 0,
+            TelephonyIcons.TELEPHONY_NO_NETWORK,
+            TelephonyIcons.QS_TELEPHONY_NO_NETWORK,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
+            R.string.accessibility_data_connection_roaming,
+            TelephonyIcons.ROAMING_ICON,
+            false,
+            TelephonyIcons.QS_DATA_R
+            );
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
index 49af979..c56646f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
@@ -45,5 +45,8 @@
               R.drawable.ic_qs_wifi_full_4 }
         };
 
+    static final int QS_WIFI_NO_NETWORK = R.drawable.ic_qs_wifi_no_network;
+    static final int WIFI_NO_NETWORK = R.drawable.stat_sys_wifi_signal_null;
+
     static final int WIFI_LEVEL_COUNT = WIFI_SIGNAL_STRENGTH[0].length;
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WimaxIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WimaxIcons.java
deleted file mode 100644
index 4877828..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WimaxIcons.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 com.android.systemui.statusbar.policy;
-
-import com.android.systemui.statusbar.policy.TelephonyIcons;
-
-class WimaxIcons {
-    static final int[][] WIMAX_SIGNAL_STRENGTH = TelephonyIcons.DATA_SIGNAL_STRENGTH;
-
-    static final int WIMAX_DISCONNECTED = WIMAX_SIGNAL_STRENGTH[0][0];
-
-    static final int WIMAX_IDLE = WIMAX_DISCONNECTED; // XXX: unclear if we need a different icon
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
index 3c93b19..3d4cda6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
@@ -33,6 +33,7 @@
     boolean animateHideSensitive;
     boolean hasDelays;
     boolean hasGoToFullShadeEvent;
+    boolean hasDarkEvent;
 
     public AnimationFilter animateAlpha() {
         animateAlpha = true;
@@ -98,6 +99,10 @@
                     NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_GO_TO_FULL_SHADE) {
                 hasGoToFullShadeEvent = true;
             }
+            if (events.get(i).animationType ==
+                    NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_DARK) {
+                hasDarkEvent = true;
+            }
         }
     }
 
@@ -126,5 +131,6 @@
         animateHideSensitive = false;
         hasDelays = false;
         hasGoToFullShadeEvent = false;
+        hasDarkEvent = false;
     }
 }
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 e63be97..c5f1161 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -2455,7 +2455,8 @@
 
                 // ANIMATION_TYPE_DARK
                 new AnimationFilter()
-                        .animateDark(),
+                        .animateDark()
+                        .hasDelays(),
 
                 // ANIMATION_TYPE_GO_TO_FULL_SHADE
                 new AnimationFilter()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
index 4611370..0b1ce8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
@@ -154,7 +154,7 @@
                 child.setDimmed(state.dimmed, false /* animate */);
 
                 // apply dark
-                child.setDark(state.dark, false /* animate */);
+                child.setDark(state.dark, false /* animate */, 0 /* delay */);
 
                 // apply hiding sensitive
                 child.setHideSensitive(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index a56440c..05077bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -46,6 +46,7 @@
     public static final int ANIMATION_DELAY_PER_ELEMENT_INTERRUPTING = 80;
     public static final int ANIMATION_DELAY_PER_ELEMENT_MANUAL = 32;
     public static final int ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE = 48;
+    public static final int ANIMATION_DELAY_PER_ELEMENT_DARK = 24;
     private static final int DELAY_EFFECT_MAX_INDEX_DIFFERENCE = 2;
 
     private static final int TAG_ANIMATOR_TRANSLATION_Y = R.id.translation_y_animator_tag;
@@ -161,11 +162,12 @@
         boolean scaleChanging = child.getScaleX() != viewState.scale;
         boolean alphaChanging = alpha != child.getAlpha();
         boolean heightChanging = viewState.height != child.getActualHeight();
+        boolean darkChanging = viewState.dark != child.isDark();
         boolean topInsetChanging = viewState.clipTopAmount != child.getClipTopAmount();
         boolean wasAdded = mNewAddChildren.contains(child);
         boolean hasDelays = mAnimationFilter.hasDelays;
         boolean isDelayRelevant = yTranslationChanging || zTranslationChanging || scaleChanging ||
-                alphaChanging || heightChanging || topInsetChanging;
+                alphaChanging || heightChanging || topInsetChanging || darkChanging;
         boolean noAnimation = wasAdded;
         long delay = 0;
         long duration = mCurrentLength;
@@ -242,7 +244,7 @@
                 && !noAnimation);
 
         // start dark animation
-        child.setDark(viewState.dark, mAnimationFilter.animateDark && !noAnimation);
+        child.setDark(viewState.dark, mAnimationFilter.animateDark && !noAnimation, delay);
 
         // apply speed bump state
         child.setBelowSpeedBump(viewState.belowSpeedBump);
@@ -262,6 +264,9 @@
 
     private long calculateChildAnimationDelay(StackScrollState.ViewState viewState,
             StackScrollState finalState) {
+        if (mAnimationFilter.hasDarkEvent) {
+            return calculateDelayDark(viewState);
+        }
         if (mAnimationFilter.hasGoToFullShadeEvent) {
             return calculateDelayGoToFullShade(viewState);
         }
@@ -309,6 +314,10 @@
         return minDelay;
     }
 
+    private long calculateDelayDark(StackScrollState.ViewState viewState) {
+        return viewState.notGoneIndex * ANIMATION_DELAY_PER_ELEMENT_DARK;
+    }
+
     private long calculateDelayGoToFullShade(StackScrollState.ViewState viewState) {
         float index = viewState.notGoneIndex;
         index = (float) Math.pow(index, 0.7f);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java
index 31adc95..e3f8f3d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java
@@ -21,4 +21,5 @@
 
 public interface VolumeComponent extends DemoMode {
     ZenModeController getZenController();
+    void dismissNow();
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
index f12053c..351911c 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
@@ -793,7 +793,7 @@
             sc.icon.setAlpha(mDisabledAlpha);
             sc.icon.setClickable(false);
         } else if (fixedVolume ||
-                (sc.streamType != mAudioManager.getMasterStreamType() && muted) ||
+                (sc.streamType != mAudioManager.getMasterStreamType() && !isRinger && muted) ||
                 (sSafetyWarning != null)) {
             sc.seekbarView.setEnabled(false);
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
index 5232a17..7102c2a 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
@@ -178,7 +178,7 @@
 
         @Override
         public void dismiss() throws RemoteException {
-            mPanel.postDismiss(0);
+            dismissNow();
         }
 
         @Override
@@ -190,6 +190,11 @@
         public void dispatchDemoCommand(String command, Bundle args) {
             mPanel.dispatchDemoCommand(command, args);
         }
+
+        @Override
+        public void dismissNow() {
+            mPanel.postDismiss(0);
+        }
     }
 
     private final class RemoteVolumeController extends IRemoteVolumeController.Stub {
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index 8b87522..5a90324 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -17,14 +17,20 @@
 
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_AAPT_FLAGS := --auto-add-overlay --extra-packages com.android.systemui:com.android.keyguard
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+    $(call all-java-files-under, ../src) \
+    src/com/android/systemui/EventLogTags.logtags
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res \
+    frameworks/base/packages/SystemUI/res \
+    frameworks/base/packages/Keyguard/res
 
 LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
 
 LOCAL_PACKAGE_NAME := SystemUITests
-LOCAL_INSTRUMENTATION_FOR := SystemUI
 
-LOCAL_STATIC_JAVA_LIBRARIES := mockito-target
+LOCAL_STATIC_JAVA_LIBRARIES := mockito-target Keyguard
 
 # sign this with platform cert, so this test is allowed to inject key events into
 # UI it doesn't own. This is necessary to allow screenshots to be taken
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 1d319cf..e52806d 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -25,7 +25,7 @@
     </application>
 
     <instrumentation android:name="android.test.InstrumentationTestRunner"
-        android:targetPackage="com.android.systemui"
+        android:targetPackage="com.android.systemui.tests"
         android:label="Tests for SystemUI">
     </instrumentation>
 </manifest>
diff --git a/packages/SystemUI/tests/src/com/android/systemui/EventLogTags.logtags b/packages/SystemUI/tests/src/com/android/systemui/EventLogTags.logtags
new file mode 120000
index 0000000..2f243d7
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/EventLogTags.logtags
@@ -0,0 +1 @@
+../../../../../src/com/android/systemui/EventLogTags.logtags
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotStubActivity.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotStubActivity.java
index 2935373..784d035 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotStubActivity.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotStubActivity.java
@@ -15,7 +15,7 @@
  */
 package com.android.systemui.screenshot;
 
-import com.android.systemui.tests.R;
+import com.android.systemui.R;
 
 import android.app.Activity;
 import android.os.Bundle;
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 97605ea..49fe1e3 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
@@ -17,6 +17,7 @@
 
 import com.android.internal.telephony.cdma.EriInfo;
 import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
+import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
 import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster;
 
 import org.mockito.ArgumentCaptor;
@@ -44,6 +45,7 @@
     protected ConnectivityManager mMockCm;
     protected WifiManager mMockWm;
     protected TelephonyManager mMockTm;
+    protected Config mConfig;
 
     @Override
     protected void setUp() throws Exception {
@@ -59,15 +61,19 @@
 
         mSignalStrength = mock(SignalStrength.class);
         mServiceState = mock(ServiceState.class);
-        mSignalCluster = mock(SignalCluster.class);
-        mNetworkSignalChangedCallback = mock(NetworkSignalChangedCallback.class);
 
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm);
+        mConfig = new Config();
+        mConfig.hspaDataDistinguishable = true;
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm,
+                mConfig, mock(AccessPointControllerImpl.class),
+                mock(MobileDataControllerImpl.class));
         setupNetworkController();
     }
 
     protected void setupNetworkController() {
-        mPhoneStateListener = mNetworkController.mPhoneStateListener;
+        mPhoneStateListener = mNetworkController.mMobileSignalController.mPhoneStateListener;
+        mSignalCluster = mock(SignalCluster.class);
+        mNetworkSignalChangedCallback = mock(NetworkSignalChangedCallback.class);
         mNetworkController.addSignalCluster(mSignalCluster);
         mNetworkController.addNetworkSignalChangedCallback(mNetworkSignalChangedCallback);
     }
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 ed76ae5..bb2ff7c 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
@@ -1,5 +1,7 @@
 package com.android.systemui.statusbar.policy;
 
+import static org.mockito.Mockito.mock;
+
 import android.net.ConnectivityManager;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
@@ -15,7 +17,9 @@
         // 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, mMockTm, mMockWm);
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm,
+                mConfig, mock(AccessPointControllerImpl.class),
+                mock(MobileDataControllerImpl.class));
         setupNetworkController();
 
         verifyLastMobileDataIndicators(false, 0, 0);
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 4ffdff2..7f0a8f4 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
@@ -6,8 +6,6 @@
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 
-import com.android.systemui.R;
-
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 
@@ -16,14 +14,10 @@
     private static final int MIN_RSSI = -100;
     private static final int MAX_RSSI = -55;
 
-    // TODO: Move this into WifiIcons, remove all R.drawable from NetworkControllerImpl.
-    private static final int NULL_SIGNAL = R.drawable.stat_sys_wifi_signal_null;
-    private static final int QS_NO_NET = R.drawable.ic_qs_wifi_no_network;
-
     public void testWifiIcon() {
         String testSsid = "Test SSID";
         setWifiEnabled(true);
-        verifyLastWifiIcon(false, NULL_SIGNAL);
+        verifyLastWifiIcon(false, WifiIcons.WIFI_NO_NETWORK);
 
         setWifiState(true, testSsid);
         verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[0][0]);
@@ -42,10 +36,10 @@
         String testSsid = "Test SSID";
 
         setWifiEnabled(false);
-        verifyLastQsWifiIcon(false, false, 0, null);
+        verifyLastQsWifiIcon(false, false, WifiIcons.QS_WIFI_NO_NETWORK, null);
 
         setWifiEnabled(true);
-        verifyLastQsWifiIcon(true, false, QS_NO_NET, null);
+        verifyLastQsWifiIcon(true, false, WifiIcons.QS_WIFI_NO_NETWORK, null);
 
         setWifiState(true, testSsid);
         for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
@@ -118,8 +112,7 @@
 
     protected void setWifiActivity(int activity) {
         // TODO: Not this, because this variable probably isn't sticking around.
-        mNetworkController.mWifiActivity = activity;
-        mNetworkController.refreshViews();
+        mNetworkController.mWifiSignalController.setActivity(activity);
     }
 
     protected void setWifiLevel(int level) {
diff --git a/packages/VpnDialogs/AndroidManifest.xml b/packages/VpnDialogs/AndroidManifest.xml
index 03d920a..375c5d8 100644
--- a/packages/VpnDialogs/AndroidManifest.xml
+++ b/packages/VpnDialogs/AndroidManifest.xml
@@ -19,6 +19,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.vpndialogs">
 
+    <uses-permission android:name="android.permission.CONTROL_VPN" />
+
     <application android:label="VpnDialogs"
             android:allowBackup="false" >
         <activity android:name=".ConfirmDialog"
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index c34316b..30a271e 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -101,6 +101,7 @@
 import android.view.accessibility.AccessibilityManager;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.PopupWindow;
@@ -2153,6 +2154,7 @@
     }
 
     private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {
+
         /* package */int mDefaultOpacity = PixelFormat.OPAQUE;
 
         /** The feature ID of the panel, or -1 if this is the application's DecorView */
@@ -2182,19 +2184,45 @@
         // View added at runtime to draw under the navigation bar area
         private View mNavigationGuard;
 
-        private View mStatusColorView;
-        private View mNavigationColorView;
+        private final ColorViewState mStatusColorViewState = new ColorViewState(
+                SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS,
+                Gravity.TOP,
+                STATUS_BAR_BACKGROUND_TRANSITION_NAME,
+                com.android.internal.R.id.statusBarBackground,
+                FLAG_FULLSCREEN);
+        private final ColorViewState mNavigationColorViewState = new ColorViewState(
+                SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION,
+                Gravity.BOTTOM,
+                NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME,
+                com.android.internal.R.id.navigationBarBackground,
+                0 /* hideWindowFlag */);
+
+        private final Interpolator mShowInterpolator;
+        private final Interpolator mHideInterpolator;
+        private final int mBarEnterExitDuration;
+
         private final BackgroundFallback mBackgroundFallback = new BackgroundFallback();
 
         private int mLastTopInset = 0;
         private int mLastBottomInset = 0;
         private int mLastRightInset = 0;
+        private boolean mLastHasTopStableInset = false;
+        private boolean mLastHasBottomStableInset = false;
+        private int mLastWindowFlags = 0;
 
         private int mRootScrollY = 0;
 
         public DecorView(Context context, int featureId) {
             super(context);
             mFeatureId = featureId;
+
+            mShowInterpolator = AnimationUtils.loadInterpolator(context,
+                    android.R.interpolator.linear_out_slow_in);
+            mHideInterpolator = AnimationUtils.loadInterpolator(context,
+                    android.R.interpolator.fast_out_linear_in);
+
+            mBarEnterExitDuration = context.getResources().getInteger(
+                    R.integer.dock_enter_exit_duration);
         }
 
         public void setBackgroundFallback(int resId) {
@@ -2787,13 +2815,13 @@
 
         @Override
         public void onWindowSystemUiVisibilityChanged(int visible) {
-            updateColorViews(null /* insets */);
+            updateColorViews(null /* insets */, true /* animate */);
         }
 
         @Override
         public WindowInsets onApplyWindowInsets(WindowInsets insets) {
             mFrameOffsets.set(insets.getSystemWindowInsets());
-            insets = updateColorViews(insets);
+            insets = updateColorViews(insets, true /* animate */);
             insets = updateStatusGuard(insets);
             updateNavigationGuard(insets);
             if (getForeground() != null) {
@@ -2807,11 +2835,16 @@
             return false;
         }
 
-        private WindowInsets updateColorViews(WindowInsets insets) {
+        private WindowInsets updateColorViews(WindowInsets insets, boolean animate) {
             WindowManager.LayoutParams attrs = getAttributes();
             int sysUiVisibility = attrs.systemUiVisibility | getWindowSystemUiVisibility();
 
             if (!mIsFloating && ActivityManager.isHighEndGfx()) {
+                boolean disallowAnimate = !isLaidOut();
+                disallowAnimate |= ((mLastWindowFlags ^ attrs.flags)
+                        & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
+                mLastWindowFlags = attrs.flags;
+
                 if (insets != null) {
                     mLastTopInset = Math.min(insets.getStableInsetTop(),
                             insets.getSystemWindowInsetTop());
@@ -2819,19 +2852,23 @@
                             insets.getSystemWindowInsetBottom());
                     mLastRightInset = Math.min(insets.getStableInsetRight(),
                             insets.getSystemWindowInsetRight());
+
+                    // Don't animate if the presence of stable insets has changed, because that
+                    // indicates that the window was either just added and received them for the
+                    // first time, or the window size or position has changed.
+                    boolean hasTopStableInset = insets.getStableInsetTop() != 0;
+                    disallowAnimate |= hasTopStableInset && !mLastHasTopStableInset;
+                    mLastHasTopStableInset = hasTopStableInset;
+
+                    boolean hasBottomStableInset = insets.getStableInsetBottom() != 0;
+                    disallowAnimate |= hasBottomStableInset && !mLastHasBottomStableInset;
+                    mLastHasBottomStableInset = hasBottomStableInset;
                 }
-                mStatusColorView = updateColorViewInt(mStatusColorView, sysUiVisibility,
-                        SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS,
-                        mStatusBarColor, mLastTopInset, Gravity.TOP,
-                        STATUS_BAR_BACKGROUND_TRANSITION_NAME,
-                        com.android.internal.R.id.statusBarBackground,
-                        (getAttributes().flags & FLAG_FULLSCREEN) != 0);
-                mNavigationColorView = updateColorViewInt(mNavigationColorView, sysUiVisibility,
-                        SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION,
-                        mNavigationBarColor, mLastBottomInset, Gravity.BOTTOM,
-                        NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME,
-                        com.android.internal.R.id.navigationBarBackground,
-                        false /* hiddenByWindowFlag */);
+
+                updateColorViewInt(mStatusColorViewState, sysUiVisibility, mStatusBarColor,
+                        mLastTopInset, animate && !disallowAnimate);
+                updateColorViewInt(mNavigationColorViewState, sysUiVisibility, mNavigationBarColor,
+                        mLastBottomInset, animate && !disallowAnimate);
             }
 
             // When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, we still need
@@ -2875,28 +2912,35 @@
             return insets;
         }
 
-        private View updateColorViewInt(View view, int sysUiVis, int systemUiHideFlag,
-                int translucentFlag, int color, int height, int verticalGravity,
-                String transitionName, int id, boolean hiddenByWindowFlag) {
-            boolean show = height > 0 && (sysUiVis & systemUiHideFlag) == 0
-                    && !hiddenByWindowFlag
-                    && (getAttributes().flags & translucentFlag) == 0
+        private void updateColorViewInt(final ColorViewState state, int sysUiVis, int color,
+                int height, boolean animate) {
+            boolean show = height > 0 && (sysUiVis & state.systemUiHideFlag) == 0
+                    && (getAttributes().flags & state.hideWindowFlag) == 0
+                    && (getAttributes().flags & state.translucentFlag) == 0
                     && (color & Color.BLACK) != 0
                     && (getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
 
+            boolean visibilityChanged = false;
+            View view = state.view;
+
             if (view == null) {
                 if (show) {
-                    view = new View(mContext);
+                    state.view = view = new View(mContext);
                     view.setBackgroundColor(color);
-                    view.setTransitionName(transitionName);
-                    view.setId(id);
+                    view.setTransitionName(state.transitionName);
+                    view.setId(state.id);
+                    visibilityChanged = true;
+                    view.setVisibility(INVISIBLE);
+                    state.targetVisibility = VISIBLE;
+
                     addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, height,
-                            Gravity.START | verticalGravity));
+                            Gravity.START | state.verticalGravity));
                     updateColorViewTranslations();
                 }
             } else {
                 int vis = show ? VISIBLE : INVISIBLE;
-                view.setVisibility(vis);
+                visibilityChanged = state.targetVisibility != vis;
+                state.targetVisibility = vis;
                 if (show) {
                     LayoutParams lp = (LayoutParams) view.getLayoutParams();
                     if (lp.height != height) {
@@ -2906,18 +2950,43 @@
                     view.setBackgroundColor(color);
                 }
             }
-            return view;
+            if (visibilityChanged) {
+                view.animate().cancel();
+                if (animate) {
+                    if (show) {
+                        if (view.getVisibility() != VISIBLE) {
+                            view.setVisibility(VISIBLE);
+                            view.setAlpha(0.0f);
+                        }
+                        view.animate().alpha(1.0f).setInterpolator(mShowInterpolator).
+                                setDuration(mBarEnterExitDuration);
+                    } else {
+                        view.animate().alpha(0.0f).setInterpolator(mHideInterpolator)
+                                .setDuration(mBarEnterExitDuration)
+                                .withEndAction(new Runnable() {
+                                    @Override
+                                    public void run() {
+                                        state.view.setAlpha(1.0f);
+                                        state.view.setVisibility(INVISIBLE);
+                                    }
+                                });
+                    }
+                } else {
+                    view.setAlpha(1.0f);
+                    view.setVisibility(show ? VISIBLE : INVISIBLE);
+                }
+            }
         }
 
         private void updateColorViewTranslations() {
             // Put the color views back in place when they get moved off the screen
             // due to the the ViewRootImpl panning.
             int rootScrollY = mRootScrollY;
-            if (mStatusColorView != null) {
-                mStatusColorView.setTranslationY(rootScrollY > 0 ? rootScrollY : 0);
+            if (mStatusColorViewState.view != null) {
+                mStatusColorViewState.view.setTranslationY(rootScrollY > 0 ? rootScrollY : 0);
             }
-            if (mNavigationColorView != null) {
-                mNavigationColorView.setTranslationY(rootScrollY < 0 ? rootScrollY : 0);
+            if (mNavigationColorViewState.view != null) {
+                mNavigationColorViewState.view.setTranslationY(rootScrollY < 0 ? rootScrollY : 0);
             }
         }
 
@@ -2948,7 +3017,7 @@
                                 mStatusGuard = new View(mContext);
                                 mStatusGuard.setBackgroundColor(mContext.getResources()
                                         .getColor(R.color.input_method_navigation_guard));
-                                addView(mStatusGuard, indexOfChild(mStatusColorView),
+                                addView(mStatusGuard, indexOfChild(mStatusColorViewState.view),
                                         new LayoutParams(LayoutParams.MATCH_PARENT,
                                                 mlp.topMargin, Gravity.START | Gravity.TOP));
                             } else {
@@ -3008,9 +3077,10 @@
                     mNavigationGuard = new View(mContext);
                     mNavigationGuard.setBackgroundColor(mContext.getResources()
                             .getColor(R.color.input_method_navigation_guard));
-                    addView(mNavigationGuard, indexOfChild(mNavigationColorView), new LayoutParams(
-                            LayoutParams.MATCH_PARENT, insets.getSystemWindowInsetBottom(),
-                            Gravity.START | Gravity.BOTTOM));
+                    addView(mNavigationGuard, indexOfChild(mNavigationColorViewState.view),
+                            new LayoutParams(LayoutParams.MATCH_PARENT,
+                                    insets.getSystemWindowInsetBottom(),
+                                    Gravity.START | Gravity.BOTTOM));
                 } else {
                     LayoutParams lp = (LayoutParams) mNavigationGuard.getLayoutParams();
                     lp.height = insets.getSystemWindowInsetBottom();
@@ -3912,7 +3982,7 @@
     protected void dispatchWindowAttributesChanged(WindowManager.LayoutParams attrs) {
         super.dispatchWindowAttributesChanged(attrs);
         if (mDecor != null) {
-            mDecor.updateColorViews(null /* insets */);
+            mDecor.updateColorViews(null /* insets */, true /* animate */);
         }
     }
 
@@ -4639,6 +4709,29 @@
         }
     }
 
+    private static class ColorViewState {
+        View view = null;
+        int targetVisibility = View.INVISIBLE;
+
+        final int id;
+        final int systemUiHideFlag;
+        final int translucentFlag;
+        final int verticalGravity;
+        final String transitionName;
+        final int hideWindowFlag;
+
+        ColorViewState(int systemUiHideFlag,
+                int translucentFlag, int verticalGravity,
+                String transitionName, int id, int hideWindowFlag) {
+            this.id = id;
+            this.systemUiHideFlag = systemUiHideFlag;
+            this.translucentFlag = translucentFlag;
+            this.verticalGravity = verticalGravity;
+            this.transitionName = transitionName;
+            this.hideWindowFlag = hideWindowFlag;
+        }
+    }
+
     void sendCloseSystemWindows() {
         PhoneWindowManager.sendCloseSystemWindows(getContext(), null);
     }
@@ -4657,7 +4750,7 @@
         mStatusBarColor = color;
         mForcedStatusBarColor = true;
         if (mDecor != null) {
-            mDecor.updateColorViews(null);
+            mDecor.updateColorViews(null, false /* animate */);
         }
     }
 
@@ -4671,7 +4764,7 @@
         mNavigationBarColor = color;
         mForcedNavigationBarColor = true;
         if (mDecor != null) {
-            mDecor.updateColorViews(null);
+            mDecor.updateColorViews(null, false /* animate */);
         }
     }
 }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 1ac956a..dea9932 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -319,6 +319,7 @@
     // handler thread.  We'll need to resolve this someday by teaching the input dispatcher
     // to hold wakelocks during dispatch and eliminating the critical path.
     volatile boolean mPowerKeyHandled;
+    volatile boolean mBeganFromNonInteractive;
     volatile int mPowerKeyPressCounter;
     volatile boolean mEndCallKeyHandled;
 
@@ -882,15 +883,13 @@
                             ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
                 }
             } else {
-                // When non-interactive, we ordinarily wake up immediately and
-                // consume the key.  However on some devices we need to support multi-press
-                // without waking so we will delay handling for later in that case
-                // (at the cost of increased latency).
+                wakeUpFromPowerKey(event.getDownTime());
                 final int maxCount = getMaxMultiPressPowerCount();
+
                 if (maxCount <= 1) {
-                    // No other actions.  We can wake immediately.
-                    wakeUpFromPowerKey(event.getDownTime());
                     mPowerKeyHandled = true;
+                } else {
+                    mBeganFromNonInteractive = true;
                 }
             }
         }
@@ -927,6 +926,7 @@
     }
 
     private void finishPowerKeyPress() {
+        mBeganFromNonInteractive = false;
         mPowerKeyPressCounter = 0;
         if (mPowerKeyWakeLock.isHeld()) {
             mPowerKeyWakeLock.release();
@@ -951,9 +951,7 @@
             powerMultiPressAction(eventTime, interactive, mDoublePressOnPowerBehavior);
         } else if (count == 3) {
             powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior);
-        } else if (!interactive) {
-            wakeUpFromPowerKey(eventTime);
-        } else {
+        } else if (interactive && !mBeganFromNonInteractive) {
             switch (mShortPressOnPowerBehavior) {
                 case SHORT_PRESS_POWER_NOTHING:
                     break;
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 8b524dd..08c47dc 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -75,6 +75,12 @@
     // warning message.  The time duration is in milliseconds.
     private static final long LATE_ALARM_THRESHOLD = 10 * 1000;
 
+    // Minimum futurity of a new alarm
+    private static final long MIN_FUTURITY = 5 * 1000;  // 5 seconds, in millis
+
+    // Minimum alarm recurrence interval
+    private static final long MIN_INTERVAL = 60 * 1000;  // one minute, in millis
+
     private static final int RTC_WAKEUP_MASK = 1 << RTC_WAKEUP;
     private static final int RTC_MASK = 1 << RTC;
     private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP;
@@ -696,6 +702,15 @@
             windowLength = AlarmManager.INTERVAL_HOUR;
         }
 
+        // Sanity check the recurrence interval.  This will catch people who supply
+        // seconds when the API expects milliseconds.
+        if (interval > 0 && interval < MIN_INTERVAL) {
+            Slog.w(TAG, "Suspiciously short interval " + interval
+                    + " millis; expanding to " + (int)(MIN_INTERVAL/1000)
+                    + " seconds");
+            interval = MIN_INTERVAL;
+        }
+
         if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) {
             throw new IllegalArgumentException("Invalid alarm type " + type);
         }
@@ -709,7 +724,11 @@
         }
 
         final long nowElapsed = SystemClock.elapsedRealtime();
-        final long triggerElapsed = convertToElapsed(triggerAtTime, type);
+        final long nominalTrigger = convertToElapsed(triggerAtTime, type);
+        // Try to prevent spamming by making sure we aren't firing alarms in the immediate future
+        final long minTrigger = nowElapsed + MIN_FUTURITY;
+        final long triggerElapsed = (nominalTrigger > minTrigger) ? nominalTrigger : minTrigger;
+
         final long maxElapsed;
         if (windowLength == AlarmManager.WINDOW_EXACT) {
             maxElapsed = triggerElapsed;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 5997680..17889ea 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2813,9 +2813,8 @@
     }
 
     /**
-     * Prepare for a VPN application. This method is used by VpnDialogs
-     * and not available in ConnectivityManager. Permissions are checked
-     * in Vpn class.
+     * Prepare for a VPN application. This method is used by system-privileged apps.
+     * Permissions are checked in Vpn class.
      * @hide
      */
     @Override
@@ -2829,8 +2828,8 @@
 
     /**
      * Set whether the current VPN package has the ability to launch VPNs without
-     * user intervention. This method is used by system UIs and not available
-     * in ConnectivityManager. Permissions are checked in Vpn class.
+     * user intervention. This method is used by system-privileged apps.
+     * Permissions are checked in Vpn class.
      * @hide
      */
     @Override
@@ -3247,7 +3246,7 @@
             Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, enable ? 1 : 0);
             Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
             intent.putExtra("state", enable);
-            mContext.sendBroadcast(intent);
+            mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java
index de90aa2..17edb53 100644
--- a/services/core/java/com/android/server/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/PersistentDataBlockService.java
@@ -41,6 +41,9 @@
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
 
 /**
  * Service for reading and writing blocks to a persistent partition.
@@ -63,22 +66,16 @@
     private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
     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 = 0x1990;
+    private static final int PARTITION_TYPE_MARKER = 0x19901873;
     // Limit to 100k as blocks larger than this might cause strain on Binder.
-    // TODO(anmorales): Consider splitting up too-large blocks in PersistentDataBlockManager
     private static final int MAX_DATA_BLOCK_SIZE = 1024 * 100;
+    public static final int DIGEST_SIZE_BYTES = 32;
 
     private final Context mContext;
     private final String mDataBlockFile;
     private final Object mLock = new Object();
 
     private int mAllowedUid = -1;
-    /*
-     * Separate lock for OEM unlock related operations as they can happen in parallel with regular
-     * block operations.
-     */
-    private final Object mOemLock = new Object();
-
     private long mBlockDeviceSize;
 
     public PersistentDataBlockService(Context context) {
@@ -89,7 +86,6 @@
         mAllowedUid = getAllowedUid(UserHandle.USER_OWNER);
     }
 
-
     private int getAllowedUid(int userHandle) {
         String allowedPackage = mContext.getResources()
                 .getString(R.string.config_persistentDataPackageName);
@@ -106,6 +102,7 @@
 
     @Override
     public void onStart() {
+        enforceChecksumValidity();
         publishBinderService(Context.PERSISTENT_DATA_BLOCK_SERVICE, mService);
     }
 
@@ -128,6 +125,9 @@
     }
 
     private int getTotalDataSizeLocked(DataInputStream inputStream) throws IOException {
+        // skip over checksum
+        inputStream.skipBytes(DIGEST_SIZE_BYTES);
+
         int totalDataSize;
         int blockId = inputStream.readInt();
         if (blockId == PARTITION_TYPE_MARKER) {
@@ -148,6 +148,143 @@
         return mBlockDeviceSize;
     }
 
+    private boolean enforceChecksumValidity() {
+        byte[] storedDigest = new byte[DIGEST_SIZE_BYTES];
+
+        synchronized (mLock) {
+            byte[] digest = computeDigestLocked(storedDigest);
+            if (digest == null || !Arrays.equals(storedDigest, digest)) {
+                Slog.i(TAG, "Formatting FRP partition...");
+                formatPartitionLocked();
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private boolean computeAndWriteDigestLocked() {
+        byte[] digest = computeDigestLocked(null);
+        if (digest != null) {
+            DataOutputStream outputStream;
+            try {
+                outputStream = new DataOutputStream(
+                        new FileOutputStream(new File(mDataBlockFile)));
+            } catch (FileNotFoundException e) {
+                Slog.e(TAG, "partition not available?", e);
+                return false;
+            }
+
+            try {
+                outputStream.write(digest, 0, DIGEST_SIZE_BYTES);
+                outputStream.flush();
+            } catch (IOException e) {
+                Slog.e(TAG, "failed to write block checksum", e);
+                return false;
+            } finally {
+                IoUtils.closeQuietly(outputStream);
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private byte[] computeDigestLocked(byte[] storedDigest) {
+        DataInputStream inputStream;
+        try {
+            inputStream = new DataInputStream(new FileInputStream(new File(mDataBlockFile)));
+        } catch (FileNotFoundException e) {
+            Slog.e(TAG, "partition not available?", e);
+            return null;
+        }
+
+        MessageDigest md;
+        try {
+            md = MessageDigest.getInstance("SHA-256");
+        } catch (NoSuchAlgorithmException e) {
+            // won't ever happen -- every implementation is required to support SHA-256
+            Slog.e(TAG, "SHA-256 not supported?", e);
+            IoUtils.closeQuietly(inputStream);
+            return null;
+        }
+
+        try {
+            if (storedDigest != null && storedDigest.length == DIGEST_SIZE_BYTES) {
+                inputStream.read(storedDigest);
+            } else {
+                inputStream.skipBytes(DIGEST_SIZE_BYTES);
+            }
+
+            int read;
+            byte[] data = new byte[1024];
+            md.update(data, 0, DIGEST_SIZE_BYTES); // include 0 checksum in digest
+            while ((read = inputStream.read(data)) != -1) {
+                md.update(data, 0, read);
+            }
+        } catch (IOException e) {
+            Slog.e(TAG, "failed to read partition", e);
+            return null;
+        } finally {
+            IoUtils.closeQuietly(inputStream);
+        }
+
+        return md.digest();
+    }
+
+    private void formatPartitionLocked() {
+        DataOutputStream outputStream;
+        try {
+            outputStream = new DataOutputStream(new FileOutputStream(new File(mDataBlockFile)));
+        } catch (FileNotFoundException e) {
+            Slog.e(TAG, "partition not available?", e);
+            return;
+        }
+
+        byte[] data = new byte[DIGEST_SIZE_BYTES];
+        try {
+            outputStream.write(data, 0, DIGEST_SIZE_BYTES);
+            outputStream.writeInt(PARTITION_TYPE_MARKER);
+            outputStream.writeInt(0); // data size
+            outputStream.flush();
+        } catch (IOException e) {
+            Slog.e(TAG, "failed to format block", e);
+            return;
+        } finally {
+            IoUtils.closeQuietly(outputStream);
+        }
+
+        doSetOemUnlockEnabledLocked(false);
+        computeAndWriteDigestLocked();
+    }
+
+    private void doSetOemUnlockEnabledLocked(boolean enabled) {
+        FileOutputStream outputStream;
+        try {
+            outputStream = new FileOutputStream(new File(mDataBlockFile));
+        } catch (FileNotFoundException e) {
+            Slog.e(TAG, "partition not available", e);
+            return;
+        }
+
+        try {
+            FileChannel channel = outputStream.getChannel();
+
+            channel.position(getBlockDeviceSize() - 1);
+
+            ByteBuffer data = ByteBuffer.allocate(1);
+            data.put(enabled ? (byte) 1 : (byte) 0);
+            data.flip();
+            channel.write(data);
+            outputStream.flush();
+        } catch (IOException e) {
+            Slog.e(TAG, "unable to access persistent partition", e);
+            return;
+        } finally {
+            IoUtils.closeQuietly(outputStream);
+        }
+    }
+
     private native long nativeGetBlockDeviceSize(String path);
     private native int nativeWipe(String path);
 
@@ -176,19 +313,23 @@
             headerAndData.putInt(data.length);
             headerAndData.put(data);
 
-            try {
-                synchronized (mLock) {
-                    outputStream.write(headerAndData.array());
-                    return data.length;
-                }
-            } catch (IOException e) {
-                Slog.e(TAG, "failed writing to the persistent data block", e);
-                return -1;
-            } finally {
+            synchronized (mLock) {
                 try {
-                    outputStream.close();
+                    byte[] checksum = new byte[DIGEST_SIZE_BYTES];
+                    outputStream.write(checksum, 0, DIGEST_SIZE_BYTES);
+                    outputStream.write(headerAndData.array());
+                    outputStream.flush();
                 } catch (IOException e) {
-                    Slog.e(TAG, "failed closing output stream", e);
+                    Slog.e(TAG, "failed writing to the persistent data block", e);
+                    return -1;
+                } finally {
+                    IoUtils.closeQuietly(outputStream);
+                }
+
+                if (computeAndWriteDigestLocked()) {
+                    return data.length;
+                } else {
+                    return -1;
                 }
             }
         }
@@ -196,6 +337,9 @@
         @Override
         public byte[] read() {
             enforceUid(Binder.getCallingUid());
+            if (!enforceChecksumValidity()) {
+                return new byte[0];
+            }
 
             DataInputStream inputStream;
             try {
@@ -256,30 +400,10 @@
             }
             enforceOemUnlockPermission();
             enforceIsOwner();
-            FileOutputStream outputStream;
-            try {
-                outputStream = new FileOutputStream(new File(mDataBlockFile));
-            } catch (FileNotFoundException e) {
-                Slog.e(TAG, "parition not available", e);
-                return;
-            }
 
-            try {
-                FileChannel channel = outputStream.getChannel();
-
-                channel.position(getBlockDeviceSize() - 1);
-
-                ByteBuffer data = ByteBuffer.allocate(1);
-                data.put(enabled ? (byte) 1 : (byte) 0);
-                data.flip();
-
-                synchronized (mOemLock) {
-                    channel.write(data);
-                }
-            } catch (IOException e) {
-                Slog.e(TAG, "unable to access persistent partition", e);
-            } finally {
-                IoUtils.closeQuietly(outputStream);
+            synchronized (mLock) {
+                doSetOemUnlockEnabledLocked(enabled);
+                computeAndWriteDigestLocked();
             }
         }
 
@@ -295,8 +419,8 @@
             }
 
             try {
-                inputStream.skip(getBlockDeviceSize() - 1);
-                synchronized (mOemLock) {
+                synchronized (mLock) {
+                    inputStream.skip(getBlockDeviceSize() - 1);
                     return inputStream.readByte() != 0;
                 }
             } catch (IOException e) {
@@ -336,6 +460,5 @@
             long actualSize = getBlockDeviceSize() - HEADER_SIZE - 1;
             return actualSize <= MAX_DATA_BLOCK_SIZE ? actualSize : MAX_DATA_BLOCK_SIZE;
         }
-
     };
 }
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index f4fb519..92fbc1e 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import android.app.ActivityManager;
 import android.content.pm.FeatureInfo;
 import android.os.*;
 import android.os.Process;
@@ -177,6 +178,8 @@
             return;
         }
 
+        final boolean lowRam = ActivityManager.isLowRamDeviceStatic();
+
         try {
             XmlPullParser parser = Xml.newPullParser();
             parser.setInput(permReader);
@@ -276,10 +279,17 @@
 
                 } else if ("feature".equals(name)) {
                     String fname = parser.getAttributeValue(null, "name");
+                    boolean allowed;
+                    if (!lowRam) {
+                        allowed = true;
+                    } else {
+                        String notLowRam = parser.getAttributeValue(null, "notLowRam");
+                        allowed = !"true".equals(notLowRam);
+                    }
                     if (fname == null) {
                         Slog.w(TAG, "<feature> without name at "
                                 + parser.getPositionDescription());
-                    } else {
+                    } else if (allowed) {
                         //Log.i(TAG, "Got feature " + fname);
                         FeatureInfo fi = new FeatureInfo();
                         fi.name = fname;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6d9f0c5..f0fb9e6 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -61,7 +61,6 @@
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.app.ProcessMap;
 import com.android.internal.app.ProcessStats;
-import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.BatteryStatsImpl;
 import com.android.internal.os.ProcessCpuTracker;
@@ -796,7 +795,11 @@
 
         @Override
         public int hashCode() {
-            return toString().hashCode();
+            int hashCode = 1;
+            hashCode = 31 * hashCode + sourceUserId;
+            hashCode = 31 * hashCode + uri.hashCode();
+            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
+            return hashCode;
         }
 
         @Override
@@ -835,10 +838,12 @@
      * indirect content-provider access.
      */
     private class Identity {
-        public int pid;
-        public int uid;
+        public final IBinder token;
+        public final int pid;
+        public final int uid;
 
-        Identity(int _pid, int _uid) {
+        Identity(IBinder _token, int _pid, int _uid) {
+            token = _token;
             pid = _pid;
             uid = _uid;
         }
@@ -1832,99 +1837,6 @@
         }
     };
 
-    /**
-     * Monitor for package changes and update our internal state.
-     */
-    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
-        @Override
-        public void onPackageRemoved(String packageName, int uid) {
-            // Remove all tasks with activities in the specified package from the list of recent tasks
-            final int eventUserId = getChangingUserId();
-            synchronized (ActivityManagerService.this) {
-                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
-                    TaskRecord tr = mRecentTasks.get(i);
-                    if (tr.userId != eventUserId) continue;
-
-                    ComponentName cn = tr.intent.getComponent();
-                    if (cn != null && cn.getPackageName().equals(packageName)) {
-                        // If the package name matches, remove the task
-                        removeTaskByIdLocked(tr.taskId, true);
-                    }
-                }
-            }
-        }
-
-        @Override
-        public boolean onPackageChanged(String packageName, int uid, String[] components) {
-            onPackageModified(packageName);
-            return true;
-        }
-
-        @Override
-        public void onPackageModified(String packageName) {
-            final int eventUserId = getChangingUserId();
-            final IPackageManager pm = AppGlobals.getPackageManager();
-            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
-                    new ArrayList<Pair<Intent, Integer>>();
-            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
-            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
-            // Copy the list of recent tasks so that we don't hold onto the lock on
-            // ActivityManagerService for long periods while checking if components exist.
-            synchronized (ActivityManagerService.this) {
-                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
-                    TaskRecord tr = mRecentTasks.get(i);
-                    if (tr.userId != eventUserId) continue;
-
-                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
-                }
-            }
-            // Check the recent tasks and filter out all tasks with components that no longer exist.
-            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
-                Pair<Intent, Integer> p = recentTaskIntents.get(i);
-                ComponentName cn = p.first.getComponent();
-                if (cn != null && cn.getPackageName().equals(packageName)) {
-                    if (componentsKnownToExist.contains(cn)) {
-                        // If we know that the component still exists in the package, then skip
-                        continue;
-                    }
-                    try {
-                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
-                        if (info != null) {
-                            componentsKnownToExist.add(cn);
-                        } else {
-                            tasksToRemove.add(p.second);
-                        }
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
-                    }
-                }
-            }
-            // Prune all the tasks with removed components from the list of recent tasks
-            synchronized (ActivityManagerService.this) {
-                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
-                    removeTaskByIdLocked(tasksToRemove.get(i), false);
-                }
-            }
-        }
-
-        @Override
-        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
-            // Force stop the specified packages
-            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-            if (packages != null) {
-                for (String pkg : packages) {
-                    synchronized (ActivityManagerService.this) {
-                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
-                                userId, "finished booting")) {
-                            return true;
-                        }
-                    }
-                }
-            }
-            return false;
-        }
-    };
-
     public void setSystemProcess() {
         try {
             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
@@ -2365,15 +2277,19 @@
      * process when the bindApplication() IPC is sent to the process. They're
      * lazily setup to make sure the services are running when they're asked for.
      */
-    private HashMap<String, IBinder> getCommonServicesLocked() {
+    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
         if (mAppBindArgs == null) {
-            mAppBindArgs = new HashMap<String, IBinder>();
+            mAppBindArgs = new HashMap<>();
 
-            // Setup the application init args
-            mAppBindArgs.put("package", ServiceManager.getService("package"));
-            mAppBindArgs.put("window", ServiceManager.getService("window"));
-            mAppBindArgs.put(Context.ALARM_SERVICE,
-                    ServiceManager.getService(Context.ALARM_SERVICE));
+            // Isolated processes won't get this optimization, so that we don't
+            // violate the rules about which services they have access to.
+            if (!isolated) {
+                // Setup the application init args
+                mAppBindArgs.put("package", ServiceManager.getService("package"));
+                mAppBindArgs.put("window", ServiceManager.getService("window"));
+                mAppBindArgs.put(Context.ALARM_SERVICE,
+                        ServiceManager.getService(Context.ALARM_SERVICE));
+            }
         }
         return mAppBindArgs;
     }
@@ -5996,7 +5912,8 @@
                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                     isRestrictedBackupMode || !normalMode, app.persistent,
-                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
+                    new Configuration(mConfiguration), app.compat,
+                    getCommonServicesLocked(app.isolated),
                     mCoreSettingsObserver.getCoreSettingsLocked());
             updateLruProcessLocked(app, false, null);
             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
@@ -6172,8 +6089,26 @@
             }
         }
 
-        // Register receivers to handle package update events
-        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
+        IntentFilter pkgFilter = new IntentFilter();
+        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
+        pkgFilter.addDataScheme("package");
+        mContext.registerReceiver(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
+                if (pkgs != null) {
+                    for (String pkg : pkgs) {
+                        synchronized (ActivityManagerService.this) {
+                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
+                                    0, "finished booting")) {
+                                setResultCode(Activity.RESULT_OK);
+                                return;
+                            }
+                        }
+                    }
+                }
+            }
+        }, pkgFilter);
 
         // Let system services know.
         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
@@ -6332,7 +6267,7 @@
             synchronized (this) {
                 ActivityStack stack = ActivityRecord.getStackLocked(token);
                 if (stack != null) {
-                    stack.backgroundResourcesReleased(token);
+                    stack.backgroundResourcesReleased();
                 }
             }
         } finally {
@@ -6798,21 +6733,9 @@
      */
     int checkComponentPermission(String permission, int pid, int uid,
             int owningUid, boolean exported) {
-        // We might be performing an operation on behalf of an indirect binder
-        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
-        // client identity accordingly before proceeding.
-        Identity tlsIdentity = sCallerIdentity.get();
-        if (tlsIdentity != null) {
-            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
-                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
-            uid = tlsIdentity.uid;
-            pid = tlsIdentity.pid;
-        }
-
         if (pid == MY_PID) {
             return PackageManager.PERMISSION_GRANTED;
         }
-
         return ActivityManager.checkComponentPermission(permission, uid,
                 owningUid, exported);
     }
@@ -6834,6 +6757,26 @@
         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
     }
 
+    @Override
+    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
+        if (permission == null) {
+            return PackageManager.PERMISSION_DENIED;
+        }
+
+        // We might be performing an operation on behalf of an indirect binder
+        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
+        // client identity accordingly before proceeding.
+        Identity tlsIdentity = sCallerIdentity.get();
+        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
+            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
+                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
+            uid = tlsIdentity.uid;
+            pid = tlsIdentity.pid;
+        }
+
+        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
+    }
+
     /**
      * Binder IPC calls go through the public entry point.
      * This can be called with or without the global lock held.
@@ -7039,13 +6982,13 @@
      */
     @Override
     public int checkUriPermission(Uri uri, int pid, int uid,
-            final int modeFlags, int userId) {
+            final int modeFlags, int userId, IBinder callerToken) {
         enforceNotIsolatedCaller("checkUriPermission");
 
         // Another redirected-binder-call permissions check as in
-        // {@link checkComponentPermission}.
+        // {@link checkPermissionWithToken}.
         Identity tlsIdentity = sCallerIdentity.get();
-        if (tlsIdentity != null) {
+        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
             uid = tlsIdentity.uid;
             pid = tlsIdentity.pid;
         }
@@ -8407,6 +8350,47 @@
         }
     }
 
+    private void removeTasksByPackageNameLocked(String packageName, int userId) {
+        // Remove all tasks with activities in the specified package from the list of recent tasks
+        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
+            TaskRecord tr = mRecentTasks.get(i);
+            if (tr.userId != userId) continue;
+
+            ComponentName cn = tr.intent.getComponent();
+            if (cn != null && cn.getPackageName().equals(packageName)) {
+                // If the package name matches, remove the task.
+                removeTaskByIdLocked(tr.taskId, true);
+            }
+        }
+    }
+
+    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
+        final IPackageManager pm = AppGlobals.getPackageManager();
+        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
+
+        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
+            TaskRecord tr = mRecentTasks.get(i);
+            if (tr.userId != userId) continue;
+
+            ComponentName cn = tr.intent.getComponent();
+            if (cn != null && cn.getPackageName().equals(packageName)) {
+                // Skip if component still exists in the package.
+                if (componentsKnownToExist.contains(cn)) continue;
+
+                try {
+                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
+                    if (info != null) {
+                        componentsKnownToExist.add(cn);
+                    } else {
+                        removeTaskByIdLocked(tr.taskId, false);
+                    }
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
+                }
+            }
+        }
+    }
+
     /**
      * Removes the task with the specified task id.
      *
@@ -9911,10 +9895,11 @@
             // we do the check against the caller's permissions even though it looks
             // to the content provider like the Activity Manager itself is making
             // the request.
+            Binder token = new Binder();
             sCallerIdentity.set(new Identity(
-                    Binder.getCallingPid(), Binder.getCallingUid()));
+                    token, Binder.getCallingPid(), Binder.getCallingUid()));
             try {
-                pfd = cph.provider.openFile(null, uri, "r", null);
+                pfd = cph.provider.openFile(null, uri, "r", null, token);
             } catch (FileNotFoundException e) {
                 // do nothing; pfd will be returned null
             } finally {
@@ -15674,126 +15659,133 @@
             }
         }
 
-        // Handle special intents: if this broadcast is from the package
-        // manager about a package being removed, we need to remove all of
-        // its activities from the history stack.
-        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
-                intent.getAction());
-        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
-                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
-                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
-                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
-                || uidRemoved) {
-            if (checkComponentPermission(
-                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
-                    callingPid, callingUid, -1, true)
-                    == PackageManager.PERMISSION_GRANTED) {
-                if (uidRemoved) {
-                    final Bundle intentExtras = intent.getExtras();
-                    final int uid = intentExtras != null
-                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
-                    if (uid >= 0) {
-                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
-                        synchronized (bs) {
-                            bs.removeUidStatsLocked(uid);
-                        }
-                        mAppOpsService.uidRemoved(uid);
+        final String action = intent.getAction();
+        if (action != null) {
+            switch (action) {
+                case Intent.ACTION_UID_REMOVED:
+                case Intent.ACTION_PACKAGE_REMOVED:
+                case Intent.ACTION_PACKAGE_CHANGED:
+                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
+                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
+                    // Handle special intents: if this broadcast is from the package
+                    // manager about a package being removed, we need to remove all of
+                    // its activities from the history stack.
+                    if (checkComponentPermission(
+                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
+                            callingPid, callingUid, -1, true)
+                            != PackageManager.PERMISSION_GRANTED) {
+                        String msg = "Permission Denial: " + intent.getAction()
+                                + " broadcast from " + callerPackage + " (pid=" + callingPid
+                                + ", uid=" + callingUid + ")"
+                                + " requires "
+                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
+                        Slog.w(TAG, msg);
+                        throw new SecurityException(msg);
                     }
-                } else {
-                    // If resources are unavailable just force stop all
-                    // those packages and flush the attribute cache as well.
-                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
-                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
-                        if (list != null && (list.length > 0)) {
-                            for (String pkg : list) {
-                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
-                                        "storage unmount");
+                    switch (action) {
+                        case Intent.ACTION_UID_REMOVED:
+                            final Bundle intentExtras = intent.getExtras();
+                            final int uid = intentExtras != null
+                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
+                            if (uid >= 0) {
+                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
+                                synchronized (bs) {
+                                    bs.removeUidStatsLocked(uid);
+                                }
+                                mAppOpsService.uidRemoved(uid);
                             }
+                            break;
+                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
+                            // If resources are unavailable just force stop all those packages
+                            // and flush the attribute cache as well.
+                            String list[] =
+                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+                            if (list != null && list.length > 0) {
+                                for (int i = 0; i < list.length; i++) {
+                                    forceStopPackageLocked(list[i], -1, false, true, true,
+                                            false, false, userId, "storage unmount");
+                                }
+                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
+                                sendPackageBroadcastLocked(
+                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
+                                        userId);
+                            }
+                            break;
+                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
                             cleanupRecentTasksLocked(UserHandle.USER_ALL);
-                            sendPackageBroadcastLocked(
-                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
-                        }
-                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
-                            intent.getAction())) {
-                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
-                    } else {
-                        Uri data = intent.getData();
-                        String ssp;
-                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
-                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
-                                    intent.getAction());
-                            boolean fullUninstall = removed &&
-                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
-                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
-                                forceStopPackageLocked(ssp, UserHandle.getAppId(
-                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
-                                        false, fullUninstall, userId,
-                                        removed ? "pkg removed" : "pkg changed");
-                            }
-                            if (removed) {
-                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
-                                        new String[] {ssp}, userId);
-                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
-                                    mAppOpsService.packageRemoved(
-                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
+                            break;
+                        case Intent.ACTION_PACKAGE_REMOVED:
+                        case Intent.ACTION_PACKAGE_CHANGED:
+                            Uri data = intent.getData();
+                            String ssp;
+                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
+                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
+                                boolean fullUninstall = removed &&
+                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
+                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
+                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
+                                            false, true, true, false, fullUninstall, userId,
+                                            removed ? "pkg removed" : "pkg changed");
+                                }
+                                if (removed) {
+                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
+                                            new String[] {ssp}, userId);
+                                    if (fullUninstall) {
+                                        mAppOpsService.packageRemoved(
+                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
 
-                                    // Remove all permissions granted from/to this package
-                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
+                                        // Remove all permissions granted from/to this package
+                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
+
+                                        removeTasksByPackageNameLocked(ssp, userId);
+                                    }
+                                } else {
+                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
                                 }
                             }
+                            break;
+                    }
+                    break;
+                case Intent.ACTION_PACKAGE_ADDED:
+                    // Special case for adding a package: by default turn on compatibility mode.
+                    Uri data = intent.getData();
+                    String ssp;
+                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
+                        final boolean replacing =
+                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
+
+                        if (replacing) {
+                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
                         }
                     }
-                }
-            } else {
-                String msg = "Permission Denial: " + intent.getAction()
-                        + " broadcast from " + callerPackage + " (pid=" + callingPid
-                        + ", uid=" + callingUid + ")"
-                        + " requires "
-                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
-                Slog.w(TAG, msg);
-                throw new SecurityException(msg);
+                    break;
+                case Intent.ACTION_TIMEZONE_CHANGED:
+                    // If this is the time zone changed action, queue up a message that will reset
+                    // the timezone of all currently running processes. This message will get
+                    // queued up before the broadcast happens.
+                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
+                    break;
+                case Intent.ACTION_TIME_CHANGED:
+                    // If the user set the time, let all running processes know.
+                    final int is24Hour =
+                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
+                                    : 0;
+                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
+                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
+                    synchronized (stats) {
+                        stats.noteCurrentTimeChangedLocked();
+                    }
+                    break;
+                case Intent.ACTION_CLEAR_DNS_CACHE:
+                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
+                    break;
+                case Proxy.PROXY_CHANGE_ACTION:
+                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
+                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
+                    break;
             }
-
-        // Special case for adding a package: by default turn on compatibility
-        // mode.
-        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
-            Uri data = intent.getData();
-            String ssp;
-            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
-                mCompatModePackages.handlePackageAddedLocked(ssp,
-                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
-            }
-        }
-
-        /*
-         * If this is the time zone changed action, queue up a message that will reset the timezone
-         * of all currently running processes. This message will get queued up before the broadcast
-         * happens.
-         */
-        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
-            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
-        }
-
-        /*
-         * If the user set the time, let all running processes know.
-         */
-        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
-            final int is24Hour = intent.getBooleanExtra(
-                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
-            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
-            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
-            synchronized (stats) {
-                stats.noteCurrentTimeChangedLocked();
-            }
-        }
-
-        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
-            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
-        }
-
-        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
-            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
-            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
         }
 
         // Add to the sticky list if requested.
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 3a1fafe..c8b7205 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3317,17 +3317,18 @@
                 mHandler.sendEmptyMessageDelayed(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG, 500);
             } else {
                 Slog.e(TAG, "releaseBackgroundResources: activity " + r + " no longer running");
-                backgroundResourcesReleased(r.appToken);
+                backgroundResourcesReleased();
             }
         }
     }
 
-    final void backgroundResourcesReleased(IBinder token) {
+    final void backgroundResourcesReleased() {
         mHandler.removeMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG);
         final ActivityRecord r = getVisibleBehindActivity();
         if (r != null) {
             mStackSupervisor.mStoppingActivities.add(r);
             setVisibleBehindActivity(null);
+            mStackSupervisor.scheduleIdleTimeoutLocked(null);
         }
         mStackSupervisor.resumeTopActivitiesLocked();
     }
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index 576556b..3fa21d0 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -63,8 +63,8 @@
     //  - Idle: start() not called. Everything is null.
     //  - Starting: start() called. Interfaces are non-null. isStarted() returns true.
     //    mIsRunning is false.
-    //  - Running: start() called, and interfaceAdded() told us that mIface is up. Clat IP address
-    //    is non-null. mIsRunning is true.
+    //  - Running: start() called, and interfaceLinkStateChanged() told us that mIface is up.
+    //    mIsRunning is true.
     //
     // Once mIface is non-null and isStarted() is true, methods called by ConnectivityService on
     // its handler thread must not modify any internal state variables; they are only updated by the
@@ -236,10 +236,10 @@
     }
 
     @Override
-    public void interfaceAdded(String iface) {
+    public void interfaceLinkStateChanged(String iface, boolean up) {
         // Called by the InterfaceObserver on its own thread, so can race with stop().
-        if (isStarted() && mIface.equals(iface)) {
-            Slog.i(TAG, "interface " + iface + " added, mIsRunning " + mIsRunning + "->true");
+        if (isStarted() && up && mIface.equals(iface)) {
+            Slog.i(TAG, "interface " + iface + " is up, mIsRunning " + mIsRunning + "->true");
 
             if (!mIsRunning) {
                 LinkAddress clatAddress = getLinkAddress(iface);
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 83756aa..03c05ec 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -23,6 +23,7 @@
 import static android.system.OsConstants.AF_INET;
 import static android.system.OsConstants.AF_INET6;
 
+import android.Manifest;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
@@ -739,31 +740,7 @@
     };
 
     private void enforceControlPermission() {
-        // System user is allowed to control VPN.
-        if (Binder.getCallingUid() == Process.SYSTEM_UID) {
-            return;
-        }
-        int appId = UserHandle.getAppId(Binder.getCallingUid());
-        final long token = Binder.clearCallingIdentity();
-        try {
-            // System VPN dialogs are also allowed to control VPN.
-            PackageManager pm = mContext.getPackageManager();
-            ApplicationInfo app = pm.getApplicationInfo(VpnConfig.DIALOGS_PACKAGE, 0);
-            if (((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) && (appId == app.uid)) {
-                return;
-            }
-            // SystemUI dialogs are also allowed to control VPN.
-            ApplicationInfo sysUiApp = pm.getApplicationInfo("com.android.systemui", 0);
-            if (((sysUiApp.flags & ApplicationInfo.FLAG_SYSTEM) != 0) && (appId == sysUiApp.uid)) {
-                return;
-            }
-        } catch (Exception e) {
-            // ignore
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-
-        throw new SecurityException("Unauthorized Caller");
+        mContext.enforceCallingPermission(Manifest.permission.CONTROL_VPN, "Unauthorized Caller");
     }
 
     private class Connection implements ServiceConnection {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 0cdb4d5..ec38124 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -798,7 +798,7 @@
     }
 
     boolean isSystemAudioActivated() {
-        if (getAvrDeviceInfo() == null) {
+        if (!hasSystemAudioDevice()) {
             return false;
         }
         synchronized (mLock) {
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 921b68b..9440697 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -90,6 +90,7 @@
     private final SessionStub mSession;
     private final SessionCb mSessionCb;
     private final MediaSessionService mService;
+    private final boolean mUseMasterVolume;
 
     private final Object mLock = new Object();
     private final ArrayList<ISessionControllerCallback> mControllerCallbacks =
@@ -139,6 +140,8 @@
         mAudioManager = (AudioManager) service.getContext().getSystemService(Context.AUDIO_SERVICE);
         mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
         mAudioAttrs = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
+        mUseMasterVolume = service.getContext().getResources().getBoolean(
+                com.android.internal.R.bool.config_useMasterVolume);
     }
 
     /**
@@ -248,6 +251,12 @@
             direction = -1;
         }
         if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
+            if (mUseMasterVolume) {
+                // If this device only uses master volume and playback is local
+                // just adjust the master volume and return.
+                mAudioManagerInternal.adjustMasterVolumeForUid(direction, flags, packageName, uid);
+                return;
+            }
             int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
             if (useSuggested) {
                 if (AudioSystem.isStreamActive(stream, 0)) {
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index ba18f48..98a3970 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -86,6 +86,7 @@
     private final Object mLock = new Object();
     private final MessageHandler mHandler = new MessageHandler();
     private final PowerManager.WakeLock mMediaEventWakeLock;
+    private final boolean mUseMasterVolume;
 
     private KeyguardManager mKeyguardManager;
     private IAudioService mAudioService;
@@ -104,6 +105,8 @@
         mPriorityStack = new MediaSessionStack();
         PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mMediaEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleMediaEvent");
+        mUseMasterVolume = context.getResources().getBoolean(
+                com.android.internal.R.bool.config_useMasterVolume);
     }
 
     @Override
@@ -819,8 +822,13 @@
                     return;
                 }
                 try {
-                    mAudioService.adjustSuggestedStreamVolume(direction, suggestedStream, flags,
-                            getContext().getOpPackageName());
+                    if (mUseMasterVolume) {
+                        mAudioService.adjustMasterVolume(direction, flags,
+                                getContext().getOpPackageName());
+                    } else {
+                        mAudioService.adjustSuggestedStreamVolume(direction, suggestedStream, flags,
+                                getContext().getOpPackageName());
+                    }
                 } catch (RemoteException e) {
                     Log.e(TAG, "Error adjusting default volume.", e);
                 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 42a8551..6958ff8 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1931,12 +1931,7 @@
             if (hasValidSound) {
                 boolean looping =
                         (notification.flags & Notification.FLAG_INSISTENT) != 0;
-                AudioAttributes audioAttributes;
-                if (notification.audioAttributes != null) {
-                    audioAttributes = notification.audioAttributes;
-                } else {
-                    audioAttributes = Notification.AUDIO_ATTRIBUTES_DEFAULT;
-                }
+                AudioAttributes audioAttributes = audioAttributesForNotification(notification);
                 mSoundNotification = record;
                 // do not play notifications if stream volume is 0 (typically because
                 // ringer mode is silent) or if there is a user of exclusive audio focus
@@ -2030,7 +2025,9 @@
     }
 
     private static AudioAttributes audioAttributesForNotification(Notification n) {
-        if (n.audioAttributes != null) {
+        if (n.audioAttributes != null
+                && !Notification.AUDIO_ATTRIBUTES_DEFAULT.equals(n.audioAttributes)) {
+            // the audio attributes are set and different from the default, use them
             return n.audioAttributes;
         } else if (n.audioStreamType >= 0 && n.audioStreamType < AudioSystem.getNumStreamTypes()) {
             // the stream type is valid, use it
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index 4906bd1..57b204d 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -232,6 +232,12 @@
             mTrustManagerService.mArchive.logAgentConnected(mUserId, name);
             setCallback(mCallback);
             updateDevicePolicyFeatures();
+
+            if (mTrustManagerService.isDeviceLockedInner(mUserId)) {
+                onDeviceLocked();
+            } else {
+                onDeviceUnlocked();
+            }
         }
 
         @Override
@@ -287,6 +293,7 @@
             onError(e);
         }
     }
+
     /**
      * @see android.service.trust.TrustAgentService#onUnlockAttempt(boolean)
      */
@@ -298,6 +305,28 @@
         }
     }
 
+    /**
+     * @see android.service.trust.TrustAgentService#onDeviceLocked()
+     */
+    public void onDeviceLocked() {
+        try {
+            if (mTrustAgentService != null) mTrustAgentService.onDeviceLocked();
+        } catch (RemoteException e) {
+            onError(e);
+        }
+    }
+
+    /**
+     * @see android.service.trust.TrustAgentService#onDeviceUnlocked()
+     */
+    public void onDeviceUnlocked() {
+        try {
+            if (mTrustAgentService != null) mTrustAgentService.onDeviceUnlocked();
+        } catch (RemoteException e) {
+            onError(e);
+        }
+    }
+
     private void setCallback(ITrustAgentServiceCallback callback) {
         try {
             if (mTrustAgentService != null) {
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 2388c85..a2ea1c8 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -26,7 +26,6 @@
 
 import android.Manifest;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.admin.DevicePolicyManager;
 import android.app.trust.ITrustListener;
 import android.app.trust.ITrustManager;
@@ -61,6 +60,8 @@
 import android.util.Slog;
 import android.util.SparseBooleanArray;
 import android.util.Xml;
+import android.view.IWindowManager;
+import android.view.WindowManagerGlobal;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -96,6 +97,10 @@
     private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
     private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
     private static final int MSG_REQUIRE_CREDENTIAL_ENTRY = 5;
+    private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6;
+    private static final int MSG_START_USER = 7;
+    private static final int MSG_CLEANUP_USER = 8;
+    private static final int MSG_SWITCH_USER = 9;
 
     private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<AgentInfo>();
     private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<ITrustListener>();
@@ -110,7 +115,11 @@
     @GuardedBy("mUserIsTrusted")
     private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
 
+    @GuardedBy("mDeviceLockedForUser")
+    private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
+
     private boolean mTrustAgentsCanRun = false;
+    private int mCurrentUser = UserHandle.USER_OWNER;
 
     public TrustManagerService(Context context) {
         super(context);
@@ -177,10 +186,15 @@
     public void updateTrust(int userId, boolean initiatedByUser) {
         dispatchOnTrustManagedChanged(aggregateIsTrustManaged(userId), userId);
         boolean trusted = aggregateIsTrusted(userId);
+        boolean changed;
         synchronized (mUserIsTrusted) {
+            changed = mUserIsTrusted.get(userId) != trusted;
             mUserIsTrusted.put(userId, trusted);
         }
         dispatchOnTrustChanged(trusted, userId, initiatedByUser);
+        if (changed) {
+            refreshDeviceLockedForUser(userId);
+        }
     }
 
     void refreshAgentList(int userId) {
@@ -212,8 +226,7 @@
                     || userInfo.guestToRemove) continue;
             if (!userInfo.supportsSwitchTo()) continue;
             if (!mActivityManager.isUserRunning(userInfo.id)) continue;
-            if (lockPatternUtils.getKeyguardStoredPasswordQuality(userInfo.id)
-                    == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) continue;
+            if (!lockPatternUtils.isSecure(userInfo.id)) continue;
             if (!mUserHasAuthenticatedSinceBoot.get(userInfo.id)) continue;
             DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
             int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
@@ -273,6 +286,73 @@
         }
     }
 
+    boolean isDeviceLockedInner(int userId) {
+        synchronized (mDeviceLockedForUser) {
+            return mDeviceLockedForUser.get(userId, true);
+        }
+    }
+
+    private void refreshDeviceLockedForUser(int userId) {
+        if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_OWNER) {
+            Log.e(TAG, "refreshAgentList(userId=" + userId + "): Invalid user handle,"
+                    + " 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 */);
+        } else {
+            userInfos = new ArrayList<>();
+            userInfos.add(mUserManager.getUserInfo(userId));
+        }
+
+        IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+
+        for (int i = 0; i < userInfos.size(); i++) {
+            UserInfo info = userInfos.get(i);
+
+            if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
+                    || !info.supportsSwitchTo()) {
+                continue;
+            }
+
+            int id = info.id;
+            boolean secure = mLockPatternUtils.isSecure(id);
+            boolean trusted = aggregateIsTrusted(id);
+            boolean showingKeyguard = true;
+            if (mCurrentUser == id) {
+                try {
+                    showingKeyguard = wm.isKeyguardLocked();
+                } catch (RemoteException e) {
+                }
+            }
+            boolean deviceLocked = secure && showingKeyguard && !trusted;
+
+            boolean changed;
+            synchronized (mDeviceLockedForUser) {
+                changed = isDeviceLockedInner(id) != deviceLocked;
+                mDeviceLockedForUser.put(id, deviceLocked);
+            }
+            if (changed) {
+                dispatchDeviceLocked(id, deviceLocked);
+            }
+        }
+    }
+
+    private void dispatchDeviceLocked(int userId, boolean isLocked) {
+        for (int i = 0; i < mActiveAgents.size(); i++) {
+            AgentInfo agent = mActiveAgents.valueAt(i);
+            if (agent.userId == userId) {
+                if (isLocked) {
+                    agent.agent.onDeviceLocked();
+                } else{
+                    agent.agent.onDeviceUnlocked();
+                }
+            }
+        }
+    }
+
     void updateDevicePolicyFeatures() {
         for (int i = 0; i < mActiveAgents.size(); i++) {
             AgentInfo info = mActiveAgents.valueAt(i);
@@ -540,12 +620,17 @@
 
     @Override
     public void onStartUser(int userId) {
-        refreshAgentList(userId);
+        mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
     }
 
     @Override
     public void onCleanupUser(int userId) {
-        refreshAgentList(userId);
+        mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
+    }
+
+    @Override
+    public void onSwitchUser(int userId) {
+        mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
     }
 
     // Plumbing
@@ -578,6 +663,14 @@
         }
 
         @Override
+        public void reportKeyguardShowingChanged() throws RemoteException {
+            enforceReportPermission();
+            // coalesce refresh messages.
+            mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
+            mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
+        }
+
+        @Override
         public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
             enforceListenerPermission();
             mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
@@ -590,13 +683,12 @@
         }
 
         @Override
-        public boolean isTrusted(int userId) throws RemoteException {
+        public boolean isDeviceLocked(int userId) throws RemoteException {
             userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
-                    false /* allowAll */, true /* requireFull */, "isTrusted", null);
+                    false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
             userId = resolveProfileParent(userId);
-            synchronized (mUserIsTrusted) {
-                return mUserIsTrusted.get(userId);
-            }
+
+            return isDeviceLockedInner(userId);
         }
 
         private void enforceReportPermission() {
@@ -621,19 +713,13 @@
                 fout.println("disabled because the third-party apps can't run yet.");
                 return;
             }
-            final UserInfo currentUser;
             final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
-            try {
-                currentUser = ActivityManagerNative.getDefault().getCurrentUser();
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
             mHandler.runWithScissors(new Runnable() {
                 @Override
                 public void run() {
                     fout.println("Trust manager state:");
                     for (UserInfo user : userInfos) {
-                        dumpUser(fout, user, user.id == currentUser.id);
+                        dumpUser(fout, user, user.id == mCurrentUser);
                     }
                 }
             }, 1500);
@@ -642,11 +728,17 @@
         private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
             fout.printf(" User \"%s\" (id=%d, flags=%#x)",
                     user.name, user.id, user.flags);
+            if (!user.supportsSwitchTo()) {
+                fout.println("(managed profile)");
+                fout.println("   disabled because switching to this user is not possible.");
+                return;
+            }
             if (isCurrent) {
                 fout.print(" (current)");
             }
             fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
             fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
+            fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
             fout.println();
             fout.println("   Enabled agents:");
             boolean duplicateSimpleNames = false;
@@ -711,10 +803,23 @@
                     break;
                 case MSG_ENABLED_AGENTS_CHANGED:
                     refreshAgentList(UserHandle.USER_ALL);
+                    // This is also called when the security mode of a user changes.
+                    refreshDeviceLockedForUser(UserHandle.USER_ALL);
                     break;
                 case MSG_REQUIRE_CREDENTIAL_ENTRY:
                     requireCredentialEntry(msg.arg1);
                     break;
+                case MSG_KEYGUARD_SHOWING_CHANGED:
+                    refreshDeviceLockedForUser(UserHandle.USER_CURRENT);
+                    break;
+                case MSG_START_USER:
+                case MSG_CLEANUP_USER:
+                    refreshAgentList(msg.arg1);
+                    break;
+                case MSG_SWITCH_USER:
+                    mCurrentUser = msg.arg1;
+                    refreshDeviceLockedForUser(UserHandle.USER_ALL);
+                    break;
             }
         }
     };
@@ -756,8 +861,14 @@
                 int userId = getUserId(intent);
                 if (userId > 0) {
                     mUserHasAuthenticatedSinceBoot.delete(userId);
-                    mUserIsTrusted.delete(userId);
+                    synchronized (mUserIsTrusted) {
+                        mUserIsTrusted.delete(userId);
+                    }
+                    synchronized (mDeviceLockedForUser) {
+                        mDeviceLockedForUser.delete(userId);
+                    }
                     refreshAgentList(userId);
+                    refreshDeviceLockedForUser(userId);
                 }
             }
         }
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 85659cf..716487c 100644
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -299,6 +299,13 @@
         return -1;
     }
 
+    private static boolean intArrayContains(int[] array, int value) {
+        for (int element : array) {
+            if (element == value) return true;
+        }
+        return false;
+    }
+
     public void addHdmiTvInput(int id, TvInputInfo info) {
         if (info.getType() != TvInputInfo.TYPE_HDMI) {
             throw new IllegalArgumentException("info (" + info + ") has non-HDMI type.");
@@ -673,28 +680,35 @@
                 if (mReleased) {
                     throw new IllegalStateException("Device already released.");
                 }
-                if (surface != null && config == null) {
-                    return false;
-                }
-                if (surface == null && mActiveConfig == null) {
-                    return false;
-                }
 
-                int result = TvInputHal.ERROR_UNKNOWN;
+                int result = TvInputHal.SUCCESS;
                 if (surface == null) {
-                    result = mHal.removeStream(mInfo.getDeviceId(), mActiveConfig);
-                    mActiveConfig = null;
+                    // The value of config is ignored when surface == null.
+                    if (mActiveConfig != null) {
+                        result = mHal.removeStream(mInfo.getDeviceId(), mActiveConfig);
+                        mActiveConfig = null;
+                    } else {
+                        // We already have no active stream.
+                        return true;
+                    }
                 } else {
-                    if (!config.equals(mActiveConfig)) {
+                    // It's impossible to set a non-null surface with a null config.
+                    if (config == null) {
+                        return false;
+                    }
+                    // Remove stream only if we have an existing active configuration.
+                    if (mActiveConfig != null && !config.equals(mActiveConfig)) {
                         result = mHal.removeStream(mInfo.getDeviceId(), mActiveConfig);
                         if (result != TvInputHal.SUCCESS) {
                             mActiveConfig = null;
-                            return false;
                         }
                     }
-                    result = mHal.addOrUpdateStream(mInfo.getDeviceId(), surface, config);
+                    // Proceed only if all previous operations succeeded.
                     if (result == TvInputHal.SUCCESS) {
-                        mActiveConfig = config;
+                        result = mHal.addOrUpdateStream(mInfo.getDeviceId(), surface, config);
+                        if (result == TvInputHal.SUCCESS) {
+                            mActiveConfig = config;
+                        }
                     }
                 }
                 updateAudioConfigLocked();
@@ -755,20 +769,64 @@
             AudioPortConfig sinkConfig = mAudioSink.activeConfig();
             AudioPatch[] audioPatchArray = new AudioPatch[] { mAudioPatch };
             boolean shouldRecreateAudioPatch = sourceUpdated || sinkUpdated;
+
+            int sinkSamplingRate = mDesiredSamplingRate;
+            int sinkChannelMask = mDesiredChannelMask;
+            int sinkFormat = mDesiredFormat;
+            // If sinkConfig != null and values are set to default, fill in the sinkConfig values.
+            if (sinkConfig != null) {
+                if (sinkSamplingRate == 0) {
+                    sinkSamplingRate = sinkConfig.samplingRate();
+                }
+                if (sinkChannelMask == AudioFormat.CHANNEL_OUT_DEFAULT) {
+                    sinkChannelMask = sinkConfig.channelMask();
+                }
+                if (sinkFormat == AudioFormat.ENCODING_DEFAULT) {
+                    sinkChannelMask = sinkConfig.format();
+                }
+            }
+
             if (sinkConfig == null
-                    || (mDesiredSamplingRate != 0
-                            && sinkConfig.samplingRate() != mDesiredSamplingRate)
-                    || (mDesiredChannelMask != AudioFormat.CHANNEL_OUT_DEFAULT
-                            && sinkConfig.channelMask() != mDesiredChannelMask)
-                    || (mDesiredFormat != AudioFormat.ENCODING_DEFAULT
-                            && sinkConfig.format() != mDesiredFormat)) {
-                sinkConfig = mAudioSink.buildConfig(mDesiredSamplingRate, mDesiredChannelMask,
-                        mDesiredFormat, null);
+                    || sinkConfig.samplingRate() != sinkSamplingRate
+                    || sinkConfig.channelMask() != sinkChannelMask
+                    || sinkConfig.format() != sinkFormat) {
+                // Check for compatibility and reset to default if necessary.
+                if (!intArrayContains(mAudioSink.samplingRates(), sinkSamplingRate)
+                        && mAudioSink.samplingRates().length > 0) {
+                    sinkSamplingRate = mAudioSink.samplingRates()[0];
+                }
+                if (!intArrayContains(mAudioSink.channelMasks(), sinkChannelMask)) {
+                    sinkChannelMask = AudioFormat.CHANNEL_OUT_DEFAULT;
+                }
+                if (!intArrayContains(mAudioSink.formats(), sinkFormat)) {
+                    sinkFormat = AudioFormat.ENCODING_DEFAULT;
+                }
+                sinkConfig = mAudioSink.buildConfig(sinkSamplingRate, sinkChannelMask,
+                        sinkFormat, null);
                 shouldRecreateAudioPatch = true;
             }
             if (sourceConfig == null || sourceGainConfig != null) {
-                sourceConfig = mAudioSource.buildConfig(sinkConfig.samplingRate(),
-                        sinkConfig.channelMask(), sinkConfig.format(), sourceGainConfig);
+                int sourceSamplingRate = 0;
+                if (intArrayContains(mAudioSource.samplingRates(), sinkConfig.samplingRate())) {
+                    sourceSamplingRate = sinkConfig.samplingRate();
+                } else if (mAudioSource.samplingRates().length > 0) {
+                    // Use any sampling rate and hope audio patch can handle resampling...
+                    sourceSamplingRate = mAudioSource.samplingRates()[0];
+                }
+                int sourceChannelMask = AudioFormat.CHANNEL_IN_DEFAULT;
+                for (int inChannelMask : mAudioSource.channelMasks()) {
+                    if (AudioFormat.channelCountFromOutChannelMask(sinkConfig.channelMask())
+                            == AudioFormat.channelCountFromInChannelMask(inChannelMask)) {
+                        sourceChannelMask = inChannelMask;
+                        break;
+                    }
+                }
+                int sourceFormat = AudioFormat.ENCODING_DEFAULT;
+                if (intArrayContains(mAudioSource.formats(), sinkConfig.format())) {
+                    sourceFormat = sinkConfig.format();
+                }
+                sourceConfig = mAudioSource.buildConfig(sourceSamplingRate, sourceChannelMask,
+                        sourceFormat, sourceGainConfig);
                 shouldRecreateAudioPatch = true;
             }
             if (shouldRecreateAudioPatch) {
@@ -778,6 +836,9 @@
                         new AudioPortConfig[] { sourceConfig },
                         new AudioPortConfig[] { sinkConfig });
                 mAudioPatch = audioPatchArray[0];
+                if (sourceGainConfig != null) {
+                    mAudioManager.setAudioPortGain(mAudioSource, sourceGainConfig);
+                }
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 7e6da8b5..0cbf03a 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -992,12 +992,6 @@
                         continue;
                     }
 
-                    // If the window is an accessibility overlay - ignore.
-                    if (windowState.mAttrs.type ==
-                            WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
-                        continue;
-                    }
-
                     // Compute the bounds in the screen.
                     final Rect boundsInScreen = mTempRect;
                     computeWindowBoundsInScreen(windowState, boundsInScreen);
@@ -1018,8 +1012,14 @@
                         }
                     }
 
-                    unaccountedSpace.op(boundsInScreen, unaccountedSpace,
-                            Region.Op.REVERSE_DIFFERENCE);
+                    // Account for the space this window takes if the window
+                    // is not an accessibility overlay which does not change
+                    // the reported windows.
+                    if (windowState.mAttrs.type !=
+                            WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
+                        unaccountedSpace.op(boundsInScreen, unaccountedSpace,
+                                Region.Op.REVERSE_DIFFERENCE);
+                    }
 
                     // We figured out what is touchable for the entire screen - done.
                     if (unaccountedSpace.isEmpty()) {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 1086eb2..f859fd2 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -254,15 +254,18 @@
 
     @Override
     void removeAllWindows() {
-        int winNdx;
-        while ((winNdx = allAppWindows.size()) > 0) {
-            WindowState win = allAppWindows.get(winNdx - 1);
+        for (int winNdx = allAppWindows.size() - 1; winNdx >= 0;
+                // removeWindowLocked at bottom of loop may remove multiple entries from
+                // allAppWindows if the window to be removed has child windows. It also may
+                // not remove any windows from allAppWindows at all if win is exiting and
+                // currently animating away. This ensures that winNdx is monotonically decreasing
+                // and never beyond allAppWindows bounds.
+                winNdx = Math.min(winNdx - 1, allAppWindows.size() - 1)) {
+            WindowState win = allAppWindows.get(winNdx);
             if (WindowManagerService.DEBUG_WINDOW_MOVEMENT) {
                 Slog.w(WindowManagerService.TAG, "removeAllWindows: removing win=" + win);
             }
 
-            // {@link WindowManagerService.removeWindowLocked} may remove multiple entries from
-            // {@link #allAppWindows} if the window to be removed has child windows.
             win.mService.removeWindowLocked(win.mSession, win);
         }
     }
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 345e8af..fe2e0a6 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -221,6 +221,24 @@
         }
     }
 
+    private boolean shouldForceHide(WindowState win) {
+        final WindowState imeTarget = mService.mInputMethodTarget;
+        final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleNow() &&
+                (imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0;
+
+        final WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw();
+        final AppWindowToken appShowWhenLocked = winShowWhenLocked == null ?
+                null : winShowWhenLocked.mAppToken;
+        final boolean hideWhenLocked =
+                !(((win.mIsImWindow || imeTarget == win) && showImeOverKeyguard)
+                        || (appShowWhenLocked != null && (appShowWhenLocked == win.mAppToken ||
+                        // Show error dialogs over apps that dismiss keyguard.
+                        (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0)));
+        return ((mForceHiding == KEYGUARD_ANIMATING_IN)
+                && (!win.mWinAnimator.isAnimating() || hideWhenLocked))
+                || ((mForceHiding == KEYGUARD_SHOWN) && hideWhenLocked);
+    }
+
     private void updateWindowsLocked(final int displayId) {
         ++mAnimTransactionSequence;
 
@@ -256,14 +274,6 @@
 
         mForceHiding = KEYGUARD_NOT_SHOWN;
 
-        final WindowState imeTarget = mService.mInputMethodTarget;
-        final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleNow() &&
-                (imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0;
-
-        final WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw();
-        final AppWindowToken appShowWhenLocked = winShowWhenLocked == null ?
-                null : winShowWhenLocked.mAppToken;
-
         boolean wallpaperInUnForceHiding = false;
         boolean startingInUnForceHiding = false;
         ArrayList<WindowStateAnimator> unForceHiding = null;
@@ -272,7 +282,8 @@
             WindowState win = windows.get(i);
             WindowStateAnimator winAnimator = win.mWinAnimator;
             final int flags = win.mAttrs.flags;
-
+            boolean canBeForceHidden = mPolicy.canBeForceHidden(win, win.mAttrs);
+            boolean shouldBeForceHidden = shouldForceHide(win);
             if (winAnimator.mSurfaceControl != null) {
                 final boolean wasAnimating = winAnimator.mWasAnimating;
                 final boolean nowAnimating = winAnimator.stepAnimationLocked(mCurrentTime);
@@ -332,15 +343,8 @@
                             + " vis=" + win.mViewVisibility
                             + " hidden=" + win.mRootToken.hidden
                             + " anim=" + win.mWinAnimator.mAnimation);
-                } else if (mPolicy.canBeForceHidden(win, win.mAttrs)) {
-                    final boolean hideWhenLocked =
-                            !(((win.mIsImWindow || imeTarget == win) && showImeOverKeyguard)
-                            || (appShowWhenLocked != null && (appShowWhenLocked == win.mAppToken ||
-                            // Show error dialogs over apps that dismiss keyguard.
-                            (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0)));
-                    if (((mForceHiding == KEYGUARD_ANIMATING_IN)
-                                && (!winAnimator.isAnimating() || hideWhenLocked))
-                            || ((mForceHiding == KEYGUARD_SHOWN) && hideWhenLocked)) {
+                } else if (canBeForceHidden) {
+                    if (shouldBeForceHidden) {
                         if (!win.hideLw(false, false)) {
                             // Was already hidden
                             continue;
@@ -411,6 +415,16 @@
                 }
             }
 
+            // If the window doesn't have a surface, the only thing we care about is the correct
+            // policy visibility.
+            else if (canBeForceHidden) {
+                if (shouldBeForceHidden) {
+                    win.hideLw(false, false);
+                } else {
+                    win.showLw(false, false);
+                }
+            }
+
             final AppWindowToken atoken = win.mAppToken;
             if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) {
                 if (atoken == null || atoken.allDrawn) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 9e51849..3b0a511 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -3923,7 +3923,7 @@
         final int n = policy.mAdminList.size();
         for (int i = 0; i < n; i++) {
             ActiveAdmin admin = policy.mAdminList.get(i);
-            if (profileOwner.equals(admin.info)) {
+            if (profileOwner.equals(admin.info.getComponent())) {
                 return admin;
             }
         }
@@ -5040,13 +5040,15 @@
 
     @Override
     public boolean isUninstallBlocked(ComponentName who, String packageName) {
+        // This function should return true if and only if the package is blocked by
+        // setUninstallBlocked(). It should still return false for other cases of blocks, such as
+        // when the package is a system app, or when it is an active device admin.
         final int userId = UserHandle.getCallingUserId();
 
         synchronized (this) {
-            if (who == null) {
-                throw new NullPointerException("ComponentName is null");
+            if (who != null) {
+                getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
             }
-            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
             long id = Binder.clearCallingIdentity();
             try {
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index c63eb18..23ba3b6 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -209,8 +209,13 @@
         mUseUsbNotification = !massStorageSupported;
 
         // make sure the ADB_ENABLED setting value matches the current state
-        Settings.Global.putInt(mContentResolver, Settings.Global.ADB_ENABLED, mAdbEnabled ? 1 : 0);
-
+        try {
+            Settings.Global.putInt(mContentResolver,
+                    Settings.Global.ADB_ENABLED, mAdbEnabled ? 1 : 0);
+        } catch (SecurityException e) {
+            // If UserManager.DISALLOW_DEBUGGING_FEATURES is on, that this setting can't be changed.
+            Slog.d(TAG, "ADB_ENABLED is restricted.");
+        }
         mHandler.sendEmptyMessage(MSG_SYSTEM_READY);
     }
 
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 82b7f8b..f5d4867 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -136,11 +136,14 @@
                     Settings.Secure.VOICE_INTERACTION_SERVICE, userHandle);
             ComponentName curRecognizer = getCurRecognizer(userHandle);
             VoiceInteractionServiceInfo curInteractorInfo = null;
-            if (curInteractorStr == null && curRecognizer != null) {
+            if (curInteractorStr == null && curRecognizer != null
+                    && !ActivityManager.isLowRamDeviceStatic()) {
                 // If there is no interactor setting, that means we are upgrading
                 // from an older platform version.  If the current recognizer is not
                 // set or matches the preferred recognizer, then we want to upgrade
                 // the user to have the default voice interaction service enabled.
+                // Note that we don't do this for low-RAM devices, since we aren't
+                // supporting voice interaction services there.
                 curInteractorInfo = findAvailInteractor(userHandle, curRecognizer);
                 if (curInteractorInfo != null) {
                     // Looks good!  We'll apply this one.  To make it happen, we clear the
@@ -150,6 +153,15 @@
                 }
             }
 
+            // If we are on a svelte device, make sure an interactor is not currently
+            // enabled; if it is, turn it off.
+            if (ActivityManager.isLowRamDeviceStatic() && curInteractorStr != null) {
+                if (!TextUtils.isEmpty(curInteractorStr)) {
+                    setCurInteractor(null, userHandle);
+                    curInteractorStr = "";
+                }
+            }
+
             if (curRecognizer != null) {
                 // If we already have at least a recognizer, then we probably want to
                 // leave things as they are...  unless something has disappeared.
@@ -171,10 +183,11 @@
                 }
             }
 
-            // Initializing settings, look for an interactor first.
-            if (curInteractorInfo == null) {
+            // Initializing settings, look for an interactor first (but only on non-svelte).
+            if (curInteractorInfo == null && !ActivityManager.isLowRamDeviceStatic()) {
                 curInteractorInfo = findAvailInteractor(userHandle, null);
             }
+
             if (curInteractorInfo != null) {
                 // Eventually it will be an error to not specify this.
                 setCurInteractor(new ComponentName(curInteractorInfo.getServiceInfo().packageName,
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index 215c682..6e404de 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -30,7 +30,7 @@
  * @hide
  */
 @SystemApi
-public abstract class Conference {
+public abstract class Conference implements IConferenceable {
 
     /** @hide */
     public abstract static class Listener {
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 63b44a6..fb63c85 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -47,7 +47,7 @@
  * @hide
  */
 @SystemApi
-public abstract class Connection {
+public abstract class Connection implements IConferenceable {
 
     public static final int STATE_INITIALIZING = 0;
 
@@ -82,8 +82,8 @@
                 Connection c, VideoProvider videoProvider) {}
         public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {}
         public void onStatusHintsChanged(Connection c, StatusHints statusHints) {}
-        public void onConferenceableConnectionsChanged(
-                Connection c, List<Connection> conferenceableConnections) {}
+        public void onConferenceablesChanged(
+                Connection c, List<IConferenceable> conferenceables) {}
         public void onConferenceChanged(Connection c, Conference conference) {}
         /** @hide */
         public void onConferenceParticipantsChanged(Connection c,
@@ -449,7 +449,16 @@
     private final Listener mConnectionDeathListener = new Listener() {
         @Override
         public void onDestroyed(Connection c) {
-            if (mConferenceableConnections.remove(c)) {
+            if (mConferenceables.remove(c)) {
+                fireOnConferenceableConnectionsChanged();
+            }
+        }
+    };
+
+    private final Conference.Listener mConferenceDeathListener = new Conference.Listener() {
+        @Override
+        public void onDestroyed(Conference c) {
+            if (mConferenceables.remove(c)) {
                 fireOnConferenceableConnectionsChanged();
             }
         }
@@ -462,9 +471,9 @@
      */
     private final Set<Listener> mListeners = Collections.newSetFromMap(
             new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
-    private final List<Connection> mConferenceableConnections = new ArrayList<>();
-    private final List<Connection> mUnmodifiableConferenceableConnections =
-            Collections.unmodifiableList(mConferenceableConnections);
+    private final List<IConferenceable> mConferenceables = new ArrayList<>();
+    private final List<IConferenceable> mUnmodifiableConferenceables =
+            Collections.unmodifiableList(mConferenceables);
 
     private int mState = STATE_NEW;
     private AudioState mAudioState;
@@ -864,19 +873,44 @@
         for (Connection c : conferenceableConnections) {
             // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
             // small amount of items here.
-            if (!mConferenceableConnections.contains(c)) {
+            if (!mConferenceables.contains(c)) {
                 c.addConnectionListener(mConnectionDeathListener);
-                mConferenceableConnections.add(c);
+                mConferenceables.add(c);
             }
         }
         fireOnConferenceableConnectionsChanged();
     }
 
     /**
-     * Returns the connections with which this connection can be conferenced.
+     * Similar to {@link #setConferenceableConnections(java.util.List)}, sets a list of connections
+     * or conferences with which this connection can be conferenced.
+     *
+     * @param conferenceables The conferenceables.
      */
-    public final List<Connection> getConferenceableConnections() {
-        return mUnmodifiableConferenceableConnections;
+    public final void setConferenceables(List<IConferenceable> conferenceables) {
+        clearConferenceableList();
+        for (IConferenceable c : conferenceables) {
+            // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
+            // small amount of items here.
+            if (!mConferenceables.contains(c)) {
+                if (c instanceof Connection) {
+                    Connection connection = (Connection) c;
+                    connection.addConnectionListener(mConnectionDeathListener);
+                } else if (c instanceof Conference) {
+                    Conference conference = (Conference) c;
+                    conference.addListener(mConferenceDeathListener);
+                }
+                mConferenceables.add(c);
+            }
+        }
+        fireOnConferenceableConnectionsChanged();
+    }
+
+    /**
+     * Returns the connections or conferences with which this connection can be conferenced.
+     */
+    public final List<IConferenceable> getConferenceables() {
+        return mUnmodifiableConferenceables;
     }
 
     /*
@@ -1109,7 +1143,7 @@
 
     private final void  fireOnConferenceableConnectionsChanged() {
         for (Listener l : mListeners) {
-            l.onConferenceableConnectionsChanged(this, getConferenceableConnections());
+            l.onConferenceablesChanged(this, getConferenceables());
         }
     }
 
@@ -1120,10 +1154,16 @@
     }
 
     private final void clearConferenceableList() {
-        for (Connection c : mConferenceableConnections) {
-            c.removeConnectionListener(mConnectionDeathListener);
+        for (IConferenceable c : mConferenceables) {
+            if (c instanceof Connection) {
+                Connection connection = (Connection) c;
+                connection.removeConnectionListener(mConnectionDeathListener);
+            } else if (c instanceof Conference) {
+                Conference conference = (Conference) c;
+                conference.removeListener(mConferenceDeathListener);
+            }
         }
-        mConferenceableConnections.clear();
+        mConferenceables.clear();
     }
 
     /**
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 48e6ff3..08f3853 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -515,11 +515,11 @@
         }
 
         @Override
-        public void onConferenceableConnectionsChanged(
-                Connection connection, List<Connection> conferenceableConnections) {
+        public void onConferenceablesChanged(
+                Connection connection, List<IConferenceable> conferenceables) {
             mAdapter.setConferenceableConnections(
                     mIdByConnection.get(connection),
-                    createConnectionIdList(conferenceableConnections));
+                    createIdList(conferenceables));
         }
 
         @Override
@@ -602,7 +602,7 @@
                         connection.getAudioModeIsVoip(),
                         connection.getStatusHints(),
                         connection.getDisconnectCause(),
-                        createConnectionIdList(connection.getConferenceableConnections())));
+                        createIdList(connection.getConferenceables())));
     }
 
     private void abort(String callId) {
@@ -682,12 +682,19 @@
     private void conference(String callId1, String callId2) {
         Log.d(this, "conference %s, %s", callId1, callId2);
 
+        // Attempt to get second connection or conference.
         Connection connection2 = findConnectionForAction(callId2, "conference");
+        Conference conference2 = getNullConference();
         if (connection2 == getNullConnection()) {
-            Log.w(this, "Connection2 missing in conference request %s.", callId2);
-            return;
+            conference2 = findConferenceForAction(callId2, "conference");
+            if (conference2 == getNullConference()) {
+                Log.w(this, "Connection2 or Conference2 missing in conference request %s.",
+                        callId2);
+                return;
+            }
         }
 
+        // Attempt to get first connection or conference and perform merge.
         Connection connection1 = findConnectionForAction(callId1, "conference");
         if (connection1 == getNullConnection()) {
             Conference conference1 = findConferenceForAction(callId1, "addConnection");
@@ -696,10 +703,26 @@
                         "Connection1 or Conference1 missing in conference request %s.",
                         callId1);
             } else {
-                conference1.onMerge(connection2);
+                // Call 1 is a conference.
+                if (connection2 != getNullConnection()) {
+                    // Call 2 is a connection so merge via call 1 (conference).
+                    conference1.onMerge(connection2);
+                } else {
+                    // Call 2 is ALSO a conference; this should never happen.
+                    Log.wtf(this, "There can only be one conference and an attempt was made to " +
+                            "merge two conferences.");
+                    return;
+                }
             }
         } else {
-            onConference(connection1, connection2);
+            // Call 1 is a connection.
+            if (conference2 != getNullConference()) {
+                // Call 2 is a conference, so merge via call 2.
+                conference2.onMerge(connection1);
+            } else {
+                // Call 2 is a connection, so merge together.
+                onConference(connection1, connection2);
+            }
         }
     }
 
@@ -1111,6 +1134,33 @@
         return ids;
     }
 
+    /**
+     * Builds a list of {@link Connection} and {@link Conference} IDs based on the list of
+     * {@link IConferenceable}s passed in.
+     *
+     * @param conferenceables The {@link IConferenceable} connections and conferences.
+     * @return List of string conference and call Ids.
+     */
+    private List<String> createIdList(List<IConferenceable> conferenceables) {
+        List<String> ids = new ArrayList<>();
+        for (IConferenceable c : conferenceables) {
+            // Only allow Connection and Conference conferenceables.
+            if (c instanceof Connection) {
+                Connection connection = (Connection) c;
+                if (mIdByConnection.containsKey(connection)) {
+                    ids.add(mIdByConnection.get(connection));
+                }
+            } else if (c instanceof Conference) {
+                Conference conference = (Conference) c;
+                if (mIdByConference.containsKey(conference)) {
+                    ids.add(mIdByConference.get(conference));
+                }
+            }
+        }
+        Collections.sort(ids);
+        return ids;
+    }
+
     private Conference getNullConference() {
         if (sNullConference == null) {
             sNullConference = new Conference(null) {};
diff --git a/telecomm/java/android/telecom/IConferenceable.java b/telecomm/java/android/telecom/IConferenceable.java
new file mode 100644
index 0000000..095d7cb
--- /dev/null
+++ b/telecomm/java/android/telecom/IConferenceable.java
@@ -0,0 +1,31 @@
+/*
+ * 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.telecom;
+
+import android.annotation.SystemApi;
+
+/**
+ * Interface used to identify entities with which another entity can participate in a conference
+ * call with.  The {@link ConnectionService} implementation will only recognize
+ * {@link IConferenceable}s which are {@link Connection}s or {@link Conference}s.
+ *
+ * @hide
+ */
+@SystemApi
+public interface IConferenceable {
+
+}
diff --git a/telecomm/java/android/telecom/PhoneCapabilities.java b/telecomm/java/android/telecom/PhoneCapabilities.java
index feb7a95..c21a6d1 100644
--- a/telecomm/java/android/telecom/PhoneCapabilities.java
+++ b/telecomm/java/android/telecom/PhoneCapabilities.java
@@ -101,6 +101,16 @@
      */
     public static final int DISCONNECT_FROM_CONFERENCE = 0x00002000;
 
+    /**
+     * Whether the call is a generic conference, where we do not know the precise state of
+     * participants in the conference (eg. on CDMA).
+     *
+     * TODO: Move to CallProperties.
+     *
+     * @hide
+     */
+    public static final int GENERIC_CONFERENCE = 0x00004000;
+
     public static final int ALL = HOLD | SUPPORT_HOLD | MERGE_CONFERENCE | SWAP_CONFERENCE
             | RESPOND_VIA_TEXT | MUTE | MANAGE_CONFERENCE | SEPARATE_FROM_CONFERENCE
             | DISCONNECT_FROM_CONFERENCE;
@@ -163,6 +173,10 @@
         if (can(capabilities, VoWIFI)) {
             builder.append(" VoWIFI");
         }
+        if (can(capabilities, GENERIC_CONFERENCE)) {
+            builder.append(" GENERIC_CONFERENCE");
+        }
+
         builder.append("]");
         return builder.toString();
     }
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index 1891976..674777e 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -165,6 +165,22 @@
      */
     public static final int IMS_MERGED_SUCCESSFULLY = 45;
 
+    /**
+     * Stk Call Control modified DIAL request to USSD request.
+     * {@hide}
+     */
+    public static final int DIAL_MODIFIED_TO_USSD          = 46;
+    /**
+     * Stk Call Control modified DIAL request to SS request.
+     * {@hide}
+     */
+    public static final int DIAL_MODIFIED_TO_SS            = 47;
+    /**
+     * Stk Call Control modified DIAL request to DIAL with modified data.
+     * {@hide}
+     */
+    public static final int DIAL_MODIFIED_TO_DIAL          = 48;
+
     //*********************************************************************************************
     // When adding a disconnect type:
     // 1) Please assign the new type the next id value below.
@@ -173,14 +189,14 @@
     // 4) Update toString() with the newly added disconnect type.
     // 5) Update android.telecom.DisconnectCauseUtil with any mappings to a telecom.DisconnectCause.
     //
-    // NextId: 46
+    // NextId: 49
     //*********************************************************************************************
 
     /** Smallest valid value for call disconnect codes. */
     public static final int MINIMUM_VALID_VALUE = NOT_DISCONNECTED;
 
     /** Largest valid value for call disconnect codes. */
-    public static final int MAXIMUM_VALID_VALUE = IMS_MERGED_SUCCESSFULLY;
+    public static final int MAXIMUM_VALID_VALUE = DIAL_MODIFIED_TO_DIAL;
 
     /** Private constructor to avoid class instantiation. */
     private DisconnectCause() {
@@ -272,6 +288,12 @@
             return "CDMA_CALL_LOST";
         case EXITED_ECM:
             return "EXITED_ECM";
+        case DIAL_MODIFIED_TO_USSD:
+            return "DIAL_MODIFIED_TO_USSD";
+        case DIAL_MODIFIED_TO_SS:
+            return "DIAL_MODIFIED_TO_SS";
+        case DIAL_MODIFIED_TO_DIAL:
+            return "DIAL_MODIFIED_TO_DIAL";
         case ERROR_UNSPECIFIED:
             return "ERROR_UNSPECIFIED";
         case OUTGOING_FAILURE:
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 26f17c8..a3ace36 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -34,6 +34,11 @@
 public class SubscriptionInfo implements Parcelable {
 
     /**
+     * Size of text to render on the icon.
+     */
+    private static final int TEXT_SIZE = 22;
+
+    /**
      * Subscription Identifier, this is a device unique number
      * and not an index into an array
      */
@@ -201,10 +206,11 @@
         paint.setColorFilter(null);
 
         // Write the sim slot index.
+        paint.setAntiAlias(true);
         paint.setTypeface(Typeface.create("sans-serif", Typeface.NORMAL));
         paint.setColor(Color.WHITE);
-        paint.setTextSize(12);
-        final String index = Integer.toString(mSimSlotIndex);
+        paint.setTextSize(TEXT_SIZE);
+        final String index = Integer.toString(mSimSlotIndex + 1);
         final Rect textBound = new Rect();
         paint.getTextBounds(index, 0, 1, textBound);
         final float xOffset = (width / 2.f) - textBound.centerX();
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index b06d44c..7c03d42 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1797,10 +1797,9 @@
      * for display purpose only, for example, displayed in Phone Status. It won't
      * change the actual MSISDN/MDN. To unset alphatag or number, pass in a null
      * value.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
-     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
+     *
+     * <p>Requires that the calling app has carrier privileges.
+     * @see #hasCarrierPrivileges
      *
      * @param alphaTag alpha-tagging of the dailing nubmer
      * @param number The dialing number
@@ -1814,10 +1813,9 @@
      * for display purpose only, for example, displayed in Phone Status. It won't
      * change the actual MSISDN/MDN. To unset alphatag or number, pass in a null
      * value.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
-     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
+     *
+     * <p>Requires that the calling app has carrier privileges.
+     * @see #hasCarrierPrivileges
      *
      * @param subId the subscriber that the alphatag and dialing number belongs to.
      * @param alphaTag alpha-tagging of the dailing nubmer
@@ -1973,6 +1971,39 @@
     }
 
     /**
+     * Sets the voice mail number.
+     *
+     * <p>Requires that the calling app has carrier privileges.
+     * @see #hasCarrierPrivileges
+     *
+     * @param alphaTag The alpha tag to display.
+     * @param number The voicemail number.
+     */
+    public boolean setVoiceMailNumber(String alphaTag, String number) {
+        return setVoiceMailNumber(getDefaultSubscription(), alphaTag, number);
+    }
+
+    /**
+     * Sets the voicemail number for the given subscriber.
+     *
+     * <p>Requires that the calling app has carrier privileges.
+     * @see #hasCarrierPrivileges
+     *
+     * @param subId The subscriber id.
+     * @param alphaTag The alpha tag to display.
+     * @param number The voicemail number.
+     */
+    /** {@hide} */
+    public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
+        try {
+            return getITelephony().setVoiceMailNumber(subId, alphaTag, number);
+        } catch (RemoteException ex) {
+        } catch (NullPointerException ex) {
+        }
+        return false;
+    }
+
+    /**
      * Returns the voice mail count. Return 0 if unavailable.
      * <p>
      * Requires Permission:
@@ -3037,9 +3068,8 @@
      * Set the preferred network type to global mode which includes LTE, CDMA, EvDo and GSM/WCDMA.
      *
      * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
-     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
+     * Requires that the calling app has carrier privileges.
+     * @see #hasCarrierPrivileges
      *
      * @return true on success; false on any failure.
      */
@@ -3050,9 +3080,13 @@
     /**
      * Values used to return status for hasCarrierPrivileges call.
      */
+    /** @hide */
     public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1;
+    /** @hide */
     public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0;
+    /** @hide */
     public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1;
+    /** @hide */
     public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2;
 
     /**
@@ -3064,21 +3098,18 @@
      *
      * TODO: Add a link to documentation.
      *
-     * @return CARRIER_PRIVILEGE_STATUS_HAS_ACCESS if the app has carrier privileges.
-     *         CARRIER_PRIVILEGE_STATUS_NO_ACCESS if the app does not have carrier privileges.
-     *         CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED if the carrier rules are not loaded.
-     *         CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES if there was an error loading carrier
-     *             rules (or if there are no rules).
+     * @return true if the app has carrier privileges.
      */
-    public int hasCarrierPrivileges() {
+    public boolean hasCarrierPrivileges() {
         try {
-            return getITelephony().hasCarrierPrivileges();
+            return getITelephony().getCarrierPrivilegeStatus() ==
+                CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
         } catch (RemoteException ex) {
             Rlog.e(TAG, "hasCarrierPrivileges RemoteException", ex);
         } catch (NullPointerException ex) {
             Rlog.e(TAG, "hasCarrierPrivileges NPE", ex);
         }
-        return CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
+        return false;
     }
 
     /**
@@ -3089,9 +3120,8 @@
      * brand value input. To unset the value, the same function should be
      * called with a null brand value.
      *
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
-     *  or has to be carrier app - see #hasCarrierPrivileges.
+     * <p>Requires that the calling app has carrier privileges.
+     * @see #hasCarrierPrivileges
      *
      * @param brand The brand name to display/set.
      * @return true if the operation was executed correctly.
@@ -3153,9 +3183,9 @@
         try {
             return getITelephony().checkCarrierPrivilegesForPackage(pkgname);
         } catch (RemoteException ex) {
-            Rlog.e(TAG, "hasCarrierPrivileges RemoteException", ex);
+            Rlog.e(TAG, "checkCarrierPrivilegesForPackage RemoteException", ex);
         } catch (NullPointerException ex) {
-            Rlog.e(TAG, "hasCarrierPrivileges NPE", ex);
+            Rlog.e(TAG, "checkCarrierPrivilegesForPackage NPE", ex);
         }
         return CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
     }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index c50261d..adb3bc4 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -417,6 +417,11 @@
     boolean needsOtaServiceProvisioning();
 
     /**
+     * Sets the voicemail number for a particular subscriber.
+     */
+    boolean setVoiceMailNumber(int subId, String alphaTag, String number);
+
+    /**
       * Returns the unread count of voicemails
       */
     int getVoiceMessageCount();
@@ -708,7 +713,7 @@
      *
      * @return carrier privilege status defined in TelephonyManager.
      */
-    int hasCarrierPrivileges();
+    int getCarrierPrivilegeStatus();
 
     /**
      * Similar to above, but check for pkg whose name is pkgname.
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index b5e82e3..082e8bbb 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -24,6 +24,8 @@
  * Also they should all probably be static final.
  */
 
+import android.os.SystemProperties;
+
 /**
  * {@hide}
  */
@@ -57,7 +59,17 @@
                                                  retries needed */
     int MISSING_RESOURCE = 16;                /* no logical channel available */
     int NO_SUCH_ELEMENT = 17;                 /* application not found on SIM */
+    int DIAL_MODIFIED_TO_USSD = 18;           /* DIAL request modified to USSD */
+    int DIAL_MODIFIED_TO_SS = 19;             /* DIAL request modified to SS */
+    int DIAL_MODIFIED_TO_DIAL = 20;           /* DIAL request modified to DIAL with different data*/
+    int USSD_MODIFIED_TO_DIAL = 21;           /* USSD request modified to DIAL */
+    int USSD_MODIFIED_TO_SS = 22;             /* USSD request modified to SS */
+    int USSD_MODIFIED_TO_USSD = 23;           /* USSD request modified to different USSD request */
+    int SS_MODIFIED_TO_DIAL = 24;             /* SS request modified to DIAL */
+    int SS_MODIFIED_TO_USSD = 25;             /* SS request modified to USSD */
     int SUBSCRIPTION_NOT_SUPPORTED = 26;      /* Subscription not supported */
+    int SS_MODIFIED_TO_SS = 27;               /* SS request modified to different SS request */
+
 
     /* NETWORK_MODE_* See ril.h RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */
     int NETWORK_MODE_WCDMA_PREF     = 0; /* GSM/WCDMA (WCDMA preferred) */
@@ -76,7 +88,8 @@
     int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10; /* LTE, CDMA, EvDo, GSM/WCDMA */
     int NETWORK_MODE_LTE_ONLY       = 11; /* LTE Only mode. */
     int NETWORK_MODE_LTE_WCDMA      = 12; /* LTE/WCDMA */
-    int PREFERRED_NETWORK_MODE      = NETWORK_MODE_WCDMA_PREF;
+    int PREFERRED_NETWORK_MODE      = SystemProperties.getInt("ro.telephony.default_network",
+            NETWORK_MODE_WCDMA_PREF);
 
     int CDMA_CELL_BROADCAST_SMS_DISABLED = 1;
     int CDMA_CELL_BROADCAST_SMS_ENABLED  = 0;
@@ -339,4 +352,6 @@
     int RIL_UNSOL_HARDWARE_CONFIG_CHANGED = 1040;
     int RIL_UNSOL_DC_RT_INFO_CHANGED = 1041;
     int RIL_UNSOL_RADIO_CAPABILITY = 1042;
+    int RIL_UNSOL_ON_SS = 1043;
+    int RIL_UNSOL_STK_CC_ALPHA_NOTIFY = 1044;
 }
diff --git a/test-runner/src/android/test/mock/MockContentProvider.java b/test-runner/src/android/test/mock/MockContentProvider.java
index 28d52b0..5ef71df 100644
--- a/test-runner/src/android/test/mock/MockContentProvider.java
+++ b/test-runner/src/android/test/mock/MockContentProvider.java
@@ -91,8 +91,8 @@
 
         @Override
         public ParcelFileDescriptor openFile(
-                String callingPackage, Uri url, String mode, ICancellationSignal signal)
-                throws RemoteException, FileNotFoundException {
+                String callingPackage, Uri url, String mode, ICancellationSignal signal,
+                IBinder callerToken) throws RemoteException, FileNotFoundException {
             return MockContentProvider.this.openFile(url, mode);
         }
 
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index 46c81b6..3378872 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -37,6 +37,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Looper;
 import android.os.UserHandle;
 import android.view.DisplayAdjustments;
@@ -483,6 +484,12 @@
         throw new UnsupportedOperationException();
     }
 
+    /** @hide */
+    @Override
+    public int checkPermission(String permission, int pid, int uid, IBinder callerToken) {
+        return checkPermission(permission, pid, uid);
+    }
+
     @Override
     public int checkCallingPermission(String permission) {
         throw new UnsupportedOperationException();
@@ -524,6 +531,12 @@
         throw new UnsupportedOperationException();
     }
 
+    /** @hide */
+    @Override
+    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) {
+        return checkUriPermission(uri, pid, uid, modeFlags);
+    }
+
     @Override
     public int checkCallingUriPermission(Uri uri, int modeFlags) {
         throw new UnsupportedOperationException();
diff --git a/test-runner/src/android/test/mock/MockIContentProvider.java b/test-runner/src/android/test/mock/MockIContentProvider.java
index c0dc7c3..ee8c376 100644
--- a/test-runner/src/android/test/mock/MockIContentProvider.java
+++ b/test-runner/src/android/test/mock/MockIContentProvider.java
@@ -62,7 +62,8 @@
     }
 
     public ParcelFileDescriptor openFile(
-            String callingPackage, Uri url, String mode, ICancellationSignal signal) {
+            String callingPackage, Uri url, String mode, ICancellationSignal signal,
+            IBinder callerToken) {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
diff --git a/tests/ActivityTests/AndroidManifest.xml b/tests/ActivityTests/AndroidManifest.xml
index 3930fd6..513f622 100644
--- a/tests/ActivityTests/AndroidManifest.xml
+++ b/tests/ActivityTests/AndroidManifest.xml
@@ -57,6 +57,16 @@
         </service>
         <receiver android:name="UserTarget">
         </receiver>
+        <receiver android:name="StartEmpty" android:exported="true">
+            <intent-filter>
+                <action android:name="com.example.START_EMPTY" />
+            </intent-filter>
+        </receiver>
+        <service android:name="EmptyService" android:exported="true">
+            <intent-filter>
+                <action android:name="com.example.START_EMPTY" />
+            </intent-filter>
+        </service>
         <receiver android:name="SingleUserReceiver"
             android:singleUser="true" android:exported="true" >
         </receiver>
diff --git a/tests/ActivityTests/src/com/google/android/test/activity/EmptyService.java b/tests/ActivityTests/src/com/google/android/test/activity/EmptyService.java
new file mode 100644
index 0000000..1134d90
--- /dev/null
+++ b/tests/ActivityTests/src/com/google/android/test/activity/EmptyService.java
@@ -0,0 +1,35 @@
+/*
+ * 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.google.android.test.activity;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.util.Log;
+
+public class EmptyService extends Service {
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.i("StartEmpty", "STARTED!");
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+}
diff --git a/tests/ActivityTests/src/com/google/android/test/activity/StartEmpty.java b/tests/ActivityTests/src/com/google/android/test/activity/StartEmpty.java
new file mode 100644
index 0000000..5e74ead
--- /dev/null
+++ b/tests/ActivityTests/src/com/google/android/test/activity/StartEmpty.java
@@ -0,0 +1,29 @@
+/*
+ * 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.google.android.test.activity;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+public class StartEmpty extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        Log.i("StartEmpty", "STARTED!");
+    }
+}
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
index 89288bf..e4cbb2f 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
@@ -90,7 +90,7 @@
 
     @Override
     public ParcelFileDescriptor openFile(
-            String callingPackage, Uri arg0, String arg1, ICancellationSignal signal)
+            String callingPackage, Uri arg0, String arg1, ICancellationSignal signal, IBinder token)
             throws RemoteException, FileNotFoundException {
         // TODO Auto-generated method stub
         return null;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index aeb70e9..2c3736f 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -16,6 +16,7 @@
 
 package com.android.layoutlib.bridge.android;
 
+import android.os.IBinder;
 import com.android.annotations.Nullable;
 import com.android.ide.common.rendering.api.ILayoutPullParser;
 import com.android.ide.common.rendering.api.IProjectCallback;
@@ -938,12 +939,24 @@
     }
 
     @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
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 1393bce..6ddebde 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1968,7 +1968,7 @@
     /**
      * Start Wi-fi Protected Setup
      *
-     * @param config WPS configuration
+     * @param config WPS configuration (does not support {@link WpsInfo#LABEL})
      * @param listener for callbacks on success or failure. Can be null.
      * @throws IllegalStateException if the WifiManager instance needs to be
      * initialized again