Merge "Do not extract colors of live wallpapers." into oc-dr1-dev
diff --git a/Android.mk b/Android.mk
index 933ac62..55ea69a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -292,6 +292,7 @@
 	core/java/android/service/euicc/IGetEidCallback.aidl \
 	core/java/android/service/euicc/IGetEuiccInfoCallback.aidl \
 	core/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl \
+	core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl \
 	core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl \
 	core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl \
 	core/java/android/service/gatekeeper/IGateKeeperService.aidl \
diff --git a/api/system-current.txt b/api/system-current.txt
index 85e9175..34bba38 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -50268,6 +50268,7 @@
   }
 
   public abstract interface WindowManager implements android.view.ViewManager {
+    method public abstract android.graphics.Region getCurrentImeTouchRegion();
     method public abstract android.view.Display getDefaultDisplay();
     method public abstract void removeViewImmediate(android.view.View);
   }
diff --git a/cmds/vr/src/com/android/commands/vr/Vr.java b/cmds/vr/src/com/android/commands/vr/Vr.java
index b765866..8fb1b7b 100644
--- a/cmds/vr/src/com/android/commands/vr/Vr.java
+++ b/cmds/vr/src/com/android/commands/vr/Vr.java
@@ -41,6 +41,7 @@
         "set-persistent-vr-mode-enabled";
     private static final String COMMAND_SET_VR2D_DISPLAY_PROPERTIES =
         "set-display-props";
+    private static final String COMMAND_ENABLE_VD = "enable-virtual-display";
 
     private IVrManager mVrService;
 
@@ -49,7 +50,8 @@
         out.println(
                 "usage: vr [subcommand]\n" +
                 "usage: vr set-persistent-vr-mode-enabled [true|false]\n" +
-                "usage: vr set-display-props [width] [height] [dpi]\n"
+                "usage: vr set-display-props [width] [height] [dpi]\n" +
+                "usage: vr enable-virtual-display [true|false]\n"
                 );
     }
 
@@ -69,6 +71,9 @@
             case COMMAND_SET_PERSISTENT_VR_MODE_ENABLED:
                 runSetPersistentVrModeEnabled();
                 break;
+            case COMMAND_ENABLE_VD:
+                runEnableVd();
+                break;
             default:
                 throw new IllegalArgumentException ("unknown command '" + command + "'");
         }
@@ -94,6 +99,23 @@
         }
     }
 
+    private void runEnableVd() throws RemoteException {
+        Vr2dDisplayProperties.Builder builder = new Vr2dDisplayProperties.Builder();
+
+        String value = nextArgRequired();
+        if ("true".equals(value)) {
+            builder.setEnabled(true);
+        } else if ("false".equals(value)) {
+            builder.setEnabled(false);
+        } // Don't do anything if not exactly true/false
+
+        try {
+            mVrService.setVr2dDisplayProperties(builder.build());
+        } catch (RemoteException re) {
+            System.err.println("Error: Can't enable (" + value +") virtual display" + re);
+        }
+    }
+
     private void runSetPersistentVrModeEnabled() throws RemoteException {
         String enableStr = nextArg();
         boolean enabled = Boolean.parseBoolean(enableStr);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index bc6e9cd..0ff3215 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -6416,17 +6416,7 @@
      */
     @Deprecated
     public boolean requestVisibleBehind(boolean visible) {
-        if (!mResumed) {
-            // Do not permit paused or stopped activities to do this.
-            visible = false;
-        }
-        try {
-            mVisibleBehind = ActivityManager.getService()
-                    .requestVisibleBehind(mToken, visible) && visible;
-        } catch (RemoteException e) {
-            mVisibleBehind = false;
-        }
-        return mVisibleBehind;
+        return false;
     }
 
     /**
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 199e856..06dbe82 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -360,6 +360,13 @@
             FIRST_START_NON_FATAL_ERROR_CODE + 1;
 
     /**
+     * Result for IActivityManaqer.startActivity: a new activity start was aborted. Never returned
+     * externally.
+     * @hide
+     */
+    public static final int START_ABORTED = FIRST_START_NON_FATAL_ERROR_CODE + 2;
+
+    /**
      * Flag for IActivityManaqer.startActivity: do special start mode where
      * a new activity is launched only if it is needed.
      * @hide
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 8a8f8dd..204df63 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2391,13 +2391,13 @@
                         memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
                         memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
                         memInfo.nativePrivateClean, memInfo.hasSwappedOutPss ?
-                        memInfo.nativeSwappedOut : memInfo.nativeSwappedOutPss,
+                        memInfo.nativeSwappedOutPss : memInfo.nativeSwappedOut,
                         nativeMax, nativeAllocated, nativeFree);
                 printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
                         memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
                         memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
                         memInfo.dalvikPrivateClean, memInfo.hasSwappedOutPss ?
-                        memInfo.dalvikSwappedOut : memInfo.dalvikSwappedOutPss,
+                        memInfo.dalvikSwappedOutPss : memInfo.dalvikSwappedOut,
                         dalvikMax, dalvikAllocated, dalvikFree);
             } else {
                 printRow(pw, HEAP_COLUMN, "", "Pss", "Private",
diff --git a/core/java/android/app/Vr2dDisplayProperties.java b/core/java/android/app/Vr2dDisplayProperties.java
index a608bb0..0eb2af3 100644
--- a/core/java/android/app/Vr2dDisplayProperties.java
+++ b/core/java/android/app/Vr2dDisplayProperties.java
@@ -16,7 +16,6 @@
 
 package android.app;
 
-import android.content.ComponentName;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -27,19 +26,31 @@
  *
  * @hide
  */
-public class Vr2dDisplayProperties implements Parcelable {
+public final class Vr2dDisplayProperties implements Parcelable {
 
-   /**
-    * The actual width, height and dpi.
-    */
+    public static final int FLAG_VIRTUAL_DISPLAY_ENABLED = 1;
+
+    /**
+     * The actual width, height and dpi.
+     */
     private final int mWidth;
     private final int mHeight;
     private final int mDpi;
 
+    // Flags describing the virtual display behavior.
+    private final int mAddedFlags;
+    private final int mRemovedFlags;
+
     public Vr2dDisplayProperties(int width, int height, int dpi) {
+        this(width, height, dpi, 0, 0);
+    }
+
+    private Vr2dDisplayProperties(int width, int height, int dpi, int flags, int removedFlags) {
         mWidth = width;
         mHeight = height;
         mDpi = dpi;
+        mAddedFlags = flags;
+        mRemovedFlags = removedFlags;
     }
 
     @Override
@@ -52,11 +63,13 @@
 
     @Override
     public String toString() {
-        return "Vr2dDisplayProperties{" +
-                "mWidth=" + mWidth +
-                ", mHeight=" + mHeight +
-                ", mDpi=" + mDpi +
-                "}";
+        return "Vr2dDisplayProperties{"
+                + "mWidth=" + mWidth
+                + ", mHeight=" + mHeight
+                + ", mDpi=" + mDpi
+                + ", flags=" + toReadableFlags(mAddedFlags)
+                + ", removed_flags=" + toReadableFlags(mRemovedFlags)
+                + "}";
     }
 
     @Override
@@ -66,6 +79,8 @@
 
         Vr2dDisplayProperties that = (Vr2dDisplayProperties) o;
 
+        if (getFlags() != that.getFlags()) return false;
+        if (getRemovedFlags() != that.getRemovedFlags()) return false;
         if (getWidth() != that.getWidth()) return false;
         if (getHeight() != that.getHeight()) return false;
         return getDpi() == that.getDpi();
@@ -81,6 +96,8 @@
         dest.writeInt(mWidth);
         dest.writeInt(mHeight);
         dest.writeInt(mDpi);
+        dest.writeInt(mAddedFlags);
+        dest.writeInt(mRemovedFlags);
     }
 
     public static final Parcelable.Creator<Vr2dDisplayProperties> CREATOR
@@ -100,13 +117,12 @@
         mWidth = source.readInt();
         mHeight = source.readInt();
         mDpi = source.readInt();
+        mAddedFlags = source.readInt();
+        mRemovedFlags = source.readInt();
     }
 
     public void dump(PrintWriter pw, String prefix) {
-        pw.println(prefix + "Vr2dDisplayProperties:");
-        pw.println(prefix + "  width=" + mWidth);
-        pw.println(prefix + "  height=" + mHeight);
-        pw.println(prefix + "  dpi=" + mDpi);
+        pw.println(prefix + toString());
     }
 
     public int getWidth() {
@@ -120,4 +136,83 @@
     public int getDpi() {
         return mDpi;
     }
+
+    public int getFlags() {
+        return mAddedFlags;
+    }
+
+    public int getRemovedFlags() {
+        return mRemovedFlags;
+    }
+
+    private static String toReadableFlags(int flags) {
+        String retval = "{";
+        if ((flags & FLAG_VIRTUAL_DISPLAY_ENABLED) == FLAG_VIRTUAL_DISPLAY_ENABLED) {
+            retval += "enabled";
+        }
+        return retval + "}";
+    }
+
+    /**
+     * Convenience class for creating Vr2dDisplayProperties.
+     */
+    public static class Builder {
+        private int mAddedFlags = 0;
+        private int mRemovedFlags = 0;
+
+        // Negative values are translated as an "ignore" to VrManagerService.
+        private int mWidth = -1;
+        private int mHeight = -1;
+        private int mDpi = -1;
+
+        public Builder() {
+        }
+
+        /**
+         * Sets the dimensions to use for the virtual display.
+         */
+        public Builder setDimensions(int width, int height, int dpi) {
+            mWidth = width;
+            mHeight = height;
+            mDpi = dpi;
+            return this;
+        }
+
+        /**
+         * Toggles the virtual display functionality for 2D activities in VR.
+         */
+        public Builder setEnabled(boolean enabled) {
+            if (enabled) {
+                addFlags(FLAG_VIRTUAL_DISPLAY_ENABLED);
+            } else {
+                removeFlags(FLAG_VIRTUAL_DISPLAY_ENABLED);
+            }
+            return this;
+        }
+
+        /**
+         * Adds property flags.
+         */
+        public Builder addFlags(int flags) {
+            mAddedFlags |= flags;
+            mRemovedFlags &= ~flags;
+            return this;
+        }
+
+        /**
+         * Removes property flags.
+         */
+        public Builder removeFlags(int flags) {
+            mRemovedFlags |= flags;
+            mAddedFlags &= ~flags;
+            return this;
+        }
+
+        /**
+         * Builds the Vr2dDisplayProperty instance.
+         */
+        public Vr2dDisplayProperties build() {
+            return new Vr2dDisplayProperties(mWidth, mHeight, mDpi, mAddedFlags, mRemovedFlags);
+        }
+    }
 }
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index dfcbfc4..0b8b689 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -22,9 +22,9 @@
 import android.annotation.RawRes;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
-import android.annotation.SdkConstant.SdkConstantType;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -74,7 +74,6 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -369,18 +368,17 @@
         }
 
         WallpaperColors getWallpaperColors(int which) {
-            synchronized (this) {
-                if (which != FLAG_LOCK && which != FLAG_SYSTEM)
-                    throw new IllegalArgumentException(
-                            "which should be either FLAG_LOCK or FLAG_SYSTEM");
-
-                try {
-                    return mService.getWallpaperColors(which);
-                } catch (RemoteException e) {
-                    // Can't get colors, connection lost.
-                }
-                return null;
+            if (which != FLAG_LOCK && which != FLAG_SYSTEM) {
+                throw new IllegalArgumentException(
+                        "Must request colors for exactly one kind of wallpaper");
             }
+
+            try {
+                return mService.getWallpaperColors(which);
+            } catch (RemoteException e) {
+                // Can't get colors, connection lost.
+            }
+            return null;
         }
 
         public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault,
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 9eacd21..ea0829f 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -55,7 +55,6 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.ContactsContract.Directory;
-import android.provider.Settings;
 import android.security.Credentials;
 import android.service.restrictions.RestrictionsReceiver;
 import android.telephony.TelephonyManager;
@@ -3134,6 +3133,14 @@
     public static final int WIPE_RESET_PROTECTION_DATA = 0x0002;
 
     /**
+     * Flag for {@link #wipeData(int)}: also erase the device's eUICC data.
+     *
+     * TODO(b/35851809): make this public.
+     * @hide
+     */
+    public static final int WIPE_EUICC = 0x0004;
+
+    /**
      * Ask that all user data be wiped. If called as a secondary user, the user will be removed and
      * other users will remain unaffected. Calling from the primary user will cause the device to
      * reboot, erasing all device data - including all the secondary users and their data - while
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 7ff37d2..27b802e 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -203,6 +203,34 @@
             "android.bluetooth.device.action.BOND_STATE_CHANGED";
 
     /**
+     * Broadcast Action: Indicates the battery level of a remote device has
+     * been retrieved for the first time, or changed since the last retrieval
+     * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
+     * #EXTRA_BATTERY_LEVEL}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_BATTERY_LEVEL_CHANGED =
+            "android.bluetooth.device.action.BATTERY_LEVEL_CHANGED";
+
+    /**
+     * Used as an Integer extra field in {@link #ACTION_BATTERY_LEVEL_CHANGED}
+     * intent. It contains the most recently retrieved battery level information
+     * ranging from 0% to 100% for a remote device, {@link #BATTERY_LEVEL_UNKNOWN}
+     * when the valid is unknown or there is an error
+     * @hide
+     */
+    public static final String EXTRA_BATTERY_LEVEL =
+            "android.bluetooth.device.extra.BATTERY_LEVEL";
+
+    /**
+     * Used as the unknown value for {@link #EXTRA_BATTERY_LEVEL} and {@link #getBatteryLevel()}
+     * @hide
+     */
+    public static final int BATTERY_LEVEL_UNKNOWN = -1;
+
+    /**
      * Used as a Parcelable {@link BluetoothDevice} extra field in every intent
      * broadcast by this class. It contains the {@link BluetoothDevice} that
      * the intent applies to.
@@ -861,6 +889,27 @@
     }
 
     /**
+     * Get the most recent identified battery level of this Bluetooth device
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+     *
+     * @return Battery level in percents from 0 to 100, or {@link #BATTERY_LEVEL_UNKNOWN} if
+     *         Bluetooth is disabled, or device is disconnected, or does not have any battery
+     *         reporting service, or return value is invalid
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    public int getBatteryLevel() {
+        if (sService == null) {
+            Log.e(TAG, "Bluetooth disabled. Cannot get remote device battery level");
+            return BATTERY_LEVEL_UNKNOWN;
+        }
+        try {
+            return sService.getBatteryLevel(this);
+        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        return BATTERY_LEVEL_UNKNOWN;
+    }
+
+    /**
      * Start the bonding (pairing) process with the remote device.
      * <p>This is an asynchronous call, it will return immediately. Register
      * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 57b954f..c84643f 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -200,6 +200,37 @@
     public static final String VENDOR_RESULT_CODE_COMMAND_ANDROID = "+ANDROID";
 
     /**
+     * A vendor-specific AT command
+     * @hide
+     */
+    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XAPL = "+XAPL";
+
+    /**
+     * A vendor-specific AT command
+     * @hide
+     */
+    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV = "+IPHONEACCEV";
+
+    /**
+     * Battery level indicator associated with
+     * {@link #VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV}
+     * @hide
+     */
+    public static final int VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL = 1;
+
+    /**
+     * A vendor-specific AT command
+     * @hide
+     */
+    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT = "+XEVENT";
+
+    /**
+     * Battery level indicator associated with {@link #VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT}
+     * @hide
+     */
+    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT_BATTERY_LEVEL = "BATTERY";
+
+    /**
      * Headset state when SCO audio is not connected.
      * This state can be one of
      * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
@@ -227,34 +258,33 @@
      *
      * <p>This intent will have 3 extras:
      * <ul>
-     *   <li> {@link #EXTRA_IND_ID} - The Assigned number of headset Indicator which is supported by
-                                        the headset ( as indicated by AT+BIND
-                                        command in the SLC sequence).or whose value
-                                        is changed (indicated by AT+BIEV command)</li>
-     *   <li> {@link #EXTRA_IND_VALUE}- The updated value of headset indicator. </li>
-     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     *   <li> {@link #EXTRA_HF_INDICATORS_IND_ID} - The Assigned number of headset Indicator which
+     *              is supported by the headset ( as indicated by AT+BIND command in the SLC
+     *              sequence) or whose value is changed (indicated by AT+BIEV command) </li>
+     *   <li> {@link #EXTRA_HF_INDICATORS_IND_VALUE} - Updated value of headset indicator. </li>
+     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - Remote device. </li>
      * </ul>
-     * <p>{@link #EXTRA_IND_ID} is defined by Bluetooth SIG and each of the indicators are
-     * given an assigned number. Below shows the assigned number of Indicator added so far
-     * - Enhanced Safety - 1
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
-     * receive.
+     * <p>{@link #EXTRA_HF_INDICATORS_IND_ID} is defined by Bluetooth SIG and each of the indicators
+     *     are given an assigned number. Below shows the assigned number of Indicator added so far
+     * - Enhanced Safety - 1, Valid Values: 0 - Disabled, 1 - Enabled
+     * - Battery Level - 2, Valid Values: 0~100 - Remaining level of Battery
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to receive.
      * @hide
      */
     public static final String ACTION_HF_INDICATORS_VALUE_CHANGED =
             "android.bluetooth.headset.action.HF_INDICATORS_VALUE_CHANGED";
 
     /**
-     * A String extra field in {@link #ACTION_HF_INDICATORS_VALUE_CHANGED}
-     * intents that contains the UUID of the headset  indicator (as defined by Bluetooth SIG)
-     * that is being sent.
+     * A int extra field in {@link #ACTION_HF_INDICATORS_VALUE_CHANGED}
+     * intents that contains the assigned number of the headset indicator as defined by
+     * Bluetooth SIG that is being sent. Value range is 0-65535 as defined in HFP 1.7
      * @hide
      */
     public static final String EXTRA_HF_INDICATORS_IND_ID =
             "android.bluetooth.headset.extra.HF_INDICATORS_IND_ID";
 
     /**
-     * A int  extra field in {@link #ACTION_HF_INDICATORS_VALUE_CHANGED}
+     * A int extra field in {@link #ACTION_HF_INDICATORS_VALUE_CHANGED}
      * intents that contains the value of the Headset indicator that is being sent.
      * @hide
      */
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 43c5ae4..1d7cfc9 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -75,6 +75,7 @@
     ParcelUuid[] getRemoteUuids(in BluetoothDevice device);
     boolean fetchRemoteUuids(in BluetoothDevice device);
     boolean sdpSearch(in BluetoothDevice device, in ParcelUuid uuid);
+    int getBatteryLevel(in BluetoothDevice device);
 
     boolean setPin(in BluetoothDevice device, boolean accept, int len, in byte[] pinCode);
     boolean setPasskey(in BluetoothDevice device, boolean accept, int len, in byte[]
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 852e5f7..f70215b 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -16,6 +16,8 @@
 
 package android.content;
 
+import static android.content.ContentProvider.maybeAddUserId;
+
 import android.annotation.AnyRes;
 import android.annotation.BroadcastBehavior;
 import android.annotation.IntDef;
@@ -43,7 +45,7 @@
 import android.os.ShellCommand;
 import android.os.StrictMode;
 import android.os.UserHandle;
-import android.os.storage.StorageManager;
+import android.provider.ContactsContract.QuickContact;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsProvider;
 import android.provider.MediaStore;
@@ -51,7 +53,9 @@
 import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.Log;
+
 import com.android.internal.util.XmlUtils;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -69,8 +73,6 @@
 import java.util.Objects;
 import java.util.Set;
 
-import static android.content.ContentProvider.maybeAddUserId;
-
 /**
  * An intent is an abstract description of an operation to be performed.  It
  * can be used with {@link Context#startActivity(Intent) startActivity} to
@@ -9782,6 +9784,7 @@
                 && leavingPackage) {
             switch (mAction) {
                 case ACTION_PROVIDER_CHANGED:
+                case QuickContact.ACTION_QUICK_CONTACT:
                     // Ignore actions that don't need to grant
                     break;
                 default:
diff --git a/core/java/android/content/pm/LauncherActivityInfo.java b/core/java/android/content/pm/LauncherActivityInfo.java
index 358787e..e9c9588 100644
--- a/core/java/android/content/pm/LauncherActivityInfo.java
+++ b/core/java/android/content/pm/LauncherActivityInfo.java
@@ -20,12 +20,10 @@
 import android.content.Context;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
-import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.DisplayMetrics;
-import android.util.Log;
 
 /**
  * A representation of an activity that can belong to this user or a managed
@@ -173,12 +171,6 @@
     public Drawable getBadgedIcon(int density) {
         Drawable originalIcon = getIcon(density);
 
-        if (originalIcon instanceof BitmapDrawable) {
-            // TODO: Go through LauncherAppsService
-            return mPm.getUserBadgedIcon(originalIcon, mUser);
-        } else {
-            Log.e(TAG, "Unable to create badged icon for " + mActivityInfo);
-        }
-        return originalIcon;
+        return mPm.getUserBadgedIcon(originalIcon, mUser);
     }
 }
diff --git a/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl b/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
index 3c3b84d..9490e27 100644
--- a/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
+++ b/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
@@ -25,4 +25,5 @@
  */
 oneway interface IRuntimePermissionPresenter {
     void getAppPermissions(String packageName, in RemoteCallback callback);
+    void revokeRuntimePermission(String packageName, String permissionName);
 }
diff --git a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
index 6d55d2f..02d0a6d 100644
--- a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
+++ b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.content.pm.ApplicationInfo;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -31,6 +30,7 @@
 import android.os.RemoteException;
 import android.permissionpresenterservice.RuntimePermissionPresenterService;
 import android.util.Log;
+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.SomeArgs;
 
@@ -118,6 +118,22 @@
         mRemoteService.processMessage(message);
     }
 
+    /**
+     * Revoke the permission {@code permissionName} for app {@code packageName}
+     *
+     * @param packageName The package for which to revoke
+     * @param permissionName The permission to revoke
+     */
+    public void revokeRuntimePermission(String packageName, String permissionName) {
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = packageName;
+        args.arg2 = permissionName;
+
+        Message message = mRemoteService.obtainMessage(
+                RemoteService.MSG_REVOKE_APP_PERMISSIONS, args);
+        mRemoteService.processMessage(message);
+    }
+
     private static final class RemoteService
             extends Handler implements ServiceConnection {
         private static final long UNBIND_TIMEOUT_MILLIS = 10000;
@@ -125,6 +141,7 @@
         public static final int MSG_GET_APP_PERMISSIONS = 1;
         public static final int MSG_GET_APPS_USING_PERMISSIONS = 2;
         public static final int MSG_UNBIND = 3;
+        public static final int MSG_REVOKE_APP_PERMISSIONS = 4;
 
         private final Object mLock = new Object();
 
@@ -231,6 +248,25 @@
                         mRemoteInstance = null;
                     }
                 } break;
+
+                case MSG_REVOKE_APP_PERMISSIONS: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    final String packageName = (String) args.arg1;
+                    final String permissionName = (String) args.arg2;
+                    args.recycle();
+                    final IRuntimePermissionPresenter remoteInstance;
+                    synchronized (mLock) {
+                        remoteInstance = mRemoteInstance;
+                    }
+                    if (remoteInstance == null) {
+                        return;
+                    }
+                    try {
+                        remoteInstance.revokeRuntimePermission(packageName, permissionName);
+                    } catch (RemoteException re) {
+                        Log.e(TAG, "Error getting app permissions", re);
+                    }
+                } break;
             }
 
             synchronized (mLock) {
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 6834ba8..be31d1b 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -42,6 +42,9 @@
 import java.util.ArrayList;
 import java.util.Locale;
 
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_UNDEFINED;
+
 /**
  * This class describes all device configuration information that can
  * impact the resources the application retrieves.  This includes both
@@ -597,6 +600,13 @@
      */
     public int orientation;
 
+    /**
+     * The mRotation used at the time orientation was determined.
+     * TODO(b/36812336): Move mRotation out of {@link Configuration}.
+     * {@hide}
+     */
+    private int mRotation;
+
     /** Constant for {@link #uiMode}: bits that encode the mode type. */
     public static final int UI_MODE_TYPE_MASK = 0x0f;
     /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
@@ -884,6 +894,7 @@
         navigation = o.navigation;
         navigationHidden = o.navigationHidden;
         orientation = o.orientation;
+        mRotation = o.mRotation;
         screenLayout = o.screenLayout;
         colorMode = o.colorMode;
         uiMode = o.uiMode;
@@ -1074,6 +1085,7 @@
         navigation = NAVIGATION_UNDEFINED;
         navigationHidden = NAVIGATIONHIDDEN_UNDEFINED;
         orientation = ORIENTATION_UNDEFINED;
+        mRotation = ROTATION_UNDEFINED;
         screenLayout = SCREENLAYOUT_UNDEFINED;
         colorMode = COLOR_MODE_UNDEFINED;
         uiMode = UI_MODE_TYPE_UNDEFINED;
@@ -1182,6 +1194,11 @@
             changed |= ActivityInfo.CONFIG_ORIENTATION;
             orientation = delta.orientation;
         }
+        if (delta.mRotation != ROTATION_UNDEFINED
+                && mRotation != delta.mRotation) {
+            changed |= ActivityInfo.CONFIG_ORIENTATION;
+            mRotation = delta.mRotation;
+        }
 
         if (((delta.screenLayout & SCREENLAYOUT_SIZE_MASK) != SCREENLAYOUT_SIZE_UNDEFINED)
                 && (delta.screenLayout & SCREENLAYOUT_SIZE_MASK)
@@ -1376,6 +1393,10 @@
                 && orientation != delta.orientation) {
             changed |= ActivityInfo.CONFIG_ORIENTATION;
         }
+        if ((compareUndefined || delta.mRotation != ROTATION_UNDEFINED)
+                && mRotation != delta.mRotation) {
+            changed |= ActivityInfo.CONFIG_ORIENTATION;
+        }
         if ((compareUndefined || getScreenLayoutNoDirection(delta.screenLayout) !=
                 (SCREENLAYOUT_SIZE_UNDEFINED | SCREENLAYOUT_LONG_UNDEFINED))
                 && getScreenLayoutNoDirection(screenLayout) !=
@@ -1512,6 +1533,7 @@
         dest.writeInt(navigation);
         dest.writeInt(navigationHidden);
         dest.writeInt(orientation);
+        dest.writeInt(mRotation);
         dest.writeInt(screenLayout);
         dest.writeInt(colorMode);
         dest.writeInt(uiMode);
@@ -1548,6 +1570,7 @@
         navigation = source.readInt();
         navigationHidden = source.readInt();
         orientation = source.readInt();
+        mRotation = source.readInt();
         screenLayout = source.readInt();
         colorMode = source.readInt();
         uiMode = source.readInt();
@@ -1632,6 +1655,8 @@
         if (n != 0) return n;
         n = this.orientation - that.orientation;
         if (n != 0) return n;
+        n = this.mRotation - that.mRotation;
+        if (n != 0) return n;
         n = this.colorMode - that.colorMode;
         if (n != 0) return n;
         n = this.screenLayout - that.screenLayout;
@@ -1763,6 +1788,24 @@
     /**
      * @hide
      *
+     * Setter for orientation converts from {@link Surface} values to internal representation.
+     */
+    public void setRotation(int rotation) {
+        this.mRotation = rotation;
+    }
+
+    /**
+     * @hide
+     *
+     * Getter for orientation. Converts from internal representation to  {@link Surface} values.
+     */
+    public int getRotation() {
+        return mRotation != ROTATION_UNDEFINED ? mRotation : ROTATION_0;
+    }
+
+    /**
+     * @hide
+     *
      * Clears the locale without changing layout direction.
      */
     public void clearLocales() {
@@ -2193,6 +2236,10 @@
             delta.orientation = change.orientation;
         }
 
+        if (base.mRotation != change.mRotation) {
+            base.mRotation = change.mRotation;
+        }
+
         if ((base.screenLayout & SCREENLAYOUT_SIZE_MASK) !=
                 (change.screenLayout & SCREENLAYOUT_SIZE_MASK)) {
             delta.screenLayout |= change.screenLayout & SCREENLAYOUT_SIZE_MASK;
@@ -2264,6 +2311,7 @@
     private static final String XML_ATTR_NAVIGATION = "nav";
     private static final String XML_ATTR_NAVIGATION_HIDDEN = "navHid";
     private static final String XML_ATTR_ORIENTATION = "ori";
+    private static final String XML_ATTR_ROTATION = "rot";
     private static final String XML_ATTR_SCREEN_LAYOUT = "scrLay";
     private static final String XML_ATTR_COLOR_MODE = "clrMod";
     private static final String XML_ATTR_UI_MODE = "ui";
@@ -2323,6 +2371,8 @@
                 DENSITY_DPI_UNDEFINED);
         configOut.appBounds =
             Rect.unflattenFromString(XmlUtils.readStringAttribute(parser, XML_ATTR_APP_BOUNDS));
+        configOut.mRotation = XmlUtils.readIntAttribute(parser, XML_ATTR_ROTATION,
+                ROTATION_UNDEFINED);
 
         // For persistence, we don't care about assetsSeq, so do not read it out.
     }
@@ -2399,6 +2449,10 @@
                 config.appBounds.flattenToString());
         }
 
+        if (config.mRotation != ROTATION_UNDEFINED) {
+            XmlUtils.writeIntAttribute(xml, XML_ATTR_ROTATION, config.mRotation);
+        }
+
         // For persistence, we do not care about assetsSeq, so do not write it out.
     }
 }
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 6a02b6b..bda8039 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -256,6 +256,15 @@
      */
     public static final int VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH = 1 << 6;
 
+    /**
+     * Virtual display flag: Indicates that the orientation of this display device is coupled to
+     * the rotation of its associated logical display.
+     *
+     * @see #createVirtualDisplay
+     * @hide
+     */
+    public static final int VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT = 1 << 7;
+
     /** @hide */
     public DisplayManager(Context context) {
         mContext = context;
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index fa854b0..f243f37 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -699,6 +699,7 @@
             dest.writeInt(dalvikPrivateClean);
             dest.writeInt(dalvikSharedClean);
             dest.writeInt(dalvikSwappedOut);
+            dest.writeInt(dalvikSwappedOutPss);
             dest.writeInt(nativePss);
             dest.writeInt(nativeSwappablePss);
             dest.writeInt(nativePrivateDirty);
@@ -706,6 +707,7 @@
             dest.writeInt(nativePrivateClean);
             dest.writeInt(nativeSharedClean);
             dest.writeInt(nativeSwappedOut);
+            dest.writeInt(nativeSwappedOutPss);
             dest.writeInt(otherPss);
             dest.writeInt(otherSwappablePss);
             dest.writeInt(otherPrivateDirty);
@@ -726,6 +728,7 @@
             dalvikPrivateClean = source.readInt();
             dalvikSharedClean = source.readInt();
             dalvikSwappedOut = source.readInt();
+            dalvikSwappedOutPss = source.readInt();
             nativePss = source.readInt();
             nativeSwappablePss = source.readInt();
             nativePrivateDirty = source.readInt();
@@ -733,6 +736,7 @@
             nativePrivateClean = source.readInt();
             nativeSharedClean = source.readInt();
             nativeSwappedOut = source.readInt();
+            nativeSwappedOutPss = source.readInt();
             otherPss = source.readInt();
             otherSwappablePss = source.readInt();
             otherPrivateDirty = source.readInt();
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 50b4f8c..56d6e0a 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -369,11 +369,11 @@
      * constraints remain.
      *
      * @param minCount Always keep at least this many files.
-     * @param minAge Always keep files younger than this age.
+     * @param minAgeMs Always keep files younger than this age, in milliseconds.
      * @return if any files were deleted.
      */
-    public static boolean deleteOlderFiles(File dir, int minCount, long minAge) {
-        if (minCount < 0 || minAge < 0) {
+    public static boolean deleteOlderFiles(File dir, int minCount, long minAgeMs) {
+        if (minCount < 0 || minAgeMs < 0) {
             throw new IllegalArgumentException("Constraints must be positive or 0");
         }
 
@@ -393,9 +393,9 @@
         for (int i = minCount; i < files.length; i++) {
             final File file = files[i];
 
-            // Keep files newer than minAge
+            // Keep files newer than minAgeMs
             final long age = System.currentTimeMillis() - file.lastModified();
-            if (age > minAge) {
+            if (age > minAgeMs) {
                 if (file.delete()) {
                     Log.d(TAG, "Deleted old file " + file);
                     deleted = true;
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index db9f28b..6f458e0 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -22,20 +22,26 @@
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.os.UserManager;
+import android.provider.Settings;
+import android.telephony.euicc.EuiccManager;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.Display;
 import android.view.WindowManager;
 
+import com.android.internal.logging.MetricsLogger;
+
 import libcore.io.Streams;
 
-import java.io.ByteArrayInputStream;
 import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -46,22 +52,19 @@
 import java.io.RandomAccessFile;
 import java.security.GeneralSecurityException;
 import java.security.PublicKey;
-import java.security.Signature;
 import java.security.SignatureException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
 import java.util.Locale;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 import java.util.zip.ZipInputStream;
 
-import com.android.internal.logging.MetricsLogger;
-
 import sun.security.pkcs.PKCS7;
 import sun.security.pkcs.SignerInfo;
 
@@ -84,11 +87,19 @@
     /** Send progress to listeners no more often than this (in ms). */
     private static final long PUBLISH_PROGRESS_INTERVAL_MS = 500;
 
+    private static final long DEFAULT_EUICC_WIPING_TIMEOUT_MILLIS = 30000L; // 30 s
+
+    private static final long MIN_EUICC_WIPING_TIMEOUT_MILLIS = 5000L; // 5 s
+
+    private static final long MAX_EUICC_WIPING_TIMEOUT_MILLIS = 60000L; // 60 s
+
     /** Used to communicate with recovery.  See bootable/recovery/recovery.cpp. */
     private static final File RECOVERY_DIR = new File("/cache/recovery");
     private static final File LOG_FILE = new File(RECOVERY_DIR, "log");
     private static final File LAST_INSTALL_FILE = new File(RECOVERY_DIR, "last_install");
     private static final String LAST_PREFIX = "last_";
+    private static final String ACTION_WIPE_EUICC_DATA =
+            "com.android.internal.action.WIPE_EUICC_DATA";
 
     /**
      * The recovery image uses this file to identify the location (i.e. blocks)
@@ -673,18 +684,26 @@
      */
     public static void rebootWipeUserData(Context context) throws IOException {
         rebootWipeUserData(context, false /* shutdown */, context.getPackageName(),
-                false /* force */);
+                false /* force */, false /* wipeEuicc */);
     }
 
     /** {@hide} */
     public static void rebootWipeUserData(Context context, String reason) throws IOException {
-        rebootWipeUserData(context, false /* shutdown */, reason, false /* force */);
+        rebootWipeUserData(context, false /* shutdown */, reason, false /* force */,
+                false /* wipeEuicc */);
     }
 
     /** {@hide} */
     public static void rebootWipeUserData(Context context, boolean shutdown)
             throws IOException {
-        rebootWipeUserData(context, shutdown, context.getPackageName(), false /* force */);
+        rebootWipeUserData(context, shutdown, context.getPackageName(), false /* force */,
+                false /* wipeEuicc */);
+    }
+
+    /** {@hide} */
+    public static void rebootWipeUserData(Context context, boolean shutdown, String reason,
+            boolean force) throws IOException {
+        rebootWipeUserData(context, shutdown, reason, force, false /* wipeEuicc */);
     }
 
     /**
@@ -701,6 +720,7 @@
      * @param reason    the reason for the wipe that is visible in the logs
      * @param force     whether the {@link UserManager.DISALLOW_FACTORY_RESET} user restriction
      *                  should be ignored
+     * @param wipeEuicc whether wipe the euicc data
      *
      * @throws IOException  if writing the recovery command file
      * fails, or if the reboot itself fails.
@@ -709,7 +729,7 @@
      * @hide
      */
     public static void rebootWipeUserData(Context context, boolean shutdown, String reason,
-            boolean force) throws IOException {
+            boolean force, boolean wipeEuicc) throws IOException {
         UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
         if (!force && um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) {
             throw new SecurityException("Wiping data is not allowed for this user.");
@@ -731,6 +751,10 @@
         // Block until the ordered broadcast has completed.
         condition.block();
 
+        if (wipeEuicc) {
+            wipeEuiccData(context);
+        }
+
         String shutdownArg = null;
         if (shutdown) {
             shutdownArg = "--shutdown_after";
@@ -745,6 +769,61 @@
         bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg);
     }
 
+    private static void wipeEuiccData(Context context) {
+        EuiccManager euiccManager = (EuiccManager) context.getSystemService(
+                Context.EUICC_SERVICE);
+        if (euiccManager != null && euiccManager.isEnabled()) {
+            CountDownLatch euiccFactoryResetLatch = new CountDownLatch(1);
+
+            BroadcastReceiver euiccWipeFinishReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    if (ACTION_WIPE_EUICC_DATA.equals(intent.getAction())) {
+                        if (getResultCode() != EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
+                            int detailedCode = intent.getIntExtra(
+                                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0);
+                            Log.e(TAG, "Error wiping euicc data, Detailed code = "
+                                    + detailedCode);
+                        } else {
+                            Log.d(TAG, "Successfully wiped euicc data.");
+                        }
+                        euiccFactoryResetLatch.countDown();
+                    }
+                }
+            };
+
+            Intent intent = new Intent(ACTION_WIPE_EUICC_DATA);
+            intent.setPackage("android");
+            PendingIntent callbackIntent = PendingIntent.getBroadcastAsUser(
+                    context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT, UserHandle.SYSTEM);
+            IntentFilter filterConsent = new IntentFilter();
+            filterConsent.addAction(ACTION_WIPE_EUICC_DATA);
+            HandlerThread euiccHandlerThread = new HandlerThread("euiccWipeFinishReceiverThread");
+            euiccHandlerThread.start();
+            Handler euiccHandler = new Handler(euiccHandlerThread.getLooper());
+            context.registerReceiver(euiccWipeFinishReceiver, filterConsent, null, euiccHandler);
+            euiccManager.eraseSubscriptions(callbackIntent);
+            try {
+                long waitingTimeMillis = Settings.Global.getLong(
+                        context.getContentResolver(),
+                        Settings.Global.EUICC_WIPING_TIMEOUT_MILLIS,
+                        DEFAULT_EUICC_WIPING_TIMEOUT_MILLIS);
+                if (waitingTimeMillis < MIN_EUICC_WIPING_TIMEOUT_MILLIS) {
+                    waitingTimeMillis = MIN_EUICC_WIPING_TIMEOUT_MILLIS;
+                } else if (waitingTimeMillis > MAX_EUICC_WIPING_TIMEOUT_MILLIS) {
+                    waitingTimeMillis = MAX_EUICC_WIPING_TIMEOUT_MILLIS;
+                }
+                if (!euiccFactoryResetLatch.await(waitingTimeMillis, TimeUnit.MILLISECONDS)) {
+                    Log.e(TAG, "Timeout wiping eUICC data.");
+                }
+                context.unregisterReceiver(euiccWipeFinishReceiver);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                Log.e(TAG, "Wiping eUICC data interrupted", e);
+            }
+        }
+    }
+
     /** {@hide} */
     public static void rebootPromptAndWipeUserData(Context context, String reason)
             throws IOException {
diff --git a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
index 344d947..2931627f 100644
--- a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
+++ b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
@@ -20,7 +20,6 @@
 import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.permission.IRuntimePermissionPresenter;
 import android.content.pm.permission.RuntimePermissionPresentationInfo;
 import android.content.pm.permission.RuntimePermissionPresenter;
@@ -30,6 +29,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteCallback;
+
 import com.android.internal.os.SomeArgs;
 
 import java.util.List;
@@ -72,6 +72,16 @@
      */
     public abstract List<RuntimePermissionPresentationInfo> onGetAppPermissions(String packageName);
 
+    /**
+     * Revoke the permission {@code permissionName} for app {@code packageName}
+     *
+     * @param packageName The package for which to revoke
+     * @param permissionName The permission to revoke
+     *
+     * @hide
+     */
+    public abstract void onRevokeRuntimePermission(String packageName, String permissionName);
+
     @Override
     public final IBinder onBind(Intent intent) {
         return new IRuntimePermissionPresenter.Stub() {
@@ -83,12 +93,22 @@
                 mHandler.obtainMessage(MyHandler.MSG_GET_APP_PERMISSIONS,
                         args).sendToTarget();
             }
+
+            @Override
+            public void revokeRuntimePermission(String packageName, String permissionName) {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = packageName;
+                args.arg2 = permissionName;
+                mHandler.obtainMessage(MyHandler.MSG_REVOKE_APP_PERMISSION,
+                        args).sendToTarget();
+            }
         };
     }
 
     private final class MyHandler extends Handler {
         public static final int MSG_GET_APP_PERMISSIONS = 1;
         public static final int MSG_GET_APPS_USING_PERMISSIONS = 2;
+        public static final int MSG_REVOKE_APP_PERMISSION = 3;
 
         public MyHandler(Looper looper) {
             super(looper, null, false);
@@ -113,6 +133,14 @@
                         callback.sendResult(null);
                     }
                 } break;
+                case MSG_REVOKE_APP_PERMISSION: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    String packageName = (String) args.arg1;
+                    String permissionName = (String) args.arg2;
+                    args.recycle();
+
+                    onRevokeRuntimePermission(packageName, permissionName);
+                } break;
             }
         }
     }
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 2179bd4..4306bc4 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -934,6 +934,7 @@
      * @param singleLineTitle set {@code true} if the title should be constrained to one line
      */
     public void setSingleLineTitle(boolean singleLineTitle) {
+        mHasSingleLineTitleAttr = true;
         mSingleLineTitle = singleLineTitle;
         notifyChanged();
     }
diff --git a/core/java/android/provider/AlarmClock.java b/core/java/android/provider/AlarmClock.java
index d921ed4..f903012 100644
--- a/core/java/android/provider/AlarmClock.java
+++ b/core/java/android/provider/AlarmClock.java
@@ -82,7 +82,8 @@
      * If neither of the above are given then:
      * <ul>
      * <li>If exactly one active alarm exists, it is dismissed.
-     * <li>If more than one active alarm exists, the user is prompted to choose the alarm to dismiss.
+     * <li>If more than one active alarm exists, the user is prompted to choose the alarm to
+     * dismiss.
      * </ul>
      * </p><p>
      * If the extra {@link #EXTRA_ALARM_SEARCH_MODE} is used, and the search results contain two or
@@ -104,8 +105,7 @@
      * @see #EXTRA_ALARM_SEARCH_MODE
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_DISMISS_ALARM =
-            "android.intent.action.DISMISS_ALARM";
+    public static final String ACTION_DISMISS_ALARM = "android.intent.action.DISMISS_ALARM";
 
     /**
      * Activity Action: Snooze a currently ringing alarm.
@@ -124,8 +124,7 @@
      * @see #EXTRA_ALARM_SNOOZE_DURATION
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_SNOOZE_ALARM =
-            "android.intent.action.SNOOZE_ALARM";
+    public static final String ACTION_SNOOZE_ALARM = "android.intent.action.SNOOZE_ALARM";
 
     /**
      * Activity Action: Set a timer.
@@ -155,6 +154,16 @@
     public static final String ACTION_SET_TIMER = "android.intent.action.SET_TIMER";
 
     /**
+     * Activity Action: Dismiss timers.
+     * <p>
+     * Dismiss all currently expired timers. If there are no expired timers, then this is a no-op.
+     * </p>
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_DISMISS_TIMER = "android.intent.action.DISMISS_TIMER";
+
+    /**
      * Activity Action: Show the timers.
      * <p>
      * This action opens the timers page.
@@ -200,8 +209,7 @@
      * @see #ALARM_SEARCH_MODE_LABEL
      * @see #ACTION_DISMISS_ALARM
      */
-    public static final String EXTRA_ALARM_SEARCH_MODE =
-        "android.intent.extra.alarm.SEARCH_MODE";
+    public static final String EXTRA_ALARM_SEARCH_MODE = "android.intent.extra.alarm.SEARCH_MODE";
 
     /**
      * Search for the alarm that is most closely matched by the search parameters
diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java
index 875f286..0c2e4b7 100644
--- a/core/java/android/service/euicc/EuiccService.java
+++ b/core/java/android/service/euicc/EuiccService.java
@@ -97,6 +97,10 @@
     public static final String ACTION_RESOLVE_NO_PRIVILEGES =
             "android.service.euicc.action.RESOLVE_NO_PRIVILEGES";
 
+    /** Intent extra set for resolution requests containing the package name of the calling app. */
+    public static final String EXTRA_RESOLUTION_CALLING_PACKAGE =
+            "android.service.euicc.extra.RESOLUTION_CALLING_PACKAGE";
+
     /** Result code for a successful operation. */
     public static final int RESULT_OK = 0;
     /** Result code indicating that an active SIM must be deactivated to perform the operation. */
@@ -313,6 +317,21 @@
     public abstract int onEraseSubscriptions(int slotId);
 
     /**
+     * Ensure that subscriptions will be retained on the next factory reset.
+     *
+     * <p>Called directly before a factory reset. Assumes that a normal factory reset will lead to
+     * profiles being erased on first boot (to cover fastboot/recovery wipes), so the implementation
+     * should persist some bit that will remain accessible after the factory reset to bypass this
+     * flow when this method is called.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @return the result of the operation. May be one of the predefined {@code RESULT_} constants
+     *     or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
+     */
+    public abstract int onRetainSubscriptionsForFactoryReset(int slotId);
+
+    /**
      * Wrapper around IEuiccService that forwards calls to implementations of {@link EuiccService}.
      */
     private class IEuiccServiceWrapper extends IEuiccService.Stub {
@@ -484,5 +503,21 @@
                 }
             });
         }
+
+        @Override
+        public void retainSubscriptionsForFactoryReset(int slotId,
+                IRetainSubscriptionsForFactoryResetCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    int result = EuiccService.this.onRetainSubscriptionsForFactoryReset(slotId);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
     }
 }
diff --git a/core/java/android/service/euicc/IEuiccService.aidl b/core/java/android/service/euicc/IEuiccService.aidl
index 18ea915..e10dd8c 100644
--- a/core/java/android/service/euicc/IEuiccService.aidl
+++ b/core/java/android/service/euicc/IEuiccService.aidl
@@ -24,6 +24,7 @@
 import android.service.euicc.IGetEidCallback;
 import android.service.euicc.IGetEuiccInfoCallback;
 import android.service.euicc.IGetEuiccProfileInfoListCallback;
+import android.service.euicc.IRetainSubscriptionsForFactoryResetCallback;
 import android.service.euicc.ISwitchToSubscriptionCallback;
 import android.service.euicc.IUpdateSubscriptionNicknameCallback;
 import android.telephony.euicc.DownloadableSubscription;
@@ -46,4 +47,6 @@
     void updateSubscriptionNickname(int slotId, String iccid, String nickname,
             in IUpdateSubscriptionNicknameCallback callback);
     void eraseSubscriptions(int slotId, in IEraseSubscriptionsCallback callback);
+    void retainSubscriptionsForFactoryReset(
+            int slotId, in IRetainSubscriptionsForFactoryResetCallback callback);
 }
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl b/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl
new file mode 100644
index 0000000..1276830
--- /dev/null
+++ b/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.euicc;
+
+/** @hide */
+oneway interface IRetainSubscriptionsForFactoryResetCallback {
+    void onComplete(int result);
+}
\ No newline at end of file
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java
index 951aa8d..8691136 100644
--- a/core/java/android/util/Log.java
+++ b/core/java/android/util/Log.java
@@ -30,8 +30,9 @@
 /**
  * API for sending log output.
  *
- * <p>Generally, use the Log.v() Log.d() Log.i() Log.w() and Log.e()
- * methods.
+ * <p>Generally, you should use the {@link #v Log.v()}, {@link #d Log.d()},
+ * {@link #i Log.i()}, {@link #w Log.w()}, and {@link #e Log.e()} methods to write logs.
+ * You can then <a href="{@docRoot}studio/debug/am-logcat.html">view the logs in logcat</a>.
  *
  * <p>The order in terms of verbosity, from least to most is
  * ERROR, WARN, INFO, DEBUG, VERBOSE.  Verbose should never be compiled
diff --git a/core/java/android/util/MergedConfiguration.java b/core/java/android/util/MergedConfiguration.java
index 68d0309..ae66050 100644
--- a/core/java/android/util/MergedConfiguration.java
+++ b/core/java/android/util/MergedConfiguration.java
@@ -161,6 +161,21 @@
         return "{mGlobalConfig=" + mGlobalConfig + " mOverrideConfig=" + mOverrideConfig + "}";
     }
 
+    @Override
+    public int hashCode() {
+        return mMergedConfig.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+        if (!(that instanceof MergedConfiguration)) {
+            return false;
+        }
+
+        if (that == this) return true;
+        return mMergedConfig.equals(((MergedConfiguration) that).mMergedConfig);
+    }
+
     public void dump(PrintWriter pw, String prefix) {
         pw.println(prefix + "mGlobalConfig=" + mGlobalConfig);
         pw.println(prefix + "mOverrideConfig=" + mOverrideConfig);
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index cdb9b82..7346a21 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -726,6 +726,17 @@
     }
 
     /**
+     * Returns the rotation associated with this display as used during layout. This is currently
+     * derived from the {@link Configuration}.
+     *
+     * @hide
+     */
+    @Surface.Rotation
+    public int getLayoutRotation() {
+        return mResources.getConfiguration().getRotation();
+    }
+
+    /**
      * @deprecated use {@link #getRotation}
      * @return orientation of this display.
      */
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 4f9dbd5..1b70232 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -131,11 +131,17 @@
     public static final int SCALING_MODE_NO_SCALE_CROP = 3;
 
     /** @hide */
-    @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
+    @IntDef({ROTATION_UNDEFINED, ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
     @Retention(RetentionPolicy.SOURCE)
     public @interface Rotation {}
 
     /**
+     * Rotation constant: undefined
+     * @hide
+     */
+    public static final int ROTATION_UNDEFINED = -1;
+
+    /**
      * Rotation constant: 0 degree rotation (natural orientation)
      */
     public static final int ROTATION_0 = 0;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index c329db4..2646d1c 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -724,6 +724,8 @@
  * @attr ref android.R.styleable#View_nextFocusUp
  * @attr ref android.R.styleable#View_onClick
  * @attr ref android.R.styleable#View_padding
+ * @attr ref android.R.styleable#View_paddingHorizontal
+ * @attr ref android.R.styleable#View_paddingVertical
  * @attr ref android.R.styleable#View_paddingBottom
  * @attr ref android.R.styleable#View_paddingLeft
  * @attr ref android.R.styleable#View_paddingRight
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index cb92a4c..ecdfa3f 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -7609,6 +7609,16 @@
      * See
      * {@link android.R.styleable#ViewGroup_MarginLayout ViewGroup Margin Layout Attributes}
      * for a list of all child view attributes that this class supports.
+     *
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_margin
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginHorizontal
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginVertical
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginLeft
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginTop
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginRight
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginBottom
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginStart
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd
      */
     public static class MarginLayoutParams extends ViewGroup.LayoutParams {
         /**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 86b19f4..e38a55f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1904,14 +1904,16 @@
                         + " outsets=" + mPendingOutsets.toShortString()
                         + " surface=" + mSurface);
 
-                final Configuration pendingMergedConfig =
-                        mPendingMergedConfiguration.getMergedConfiguration();
-                if (pendingMergedConfig.seq != 0) {
+                // If the pending {@link MergedConfiguration} handed back from
+                // {@link #relayoutWindow} does not match the one last reported,
+                // WindowManagerService has reported back a frame from a configuration not yet
+                // handled by the client. In this case, we need to accept the configuration so we
+                // do not lay out and draw with the wrong configuration.
+                if (!mPendingMergedConfiguration.equals(mLastReportedMergedConfiguration)) {
                     if (DEBUG_CONFIGURATION) Log.v(mTag, "Visible with new config: "
-                            + pendingMergedConfig);
+                            + mPendingMergedConfiguration.getMergedConfiguration());
                     performConfigurationChange(mPendingMergedConfiguration, !mFirst,
                             INVALID_DISPLAY /* same display */);
-                    pendingMergedConfig.seq = 0;
                     updatedConfiguration = true;
                 }
 
@@ -3596,6 +3598,13 @@
                 mView.setLayoutDirection(currentLayoutDirection);
             }
             mView.dispatchConfigurationChanged(config);
+
+            // We could have gotten this {@link Configuration} update after we called
+            // {@link #performTraversals} with an older {@link Configuration}. As a result, our
+            // window frame may be stale. We must ensure the next pass of {@link #performTraversals}
+            // catches this.
+            mForceNextWindowRelayout = true;
+            requestLayout();
         }
     }
 
@@ -3757,10 +3766,10 @@
                     SomeArgs args = (SomeArgs) msg.obj;
 
                     final int displayId = args.argi3;
-                    final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4;
+                    MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4;
                     final boolean displayChanged = mDisplay.getDisplayId() != displayId;
 
-                    if (mergedConfiguration != null) {
+                    if (!mLastReportedMergedConfiguration.equals(mergedConfiguration)) {
                         // If configuration changed - notify about that and, maybe, about move to
                         // display.
                         performConfigurationChange(mergedConfiguration, false /* force */,
@@ -6094,7 +6103,7 @@
         if (params != null) {
             if (DBG) Log.d(mTag, "WindowLayout in layoutWindow:" + params);
         }
-        mPendingMergedConfiguration.getMergedConfiguration().seq = 0;
+
         //Log.d(mTag, ">>>>>> CALLING relayout");
         if (params != null && mOrigWindowType != params.type) {
             // For compatibility with old apps, don't crash here.
@@ -7895,9 +7904,14 @@
 
         @Override
         public void run() {
-            // mSource may be changed in calls below.
+            // Protect against re-entrant code and attempt to do the right thing in the case that
+            // we're multithreaded.
             View source = mSource;
             mSource = null;
+            if (source == null) {
+                Log.e(TAG, "Accessibility content change has no source");
+                return;
+            }
             // The accessibility may be turned off while we were waiting so check again.
             if (AccessibilityManager.getInstance(mContext).isEnabled()) {
                 mLastEventTimeMillis = SystemClock.uptimeMillis();
@@ -7914,6 +7928,22 @@
         }
 
         public void runOrPost(View source, int changeType) {
+            if (mHandler.getLooper() != Looper.myLooper()) {
+                CalledFromWrongThreadException e = new CalledFromWrongThreadException("Only the "
+                        + "original thread that created a view hierarchy can touch its views.");
+                // TODO: Throw the exception
+                Log.e(TAG, "Accessibility content change on non-UI thread. Future Android "
+                        + "versions will throw an exception.", e);
+                // Attempt to recover. This code does not eliminate the thread safety issue, but
+                // it should force any issues to happen near the above log.
+                mHandler.removeCallbacks(this);
+                if (mSource != null) {
+                    // Dispatch whatever was pending. It's still possible that the runnable started
+                    // just before we removed the callbacks, and bad things will happen, but at
+                    // least they should happen very close to the logged error.
+                    run();
+                }
+            }
             if (mSource != null) {
                 // If there is no common predecessor, then mSource points to
                 // a removed view, hence in this case always prefer the source.
@@ -7930,12 +7960,12 @@
             if (timeSinceLastMillis >= minEventIntevalMillis) {
                 removeCallbacksAndRun();
             } else {
-                mSource.postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
+                mHandler.postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
             }
         }
 
         public void removeCallbacksAndRun() {
-            mSource.removeCallbacks(this);
+            mHandler.removeCallbacks(this);
             run();
         }
     }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 4c0a190..48f3973 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
@@ -27,6 +28,7 @@
 import android.content.pm.ActivityInfo;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -169,6 +171,18 @@
      */
     public void requestAppKeyboardShortcuts(final KeyboardShortcutsReceiver receiver, int deviceId);
 
+    /**
+     * Return the touch region for the current IME window, or an empty region if there is none.
+     *
+     * @return The region of the IME that is accepting touch inputs, or null if there is no IME, no
+     *         region or there was an error.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
+    public Region getCurrentImeTouchRegion();
+
     public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
         /**
          * X position for this window.  With the default gravity it is ignored.
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index c1b8f04..a8722f1 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.graphics.Region;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -145,4 +146,13 @@
     public Display getDefaultDisplay() {
         return mContext.getDisplay();
     }
+
+    @Override
+    public Region getCurrentImeTouchRegion() {
+        try {
+            return WindowManagerGlobal.getWindowManagerService().getCurrentImeTouchRegion();
+        } catch (RemoteException e) {
+        }
+        return null;
+    }
 }
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 5b04f41..e1e8317 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -741,7 +741,8 @@
     }
 
     /**
-     * Returns {@code true} if Autofill is supported for this user.
+     * Returns {@code true} if autofill is supported by the current device and
+     * is supported for this user.
      *
      * <p>Autofill is typically supported, but it could be unsupported in cases like:
      * <ol>
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 8fe9100..544afd9 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -3103,12 +3103,29 @@
     }
 
     /**
+     * Check if Setup or Post-Setup update is completed on TV
+     * @return true if completed
+     */
+    private boolean isTvUserSetupComplete() {
+        boolean isTvSetupComplete = Settings.Secure.getInt(getContext().getContentResolver(),
+                Settings.Secure.USER_SETUP_COMPLETE, 0) != 0;
+        isTvSetupComplete &= Settings.Secure.getInt(getContext().getContentResolver(),
+                Settings.Secure.TV_USER_SETUP_COMPLETE, 0) != 0;
+        return isTvSetupComplete;
+    }
+
+    /**
      * Helper method for adding launch-search to most applications. Opens the
      * search window using default settings.
      *
      * @return true if search window opened
      */
     private boolean launchDefaultSearch(KeyEvent event) {
+        if (getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)
+                && !isTvUserSetupComplete()) {
+            // If we are in Setup or Post-Setup update mode on TV, consume the search key
+            return false;
+        }
         boolean result;
         final Callback cb = getCallback();
         if (cb == null || isDestroyed()) {
diff --git a/core/java/com/android/internal/policy/PipSnapAlgorithm.java b/core/java/com/android/internal/policy/PipSnapAlgorithm.java
index 95d714f..749d00c1 100644
--- a/core/java/com/android/internal/policy/PipSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/PipSnapAlgorithm.java
@@ -49,9 +49,6 @@
     // Allows snapping on the long edge in each orientation and magnets towards corners
     private static final int SNAP_MODE_LONG_EDGE_MAGNET_CORNERS = 4;
 
-    // The friction multiplier to control how slippery the PIP is when flung
-    private static final float SCROLL_FRICTION_MULTIPLIER = 8f;
-
     // Threshold to magnet to a corner
     private static final float CORNER_MAGNET_THRESHOLD = 0.3f;
 
@@ -64,8 +61,8 @@
     private final float mDefaultSizePercent;
     private final float mMinAspectRatioForMinSize;
     private final float mMaxAspectRatioForMinSize;
+    private final int mFlingDeceleration;
 
-    private Scroller mScroller;
     private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
 
     private final int mMinimizedVisibleSize;
@@ -81,6 +78,8 @@
         mMaxAspectRatioForMinSize = res.getFloat(
                 com.android.internal.R.dimen.config_pictureInPictureAspectRatioLimitForMinSize);
         mMinAspectRatioForMinSize = 1f / mMaxAspectRatioForMinSize;
+        mFlingDeceleration = mContext.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.pip_fling_deceleration);
         onConfigurationChanged();
     }
 
@@ -107,20 +106,97 @@
      * those for the given {@param stackBounds}.
      */
     public Rect findClosestSnapBounds(Rect movementBounds, Rect stackBounds, float velocityX,
-            float velocityY) {
-        final Rect finalStackBounds = new Rect(stackBounds);
-        if (mScroller == null) {
-            final ViewConfiguration viewConfig = ViewConfiguration.get(mContext);
-            mScroller = new Scroller(mContext);
-            mScroller.setFriction(viewConfig.getScrollFriction() * SCROLL_FRICTION_MULTIPLIER);
+            float velocityY, Point dragStartPosition) {
+        final Rect intersectStackBounds = new Rect(stackBounds);
+        final Point intersect = getEdgeIntersect(stackBounds, movementBounds, velocityX, velocityY,
+                dragStartPosition);
+        intersectStackBounds.offsetTo(intersect.x, intersect.y);
+        return findClosestSnapBounds(movementBounds, intersectStackBounds);
+    }
+
+    /**
+     * @return The point along the {@param movementBounds} that the PIP would intersect with based
+     *         on the provided {@param velX}, {@param velY} along with the position of the PIP when
+     *         the gesture started, {@param dragStartPosition}.
+     */
+    public Point getEdgeIntersect(Rect stackBounds, Rect movementBounds, float velX, float velY,
+            Point dragStartPosition) {
+        final boolean isLandscape = mOrientation == Configuration.ORIENTATION_LANDSCAPE;
+        final int x = stackBounds.left;
+        final int y = stackBounds.top;
+
+        // Find the line of movement the PIP is on. Line defined by: y = slope * x + yIntercept
+        final float slope = velY / velX; // slope = rise / run
+        final float yIntercept = y - slope * x; // rearrange line equation for yIntercept
+        // The PIP can have two intercept points:
+        // 1) Where the line intersects with one of the edges of the screen (vertical line)
+        Point vertPoint = new Point();
+        // 2) Where the line intersects with the top or bottom of the screen (horizontal line)
+        Point horizPoint = new Point();
+
+        // Find the vertical line intersection, x will be one of the edges
+        vertPoint.x = velX > 0 ? movementBounds.right : movementBounds.left;
+        // Sub in x in our line equation to determine y position
+        vertPoint.y = findY(slope, yIntercept, vertPoint.x);
+
+        // Find the horizontal line intersection, y will be the top or bottom of the screen
+        horizPoint.y = velY > 0 ? movementBounds.bottom : movementBounds.top;
+        // Sub in y in our line equation to determine x position
+        horizPoint.x = findX(slope, yIntercept, horizPoint.y);
+
+        // Now pick one of these points -- first determine if we're flinging along the current edge.
+        // Only fling along current edge if it's a direction with space for the PIP to move to
+        int maxDistance;
+        if (isLandscape) {
+            maxDistance = velX > 0
+                    ? movementBounds.right - stackBounds.left
+                    : stackBounds.left - movementBounds.left;
+        } else {
+            maxDistance = velY > 0
+                    ? movementBounds.bottom - stackBounds.top
+                    : stackBounds.top - movementBounds.top;
         }
-        mScroller.fling(stackBounds.left, stackBounds.top,
-                (int) velocityX, (int) velocityY,
-                movementBounds.left, movementBounds.right,
-                movementBounds.top, movementBounds.bottom);
-        finalStackBounds.offsetTo(mScroller.getFinalX(), mScroller.getFinalY());
-        mScroller.abortAnimation();
-        return findClosestSnapBounds(movementBounds, finalStackBounds);
+        if (maxDistance > 0) {
+            // Only fling along the current edge if the start and end point are on the same side
+            final int startPoint = isLandscape ? dragStartPosition.y : dragStartPosition.x;
+            final int endPoint = isLandscape ? horizPoint.y : horizPoint.x;
+            final int center = movementBounds.centerX();
+            if ((startPoint < center && endPoint < center)
+                    || (startPoint > center && endPoint > center)) {
+                // We are flinging along the current edge, figure out how far it should travel
+                // based on velocity and assumed deceleration.
+                int distance = (int) (0 - Math.pow(isLandscape ? velX : velY, 2))
+                        / (2 * mFlingDeceleration);
+                distance = Math.min(distance, maxDistance);
+                // Adjust the point for the distance
+                if (isLandscape) {
+                    horizPoint.x = stackBounds.left + (velX > 0 ? distance : -distance);
+                } else {
+                    horizPoint.y = stackBounds.top + (velY > 0 ? distance : -distance);
+                }
+                return horizPoint;
+            }
+        }
+        // If we're not flinging along the current edge, find the closest point instead.
+        final double distanceVert = Math.hypot(vertPoint.x - x, vertPoint.y - y);
+        final double distanceHoriz = Math.hypot(horizPoint.x - x, horizPoint.y - y);
+        // Ensure that we're actually going somewhere
+        if (distanceVert == 0) {
+            return horizPoint;
+        }
+        if (distanceHoriz == 0) {
+            return vertPoint;
+        }
+        // Otherwise use the closest point
+        return Math.abs(distanceVert) > Math.abs(distanceHoriz) ? horizPoint : vertPoint;
+    }
+
+    private int findY(float slope, float yIntercept, float x) {
+        return (int) ((slope * x) + yIntercept);
+    }
+
+    private int findX(float slope, float yIntercept, float y) {
+        return (int) ((y - yIntercept) / slope);
     }
 
     /**
diff --git a/core/java/com/android/internal/util/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java
index 1ba92bf..0c046a9 100644
--- a/core/java/com/android/internal/util/NotificationColorUtil.java
+++ b/core/java/com/android/internal/util/NotificationColorUtil.java
@@ -534,7 +534,7 @@
     }
 
     public static boolean satisfiesTextContrast(int backgroundColor, int foregroundColor) {
-        return NotificationColorUtil.calculateContrast(backgroundColor, foregroundColor) >= 4.5;
+        return NotificationColorUtil.calculateContrast(foregroundColor, backgroundColor) >= 4.5;
     }
 
     /**
@@ -613,7 +613,7 @@
          */
         public static double calculateContrast(@ColorInt int foreground, @ColorInt int background) {
             if (Color.alpha(background) != 255) {
-                throw new IllegalArgumentException("background can not be translucent: #"
+                Log.wtf(TAG, "background can not be translucent: #"
                         + Integer.toHexString(background));
             }
             if (Color.alpha(foreground) < 255) {
diff --git a/core/jni/android/graphics/ColorFilter.cpp b/core/jni/android/graphics/ColorFilter.cpp
index 5553a3e..4b6578b 100644
--- a/core/jni/android/graphics/ColorFilter.cpp
+++ b/core/jni/android/graphics/ColorFilter.cpp
@@ -30,9 +30,12 @@
 
 class SkColorFilterGlue {
 public:
-    static void SafeUnref(JNIEnv* env, jobject clazz, jlong skFilterHandle) {
-        SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(skFilterHandle);
-        SkSafeUnref(filter);
+    static void SafeUnref(SkShader* shader) {
+        SkSafeUnref(shader);
+    }
+
+    static jlong GetNativeFinalizer(JNIEnv*, jobject) {
+        return static_cast<jlong>(reinterpret_cast<uintptr_t>(&SafeUnref));
     }
 
     static jlong CreatePorterDuffFilter(JNIEnv* env, jobject, jint srcColor, jint modeHandle) {
@@ -57,7 +60,7 @@
 };
 
 static const JNINativeMethod colorfilter_methods[] = {
-    {"nSafeUnref", "(J)V", (void*) SkColorFilterGlue::SafeUnref}
+    {"nativeGetFinalizer", "()J", (void*) SkColorFilterGlue::GetNativeFinalizer }
 };
 
 static const JNINativeMethod porterduff_methods[] = {
diff --git a/core/jni/android_os_HwBinder.cpp b/core/jni/android_os_HwBinder.cpp
index cdd3c09..6c6fa66 100644
--- a/core/jni/android_os_HwBinder.cpp
+++ b/core/jni/android_os_HwBinder.cpp
@@ -370,7 +370,7 @@
     if (transport != IServiceManager::Transport::HWBINDER && !vintfLegacy) {
         LOG(ERROR) << "service " << ifaceName << " declares transport method "
                    << toString(transport) << " but framework expects hwbinder.";
-        signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
+        signalExceptionForError(env, NAME_NOT_FOUND, true /* canThrowRemoteException */);
         return NULL;
     }
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b4c5025..be27048 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -146,6 +146,7 @@
     <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL" />
     <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST" />
     <protected-broadcast android:name="android.bluetooth.device.action.SDP_RECORD" />
+    <protected-broadcast android:name="android.bluetooth.device.action.BATTERY_LEVEL_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.devicepicker.action.LAUNCH" />
     <protected-broadcast android:name="android.bluetooth.devicepicker.action.DEVICE_SELECTED" />
     <protected-broadcast
@@ -302,6 +303,7 @@
     <protected-broadcast android:name="com.android.server.WifiManager.action.DEVICE_IDLE" />
     <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED" />
     <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED" />
+    <protected-broadcast android:name="com.android.server.action.WIPE_EUICC_DATA" />
     <protected-broadcast android:name="com.android.server.usb.ACTION_OPEN_IN_APPS" />
     <protected-broadcast android:name="com.android.server.am.DELETE_DUMPHEAP" />
     <protected-broadcast android:name="com.android.server.net.action.SNOOZE_WARNING" />
diff --git a/core/res/res/anim/task_close_enter.xml b/core/res/res/anim/task_close_enter.xml
index b07f470..bea0ee5 100644
--- a/core/res/res/anim/task_close_enter.xml
+++ b/core/res/res/anim/task_close_enter.xml
@@ -18,7 +18,7 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal">
+        android:shareInterpolator="false" android:zAdjustment="normal">
 
     <alpha android:fromAlpha="0.6" android:toAlpha="1.0"
             android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
diff --git a/core/res/res/anim/task_close_exit.xml b/core/res/res/anim/task_close_exit.xml
index d23c74f..b6a0807 100644
--- a/core/res/res/anim/task_close_exit.xml
+++ b/core/res/res/anim/task_close_exit.xml
@@ -18,7 +18,7 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top">
+        android:shareInterpolator="false" android:zAdjustment="top">
 
     <alpha android:fromAlpha="1.0" android:toAlpha="0"
             android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
diff --git a/core/res/res/layout-land/time_picker_material.xml b/core/res/res/layout-land/time_picker_material.xml
index 863efef..d83ccb2 100644
--- a/core/res/res/layout-land/time_picker_material.xml
+++ b/core/res/res/layout-land/time_picker_material.xml
@@ -17,6 +17,7 @@
 
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layoutDirection="ltr"
     android:layout_width="match_parent"
     android:layout_height="wrap_content">
 
@@ -30,6 +31,7 @@
 
         <LinearLayout
             android:id="@+id/time_layout"
+            android:layoutDirection="ltr"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:paddingTop="@dimen/timepicker_radial_picker_top_margin"
diff --git a/core/res/res/layout/notification_template_right_icon.xml b/core/res/res/layout/notification_template_right_icon.xml
index aa4e05b..fbf7538 100644
--- a/core/res/res/layout/notification_template_right_icon.xml
+++ b/core/res/res/layout/notification_template_right_icon.xml
@@ -26,8 +26,9 @@
                android:layout_gravity="top|end"
                android:layout_marginTop="36dp"
                android:layout_marginEnd="@dimen/notification_content_margin_end"
-               android:scaleType="centerCrop"/>
-    <ImageView android:id="@+id/reply_icon_action"
+               android:scaleType="centerCrop"
+               android:importantForAccessibility="no" />
+    <ImageButton android:id="@+id/reply_icon_action"
                android:layout_width="16dp"
                android:layout_height="16dp"
                android:layout_gravity="top|end"
@@ -36,6 +37,7 @@
                android:background="@drawable/notification_reply_background"
                android:src="@drawable/ic_reply_notification"
                android:scaleType="center"
+               android:contentDescription="@string/notification_reply_button_accessibility"
                visiblity="gone"/>
 </FrameLayout>
 
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 3c74328..b0b6404 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Soek vir diens"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-oproepe"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Om oproepe te maak en boodskappe oor Wi-Fi te stuur, vra jou diensverskaffer eers om hierdie diens op te stel. Skakel Wi-Fi-oproepe dan weer in Instellings aan."</item>
+    <item msgid="3910386316304772394">"Om oproepe te maak en boodskappe oor Wi-Fi te stuur, vra eers jou diensverskaffer om hierdie diens op te stel. Skakel Wi-Fi-oproepe dan weer in Instellings aan. (Foutkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registreer by jou diensverskaffer"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Oop Wi-Fi-netwerke beskikbaar</item>
       <item quantity="one">Oop Wi-Fi-netwerk beskikbaar</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Koppel aan oop Wi-Fi-netwerk"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Koppel tans aan oop Wi‑Fi-netwerk"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Aan Wi-Fi-netwerk gekoppel"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Kon nie aan Wi-Fi-netwerk koppel nie"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tik om alle netwerke te sien"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Koppel"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle netwerke"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Meld aan by Wi-Fi-netwerk"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Meld by netwerk aan"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index d1611d7..28889fe 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"አገልግሎት ፍለጋ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"የWi-Fi ጥሪ ማድረጊያ"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ መጠየቅ አለብዎት። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ።"</item>
+    <item msgid="3910386316304772394">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ መጠየቅ አለብዎት። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ። (የስህተት ኮድ፦ <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"የአገልግሎት አቅራቢዎ ጋር ይመዝገቡ"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">የሚገኙ የWi-Fi አውታረ መረቦችን ክፈት</item>
       <item quantity="other">የሚገኙ የWi-Fi አውታረ መረቦችን ክፈት</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"ከክፍት የWi‑Fi አውታረ መረብ ጋር ያገናኙ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ከክፍት የWi‑Fi አውታረ መረብ ጋር በመገናኘት ላይ"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"ከWi‑Fi አውታረ መረብ ጋር ተገናኝቷል"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ከWi‑Fi አውታረ መረብ ጋር መገናኘት አልተቻለም"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ሁሉንም አውታረ መረቦችን ለማየት መታ ያድርጉ"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"አገናኝ"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ሁሉም አውታረ መረቦች"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ወደ Wi-Fi አውታረ መረብ በመለያ ግባ"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ወደ አውታረ መረብ በመለያ ይግቡ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index bd023a5..39348f2 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -135,7 +135,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"البحث عن خدمة"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"‏الاتصال عبر Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"‏لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذا الجهاز، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات."</item>
+    <item msgid="3910386316304772394">"‏لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذه الخدمة، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات. (رمز الخطأ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"التسجيل لدى مشغّل شبكة الجوّال"</item>
@@ -1194,20 +1194,13 @@
       <item quantity="other">‏تتوفر شبكات Wi-Fi مفتوحة</item>
       <item quantity="one">‏تتوفر شبكة Wi-Fi واحدة مفتوحة</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"‏الاتصال بشبكة Wi-Fi المفتوحة"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"‏جارٍ الاتصال بشبكة Wi-Fi المفتوحة"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"‏تم الاتصال بشبكة Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"‏تعذَّر الاتصال بشبكة Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"انقر للاطلاع على جميع الشبكات"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"اتصال"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"جميع الشبكات"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"‏تسجيل الدخول إلى شبكة Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"تسجيل الدخول إلى الشبكة"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 0cac6e8..6f39f7b 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Xidmət axtarılır"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi zəngi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi üzərindən zəng etmək və mesaj göndərmək üçün ilk öncə operatordan bu xidməti ayarlamağı tələb edin. Sonra Ayarlardan Wi-Fi çağrısını aktivləşdirin."</item>
+    <item msgid="3910386316304772394">"Zəng etmək və Wi-Fi üzərindən mesaj göndərmək üçün əvvəlcə operatordan bu cihazı quraşdırmağı tələb edin. Sonra Ayarlardan Wi-Fi zəngini deaktiv edin. (Xəta kodu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Operatorla qeydiyyatdan keçin"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Əlçatan açıq Wi-Fi şəbəkələri</item>
       <item quantity="one">Əlçatan açıq Wi-Fi şəbəkəsi</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Açıq Wi‑Fi şəbəkəsinə qoşulun"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Açıq Wi‑Fi şəbəkəsinə qoşulur"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi şəbəkəsinə qoşuldu"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi şəbəkəsinə qoşulmaq mümkün deyil"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Bütün şəbəkələri görmək üçün klikləyin"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Qoşulun"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Bütün Şəbəkələr"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi şəbəkəsinə daxil ol"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Şəbəkəyə daxil olun"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 574a181..0be7892 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -132,7 +132,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Pretraživanje usluge"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Pozivanje preko Wi-Fi-ja"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Da biste upućivali pozive i slali poruke preko Wi-Fi-ja, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko Wi-Fi-ja."</item>
+    <item msgid="3910386316304772394">"Da biste upućivali pozive i slali poruke preko Wi-Fi-ja, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko Wi-Fi-ja. (kôd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrujte se kod mobilnog operatera"</item>
@@ -1128,20 +1128,13 @@
       <item quantity="few">Otvorene Wi-Fi mreže su dostupne</item>
       <item quantity="other">Otvorene Wi-Fi mreže su dostupne</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Povežite se sa otvorenom Wi‑Fi mrežom"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Povezujete se sa otvorenom Wi‑Fi mrežom"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Povezali ste se sa Wi‑Fi mrežom"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Povezivanje sa Wi‑Fi mrežom nije uspelo"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite da biste videli sve mreže"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Poveži"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Sve mreže"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijavljivanje na Wi-Fi mrežu"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prijavite se na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index e883e97..5f1cad3 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -133,7 +133,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Пошук службы"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-тэлефанія"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Каб рабіць выклікі і адпраўляць паведамленні па Wi-Fi, спачатку папрасіце свайго аператара наладзіць гэту паслугу. Затым зноў уключыце Wi-Fi-тэлефанію ў меню Налады."</item>
+    <item msgid="3910386316304772394">"Каб рабіць выклікі і адпраўляць паведамленні па Wi-Fi, спачатку папрасіце свайго аператара наладзіць гэту паслугу. Затым зноў уключыце Wi-Fi-тэлефанію ў меню Налады. (Код памылкі: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Зарэгіструйцеся ў свайго аператара"</item>
@@ -1150,20 +1150,13 @@
       <item quantity="many">адкрытых сетак Wi-Fi даступна</item>
       <item quantity="other">адкрытай сеткі Wi-Fi даступна</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Падключыцеся да адкрытай сеткі Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ідзе падключэнне да адкрытай сеткі Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Выканана падключэнне да адкрытай сеткі Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не атрымалася падключыцца да адкрытай сеткі Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Дакраніцеся, каб убачыць усе сеткі"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Падключыцца"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Усе сеткі"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Уваход у сетку Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Увайдзіце ў сетку"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 7f81b4e..3018054 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Търси се покритие"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Обаждания през Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"За да извършвате обаждания и да изпращате съобщения през Wi-Fi, първо помолете оператора си да настрои тази услуга. След това включете отново функцията за обаждания през Wi-Fi от настройките."</item>
+    <item msgid="3910386316304772394">"За да извършвате обаждания и да изпращате съобщения през Wi-Fi, първо, помолете оператора си да настрои тази услуга. След това включете отново функцията за обаждания през Wi-Fi от настройките. (Код на грешката: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Регистриране с оператора ви"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Има достъпни отворени Wi-Fi мрежи</item>
       <item quantity="one">Има достъпна отворена Wi-Fi мрежа</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Свързване с отворена Wi‑Fi мрежа"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Установява се връзка с отворена Wi‑Fi мрежа"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Установихте връзка с Wi-Fi мрежата"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не можа да се установи връзка с Wi‑Fi мрежата"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Докоснете, за да видите всички мрежи"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Свързване"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Всички мрежи"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Влизане в Wi-Fi мрежа"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Вход в мрежата"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 2b49abd..77ea921 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -130,9 +130,7 @@
     <string name="roamingText12" msgid="1189071119992726320">"রোমিং ব্যানার বন্ধ আছে"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"পরিষেবা অনুসন্ধান করা হচ্ছে"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ওয়াই-ফাই কলিং"</string>
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"ওয়াই-ফাই এর মাধ্যমে কল করতে ও বার্তা পাঠাতে, প্রথমে আপনার পরিষেবা প্রদানকারীকে এই পরিষেবার সেট আপ করার বিষয়ে জিজ্ঞাসা করুন। তারপরে আবার সেটিংস থেকে ওয়াই-ফাই কলিং চালু করুন।"</item>
-  </string-array>
+    <!-- no translation found for wfcOperatorErrorAlertMessages:0 (3910386316304772394) -->
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"আপনার পরিষেবা প্রদানকারীকে নথিভুক্ত করুন"</item>
   </string-array>
@@ -1106,20 +1104,13 @@
       <item quantity="one">খোলা ওয়াই-ফাই নেটওয়ার্কগুলি উপলব্ধ রয়েছে</item>
       <item quantity="other">খোলা ওয়াই-ফাই নেটওয়ার্কগুলি উপলব্ধ রয়েছে</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"উন্মুক্ত ওয়াই-ফাই নেটওয়ার্কে সংযোগ করুন"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"উন্মুক্ত ওয়াই-ফাই নেটওয়ার্কে সংযোগ করা হচ্ছে"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"উন্মুক্ত ওয়াই-ফাই নেটওয়ার্কে সংযুক্ত করা হয়েছে"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ওয়াই-ফাই নেটওয়ার্কে সংযোগ করা গেল না"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"সমস্ত নেটওয়ার্ক দেখতে ট্যাপ করুন"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"সংযুক্ত করুন"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"সমস্ত নেটওয়ার্ক"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ওয়াই-ফাই নেটওয়ার্কে প্রবেশ করুন"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"নেটওয়ার্কে প্রবেশ করুন"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 002689f6..5188743 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -132,7 +132,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Traženje usluge"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi pozivanje"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Da biste pozivali i slali poruke preko Wi-Fi-ja, prvo zatražite od operatera da postavi tu uslugu. Potom u Postavkama ponovo uključite Wi-Fi pozivanje."</item>
+    <item msgid="3910386316304772394">"Da biste pozivali i slali poruke koristeći Wi-Fi mrežu, prvo zatražite od operatera da postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozivanje u Postavkama. (Kôd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrirajte se kod svog operatera"</item>
@@ -1130,20 +1130,13 @@
       <item quantity="few">Otvorene Wi-Fi mreže su dostupne</item>
       <item quantity="other">Otvorene Wi-Fi mreže su dostupne</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Povežite se na otvorenu Wi‑Fi mrežu"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Povezivanje na otvorenu Wi‑Fi mrežu"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Povezani ste na Wi‑Fi mrežu"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nije se moguće povezati na Wi‑Fi mrežu"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite da vidite sve mreže"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Povežite se"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Sve mreže"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijavljivanje na Wi-Fi mrežu"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index f7a41cc..fc86c87 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"S\'està cercant el servei"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Trucades per Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Per fer trucades i enviar missatges per Wi-Fi, primer has de demanar a l\'operador de telefonia mòbil que configuri aquest servei. Després, torna a activar les trucades per Wi-Fi des de Configuració."</item>
+    <item msgid="3910386316304772394">"Per fer trucades i enviar missatges per Wi-Fi, primer has de demanar a l\'operador de telefonia mòbil que configuri aquest servei. Després, torna a activar les trucades per Wi-Fi a Configuració. (Codi d\'error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registra\'t amb el teu operador de telefonia mòbil"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Xarxes Wi-Fi obertes disponibles</item>
       <item quantity="one">Xarxa Wi-Fi oberta disponible</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Connecta\'t a una xarxa Wi-Fi oberta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"S\'està connectant a una xarxa Wi-Fi oberta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"S\'ha connectat a la xarxa Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"No s\'ha pogut connectar a una xarxa Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca per veure totes les xarxes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connecta"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Totes les xarxes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Inicia la sessió a la xarxa Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Inicia la sessió a la xarxa"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1631,9 +1624,9 @@
     <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"No es pot deixar de fixar aquesta aplicació"</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fixada"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"Fixació de la pantalla anul·lada"</string>
-    <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Sol·licita el codi PIN per anul·lar"</string>
-    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Sol·licita el patró de desbloqueig per anul·lar"</string>
-    <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demana la contrasenya per anul·lar"</string>
+    <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Sol·licita el codi PIN per deixar de fixar"</string>
+    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Sol·licita el patró de desbloqueig per deixar de fixar"</string>
+    <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demana la contrasenya per deixar de fixar"</string>
     <string name="package_installed_device_owner" msgid="6875717669960212648">"Instal·lat per l\'administrador"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Actualitzat per l\'administrador"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Suprimit per l\'administrador"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 6d0f373..74c2474 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -133,7 +133,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Vyhledávání služby"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Volání přes Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Chcete-li volat a odesílat textové zprávy přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení."</item>
+    <item msgid="3910386316304772394">"Chcete-li volat a odesílat SMS přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení. (Kód chyby: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrace u operátora"</item>
@@ -1150,20 +1150,13 @@
       <item quantity="other">K dispozici jsou veřejné sítě Wi-Fi</item>
       <item quantity="one">K dispozici je veřejná síť Wi-Fi</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Připojení k otevřené síti Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Připojování k otevřené síti Wi-Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Připojeno k síti Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Připojení k síti Wi-Fi se nezdařilo"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Klepnutím zobrazíte všechny sítě"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Připojit"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Všechny sítě"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Přihlásit se k síti Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Přihlásit se k síti"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index bd216a6..48a4f9e 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Søger efter tjeneste"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Opkald via Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Hvis du vil foretage opkald og sende beskeder via Wi-Fi, skal du først anmode dit mobilselskab om at konfigurere denne tjeneste. Derefter skal du slå Wi-Fi-opkald til igen fra Indstillinger."</item>
+    <item msgid="3910386316304772394">"Hvis du vil foretage opkald og sende beskeder via Wi-Fi, skal du først anmode dit mobilselskab om at konfigurere denne tjeneste. Derefter skal du aktivere Wi-Fi-opkald igen fra Indstillinger. (Fejlkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrer dig hos dit mobilselskab"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">Åbne Wi-Fi-netværk er tilgængelige</item>
       <item quantity="other">Åbne Wi-Fi-netværk er tilgængelige</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Opret forbindelse til et åbent Wi-Fi-netværk"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Opretter forbindelse til et åbent Wi‑Fi-netværk"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Forbundet til Wi-Fi-netværket"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Der kan ikke oprettes forbindelse til Wi-Fi-netværket"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tryk for at se alle netværk"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Opret forbindelse"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle netværk"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Log ind på Wi-Fi-netværk"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Log ind på netværk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index f6c9143..4b4a604 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Suche nach Dienst"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Anrufe über WLAN"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann erneut über die Einstellungen."</item>
+    <item msgid="3910386316304772394">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann noch einmal über die Einstellungen. (Fehlercode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registriere dich bei deinem Mobilfunkanbieter."</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Verfügbare WLAN-Netzwerke öffnen</item>
       <item quantity="one">Verfügbares WLAN-Netzwerk öffnen</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Mit offenem WLAN verbinden"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Verbindung mit offenem WLAN wird hergestellt"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Mit WLAN verbunden"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"WLAN-Verbindung konnte nicht hergestellt werden"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tippen, um alle Netzwerke zu sehen"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Verbinden"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle Netzwerke"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"In WLAN-Netzwerk anmelden"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Im Netzwerk anmelden"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index cf8567e..969ef24 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Αναζήτηση υπηρεσιών"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Κλήση Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Για να κάνετε κλήσεις και να στέλνετε μηνύματα μέσω Wi-Fi, ζητήστε πρώτα από την εταιρεία κινητής τηλεφωνίας να ρυθμίσει την υπηρεσία. Στη συνέχεια, ενεργοποιήστε ξανά τη λειτουργία κλήσεων μέσω Wi-Fi από τις Ρυθμίσεις."</item>
+    <item msgid="3910386316304772394">"Για να κάνετε κλήσεις και να στέλνετε μηνύματα μέσω Wi-Fi, ζητήστε πρώτα από την εταιρεία κινητής τηλεφωνίας να ρυθμίσει την υπηρεσία. Στη συνέχεια, ενεργοποιήστε ξανά την Κλήση Wi-Fi από τις Ρυθμίσεις. (Κωδικός σφάλματος: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Εγγραφείτε μέσω της εταιρείας κινητής τηλεφωνίας"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Υπάρχουν διαθέσιμα ανοικτά δίκτυα Wi-Fi</item>
       <item quantity="one">Υπάρχει διαθέσιμο ανοικτό δίκτυο Wi-Fi</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Σύνδεση σε ανοιχτό δίκτυο Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Σύνδεση σε ανοιχτό δίκτυο Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ολοκληρώθηκε η σύνδεση στο δίκτυο Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Δεν ήταν δυνατή η σύνδεση σε δίκτυο Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Πατήστε για να δείτε όλα τα δίκτυα"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Σύνδεση"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Όλα τα δίκτυα"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Συνδεθείτε στο δίκτυο Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Σύνδεση στο δίκτυο"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 36d458b..fea0c69 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Searching for Service"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+    <item msgid="3910386316304772394">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Register with your operator"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Open Wi-Fi networks available</item>
       <item quantity="one">Open Wi-Fi network available</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Connect to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connecting to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connected to Wi‑Fi network"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Could not connect to Wi‑Fi network"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"All Networks"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Sign in to a Wi-Fi network"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 36d458b..fea0c69 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Searching for Service"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+    <item msgid="3910386316304772394">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Register with your operator"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Open Wi-Fi networks available</item>
       <item quantity="one">Open Wi-Fi network available</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Connect to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connecting to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connected to Wi‑Fi network"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Could not connect to Wi‑Fi network"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"All Networks"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Sign in to a Wi-Fi network"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 36d458b..fea0c69 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Searching for Service"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+    <item msgid="3910386316304772394">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Register with your operator"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Open Wi-Fi networks available</item>
       <item quantity="one">Open Wi-Fi network available</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Connect to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connecting to open Wi‑Fi network"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connected to Wi‑Fi network"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Could not connect to Wi‑Fi network"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"All Networks"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Sign in to a Wi-Fi network"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 01487dd..e8d25c6 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Buscando servicio"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Llamada por Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para realizar llamadas o enviar mensajes por Wi-Fi, primero solicítale al proveedor que instale el servicio. Luego, vuelve a activar las llamadas por Wi-Fi desde Configuración."</item>
+    <item msgid="3910386316304772394">"Para hacer llamadas y enviar mensajes mediante Wi-Fi, solicítale a tu proveedor que configure este servicio. Luego, vuelve a activar la Llamada con Wi-Fi en Configuración. (código de error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Regístrate con tu proveedor."</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Abrir redes de Wi-Fi disponibles</item>
       <item quantity="one">Abrir red de Wi-Fi disponible</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conectarse a una red Wi-Fi abierta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectándose a una red Wi-Fi abierta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Se conectó a la red Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"No fue posible conectarse a la red Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Presiona para ver todas las redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas las redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Accede a una red Wi-Fi."</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Acceder a la red"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 8e01520..33bfa1a 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Buscando servicio"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Llamadas Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para hacer llamadas y enviar mensajes por Wi-Fi, debes pedir antes a tu operador que configure este servicio. Una vez hecho esto, vuelva a activar las llamadas Wi-Fi en Ajustes."</item>
+    <item msgid="3910386316304772394">"Para hacer llamadas y enviar mensajes por Wi-Fi, pide antes a tu operador que configure este servicio. Una vez hecho esto, vuelva a activar la llamada por Wi-Fi en Ajustes. (Código de error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Regístrate con tu operador"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Redes Wi-Fi abiertas disponibles</item>
       <item quantity="one">Red Wi-Fi abierta disponible</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conectarse a una red Wi-Fi abierta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectándose a una red Wi-Fi abierta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Conectado a la red Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"No se ha podido conectar a la red Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca para ver todas las redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectarse"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas las redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Iniciar sesión en red Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Iniciar sesión en la red"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 9e67663..070ce29 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Teenuse otsimine"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"WiFi-kõned"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Üle WiFi-võrgu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse."</item>
+    <item msgid="3910386316304772394">"WiFi-võrgu kaudu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse. (Veakood: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registreeruge operaatori juures"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Avatud WiFi-võrgud on saadaval</item>
       <item quantity="one">Avatud WiFi-võrk on saadaval</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Looge ühendus avatud WiFi-võrguga"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ühenduse loomine avatud WiFi-võrguga"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ühendatud WiFi-võrguga"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"WiFi-võrguga ei õnnestunud ühendust luua"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Puudutage kõikide võrkude nägemiseks"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ühenda"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Kõik võrgud"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Logi sisse WiFi-võrku"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Võrku sisselogimine"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 2b13cd9..cea36c1 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Zerbitzu bila"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi bidezko deiak"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean."</item>
+    <item msgid="3910386316304772394">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean. (Errore-kodea: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Erregistratu operadorearekin"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Wi-Fi sare irekiak erabilgarri</item>
       <item quantity="one">Wi-Fi sare irekia erabilgarri</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Konektatu Wi‑Fi sare irekira"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Wi‑Fi sare irekira konektatzen"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi sare irekira konektatuta"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Ezin izan da konektatu Wi‑Fi sare irekira"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Sakatu hau sare guztiak ikusteko"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Konektatu"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Sare guztiak"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Hasi saioa Wi-Fi sarean"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Hasi saioa sarean"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index aaf6ea3..edcfbc2 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"جستجوی سرویس"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"‏تماس از طریق Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"‏برای برقراری تماس و ارسال پیام از طریق Wi-Fi، ابتدا از شرکت مخابراتی‌تان درخواست کنید این سرویس را راه‌اندازی کند. سپس دوباره از تنظیمات، تماس Wi-Fi را روشن کنید."</item>
+    <item msgid="3910386316304772394">"‏برای برقراری تماس و ارسال پیام ازطریق Wi-Fi، ابتدا از شرکت مخابراتی خود بخواهید این سرویس را تنظیم کند. سپس در «تنظیمات»۷ دوباره «تماس ازطریق Wi-Fi» را روشن کنید. (کد خطا: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"ثبت‌نام با شرکت مخابراتی شما"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">‏شبکه Wi-Fi باز در دسترس</item>
       <item quantity="other">‏شبکه‌ Wi-Fi باز در دسترس</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"‏اتصال به شبکه Wi‑Fi باز"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"‏درحال اتصال به شبکه Wi‑Fi باز"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"‏به شبکه Wi‑Fi متصل شد"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"‏به شبکه Wi-Fi متصل نشد"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"برای دیدن همه شبکه‌ها ضربه بزنید"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"اتصال"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"همه شبکه‌ها"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"‏ورود به شبکه Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ورود به سیستم شبکه"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 3eef3e5..6e8346b 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Etsitään signaalia"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-puhelut"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Jos haluat soittaa puheluita ja lähettää viestejä Wi-Fin kautta, pyydä ensin operaattoriasi ottamaan tämä palvelu käyttöön. Ota sitten Wi-Fi-puhelut käyttöön asetuksissa."</item>
+    <item msgid="3910386316304772394">"Jos haluat soittaa puheluita ja lähettää viestejä Wi-Fin kautta, pyydä ensin operaattoriasi ottamaan tämä palvelu käyttöön. Ota sitten Wi-Fi-puhelut käyttöön asetuksissa. (Virhekoodi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Rekisteröidy operaattorisi asiakkaaksi."</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Avoimia Wi-Fi-verkkoja käytettävissä</item>
       <item quantity="one">Avoin Wi-Fi-verkko käytettävissä</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Yhdistä avoimeen Wi‑Fi-verkkoon"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Yhdistetään avoimeen Wi‑Fi-verkkoon"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Yhdistetty Wi-Fi-verkkoon"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi-verkkoon yhdistäminen epäonnistui"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Napauta, niin näet kaikki verkot."</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Yhdistä"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Kaikki verkot"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Kirjaudu Wi-Fi-verkkoon"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Kirjaudu verkkoon"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 9cdf016..57e5fd1 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Recherche des services disponibles"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Appels Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Pour effectuer des appels et envoyer des messages par Wi-Fi, demandez tout d\'abord à votre fournisseur de services de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
+    <item msgid="3910386316304772394">"Pour effectuer des appels et envoyer des messages par Wi-Fi, demandez tout d\'abord à votre fournisseur de services de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres. (Code d\'erreur : <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Inscrivez-vous auprès de votre fournisseur de services"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">Réseau Wi-Fi ouvert à proximité</item>
       <item quantity="other">Réseaux Wi-Fi ouverts à proximité</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Connectez-vous pour ouvrir un réseau Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connexion en cours au réseau Wi-Fi ouvert…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connecté au réseau Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Impossible de se connecter au réseau Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Touchez pour afficher tous les réseaux"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connexion"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tous les réseaux"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Connectez-vous au réseau Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Connectez-vous au réseau"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index adacfa5..b5fd454 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Recherche des services disponibles"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Appels Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Pour effectuer des appels et envoyer des messages via le Wi-Fi, demandez tout d\'abord à votre opérateur de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
+    <item msgid="3910386316304772394">"Pour passer des appels et envoyer des messages via le Wi-Fi, demandez d\'abord à votre opérateur de configurer ce service. Ensuite, réactivez les appels Wi-Fi dans les paramètres. (Code d\'erreur : <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Inscrivez-vous auprès de votre opérateur."</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">Réseau Wi-Fi ouvert disponible</item>
       <item quantity="other">Réseaux Wi-Fi ouverts disponibles</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Se connecter pour ouvrir le réseau Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connexion pour ouvrir un réseau Wi-Fi…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connecté au réseau Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Impossible de se connecter au réseau Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Appuyer pour afficher tous les réseaux"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Se connecter"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tous les réseaux"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Connectez-vous au réseau Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Se connecter au réseau"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index ba56c62..b62ca2d 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Buscando servizo"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas por wifi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro pídelle ao teu operador que configure este servizo. A continuación, activa de novo as chamadas wifi en Configuración."</item>
+    <item msgid="3910386316304772394">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro solicítalle ao operador que configure este servizo. Despois, activa de novo as chamadas por wifi en Configuración. (Código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Rexístrate co teu operador"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Abrir redes wifi dispoñibles</item>
       <item quantity="one">Abrir rede wifi dispoñible</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conéctate a unha rede wifi aberta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectándose á rede wifi aberta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Conectouse á rede wifi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Non se puido conectar á rede wifi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca para ver todas as redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectarse"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas as redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Inicia sesión na rede wifi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Inicia sesión na rede"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 02311be..6dc0e0c 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"સેવા શોધી રહ્યું છે"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi કૉલિંગ"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi પર કૉલ્સ કરવા અને સંદેશા મોકલવા માટે, પહેલા તમારા કેરીઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી Wi-Fi કૉલિંગ ચાલુ કરો."</item>
+    <item msgid="3910386316304772394">"Wi-Fi પરથી કૉલ કરવા અને સંદેશા મોકલવા માટે પહેલા તમારા કૅરિઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી Wi-Fi કૉલિંગ ફરીથી ચાલુ કરો. (ભૂલ કોડ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"તમારા કેરીઅર સાથે નોંધણી કરો"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">ખુલ્લા Wi-Fi નેટવર્ક્સ ઉપલબ્ધ છે</item>
       <item quantity="other">ખુલ્લા Wi-Fi નેટવર્ક્સ ઉપલબ્ધ છે</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"ખુલ્લા Wi‑Fi નેટવર્ક સાથે કનેક્ટ કરો"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ખુલ્લા Wi‑Fi નેટવર્ક સાથે કનેક્ટ કરી રહ્યાં છીએ"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi નેટવર્ક સાથે કનેક્ટ કર્યુ"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi નેટવર્ક સાથે કનેક્ટ કરી શકાયું નથી"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"બધા નેટવર્ક જોવા ટૅપ કરો"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"કનેક્ટ કરો"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"બધા નેટવર્ક"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi નેટવર્ક પર સાઇન ઇન કરો"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"નેટવર્ક પર સાઇન ઇન કરો"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index be1233a..e534488 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"सेवा खोज रहा है"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"वाई-फ़ाई कॉलिंग"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"वाई-फ़ाई से कॉल करने और संदेश भेजने के लिए, सबसे पहले अपने वाहक से इस सेवा को सेट करने के लिए कहें. उसके बाद सेटिंग से पुन: वाई-फ़ाई कॉलिंग चालू करें."</item>
+    <item msgid="3910386316304772394">"वाई-फ़ाई से कॉल करने और संदेश भेजने के लिए, सबसे पहले अपने वाहक से इस सेवा को सेट करने के लिए कहें. उसके बाद सेटिंग से वाई-फ़ाई कॉलिंग को दोबारा चालू करें. (गड़बड़ी कोड: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"अपने वाहक के साथ पंजीकृत करें"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">खुले वाई-फ़ाई नेटवर्क उपलब्‍ध</item>
       <item quantity="other">खुले वाई-फ़ाई नेटवर्क उपलब्‍ध</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"खुले वाई-फ़ाई नेटवर्क से कनेक्ट करें"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"खुले वाई-फ़ाई नेटवर्क से कनेक्ट हो रहा है"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"वाई-फ़ाई नेटवर्क से कनेक्‍ट हो गया है"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"वाई-फ़ाई  नेटवर्क से कनेक्‍ट नहीं हो सका"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सभी नेटवर्क देखने के लिए यहां पर टैप करें"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"कनेक्ट करें"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"सभी नेटवर्क"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"वाई-फ़ाई  नेटवर्क में प्रवेश करें"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"नेटवर्क में प्रवेश करें"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 507920a..ae5bdea 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -132,7 +132,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Pretraživanje usluge"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi pozivi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Da biste telefonirali i slali pozive putem Wi-Fi-ja, morate tražiti od mobilnog operatera da vam postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozive u Postavkama."</item>
+    <item msgid="3910386316304772394">"Da biste telefonirali i slali poruke putem Wi-Fi-ja, od mobilnog operatera morate tražiti da postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozive u postavkama. (Kôd pogreške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrirajte se kod mobilnog operatera"</item>
@@ -1128,20 +1128,13 @@
       <item quantity="few">Dostupne su otvorene Wi-Fi mreže</item>
       <item quantity="other">Dostupne su otvorene Wi-Fi mreže</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Povezivanje s otvorenom Wi‑Fi mrežom"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Povezivanje s otvorenom Wi‑Fi mrežom"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Povezano s Wi-Fi mrežom"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nije uspjelo povezivanje s Wi-Fi mrežom"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite za prikaz svih mreža"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Poveži"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Sve mreže"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijava na Wi-Fi mrežu"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 7562bbc..cc71def 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Szolgáltatás keresése"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-hívás"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Ha Wi-Fi-n szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután a Beállítások menüben kapcsolhatja be újra a Wi-Fi-hívást."</item>
+    <item msgid="3910386316304772394">"Ha Wi-Fi-hálózaton szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután kapcsolja be újra a Wi-Fi-hívást a Beállításokban. (Hibakód: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Regisztráljon a szolgáltatójánál"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Nyílt Wi-Fi hálózatok érhetők el</item>
       <item quantity="one">Nyílt Wi-Fi hálózat érhető el</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Nyílt Wi-Fi-hálózathoz kapcsolódhat"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Kapcsolódás nyílt Wi‑Fi-hálózathoz…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Sikeres kapcsolódás a Wi-Fi-hálózathoz"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nem sikerült kapcsolódni a Wi‑Fi-hálózathoz"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Koppintással megjelenítheti az összes hálózatot"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kapcsolódás"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Összes hálózat"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Bejelentkezés Wi-Fi hálózatba"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Bejelentkezés a hálózatba"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index c3a2e90..0f67744 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Ծառայության որոնում..."</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Զանգեր Wi-Fi-ի միջոցով"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi-ի միջոցով զանգեր կատարելու և հաղորդագրություններ ուղարկելու համար նախ դիմեք ձեր օպերատորին՝ ծառայությունը կարգավորելու համար: Ապա նորից միացրեք Wi-Fi զանգերը Կարգավորումներում:"</item>
+    <item msgid="3910386316304772394">"Wi-Fi-ի միջոցով զանգեր կատարելու և հաղորդագրություններ ուղարկելու համար նախ դիմեք ձեր օպերատորին՝ այս ծառայությունը կարգավորելու համար: Այնուհետև նորից միացրեք «Զանգեր Wi-Fi-ի միջոցով» ընտրանքը Կարգավորումներից: (Սխալի կոդ՝ <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Գրանցվեք օպերատորի մոտ"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">Հասանելի են չպաշտպանված Wi-Fi ցանցեր</item>
       <item quantity="other">Հասանելի են չպաշտպանված Wi-Fi ցանցեր</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Միացեք բաց Wi‑Fi ցանցին"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Միացում բաց Wi‑Fi ցանցին"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Միացել է Wi‑Fi ցանցին"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Չհաջողվեց միանալ Wi‑Fi ցանցին"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Հպեք՝ բոլոր ցանցերը տեսնելու համար"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Միանալ"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Բոլոր ցանցերը"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Մուտք գործեք Wi-Fi ցանց"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Մուտք գործեք ցանց"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 4561c6c..99f9f09 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Mencari layanan"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Panggilan Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Untuk melakukan panggilan telepon dan mengirim pesan melalui Wi-Fi, terlebih dahulu minta operator untuk menyiapkan layanan ini. Lalu, aktifkan lagi panggilan telepon Wi-Fi dari Setelan."</item>
+    <item msgid="3910386316304772394">"Untuk menelepon dan mengirim pesan melalui Wi-Fi, tanyalah ke operator Anda terlebih dahulu untuk menyiapkan layanan ini. Kemudian, aktifkan kembali panggilan Wi-Fi dari Setelan. (Kode error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Harap daftarkan ke operator"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Jaringan Wi-Fi terbuka tersedia</item>
       <item quantity="one">Jaringan Wi-Fi terbuka tersedia</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Hubungkan ke jaringan Wi-Fi terbuka"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Menghubungkan ke jaringan Wi-Fi terbuka"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Terhubung ke jaringan Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Tidak dapat menghubungkan ke jaringan Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap untuk melihat semua jaringan"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Hubungkan"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Semua Jaringan"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Masuk ke jaringan Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Masuk ke jaringan"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index e645da9..32d5c10 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Leitar að þjónustu"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi símtöl"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Til að hringja og senda skilaboð yfir Wi-Fi þarftu fyrst að biðja símafyrirtækið þitt um að setja þá þjónustu upp. Kveiktu síðan á Wi-Fi símtölum í stillingunum."</item>
+    <item msgid="3910386316304772394">"Til að hringja og senda skilaboð yfir Wi-Fi þarftu fyrst að biðja símafyrirtækið þitt um að setja þá þjónustu upp. Kveiktu síðan á Wi-Fi símtölum í stillingunum. (Villukóði: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Skráðu þig hjá símafyrirtækinu"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">Opin Wi-Fi net í boði</item>
       <item quantity="other">Opin Wi-Fi net í boði</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Tengjast opnu Wi-Fi neti"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Tengist opnu Wi‑Fi neti"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Tengt við Wi‑Fi net"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Ekki hægt að tengjast Wi-Fi neti"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ýttu til að sjá öll netkerfi"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Tengjast"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Öll netkerfi"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Skrá inn á Wi-Fi net"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Skrá inn á net"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 7f7f881..ccaffae 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Ricerca servizio"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chiamate Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Per effettuare chiamate e inviare messaggi tramite Wi-Fi, è necessario prima chiedere all\'operatore telefonico di attivare il servizio. Successivamente, riattiva le chiamate Wi-Fi dalle Impostazioni."</item>
+    <item msgid="3910386316304772394">"Per effettuare chiamate e inviare messaggi tramite Wi-Fi, chiedi prima al tuo operatore di impostare questo servizio. Dopodiché, attiva di nuovo la funzione Chiamate Wi-Fi nelle impostazioni. (Codice di errore: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrati con il tuo operatore"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Apri reti Wi-Fi disponibili</item>
       <item quantity="one">Apri rete Wi-Fi disponibile</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Stabilisci la connessione per aprire la rete Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connessione per aprire la rete Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connessione alla rete Wi-Fi stabilita"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Impossibile connettersi alla rete Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tocca per vedere tutte le reti"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connetti"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tutte le reti"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Accedi a rete Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Accedi alla rete"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1383,7 +1376,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Altre opzioni"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <string name="storage_internal" msgid="3570990907910199483">"Archivio condiviso interno"</string>
+    <string name="storage_internal" msgid="3570990907910199483">"Memoria condivisa interna"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Scheda SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Scheda SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Unità USB"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 89f157e..d765403 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -133,7 +133,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"מחפש שירות"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"‏שיחות ב-Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"‏כדי להתקשר ולשלוח הודעות ברשת Wi-Fi, תחילה יש לבקש מהספק להגדיר את השירות. לאחר מכן, יש להפעיל שוב התקשרות Wi-Fi מ\'הגדרות\'."</item>
+    <item msgid="3910386316304772394">"‏כדי להתקשר ולשלוח הודעות ברשת Wi-Fi, תחילה יש לבקש מהספק להגדיר את השירות. לאחר מכן, יש להפעיל שוב שיחות Wi-Fi ב\'הגדרות\'. (קוד שגיאה: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"הירשם אצל הספק"</item>
@@ -1150,20 +1150,13 @@
       <item quantity="other">‏יש רשתות Wi-Fi פתוחות וזמינות</item>
       <item quantity="one">‏יש רשת Wi-Fi פתוחה וזמינה</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"‏התחברות לרשת Wi‑Fi פתוחה"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"‏מתחבר לרשת Wi‑Fi פתוחה"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"‏מחובר לרשת Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"‏לא ניתן היה להתחבר לרשת Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"יש להקיש כדי לראות את כל הרשתות"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"התחבר"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"כל הרשתות"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"‏היכנס לרשת Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"היכנס לרשת"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 6c70080..e223eec 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"サービスを検索中"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi通話"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi経由で音声通話の発信やメッセージの送信を行うには、携帯通信会社にWi-Fiサービスを申し込んだ上で、設定画面でWi-Fi発信を再度ONにしてください。"</item>
+    <item msgid="3910386316304772394">"Wi-Fi 経由で音声通話の発信やメッセージの送信を行うには、携帯通信会社に Wi-Fi サービスを申し込んだ上で、設定画面で Wi-Fi 発信を再度 ON にしてください(エラーコード: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"携帯通信会社に登録してください"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">複数のWi-Fiオープンネットワークが利用できます</item>
       <item quantity="one">Wi-Fiオープンネットワークが利用できます</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Wi-Fi オープン ネットワークに接続"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Wi-Fi オープン ネットワークに接続しています"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi-Fi ネットワークに接続しました"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi ネットワークに接続できませんでした"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"すべてのネットワークを表示するにはタップします"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"接続"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"すべてのネットワーク"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fiネットワークにログイン"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ネットワークにログインしてください"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index b63434c9..5b8a8bc 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"სერვისის ძიება"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"დარეკვა Wi-Fi-ს მეშვეობით"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi-ს მეშვეობით ზარების განხორციელების ან შეტყობინების გაგზავნისათვის, პირველ რიგში დაეკითხეთ თქვენს ოპერატორს აღნიშნულ მომსახურებაზე. შემდეგ ხელახლა ჩართეთ Wi-Fi ზარები პარამეტრებიდან."</item>
+    <item msgid="3910386316304772394">"Wi-Fi-ს მეშვეობით ზარების განსახორციელებლად ან შეტყობინებების გასაგზავნად, პირველ რიგში, ამ სერვისის გააქტიურება თქვენს ოპერატორს უნდა თხოვოთ. შემდეგ კი ხელახლა ჩართეთ Wi-Fi დარეკვა პარამეტრებიდან.. (შეცდომის კოდი: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"დაარეგისტრირეთ თქვენი ოპერატორი"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">ხელმისაწვდომია ღია Wi-Fi ქსელები</item>
       <item quantity="one">ხელმისაწვდომია ღია Wi-Fi ქსელი</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"დაუკავშირდით ღია Wi‑Fi ქსელს"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"მიმდინარეობს ღია Wi‑Fi ქსელთან დაკავშირება"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi ქსელთან დაკავშირება წარმატებით მოხერხდა"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi ქსელთან დაკავშირება ვერ მოხერხდა"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"შეეხეთ ყველა ქსელის სანახავად"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"დაკავშირება"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ყველა ქსელი"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi ქსელთან დაკავშირება"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ქსელში შესვლა"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index a03884c..bedcc43 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Қызметті іздеу"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi қоңыраулары"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi арқылы қоңырау шалу және хабарларды жіберу үшін алдымен жабдықтаушыңыздан осы қызметті орнатуды сұраңыз. Содан кейін Параметрлерден Wi-Fi қоңырау шалуын іске қосыңыз."</item>
+    <item msgid="3910386316304772394">"Wi-Fi арқылы қоңырау шалу немесе хабарлар жіберу үшін, алдымен операторыңыздан құрылғыны реттеуді сұраңыз. Содан кейін \"Параметрлер\" бөлімінен Wi-Fi қоңырауларын қайта қосыңыз. (Қате коды: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Жабдықтаушыңыз арқылы тіркелу"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Ашық Wi-Fi желілері қол жетімді</item>
       <item quantity="one">Ашық Wi-Fi желісі қол жетімді</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Ашық Wi‑Fi желісіне қосылу"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ашық Wi‑Fi желісіне қосылуда"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi желісіне қосылды"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi желісіне қосылмады"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Барлық желілерді көру үшін түртіңіз"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Қосылу"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Барлық желілер"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi желісіне кіру"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Желіге кіру"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 1a93326..270e467 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"​ស្វែង​រក​សេវាកម្ម"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ការហៅតាម Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"ដើម្បីធ្វើការហៅ និងផ្ញើសារតាម Wi-Fi ដំបូងឡើយអ្នកត្រូវស្នើឲ្យក្រុមហ៊ុនរបស់អ្នកដំឡើងសេវាកម្មនេះសិន។ បន្ទាប់មកបើកការហៅតាម Wi-Fi ម្តងទៀតចេញពីការកំណត់។"</item>
+    <item msgid="3910386316304772394">"ដើម្បីធ្វើការហៅ និងផ្ញើសារតាម Wi-Fi អ្នកត្រូវស្នើឲ្យក្រុមហ៊ុនបម្រើសេវាទូរសព្ទរបស់អ្នកដំឡើងសេវាកម្មនេះជាមុនសិន។ បន្ទាប់មកបើកការហៅតាម Wi-Fi ម្តងទៀតនៅក្នុងការកំណត់។ (លេខកូដបញ្ហា៖ <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"ចុះឈ្មោះជាមួយក្រុមហ៊ុនរបស់អ្នក"</item>
@@ -1108,20 +1108,13 @@
       <item quantity="other">បើកបណ្តាញ Wi-Fi ដែលមាន</item>
       <item quantity="one">បើកបណ្តាញ Wi-Fi ដែលមាន</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"ភ្ជាប់ទៅបណ្តាញ Wi‑Fi ចំហ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"កំពុងភ្ជាប់ទៅបណ្តាញ Wi‑Fi ចំហ"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"បានភ្ជាប់ទៅបណ្តាញ Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"មិនអាចភ្ជាប់ទៅបណ្តាញ Wi‑Fi បានទេ"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ចុចដើម្បីមើលបណ្តាញទាំងអស់"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"ភ្ជាប់"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"បណ្តាញទាំងអស់"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ចូល​បណ្ដាញ​វ៉ាយហ្វាយ"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ចូលទៅបណ្តាញ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 0b008b0..7783692 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"ಸೇವೆ ಹುಡುಕಲಾಗುತ್ತಿದೆ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"ವೈ-ಫೈ ಬಳಸಿಕೊಂಡು ಕರೆ ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಮೊದಲು ಈ ಸಾಧನವನ್ನು ಹೊಂದಿಸಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ತದನಂತರ ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಮತ್ತೆ ವೈ-ಫೈ ಆನ್‌ ಮಾಡಿ."</item>
+    <item msgid="3910386316304772394">"ವೈ-ಫೈ ಮೂಲಕ ಕರೆಗಳನ್ನು ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಈ ಸೇವೆಯನ್ನು ಹೊಂದಿಸಲು ಮೊದಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ಆ ನಂತರ ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಂದ ವೈ-ಫೈ ಕರೆಮಾಡುವಿಕೆಯನ್ನು ಅನ್ನು ಆನ್ ಮಾಡಿ. (ದೋಷ ಕೋಡ್: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"ನಿಮ್ಮ ವಾಹಕದಲ್ಲಿ ನೋಂದಾಯಿಸಿಕೊಳ್ಳಿ"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಲಭ್ಯವಿವೆ</item>
       <item quantity="other">ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಲಭ್ಯವಿವೆ</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಪಡಿಸಿ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗುತ್ತಿದೆ"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ಎಲ್ಲಾ ನೆಟ್‌ವರ್ಕ್‌ಗಳನ್ನು ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"ಸಂಪರ್ಕಿಸಿ"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ಎಲ್ಲಾ ನೆಟ್‌ವರ್ಕ್‌ಗಳು"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ವೈ-ಫೈ ನೆಟ್‍ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index d48c076..739f128 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"서비스 검색 중"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi 통화"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi를 사용하여 전화를 걸고 메시지를 보내려면 먼저 이동통신사에 문의하여 이 기능을 설정해야 합니다. 그런 다음 설정에서 Wi-Fi 통화를 사용 설정하시기 바랍니다."</item>
+    <item msgid="3910386316304772394">"Wi-Fi를 사용하여 전화를 걸고 메시지를 보내려면 먼저 이동통신사에 문의하여 서비스를 설정해야 합니다. 그런 다음 설정에서 Wi-Fi 통화를 사용 설정하시기 바랍니다. (오류 코드: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"이동통신사에 등록"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">개방형 Wi-Fi 네트워크 사용 가능</item>
       <item quantity="one">개방형 Wi-Fi 네트워크 사용 가능</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"공개 Wi‑Fi 네트워크에 연결"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"공개 Wi‑Fi 네트워크에 연결 중"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi 네트워크에 연결됨"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi 네트워크에 연결할 수 없음"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"모든 네트워크를 보려면 탭하세요."</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"연결"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"모든 네트워크"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi 네트워크에 로그인"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"네트워크에 로그인"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index e374edc..569bf2c 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Кызмат изделүүдө"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Чалуу"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз."</item>
+    <item msgid="3910386316304772394">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде байланыш операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз. (Ката коду: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Операторуңузга катталыңыз"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Ачык Wi-Fi тармагы жеткиликтүү</item>
       <item quantity="one">Ачык Wi-Fi тармагы жеткиликтүү</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Ачык Wi‑Fi тармагына туташуу"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ачык Wi‑Fi тармагына туташууда"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ачык Wi‑Fi тармагына туташты"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi-Fi тармагына туташпай калды"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Бардык тармактарды көрүү үчүн басыңыз"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Туташуу"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Бардык тармактар"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi түйүнүнө кирүү"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Тармакка кирүү"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index f55ee05..6c8603e 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"ຊອກຫາບໍລິການ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ການ​ໂທ Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"ເພື່ອ​ໂທ ແລະ​ສົ່ງ​ຂໍ້​ຄວາມ​ຢູ່​ເທິງ Wi-Fi, ກ່ອນ​ອື່ນ​ໝົດ​ໃຫ້​ຖ້າມ​ຜູ້​ໃຫ້​ບໍ​ລິ​ການ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ ເພື່ອ​ຕັ້ງ​ການ​ບໍ​ລິ​ການ​ນີ້. ຈາກນັ້ນ​ເປີດການ​ໂທ Wi-Fi ອີກ​ຈາກ​ການ​ຕັ້ງ​ຄ່າ."</item>
+    <item msgid="3910386316304772394">"ເພື່ອໂທ ແລະ ສົ່ງຂໍ້ຄວາມຜ່ານ Wi-Fi, ໃຫ້ແຈ້ງໃຫ້ຜູ້ໃຫ້ບໍລິການຂອງທ່ານຕັ້ງບໍລິການນີ້. ຈາກນັ້ນເປີດໃຊ້ການໂທ Wi-Fi ອີກຄັ້ງຈາກການຕັ້ງຄ່າ. (ລະຫັດຂໍ້ຜິດພາດ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"ລົງ​ທະ​ບຽນ​ກັບ​ຜູ້​ໃຫ້​ບໍ​ລິ​ການ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">ເປີດເຄືອຂ່າຍ Wi-Fi  ທີ່ມີໃຫ້</item>
       <item quantity="one">ເປີດເຄືອຂ່າຍ Wi-Fi  ທີ່ມີໃຫ້</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"ເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi ແບບເປີດ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ກຳລັງເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"ເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi ແລ້ວ"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ບໍ່ສາມາດເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi ໄດ້"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ແຕະເພື່ອເບິ່ງເຄືອຂ່າຍທັງໝົດ"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"ເຊື່ອມ​ຕໍ່"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ເຄືອຂ່າຍທັງໝົດ"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ເຂົ້າສູ່ລະບົບເຄືອຂ່າຍ Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ລົງຊື່ເຂົ້າເຄືອຂ່າຍ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index affea3c..2a82845 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -133,7 +133,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Ieškoma paslaugos"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"„Wi-Fi“ skambinimas"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Jei norite skambinti ir siųsti pranešimus „Wi-Fi“ ryšiu, pirmiausia paprašykite operatoriaus nustatyti šią paslaugą. Tada vėl įjunkite skambinimą „Wi-Fi“ ryšiu „Nustatymų“ skiltyje."</item>
+    <item msgid="3910386316304772394">"Jei norite skambinti ir siųsti pranešimus naudodami „Wi-Fi“, pirmiausia paprašykite operatoriaus nustatyti šią paslaugą. Tada vėl įjunkite „Wi-Fi“ skambinimą skiltyje „Nustatymai“. (Klaidos kodas: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Užregistruokite pas operatorių"</item>
@@ -1150,20 +1150,13 @@
       <item quantity="many">Pasiekiami atvirieji „Wi-Fi“ tinklai</item>
       <item quantity="other">Pasiekiami atvirieji „Wi-Fi“ tinklai</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Prisijunkite prie atviro „Wi‑Fi“ tinklo"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Prisijungiama prie atviro „Wi‑Fi“ tinklo"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Prisijungta prie „Wi-Fi“ tinklo"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nepavyko prisijungti prie „Wi‑Fi“ tinklo"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Palieskite, jei norite matyti visus tinklus"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Prisijungti"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Visi tinklai"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prisijungti prie „Wi-Fi“ tinklo"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prisijungti prie tinklo"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index ab82849..cfe0369 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -132,7 +132,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Pakalpojuma meklēšana"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi zvani"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Lai veiktu zvanus un sūtītu īsziņas Wi-Fi tīklā, vispirms lūdziet mobilo sakaru operatoru iestatīt šo pakalpojumu. Pēc tam iestatījumos vēlreiz ieslēdziet Wi-Fi zvanus."</item>
+    <item msgid="3910386316304772394">"Lai veiktu zvanus un sūtītu īsziņas Wi-Fi tīklā, vispirms lūdziet mobilo sakaru operatoram iestatīt šo pakalpojumu. Pēc tam iestatījumos vēlreiz ieslēdziet Wi-Fi zvanus. (Kļūdas kods: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Reģistrēt to pie sava mobilo sakaru operatora"</item>
@@ -1128,20 +1128,13 @@
       <item quantity="one">Ir pieejami atvērti Wi-Fi tīkli</item>
       <item quantity="other">Ir pieejami atvērti Wi-Fi tīkli</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Savienojuma izveide ar atvērtu Wi-Fi tīklu"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Notiek savienojuma izveide ar atvērtu Wi-Fi tīklu"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ir izveidots savienojums ar Wi-Fi tīklu"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nevarēja izveidot savienojumu ar Wi‑Fi tīklu"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Pieskarieties, lai skatītu visus tīklus"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Izveidot savienojumu"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Visi tīkli"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Pierakstieties Wi-Fi tīklā"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Pierakstīšanās tīklā"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-mcc302-mnc370-af/strings.xml b/core/res/res/values-mcc302-mnc370-af/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-af/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-am/strings.xml b/core/res/res/values-mcc302-mnc370-am/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-am/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ar/strings.xml b/core/res/res/values-mcc302-mnc370-ar/strings.xml
new file mode 100644
index 0000000..f1c8176
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ar/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"‏%s مع Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-az/strings.xml b/core/res/res/values-mcc302-mnc370-az/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-az/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-b+sr+Latn/strings.xml b/core/res/res/values-mcc302-mnc370-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-b+sr+Latn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-be/strings.xml b/core/res/res/values-mcc302-mnc370-be/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-be/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-bg/strings.xml b/core/res/res/values-mcc302-mnc370-bg/strings.xml
new file mode 100644
index 0000000..b3a9589
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-bg/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi от %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-bn/strings.xml b/core/res/res/values-mcc302-mnc370-bn/strings.xml
new file mode 100644
index 0000000..efd9b4b
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-bn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s ওয়াই-ফাই"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-bs/strings.xml b/core/res/res/values-mcc302-mnc370-bs/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-bs/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ca/strings.xml b/core/res/res/values-mcc302-mnc370-ca/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ca/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-cs/strings.xml b/core/res/res/values-mcc302-mnc370-cs/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-cs/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-da/strings.xml b/core/res/res/values-mcc302-mnc370-da/strings.xml
new file mode 100644
index 0000000..709530c
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-da/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi fra %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-de/strings.xml b/core/res/res/values-mcc302-mnc370-de/strings.xml
new file mode 100644
index 0000000..6aa7643
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-de/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"WLAN: %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-el/strings.xml b/core/res/res/values-mcc302-mnc370-el/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-el/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-en-rAU/strings.xml b/core/res/res/values-mcc302-mnc370-en-rAU/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-en-rAU/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-en-rGB/strings.xml b/core/res/res/values-mcc302-mnc370-en-rGB/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-en-rGB/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-en-rIN/strings.xml b/core/res/res/values-mcc302-mnc370-en-rIN/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-en-rIN/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-es-rUS/strings.xml b/core/res/res/values-mcc302-mnc370-es-rUS/strings.xml
new file mode 100644
index 0000000..5ba6413
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-es-rUS/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-es/strings.xml b/core/res/res/values-mcc302-mnc370-es/strings.xml
new file mode 100644
index 0000000..5ba6413
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-es/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-et/strings.xml b/core/res/res/values-mcc302-mnc370-et/strings.xml
new file mode 100644
index 0000000..648544d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-et/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s WiFi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-eu/strings.xml b/core/res/res/values-mcc302-mnc370-eu/strings.xml
new file mode 100644
index 0000000..960e1e5
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-eu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi sarea"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-fa/strings.xml b/core/res/res/values-mcc302-mnc370-fa/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-fa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-fi/strings.xml b/core/res/res/values-mcc302-mnc370-fi/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-fi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-fr-rCA/strings.xml b/core/res/res/values-mcc302-mnc370-fr-rCA/strings.xml
new file mode 100644
index 0000000..5ba6413
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-fr-rCA/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-fr/strings.xml b/core/res/res/values-mcc302-mnc370-fr/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-fr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-gl/strings.xml b/core/res/res/values-mcc302-mnc370-gl/strings.xml
new file mode 100644
index 0000000..b644471
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-gl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wifi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-gu/strings.xml b/core/res/res/values-mcc302-mnc370-gu/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-gu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-hi/strings.xml b/core/res/res/values-mcc302-mnc370-hi/strings.xml
new file mode 100644
index 0000000..3521dd4
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-hi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s वाई-फ़ाई"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-hr/strings.xml b/core/res/res/values-mcc302-mnc370-hr/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-hr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-hu/strings.xml b/core/res/res/values-mcc302-mnc370-hu/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-hu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-hy/strings.xml b/core/res/res/values-mcc302-mnc370-hy/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-hy/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-in/strings.xml b/core/res/res/values-mcc302-mnc370-in/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-in/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-is/strings.xml b/core/res/res/values-mcc302-mnc370-is/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-is/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-it/strings.xml b/core/res/res/values-mcc302-mnc370-it/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-it/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-iw/strings.xml b/core/res/res/values-mcc302-mnc370-iw/strings.xml
new file mode 100644
index 0000000..90b73ad
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-iw/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"‎%s‎"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ja/strings.xml b/core/res/res/values-mcc302-mnc370-ja/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ja/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ka/strings.xml b/core/res/res/values-mcc302-mnc370-ka/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ka/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-kk/strings.xml b/core/res/res/values-mcc302-mnc370-kk/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-kk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-km/strings.xml b/core/res/res/values-mcc302-mnc370-km/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-km/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-kn/strings.xml b/core/res/res/values-mcc302-mnc370-kn/strings.xml
new file mode 100644
index 0000000..636eb01
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-kn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s ವೈ-ಫೈ"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ko/strings.xml b/core/res/res/values-mcc302-mnc370-ko/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ko/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ky/strings.xml b/core/res/res/values-mcc302-mnc370-ky/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ky/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-lo/strings.xml b/core/res/res/values-mcc302-mnc370-lo/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-lo/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-lt/strings.xml b/core/res/res/values-mcc302-mnc370-lt/strings.xml
new file mode 100644
index 0000000..95746fb
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-lt/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"„%s“ „Wi-Fi“"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-lv/strings.xml b/core/res/res/values-mcc302-mnc370-lv/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-lv/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-mk/strings.xml b/core/res/res/values-mcc302-mnc370-mk/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-mk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ml/strings.xml b/core/res/res/values-mcc302-mnc370-ml/strings.xml
new file mode 100644
index 0000000..810b72c
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ml/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s വൈഫൈ"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-mn/strings.xml b/core/res/res/values-mcc302-mnc370-mn/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-mn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-mr/strings.xml b/core/res/res/values-mcc302-mnc370-mr/strings.xml
new file mode 100644
index 0000000..4b03333
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-mr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s वाय-फाय"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ms/strings.xml b/core/res/res/values-mcc302-mnc370-ms/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ms/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-my/strings.xml b/core/res/res/values-mcc302-mnc370-my/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-my/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-nb/strings.xml b/core/res/res/values-mcc302-mnc370-nb/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-nb/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ne/strings.xml b/core/res/res/values-mcc302-mnc370-ne/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ne/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-nl/strings.xml b/core/res/res/values-mcc302-mnc370-nl/strings.xml
new file mode 100644
index 0000000..0366335
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-nl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wifi via %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-pa/strings.xml b/core/res/res/values-mcc302-mnc370-pa/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-pa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-pl/strings.xml b/core/res/res/values-mcc302-mnc370-pl/strings.xml
new file mode 100644
index 0000000..f359c03
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-pl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi – %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-pt-rBR/strings.xml b/core/res/res/values-mcc302-mnc370-pt-rBR/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-pt-rBR/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-pt-rPT/strings.xml b/core/res/res/values-mcc302-mnc370-pt-rPT/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-pt-rPT/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-pt/strings.xml b/core/res/res/values-mcc302-mnc370-pt/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-pt/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ro/strings.xml b/core/res/res/values-mcc302-mnc370-ro/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ro/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ru/strings.xml b/core/res/res/values-mcc302-mnc370-ru/strings.xml
new file mode 100644
index 0000000..5fdf802
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ru/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Сеть Wi-Fi \"%s\""</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-si/strings.xml b/core/res/res/values-mcc302-mnc370-si/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-si/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sk/strings.xml b/core/res/res/values-mcc302-mnc370-sk/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sl/strings.xml b/core/res/res/values-mcc302-mnc370-sl/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sq/strings.xml b/core/res/res/values-mcc302-mnc370-sq/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sq/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sr/strings.xml b/core/res/res/values-mcc302-mnc370-sr/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sv/strings.xml b/core/res/res/values-mcc302-mnc370-sv/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sv/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-sw/strings.xml b/core/res/res/values-mcc302-mnc370-sw/strings.xml
new file mode 100644
index 0000000..8c1c887
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-sw/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi ya %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ta/strings.xml b/core/res/res/values-mcc302-mnc370-ta/strings.xml
new file mode 100644
index 0000000..5807593
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ta/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s வைஃபை"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-te/strings.xml b/core/res/res/values-mcc302-mnc370-te/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-te/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-th/strings.xml b/core/res/res/values-mcc302-mnc370-th/strings.xml
new file mode 100644
index 0000000..fa5ff47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-th/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi ของ %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-tl/strings.xml b/core/res/res/values-mcc302-mnc370-tl/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-tl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-tr/strings.xml b/core/res/res/values-mcc302-mnc370-tr/strings.xml
new file mode 100644
index 0000000..2f9ff04
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-tr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s kablosuz"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-uk/strings.xml b/core/res/res/values-mcc302-mnc370-uk/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-uk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-ur/strings.xml b/core/res/res/values-mcc302-mnc370-ur/strings.xml
new file mode 100644
index 0000000..81d2888
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-ur/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"‎%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-uz/strings.xml b/core/res/res/values-mcc302-mnc370-uz/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-uz/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-vi/strings.xml b/core/res/res/values-mcc302-mnc370-vi/strings.xml
new file mode 100644
index 0000000..74d4f17
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-vi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-zh-rCN/strings.xml b/core/res/res/values-mcc302-mnc370-zh-rCN/strings.xml
new file mode 100644
index 0000000..a89f6a2
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-zh-rCN/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s WLAN"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-zh-rHK/strings.xml b/core/res/res/values-mcc302-mnc370-zh-rHK/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-zh-rHK/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-zh-rTW/strings.xml b/core/res/res/values-mcc302-mnc370-zh-rTW/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-zh-rTW/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370-zu/strings.xml b/core/res/res/values-mcc302-mnc370-zu/strings.xml
new file mode 100644
index 0000000..b93949e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-zu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="5022384999749536798">"%s"</item>
+    <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-af/strings.xml b/core/res/res/values-mcc302-mnc720-af/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-af/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-am/strings.xml b/core/res/res/values-mcc302-mnc720-am/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-am/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ar/strings.xml b/core/res/res/values-mcc302-mnc720-ar/strings.xml
new file mode 100644
index 0000000..869678f
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ar/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"‏%s مع Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-az/strings.xml b/core/res/res/values-mcc302-mnc720-az/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-az/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-b+sr+Latn/strings.xml b/core/res/res/values-mcc302-mnc720-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-b+sr+Latn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-be/strings.xml b/core/res/res/values-mcc302-mnc720-be/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-be/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-bg/strings.xml b/core/res/res/values-mcc302-mnc720-bg/strings.xml
new file mode 100644
index 0000000..890f19b
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-bg/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi от %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-bn/strings.xml b/core/res/res/values-mcc302-mnc720-bn/strings.xml
new file mode 100644
index 0000000..543ec7a
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-bn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s ওয়াই-ফাই"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-bs/strings.xml b/core/res/res/values-mcc302-mnc720-bs/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-bs/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ca/strings.xml b/core/res/res/values-mcc302-mnc720-ca/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ca/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-cs/strings.xml b/core/res/res/values-mcc302-mnc720-cs/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-cs/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-da/strings.xml b/core/res/res/values-mcc302-mnc720-da/strings.xml
new file mode 100644
index 0000000..483dee5
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-da/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi fra %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-de/strings.xml b/core/res/res/values-mcc302-mnc720-de/strings.xml
new file mode 100644
index 0000000..825fa00
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-de/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"WLAN: %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-el/strings.xml b/core/res/res/values-mcc302-mnc720-el/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-el/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-en-rAU/strings.xml b/core/res/res/values-mcc302-mnc720-en-rAU/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-en-rAU/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-en-rGB/strings.xml b/core/res/res/values-mcc302-mnc720-en-rGB/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-en-rGB/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-en-rIN/strings.xml b/core/res/res/values-mcc302-mnc720-en-rIN/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-en-rIN/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-es-rUS/strings.xml b/core/res/res/values-mcc302-mnc720-es-rUS/strings.xml
new file mode 100644
index 0000000..c8c4c5e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-es-rUS/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-es/strings.xml b/core/res/res/values-mcc302-mnc720-es/strings.xml
new file mode 100644
index 0000000..c8c4c5e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-es/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-et/strings.xml b/core/res/res/values-mcc302-mnc720-et/strings.xml
new file mode 100644
index 0000000..3e5a7ef
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-et/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s WiFi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-eu/strings.xml b/core/res/res/values-mcc302-mnc720-eu/strings.xml
new file mode 100644
index 0000000..802df65
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-eu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi sarea"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-fa/strings.xml b/core/res/res/values-mcc302-mnc720-fa/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-fa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-fi/strings.xml b/core/res/res/values-mcc302-mnc720-fi/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-fi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-fr-rCA/strings.xml b/core/res/res/values-mcc302-mnc720-fr-rCA/strings.xml
new file mode 100644
index 0000000..c8c4c5e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-fr-rCA/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-fr/strings.xml b/core/res/res/values-mcc302-mnc720-fr/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-fr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-gl/strings.xml b/core/res/res/values-mcc302-mnc720-gl/strings.xml
new file mode 100644
index 0000000..d3a9055
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-gl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wifi de %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-gu/strings.xml b/core/res/res/values-mcc302-mnc720-gu/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-gu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-hi/strings.xml b/core/res/res/values-mcc302-mnc720-hi/strings.xml
new file mode 100644
index 0000000..9a10eed
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-hi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s वाई-फ़ाई"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-hr/strings.xml b/core/res/res/values-mcc302-mnc720-hr/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-hr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-hu/strings.xml b/core/res/res/values-mcc302-mnc720-hu/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-hu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-hy/strings.xml b/core/res/res/values-mcc302-mnc720-hy/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-hy/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-in/strings.xml b/core/res/res/values-mcc302-mnc720-in/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-in/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-is/strings.xml b/core/res/res/values-mcc302-mnc720-is/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-is/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-it/strings.xml b/core/res/res/values-mcc302-mnc720-it/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-it/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-iw/strings.xml b/core/res/res/values-mcc302-mnc720-iw/strings.xml
new file mode 100644
index 0000000..d0a799f
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-iw/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"‎%s‎"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ja/strings.xml b/core/res/res/values-mcc302-mnc720-ja/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ja/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ka/strings.xml b/core/res/res/values-mcc302-mnc720-ka/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ka/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-kk/strings.xml b/core/res/res/values-mcc302-mnc720-kk/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-kk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-km/strings.xml b/core/res/res/values-mcc302-mnc720-km/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-km/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-kn/strings.xml b/core/res/res/values-mcc302-mnc720-kn/strings.xml
new file mode 100644
index 0000000..6438ffb
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-kn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s ವೈ-ಫೈ"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ko/strings.xml b/core/res/res/values-mcc302-mnc720-ko/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ko/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ky/strings.xml b/core/res/res/values-mcc302-mnc720-ky/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ky/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-lo/strings.xml b/core/res/res/values-mcc302-mnc720-lo/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-lo/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-lt/strings.xml b/core/res/res/values-mcc302-mnc720-lt/strings.xml
new file mode 100644
index 0000000..2d3b87a
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-lt/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"„%s“ „Wi-Fi“"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-lv/strings.xml b/core/res/res/values-mcc302-mnc720-lv/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-lv/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-mk/strings.xml b/core/res/res/values-mcc302-mnc720-mk/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-mk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ml/strings.xml b/core/res/res/values-mcc302-mnc720-ml/strings.xml
new file mode 100644
index 0000000..325b5db
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ml/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s വൈഫൈ"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-mn/strings.xml b/core/res/res/values-mcc302-mnc720-mn/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-mn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-mr/strings.xml b/core/res/res/values-mcc302-mnc720-mr/strings.xml
new file mode 100644
index 0000000..9708843
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-mr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s वाय-फाय"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ms/strings.xml b/core/res/res/values-mcc302-mnc720-ms/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ms/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-my/strings.xml b/core/res/res/values-mcc302-mnc720-my/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-my/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-nb/strings.xml b/core/res/res/values-mcc302-mnc720-nb/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-nb/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ne/strings.xml b/core/res/res/values-mcc302-mnc720-ne/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ne/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-nl/strings.xml b/core/res/res/values-mcc302-mnc720-nl/strings.xml
new file mode 100644
index 0000000..4c5cadd
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-nl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wifi via %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-pa/strings.xml b/core/res/res/values-mcc302-mnc720-pa/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-pa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-pl/strings.xml b/core/res/res/values-mcc302-mnc720-pl/strings.xml
new file mode 100644
index 0000000..4e78857
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-pl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi – %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-pt-rBR/strings.xml b/core/res/res/values-mcc302-mnc720-pt-rBR/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-pt-rBR/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-pt-rPT/strings.xml b/core/res/res/values-mcc302-mnc720-pt-rPT/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-pt-rPT/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-pt/strings.xml b/core/res/res/values-mcc302-mnc720-pt/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-pt/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ro/strings.xml b/core/res/res/values-mcc302-mnc720-ro/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ro/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ru/strings.xml b/core/res/res/values-mcc302-mnc720-ru/strings.xml
new file mode 100644
index 0000000..b88013b
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ru/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Сеть Wi-Fi \"%s\""</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-si/strings.xml b/core/res/res/values-mcc302-mnc720-si/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-si/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sk/strings.xml b/core/res/res/values-mcc302-mnc720-sk/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sl/strings.xml b/core/res/res/values-mcc302-mnc720-sl/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sq/strings.xml b/core/res/res/values-mcc302-mnc720-sq/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sq/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sr/strings.xml b/core/res/res/values-mcc302-mnc720-sr/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sv/strings.xml b/core/res/res/values-mcc302-mnc720-sv/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sv/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-sw/strings.xml b/core/res/res/values-mcc302-mnc720-sw/strings.xml
new file mode 100644
index 0000000..ee780df
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-sw/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi ya %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ta/strings.xml b/core/res/res/values-mcc302-mnc720-ta/strings.xml
new file mode 100644
index 0000000..61c8b84
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ta/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s வைஃபை"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-te/strings.xml b/core/res/res/values-mcc302-mnc720-te/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-te/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-th/strings.xml b/core/res/res/values-mcc302-mnc720-th/strings.xml
new file mode 100644
index 0000000..d536f45
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-th/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi ของ %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-tl/strings.xml b/core/res/res/values-mcc302-mnc720-tl/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-tl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-tr/strings.xml b/core/res/res/values-mcc302-mnc720-tr/strings.xml
new file mode 100644
index 0000000..e41287a
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-tr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s kablosuz"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-uk/strings.xml b/core/res/res/values-mcc302-mnc720-uk/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-uk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-ur/strings.xml b/core/res/res/values-mcc302-mnc720-ur/strings.xml
new file mode 100644
index 0000000..566f852
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-ur/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"‎%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-uz/strings.xml b/core/res/res/values-mcc302-mnc720-uz/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-uz/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-vi/strings.xml b/core/res/res/values-mcc302-mnc720-vi/strings.xml
new file mode 100644
index 0000000..20e4f47
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-vi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"Wi-Fi %s"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-zh-rCN/strings.xml b/core/res/res/values-mcc302-mnc720-zh-rCN/strings.xml
new file mode 100644
index 0000000..c5526b2
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-zh-rCN/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s WLAN"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-zh-rHK/strings.xml b/core/res/res/values-mcc302-mnc720-zh-rHK/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-zh-rHK/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-zh-rTW/strings.xml b/core/res/res/values-mcc302-mnc720-zh-rTW/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-zh-rTW/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-zu/strings.xml b/core/res/res/values-mcc302-mnc720-zu/strings.xml
new file mode 100644
index 0000000..9b2336d
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-zu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcSpnFormats">
+    <item msgid="2776657861851140021">"%s"</item>
+    <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc404/config.xml b/core/res/res/values-mcc404/config.xml
index 17539d8..d6655f2 100644
--- a/core/res/res/values-mcc404/config.xml
+++ b/core/res/res/values-mcc404/config.xml
@@ -25,4 +25,6 @@
     </string-array>
     <!-- Whether camera shutter sound is forced or not  (country specific). -->
     <bool name="config_camera_sound_forced">true</bool>
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">true</bool>
 </resources>
diff --git a/core/res/res/values-mcc724/config.xml b/core/res/res/values-mcc724/config.xml
new file mode 100644
index 0000000..98f70d5
--- /dev/null
+++ b/core/res/res/values-mcc724/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 4e9f7ce..599eabc 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Пребарување за услуга"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Повикување преку Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"За повикување и испраќање пораки преку Wi-Fi, прво побарајте од операторот да ви ја постави оваа услуга. Потоа повторно вклучете повикување преку Wi-Fi во Поставки."</item>
+    <item msgid="3910386316304772394">"За да воспоставувате повици и да испраќате пораки преку Wi-Fi, прво побарајте од операторот да ја постави услугава. Потоа, вклучете ја повторно „Повикување преку Wi-Fi“ во „Поставки“. (Код за грешка: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Регистрирајте се со операторот"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">Отворени Wi-Fi мрежи се достапни</item>
       <item quantity="other">Отворени Wi-Fi мрежи се достапни</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Поврзете се на отворена Wi‑Fi-мрежа"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Поврзување на отворена Wi‑Fi-мрежа"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Се поврзавте на Wi‑Fi-мрежа"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не можеше да се поврзе на Wi‑Fi-мрежа"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Допрете за да ги видите сите мрежи"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Поврзете се"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Сите мрежи"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Најавете се на мрежа на Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Најавете се на мрежа"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index bbeb71b..418392c 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"സേവനത്തിനായി തിരയുന്നു"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"വൈഫൈ കോളിംഗ്"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"വൈഫൈ വഴി കോളുകൾ വിളിക്കാനും സന്ദേശങ്ങൾ അയയ്‌ക്കാനും ആദ്യം നിങ്ങളുടെ കാരിയറോട് ഈ സേവനം സജ്ജമാക്കാൻ ആവശ്യപ്പെടുക. ക്രമീകരണത്തിൽ നിന്ന് വീണ്ടും വൈഫൈ കോളിംഗ് ഓണാക്കുക."</item>
+    <item msgid="3910386316304772394">"വൈഫൈ വഴി കോളുകൾ ചെയ്യാനും സന്ദേശങ്ങൾ അയയ്‌ക്കാനും ആദ്യം നിങ്ങളുടെ കാരിയറോട് ഈ സേവനം സജ്ജമാക്കാൻ ആവശ്യപ്പെടുക. ക്രമീകരണത്തിൽ നിന്ന് വീണ്ടും വൈഫൈ കോളിംഗ് ഓണാക്കുക. (പിശക് കോഡ്: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"നിങ്ങളുടെ കാരിയറിൽ രജിസ്റ്റർ ചെയ്യുക"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">ലഭ്യമായ വൈഫൈ നെറ്റ്‌വർക്കുകൾ തുറക്കുക</item>
       <item quantity="one">ലഭ്യമായ വൈഫൈ നെറ്റ്‌വർക്ക് തുറക്കുക</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"ലഭ്യമായ വൈഫൈ നെറ്റ്‌വർക്കിലേക്ക് കണക്റ്റുചെയ്യുക"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ലഭ്യമായ വൈഫൈ നെറ്റ്‌വർക്കിലേക്ക് കണക്റ്റുചെയ്യുന്നു"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"വൈഫൈ നെറ്റ്‌വർക്കിലേക്ക് കണക്റ്റു‌ചെയ്‌‌തു"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"വൈ-ഫൈ നെറ്റ്‌വർക്കിലേക്ക് കണക്‌റ്റുചെയ്യാനായില്ല"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"എല്ലാ നെറ്റ്‌വർക്കുകളും കാണാൻ ടാപ്പുചെയ്യുക"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"കണക്റ്റുചെയ്യുക"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"എല്ലാ നെറ്റ്‌വർക്കുകളും"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"വൈഫൈ നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index dec7746..4a8698a 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Үйлчилгээг хайж байна…"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi-аар дуудлага хийх болон мессеж илгээхээр бол эхлээд оператороосоо энэ төхөөрөмжийг тохируулж өгөхийг хүсээрэй. Дараа нь Тохиргооноос Wi-Fi дуудлага хийх үйлдлийг асаагаарай."</item>
+    <item msgid="3910386316304772394">"Wi-Fi-аар дуудлага хийх, мессеж илгээх бол эхлээд оператор компаниасаа энэ үйлчилгээг тохируулж өгөхийг хүснэ үү. Дараа нь Тохиргооноос Wi-Fi дуудлага хийх үйлдлийг асаана уу. (Алдааны код: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Операторт бүртгүүлэх"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Нээлттэй Wi-Fi сүлжээ ашиглах боломжтой</item>
       <item quantity="one">Нээлттэй Wi-Fi сүлжээ ашиглах боломжтой</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Нээлттэй Wi‑Fi сүлжээнд холбогдох"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Нээлттэй Wi‑Fi сүлжээнд холбогдож байна"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi сүлжээнд холбогдлоо"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi сүлжээнд холбогдож чадсангүй"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Бүх сүлжээг харахын тулд товшино уу"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Холбогдох"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Бүх сүлжээ"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi сүлжээнд нэвтэрнэ үү"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Сүлжээнд нэвтэрнэ үү"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 99c4391..849f14d 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"सेवा शोधत आहे"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"वाय-फाय कॉलिंग"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"वाय-फायवरून कॉल करण्यासाठी आणि संदेश पाठविण्यासाठी, प्रथम आपल्या वाहकास ही सेवा सेट करण्यास सांगा. नंतर सेटिंग्जमधून पुन्हा वाय-फाय कॉलिंग चालू करा."</item>
+    <item msgid="3910386316304772394">"वाय-फायवरून कॉल करण्यासाठी आणि संदेश पाठवण्यासाठी आधी तुमच्या कॅरियरला ही सेवा सेट अप करण्यास सांगा. नंतर सेटिंग्जमधून वाय-फाय वापरून कॉल करणे पुन्हा चालू करा. (एरर कोड <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"आपल्या वाहकासह नोंदणी करा"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">खुले वाय-फाय नेटवर्क उपलब्ध</item>
       <item quantity="other">खुले वाय-फाय नेटवर्क उपलब्ध</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"खुल्या वाय-फाय नेटवर्कशी कनेक्ट करा"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"खुल्या वाय-फाय नेटवर्कशी कनेक्ट करत आहे"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"वाय-फाय नेटवर्कशी कनेक्ट केले"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"वाय-फाय नेटवर्कशी कनेक्ट करू शकत नाही"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सर्व नेटवर्क पाहण्यासाठी टॅप करा"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"कनेक्ट करा"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"सर्व नेटवर्क"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"वाय-फाय नेटवर्कमध्‍ये साइन इन करा"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"नेटवर्कवर साइन इन करा"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 1976bb7..d400f96 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Mencari Perkhidmatan"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Panggilan Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, mula-mula minta pembawa anda untuk menyediakan perkhidmatan ini. Kemudian hidupkan panggilan Wi-Fi semula daripada Tetapan."</item>
+    <item msgid="3910386316304772394">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, minta pembawa anda menyediakan perkhidmatan ini terlebih dahulu. Kemudian, hidupkan panggilan Wi-Fi sekali lagi daripada Tetapan. (Kod ralat: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Daftar dengan pembawa anda"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Rangkaian Wi-Fi terbuka tersedia</item>
       <item quantity="one">Rangkaian Wi-Fi terbuka tersedia</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Sambung ke rangkaian Wi-Fi terbuka"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Menyambung ke rangkaian Wi‑Fi terbuka"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Disambungkan ke rangkaian Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Tidak dapat menyambung ke rangkaian Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ketik untuk melihat semua rangkaian"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Sambung"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Semua Rangkaian"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Log masuk ke rangkaian Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Log masuk ke rangkaian"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 0f9fb0c..a33bec8 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"ဆားဗစ်အားရှာဖွေနေသည်"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi  ခေါ်ဆိုမှု"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi သုံး၍ ဖုန်းခေါ်ဆိုရန်နှင့် မက်ဆေ့ဂျ်များပို့ရန်၊ ဤဝန်ဆောင်မှုအား စတင်သုံးနိုင်ရန်အတွက် သင့် မိုဘိုင်းဝန်ဆောင်မှုအား ဦးစွာမေးမြန်းပါ။ ထို့နောက် ဆက်တင်မှတဆင့် Wi-Fi  ခေါ်ဆိုမှုအား ထပ်ဖွင့်ပါ။"</item>
+    <item msgid="3910386316304772394">"Wi-Fi အသုံးပြု၍ ဖုန်းခေါ်ရန်နှင့် မက်ဆေ့ဂျ်ပို့ရန်အတွက် သင့်ဝန်ဆောင်မှုပေးသူကို ဤဝန်ဆောင်မှုအား သတ်မှတ်ပေးရန် ဦးစွာတောင်းဆိုပါ။ ထို့နောက် ဆက်တင်ထဲသို့ သွား၍ Wi-Fi ဖြင့် ဖုန်းခေါ်ခြင်းကို ဖွင့်ရပါမည်။ (အမှားကုဒ်- <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"သင့် မိုဘိုင်းဝန်ဆောင်မှုဖြင့် မှတ်ပုံတင်ရန်"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Wi-Fi ကွန်ယက်များရရှိနိုင်သည်အား ဖွင့်ပါ</item>
       <item quantity="one">Wi-Fi ကွန်ယက်ရရှိနိုင်သည်အား ဖွင့်ပါ</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"အများသုံး Wi‑Fi ကွန်ရက်သို့ ချိတ်ဆက်ပါ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"အများသုံး Wi‑Fi ကွန်ရက်သို့ ချိတ်ဆက်နေသည်"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi ကွန်ရက်သို့ ချိတ်ဆက်ပြီးပါပြီ"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi ကွန်ရက်သို့ ချိတ်ဆက်၍ မရပါ"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ကွန်ရက်အားလုံးကို ကြည့်ရန် တို့ပါ"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"ချိတ်ဆက်ရန်"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ကွန်ရက်အားလုံး"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ဝိုင်ဖိုင်ကွန်ရက်သို့ လက်မှတ်ထိုးဝင်ပါ"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ကွန်ယက်သို့ လက်မှတ်ထိုးဝင်ရန်"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index cc3ecb9..f38c260 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Leter etter tjeneste"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-anrop"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"For å ringe og sende meldinger over Wi-Fi må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger."</item>
+    <item msgid="3910386316304772394">"For å ringe og sende meldinger over Wi-Fi må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger. (Feilkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrer deg hos operatøren din"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Åpne Wi-Fi-nettverk er tilgjengelig</item>
       <item quantity="one">Åpent Wi-Fi-nettverk er tilgjengelig</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Koble til et åpent Wi‑Fi-nettverk"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Kobler til åpent Wi-Fi-nettverk"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Koblet til Wi-Fi-nettverk"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Kunne ikke koble til Wi-Fi-nettverket"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Trykk for å se alle nettverkene"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Koble til"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle nettverk"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Logg på Wi-Fi-nettverket"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Logg på nettverk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 5eddfbf..2098b51 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"सेवाको खोजी गर्दै…"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi कलिङ"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi बाट कल गर्न र सन्देशहरू पठाउन, सबभन्दा पहिला यो सेवा सेटअप गर्न तपाईँको वाहकलाई भन्नुहोस्। त्यसपछि फेरि सेटिङहरूबाट Wi-Fi कलिङ सक्रिय पार्नुहोस्।"</item>
+    <item msgid="3910386316304772394">"Wi-Fi मार्फत कलहरू गर्न र सन्देशहरू पठाउन सबभन्दा पहिला आफ्नो सेवा प्रदायकलाई यो सेवा सेट गर्न भन्नुहोस्। त्यसपछि सेटिङहरूबाट Wi-Fi कलिङलाई सक्रिय पार्नुहोस्। (त्रुटिसम्बन्धी कोड: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"तपाईँको वाहकसँग दर्ता गर्नुहोस्"</item>
@@ -1112,20 +1112,13 @@
       <item quantity="other"> खुल्ला Wi-Fi सञ्जालहरू उपलब्ध छन्</item>
       <item quantity="one">खुल्ला Wi-Fi सञ्जाल उपलब्ध छ</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"खुला Wi‑Fi नेटवर्कमा जडान गर्नुहोस्"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"खुला Wi‑Fi नेटवर्कमा जडान गर्दै"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi नेटवर्कमा जडान गरियो"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi नेटवर्कमा जडान गर्न सकिएन"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सबै नेटवर्कहरू हेर्न ट्याप गर्नुहोस्"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"जडान गर्नुहोस्"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"सबै नेटवर्कहरू"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi नेटवर्कमा साइन इन गर्नुहोस्"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"सञ्जालमा साइन इन गर्नुहोस्"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b5ba93f..4d0beec 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Service zoeken"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Bellen via wifi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via \'Instellingen\'."</item>
+    <item msgid="3910386316304772394">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via Instellingen. (Foutcode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registreren bij je provider"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Open wifi-netwerken beschikbaar</item>
       <item quantity="one">Open wifi-netwerk beschikbaar</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Verbinding maken met een open wifi-netwerk"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Verbinding maken met een open wifi-netwerk…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Verbonden met een wifi-netwerk"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Kan geen verbinding maken met het wifi-netwerk"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tik om alle netwerken te bekijken"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Verbinding maken"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle netwerken"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Inloggen bij wifi-netwerk"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Inloggen bij netwerk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 5a30637..a89872f 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -130,9 +130,7 @@
     <string name="roamingText12" msgid="1189071119992726320">"ਰੋਮਿੰਗ ਬੈਨਰ ਬੰਦ"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"ਸੇਵਾ ਦੀ ਖੋਜ ਕਰ ਰਿਹਾ ਹੈ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi ਕਾਲਿੰਗ"</string>
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi ਤੇ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਸੁਨੇਹੇ ਭੇਜਣ ਲਈ, ਪਹਿਲਾਂ ਆਪਣੇ ਕੈਰੀਅਰ ਨੂੰ ਇਹ ਸੇਵਾ ਸੈਟ ਅਪ ਕਰਨ ਲਈ ਕਹੋ। ਫਿਰ ਸੈਟਿੰਗਾਂ ਵਿੱਚੋਂ Wi-Fi ਕਾਲਿੰਗ ਦੁਬਾਰਾ ਚਾਲੂ ਕਰੋ।"</item>
-  </string-array>
+    <!-- no translation found for wfcOperatorErrorAlertMessages:0 (3910386316304772394) -->
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਰਜਿਸਟਰ ਕਰੋ"</item>
   </string-array>
@@ -1106,20 +1104,13 @@
       <item quantity="one">ਉਪਲਬਧ Wi-Fi ਨੈੱਟਵਰਕ ਖੋਲ੍ਹੋ</item>
       <item quantity="other">ਉਪਲਬਧ Wi-Fi ਨੈੱਟਵਰਕ ਖੋਲ੍ਹੋ</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"ਖੁੱਲ੍ਹੇ Wi‑Fi ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਹੋਵੋ"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ਖੁੱਲ੍ਹੇ Wi‑Fi ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ਸਾਰੇ ਨੈੱਟਵਰਕਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"ਕਨੈਕਟ ਕਰੋ"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ਸਾਰੇ ਨੈੱਟਵਰਕ"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi ਨੈੱਟਵਰਕ ਵਿੱਚ ਸਾਈਨ ਇਨ ਕਰੋ"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ਨੈੱਟਵਰਕ ਤੇ ਸਾਈਨ ਇਨ ਕਰੋ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 2d90ebd..f3d5387 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -133,7 +133,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Wyszukiwanie usługi"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Połączenia przez Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach."</item>
+    <item msgid="3910386316304772394">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach. (Kod błędu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Zarejestruj u operatora"</item>
@@ -1150,20 +1150,13 @@
       <item quantity="other">Dostępne są otwarte sieci Wi-Fi</item>
       <item quantity="one">Dostępna jest otwarta sieć Wi-Fi</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Połącz się z otwartą siecią Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Łączę się z otwartą siecią Wi-Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Połączono z siecią Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nie udało się połączyć z siecią Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Kliknij, by zobaczyć wszystkie sieci"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Połącz"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Wszystkie sieci"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Zaloguj się w sieci Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Zaloguj się do sieci"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index f9561be..6c22442 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Pesquisando serviço"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas por Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item>
+    <item msgid="3910386316304772394">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois, ative novamente a chamada no Wi-Fi nas configurações. Código de erro: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Faça registro na sua operadora"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">Abrir redes Wi-Fi disponíveis</item>
       <item quantity="other">Abrir redes Wi-Fi disponíveis</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conectar-se a uma rede Wi‑Fi aberta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectando-se a uma rede Wi‑Fi aberta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Conectado a uma rede Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Não foi possível conectar-se à rede Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas as redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Fazer login na rede Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Fazer login na rede"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index bee7e67..2d9a6d4 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"A procurar Serviço"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar este serviço. Em seguida, nas Definições, ative novamente as chamadas por Wi-Fi."</item>
+    <item msgid="3910386316304772394">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar este serviço. De seguida, nas Definições, ative novamente as Chamadas Wi-Fi. (Código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registar-se junto do seu operador"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">Open Wi-Fi networks available</item>
       <item quantity="other">Redes Wi-Fi abertas disponíveis</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Ligar à rede Wi-Fi aberta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"A ligar à rede Wi-Fi aberta…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ligado à rede Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Não foi possível ligar à rede Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ligar"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas as redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Iniciar sessão na rede Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Início de sessão na rede"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index f9561be..6c22442 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Pesquisando serviço"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas por Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item>
+    <item msgid="3910386316304772394">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois, ative novamente a chamada no Wi-Fi nas configurações. Código de erro: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Faça registro na sua operadora"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">Abrir redes Wi-Fi disponíveis</item>
       <item quantity="other">Abrir redes Wi-Fi disponíveis</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conectar-se a uma rede Wi‑Fi aberta"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectando-se a uma rede Wi‑Fi aberta"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Conectado a uma rede Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Não foi possível conectar-se à rede Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas as redes"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Fazer login na rede Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Fazer login na rede"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 48b112a..320dfb5 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -132,7 +132,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Se caută serviciul"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Apelare prin Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Pentru a apela și a trimite mesaje prin Wi-Fi, mai întâi solicitați configurarea acestui serviciu la operator. Apoi, activați din nou apelarea prin Wi-Fi din Setări."</item>
+    <item msgid="3910386316304772394">"Pentru a efectua apeluri și a trimite mesaje prin Wi-Fi, mai întâi solicitați configurarea acestui serviciu la operator. Apoi, activați din nou apelarea prin Wi-Fi din Setări. (Cod de eroare: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Înregistrați-vă la operatorul dvs."</item>
@@ -1128,20 +1128,13 @@
       <item quantity="other">Rețele Wi-Fi deschise disponibile</item>
       <item quantity="one">Rețea Wi-Fi deschisă disponibilă</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Conectați-vă la o rețea Wi‑Fi deschisă"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Se stabilește conexiunea la o rețea Wi‑Fi deschisă"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"S-a realizat conexiunea la rețeaua Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nu s-a putut stabili conexiunea la rețeaua Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Atingeți pentru a vedea toate rețelele"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectați-vă"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Toate rețelele"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Conectați-vă la rețeaua Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Conectați-vă la rețea"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index d2f0952..f81c873 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -133,7 +133,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Поиск службы"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Звонки по Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Чтобы совершать звонки и отправлять сообщения по Wi-Fi, необходимо сначала обратиться к оператору связи и подключить эту услугу. После этого вы сможете снова выбрать этот параметр в настройках."</item>
+    <item msgid="3910386316304772394">"Чтобы совершать звонки и отправлять сообщения по Wi-Fi, необходимо подключить эту услугу через оператора связи. После этого вы сможете выбрать этот параметр в настройках. Код ошибки: <xliff:g id="CODE">%1$s</xliff:g>."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Укажите оператора и зарегистрируйтесь"</item>
@@ -1150,20 +1150,13 @@
       <item quantity="many">Есть открытые сети Wi-Fi</item>
       <item quantity="other">Есть открытые сети Wi-Fi</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Подключитесь к открытой сети Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Подключение к открытой сети Wi‑Fi…"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Подключено к сети Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не удалось подключиться к сети Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Нажмите, чтобы увидеть список сетей"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Подключиться"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Все сети"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Подключение к Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Регистрация в сети"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 821be36..3ed2c87 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"සේවාව සඳහා සොයමින්"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi ඇමතීම"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi හරහා ඇමතුම් සිදු කිරීමට සහ පණිවිඩ යැවීමට, පළමුව මෙම සේවාව පිහිටුවන ලෙස ඔබේ වාහකයෙන් ඉල්ලන්න. අනතුරුව සැකසීම් වෙතින් Wi-Fi ඇමතුම නැවත ක්‍රියාත්මක කරන්න."</item>
+    <item msgid="3910386316304772394">"Wi-Fi හරහා ඇමතුම් සිදු කිරීමට සහ පණිවිඩ යැවීමට, පළමුව මෙම සේවාව පිහිටුවන ලෙස ඔබේ වාහකයෙන් ඉල්ලන්න. අනතුරුව සැකසීම් වෙතින් Wi-Fi ඇමතුම නැවත ක්‍රියාත්මක කරන්න. (දෝෂ කේතය <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"ඔබගේ වාහකය සමඟ ලියාපදිංචි වන්න"</item>
@@ -1108,20 +1108,13 @@
       <item quantity="one">විවෘත Wi-Fi ජාල තිබේ</item>
       <item quantity="other">විවෘත Wi-Fi ජාල තිබේ</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"විවෘත Wi-Fi ජාලය වෙත සම්බන්ධ වෙන්න"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"විවෘත Wi-Fi ජාලය වෙත සම්බන්ධ වෙමින්"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi-Fi ජාලයක් වෙත සම්බන්ධ විය"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi-Fi ජාලයක් වෙත සම්බන්ධ විය නොහැකි විය"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"සියලු ජාල බැලීමට තට්ටු කරන්න"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"සම්බන්ධ කරන්න"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"සියලු ජාල"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi ජාලයට පුරනය වන්න"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ජාලයට පුරනය වන්න"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 0ad0721..e0767ce 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -133,7 +133,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Vyhľadávanie služby"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Volanie cez Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Ak chcete volať a odosielať správy prostredníctvom siete Wi-Fi, kontaktujte najskôr svojho operátora v súvislosti s nastavením tejto služby. Potom opäť zapnite v Nastaveniach volanie cez Wi-Fi."</item>
+    <item msgid="3910386316304772394">"Ak chcete volať a odosielať správy prostredníctvom siete Wi-Fi, kontaktujte najskôr svojho operátora v súvislosti s nastavením tejto služby. Potom opäť zapnite v Nastaveniach volanie cez Wi-Fi. (Kód chyby: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrujte sa so svojím operátorom"</item>
@@ -1150,20 +1150,13 @@
       <item quantity="other">K dispozícii sú verejné siete Wi-Fi</item>
       <item quantity="one">K dispozícii je verejná sieť Wi-Fi</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Pripojenie k otvorenej sieti Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Pripája sa k otvorenej sieti Wi-Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Pripojenie k sieti Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"K sieti Wi‑Fi sa nepodarilo pripojiť"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Klepnutím zobrazíte všetky siete"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Pripojiť"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Všetky siete"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prihlásiť sa do siete Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prihlásenie do siete"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index c6bbd31..9f0d6463 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -133,7 +133,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Iskanje storitve"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Klicanje prek Wi-Fi-ja"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Če želite klicati ali pošiljati sporočila prek omrežja Wi-Fi, se najprej obrnite na operaterja, da nastavi to storitev. Nato v nastavitvah znova vklopite klicanje prek omrežja Wi-Fi."</item>
+    <item msgid="3910386316304772394">"Če želite klicati ali pošiljati sporočila prek omrežja Wi-Fi, se najprej obrnite na operaterja, da nastavi to storitev. Nato v nastavitvah znova vklopite klicanje prek omrežja Wi-Fi. (Koda napake: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registracija pri operaterju"</item>
@@ -286,7 +286,7 @@
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"dostop do koledarja"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"pošiljanje in ogled sporočil SMS"</string>
-    <string name="permgrouplab_storage" msgid="1971118770546336966">"Prostor za shranjevanje"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Shramba"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"dostop do fotografij, predstavnosti in datotek v napravi"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"snemanje zvoka"</string>
@@ -1150,20 +1150,13 @@
       <item quantity="few">Na voljo so odprta omrežja Wi-Fi</item>
       <item quantity="other">Na voljo so odprta omrežja Wi-Fi</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Vzpostavite povezavo z odprtim omrežjem Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Vzpostavljanje povezave z odprtim omrežjem Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Povezava z omrežjem Wi-Fi je vzpostavljena"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Povezave z omrežjem Wi-Fi ni bilo mogoče vzpostaviti"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dotaknite se, če si želite ogledati vsa omrežja"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Vzpostavi povezavo"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Vsa omrežja"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijavite se v omrežje Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava v omrežje"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index bac5990..68a3642 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Po kërkon për shërbim"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Telefonatë me Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Për të bërë telefonata dhe për të dërguar mesazhe me Wi-Fi, në fillim kërkoji operatorit celular ta konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi, nga Cilësimet."</item>
+    <item msgid="3910386316304772394">"Për të bërë telefonata dhe për të dërguar mesazhe nëpërmjet Wi-Fi, në fillim kërkoji operatorit celular të konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi nga \"Cilësimet\". (Kodi i gabimit: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Regjistrohu me operatorin tënd celular"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Rrjete të hapura Wi-Fi në përdorim</item>
       <item quantity="one">Rrjet i hapur Wi-Fi në përdorim</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Lidhu me rrjetin e hapur Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Po lidhet me rrjetin e hapur Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Lidhur me rrjetin e hapur Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nuk mund të lidhet me rrjetin Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Trokit për të parë të gjitha rrjetet"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Lidhu"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Të gjitha rrjetet"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Identifikohu në rrjetin Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Identifikohu në rrjet"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 960ee85..88fb1f2 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -132,7 +132,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Претраживање услуге"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Позивање преко Wi-Fi-ја"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Да бисте упућивали позиве и слали поруке преко Wi-Fi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко Wi-Fi-ја."</item>
+    <item msgid="3910386316304772394">"Да бисте упућивали позиве и слали поруке преко Wi-Fi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко Wi-Fi-ја. (кôд грешке: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Региструјте се код мобилног оператера"</item>
@@ -1128,20 +1128,13 @@
       <item quantity="few">Отворене Wi-Fi мреже су доступне</item>
       <item quantity="other">Отворене Wi-Fi мреже су доступне</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Повежите се са отвореном Wi‑Fi мрежом"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Повезујете се са отвореном Wi‑Fi мрежом"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Повезали сте се са Wi‑Fi мрежом"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Повезивање са Wi‑Fi мрежом није успело"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Додирните да бисте видели све мреже"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Повежи"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Све мреже"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Пријављивање на Wi-Fi мрежу"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Пријавите се на мрежу"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 7e1b655..6075f72 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Söker efter tjänst"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-samtal"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar."</item>
+    <item msgid="3910386316304772394">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar. (Felkod: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Registrera dig hos operatören"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Öppna Wi-Fi-nätverk är tillgängliga</item>
       <item quantity="one">Öppet Wi-Fi-nätverk är tillgängligt</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Anslut till ett öppet Wi-Fi-nätverk"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ansluter till ett öppet Wi-Fi-nätverk"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ansluten till Wi-Fi-nätverket"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Det gick inte att ansluta till Wi‑Fi-nätverket"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tryck för att visa alla nätverk"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Anslut"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alla nätverk"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Logga in på ett Wi-Fi-nätverk"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Logga in på nätverket"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 3e626d8..673f335 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Inatafuta Huduma"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Upigaji Simu kwa Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Ili upige simu na kutuma ujumbe kupitia Wi-Fi, mwambie mtoa huduma wako asanidi huduma hii kwanza. Kisha uwashe tena upigaji simu kwa Wi-Fi kutoka kwenye Mipangilio."</item>
+    <item msgid="3910386316304772394">"Ili upige simu na kutuma ujumbe kupitia Wi-Fi, mwambie mtoa huduma wako aweke mipangilio ya huduma hii kwanza. Kisha uwashe tena kipengele cha kupiga simu kupitia Wi-Fi kwenye Mipangilio. (Msimbo wa hitilafu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Jisajili na mtoa huduma wako"</item>
@@ -1104,20 +1104,13 @@
       <item quantity="other">Fungua mitandao ya Wi-Fi inayopatikana</item>
       <item quantity="one">Fungua mtandao wa Wi-Fi unaopatikana</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Unganisha kwenye mtandao wa Wi‑Fi unaotumiwa na mtu yeyote"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Inaunganisha kwenye mtandao wa Wi‑Fi unaotumiwa na mtu yeyote"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Imeunganisha kwenye mtandao wa Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Imeshindwa kuunganisha kwenye mtandao wa Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Gonga ili uone mitandao yote"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Unganisha"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Mitandao Yote"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Ingia kwa mtandao wa Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Ingia katika mtandao"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 588e057..bb9e85f 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"சேவையைத் தேடுகிறது"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"வைஃபை அழைப்பு"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"வைஃபை மூலம் அழைக்க மற்றும் செய்திகள் அனுப்ப, முதலில் மொபைல் நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும்."</item>
+    <item msgid="3910386316304772394">"வைஃபை மூலம் அழைக்கவும் செய்திகளை அனுப்பவும், முதலில் தொலைத்தொடர்பு நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும். (பிழைக் குறியீடு <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"உங்கள் மொபைல் நிறுவனத்தில் பதிவுசெய்யவும்"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">பொது வைஃபை நெட்வொர்க்குகள் உள்ளன</item>
       <item quantity="one">பொது வைஃபை நெட்வொர்க் உள்ளது</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"திறந்த வைஃபை நெட்வொர்க்குடன் இணைக்கவும்"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"திறந்த வைஃபை நெட்வொர்க்குடன் இணைக்கிறது"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"வைஃபை நெட்வொர்க்குடன் இணைக்கப்பட்டது"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"வைஃபை நெட்வொர்க்குடன் இணைக்க முடியவில்லை"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"எல்லா நெட்வொர்க்குகளையும் பார்க்க, தட்டவும்"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"இணை"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"எல்லா நெட்வொர்க்குகளும்"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"வைஃபை நெட்வொர்க்கில் உள்நுழையவும்"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"நெட்வொர்க்கில் உள்நுழையவும்"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 099eb9c..0d5e69f 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"సేవ కోసం శోధిస్తోంది"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi కాలింగ్"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fiలో కాల్‌లు చేయడం మరియు సందేశాలు పంపడం కోసం ముందుగా ఈ సేవను సెటప్ చేయడానికి మీ క్యారియర్‌ను అడగండి. ఆపై సెట్టింగ్‌ల నుండి మళ్లీ Wi-Fi కాలింగ్‌ను ఆన్ చేయండి."</item>
+    <item msgid="3910386316304772394">"Wi-Fiతో కాల్‌లను చేయడానికి మరియు సందేశాలను పంపించడానికి, మొదట ఈ సేవను సెటప్ చేయాల్సిందిగా మీ క్యారియర్‌‌కి చెప్పండి. ఆ తర్వాత సెట్టింగ్‌ల నుండి Wi-Fi కాలింగ్‌ని మళ్లీ ఆన్ చేయండి. (లోపం కోడ్: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"మీ క్యారియర్‌తో నమోదు చేయండి"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">ఓపెన్ Wi-Fi నెట్‌వర్క్‌లు అందుబాటులో ఉన్నాయి</item>
       <item quantity="one">ఓపెన్ Wi-Fi నెట్‌వర్క్ అందుబాటులో ఉంది</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"బహిరంగ Wi‑Fi నెట్‌వర్క్‌కు కనెక్ట్ చేయండి"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"బహిరంగ Wi‑Fi నెట్‌వర్క్‌కు కనెక్ట్ చేస్తోంది"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi నెట్‌వర్క్‌కు కనెక్ట్ చేయబడింది"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi నెట్‌వర్క్‌కు కనెక్ట్ చేయడం సాధ్యపడలేదు"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"అన్ని నెట్‌వర్క్‌లు చూడటానికి నొక్కండి"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"కనెక్ట్ చేయి"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"అన్ని నెట్‌వర్క్‌లు"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index e6f439f..463db4e 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"กำลังค้นหาบริการ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"การโทรผ่าน Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"หากต้องการโทรออกและส่งข้อความผ่าน Wi-Fi โปรดสอบถามผู้ให้บริการของคุณก่อนเพื่อตั้งค่าบริการนี้ แล้วเปิดการโทรผ่าน Wi-Fi อีกครั้งจากการตั้งค่า"</item>
+    <item msgid="3910386316304772394">"หากต้องการโทรออกและส่งข้อความผ่าน Wi-Fi โปรดสอบถามผู้ให้บริการของคุณก่อนเพื่อตั้งค่าบริการนี้ แล้วเปิดการโทรผ่าน Wi-Fi อีกครั้งจากการตั้งค่า (รหัสข้อผิดพลาด: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"ลงทะเบียนกับผู้ให้บริการ"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">มีหลายเครือข่าย Wi-Fi สาธารณะที่ใช้งานได้</item>
       <item quantity="one">มี 1 เครือข่าย Wi-Fi สาธารณะที่ใช้งานได้</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"เชื่อมต่อเครือข่าย Wi‑Fi แบบเปิด"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"กำลังเชื่อมต่อเครือข่าย Wi‑Fi แบบเปิด"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"เชื่อมต่อเครือข่าย Wi-Fi แล้ว"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ไม่สามารถเชื่อมต่อเครือข่าย Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"แตะเพื่อดูเครือข่ายทั้งหมด"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"เชื่อมต่อ"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"เครือข่ายทั้งหมด"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ลงชื่อเข้าใช้เครือข่าย WiFi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"ลงชื่อเข้าใช้เครือข่าย"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 0f15b2c..dc0bf9e 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Naghahanap ng Serbisyo"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Pagtawag sa pamamagitan ng Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Upang tumawag at magpadala ng mga mensahe sa pamamagitan ng Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay muling i-on ang pagtawag sa Wi-Fi mula sa Mga Setting."</item>
+    <item msgid="3910386316304772394">"Upang makatawag at makapagpadala ng mga mensahe sa Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay i-on muli ang pagtawag gamit ang Wi-Fi mula sa Mga Setting. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Magparehistro sa iyong carrier"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">Available ang mga bukas na Wi-Fi network</item>
       <item quantity="other">Available ang mga bukas na Wi-Fi network</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Kumonekta sa bukas na Wi‑Fi network"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Kumokonekta sa bukas na Wi‑Fi network"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Nakakonekta sa Wi‑Fi network"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Hindi makakonekta sa Wi‑Fi network"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"I-tap upang makita ang lahat ng network"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kumonekta"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Lahat ng Network"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Mag-sign in sa Wi-Fi network"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Mag-sign in sa network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 02f36f0..c977465 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Hizmet Aranıyor"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Kablosuz Çağrı"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Kablosuz ağ üzerinden telefon etmek ve ileti göndermek için ilk önce operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra tekrar Ayarlar\'dan Kablosuz çağrı özelliğini açın."</item>
+    <item msgid="3910386316304772394">"Kablosuz ağ üzerinden telefon etmek ve mesaj göndermek için öncelikle operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra, Ayarlar\'dan Kablosuz çağrı özelliğini tekrar açın. (Hata kodu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Operatörünüze kaydolun"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Kullanılabilir Kablosuz ağları aç</item>
       <item quantity="one">Kullanılabilir Kablosuz ağı aç</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Açık kablosuz ağa bağlanın"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Açık kablosuz ağa bağlandı"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Kablosuz ağa bağlanıldı"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Kablosuz ağa bağlanamadı"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tüm ağları görmek için dokunun"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Bağlan"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tüm Ağlar"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Kablosuz ağda oturum açın"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Ağda oturum açın"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 64daf06..9b65f57 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -133,7 +133,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Пошук служби"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Дзвінок через Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спочатку попросіть свого оператора налаштувати цю послугу. Після цього ввімкніть дзвінки через Wi-Fi у налаштуваннях."</item>
+    <item msgid="3910386316304772394">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спершу попросіть свого оператора налаштувати цю послугу. Після цього знову ввімкніть дзвінки через Wi-Fi у налаштуваннях. (Код помилки: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Зареєструйтеся в оператора"</item>
@@ -1150,20 +1150,13 @@
       <item quantity="many">Відкриті мережі Wi-Fi доступні</item>
       <item quantity="other">Відкриті мережі Wi-Fi доступні</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Під’єднайтеся до відкритої мережі Wi-Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Під’єднання до відкритої мережі Wi-Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Під’єднано до мережі Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не вдалося під’єднатися до мережі Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Торкніться, щоб побачити всі мережі"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Під’єднатися"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Усі мережі"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Вхід у мережу Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Вхід у мережу"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index bb72b8e..e61a062 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -130,9 +130,7 @@
     <string name="roamingText12" msgid="1189071119992726320">"رومنگ بینر آف"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"سروس کی تلاش کر رہا ہے"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"‏Wi-Fi کالنگ"</string>
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"‏Wi-Fi سے کالز کرنے اور پیغامات بھیجنے کیلئے، پہلے اپنے کیریئر سے اس سروس کو ترتیب دینے کیلئے کہیں۔ پھر ترتیبات سے دوبارہ Wi-Fi کالنگ آن کریں۔"</item>
-  </string-array>
+    <!-- no translation found for wfcOperatorErrorAlertMessages:0 (3910386316304772394) -->
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"اپنے کیریئر کے ساتھ رجسٹر کریں"</item>
   </string-array>
@@ -1106,20 +1104,13 @@
       <item quantity="other">‏عوامی Wi-Fi نیٹ ورکس دستیاب ہیں</item>
       <item quantity="one">‏عوامی Wi-Fi نیٹ ورک دستیاب ہے</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"‏عوامی Wi‑Fi نیٹ ورک سے منسلک ہوں"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"‏عوامی Wi‑Fi نیٹ ورک سے منسلک ہو رہا ہے"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"‏عوامی Wi‑Fi نیٹ ورک سے منسلک ہو گيا"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"‏Wi‑Fi نیٹ ورک سے منسلک نہیں ہو سکا"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"تمام نیٹ ورکس دیکھنے کیلئے تھپتھپائيں"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"منسلک کریں"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"تمام نیٹ ورکس"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"‏Wi-Fi نیٹ ورک میں سائن ان کریں"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"نیٹ ورک میں سائن ان کریں"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 98fdc3d..36a74fe 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Xizmatlar qidirilmoqda"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi qo‘ng‘iroq"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Wi-Fi orqali qo‘ng‘iroqlarni amalga oshirish va xabarlar bilan almashinish uchun uyali aloqa operatoringizdan ushbu xizmatni yoqib qo‘yishni so‘rashingiz lozim. Keyin sozlamalarda Wi-Fi qo‘ng‘irog‘i imkoniyatini yoqib olishingiz mumkin."</item>
+    <item msgid="3910386316304772394">"Wi-Fi orqali qo‘ng‘iroqlarni amalga oshirish va xabarlar bilan almashinish uchun uyali aloqa operatoringizdan ushbu xizmatni yoqib qo‘yishni so‘rashingiz lozim. Keyin sozlamalarda Wi-Fi qo‘ng‘irog‘i imkoniyatini yoqib olishingiz mumkin. (Xato kodi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Mobil operatoringiz yordamida ro‘yxatdan o‘ting"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Ochiq Wi-Fi tarmoqlari aniqlandi</item>
       <item quantity="one">Ochiq Wi-Fi tarmog‘i aniqlandi</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Ochiq Wi‑Fi tarmoqqa ulaning"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ochiq Wi‑Fi tarmoqqa ulanilmoqda"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi tarmoqqa ulanildi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi-Fi tarmoqqa ulanib bo‘lmadi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Barcha tarmoqlarni ko‘rish uchun bosing"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ulanish"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Barcha tarmoqlar"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi tarmoqqa kirish"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Tarmoqqa kirish"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1454,7 +1447,7 @@
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", xavfsiz"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Grafik kalit esimdan chiqdi"</string>
-    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Grafik kalit noto‘g‘ri"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Grafik kalit xato"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Parol noto‘g‘ri"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN-kod noto‘g‘ri"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%1$d</xliff:g> soniyadan so‘ng qayta urinib ko‘ring."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index f2c06e5..d15a48f 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Đang tìm kiếm Dịch vụ"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Gọi qua Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại gọi qua Wi-Fi từ Cài đặt."</item>
+    <item msgid="3910386316304772394">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại gọi qua Wi-Fi từ Cài đặt. (Mã lỗi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Đăng ký với nhà cung cấp dịch vụ của bạn"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">Mở các mạng Wi-Fi khả dụng</item>
       <item quantity="one">Mở mạng Wi-Fi khả dụng</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Kết nối với mạng Wi-Fi đang mở"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Đang kết nối với mạng Wi‑Fi đang mở"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Đã kết nối với mạng Wi-Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Không thể kết nối với mạng Wi‑Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Nhấn để xem tất cả các mạng"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kết nối"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tất cả các mạng"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Đăng nhập vào mạng Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Đăng nhập vào mạng"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 5e8eb68..6e10594 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"正在搜索服务"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"WLAN 通话"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能。"</item>
+    <item msgid="3910386316304772394">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能(错误代码:<xliff:g id="CODE">%1$s</xliff:g>)。"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"向您的运营商注册"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">有可用的开放 WLAN 网络</item>
       <item quantity="one">有可用的开放 WLAN 网络</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"连接到开放的 WLAN 网络"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"正在连接到开放的 WLAN 网络"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"已连接到 WLAN 网络"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"无法连接到 WLAN 网络"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"点按即可查看所有网络"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"连接"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"所有网络"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"登录到WLAN网络"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"登录到网络"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index b5301dd..c7b59f4 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"正在搜尋服務"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi 通話"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"如要透過 Wi-Fi 撥打電話及傳送訊息,請先向您的流動網絡供應商要求設定此服務。然後再次在「設定」中開啟 Wi-Fi 通話。"</item>
+    <item msgid="3910386316304772394">"如要透過 Wi-Fi 撥打電話和傳送訊息,請先向流動網絡供應商要求設定此服務,然後再次在「設定」中開啟「Wi-Fi 通話」。(錯誤代碼:<xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"向您的流動網絡供應商註冊"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">有可用的公開 Wi-Fi 網絡</item>
       <item quantity="one">有可用的公開 Wi-Fi 網絡</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"連線至開放的 Wi-Fi 網絡"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"正在連線至開放的 Wi-Fi 網絡"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"已連線至 Wi-Fi 網絡"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"無法連線至 Wi-Fi 網絡"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"輕按即可查看所有網絡"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"連線"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"所有網絡"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"登入 Wi-Fi 網絡"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"登入網絡"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index c1fc9bb..87117e4 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"正在搜尋服務"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi 通話"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"如要透過 Wi-FI 撥打電話及傳送訊息,請先要求你的電信業者開通這項服務,然後再到「設定」啟用 Wi-Fi 通話功能。"</item>
+    <item msgid="3910386316304772394">"如要透過 Wi-Fi 網路撥打電話及傳送訊息,請先要求電信業者為你設定這項服務,然後再次前往「設定」頁面啟用 Wi-Fi 通話功能。(錯誤代碼:<xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"向你的電信業者註冊"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="other">有多個可用的開放 Wi-Fi 網路</item>
       <item quantity="one">有多個可用的開放 Wi-Fi 網路</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"連線至開放的 Wi‑Fi 網路"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"正在連線至開放的 Wi‑Fi 網路"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"已連線至 Wi-Fi 網路"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"無法連線至 Wi‑Fi 網路"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"輕觸即可查看所有網路"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"連線"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"所有網路"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"登入 Wi-Fi 網路"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"登入網路"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1202,7 +1195,7 @@
     <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"不支援的音訊配件"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"輕觸即可瞭解詳情"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
-    <string name="adb_active_notification_message" msgid="4948470599328424059">"輕觸即可停用 USB 偵錯。"</string>
+    <string name="adb_active_notification_message" msgid="4948470599328424059">"輕觸即可停用 USB 偵錯功能。"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取以停用 USB 偵錯。"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在接收錯誤報告…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享錯誤報告嗎?"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 6cd74c7..4d57f3c 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -131,7 +131,7 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"Iseshela Isevisi"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Ukushaya kwe-Wi-Fi"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"Ukuze wenze amakholi uphinde uthumele imilayezo nge-Wi-FI, qala ucele inkampani yakho yenethiwekhi ukuthi isethe le divayisi. Bese uvula ukushaya kwe-Wi-FI futhi kusukela kuzilungiselelo."</item>
+    <item msgid="3910386316304772394">"Ukuze wenze amakholi uphinde uthumele imilayezo nge-Wi-Fi, qala ucele inkampani yakho yenethiwekhi ukuthi isethe le sevisi. Bese uvula ukushaya kwe-Wi-Fi futhi kusukela kuzilungiselelo (Ikhodi yephutha: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"Bhalisa ngenkampani yakho yenethiwekhi"</item>
@@ -1106,20 +1106,13 @@
       <item quantity="one">Vula amanethiwekhi we-Wi-Fi atholakalayo</item>
       <item quantity="other">Vula amanethiwekhi we-Wi-Fi atholakalayo</item>
     </plurals>
-    <!-- no translation found for wifi_available_title (3817100557900599505) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connecting (1557292688310330032) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_connected (7542672851522241548) -->
-    <skip />
-    <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) -->
-    <skip />
-    <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_connect (2635699628459488788) -->
-    <skip />
-    <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) -->
-    <skip />
+    <string name="wifi_available_title" msgid="3817100557900599505">"Xhuma kunethiwekhi evulekile ye-Wi‑Fi"</string>
+    <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ixhuma kunethiwekhi evulekile ye-Wi‑Fi"</string>
+    <string name="wifi_available_title_connected" msgid="7542672851522241548">"Kuxhumeke kunethiwekhi ye-Wi‑Fi"</string>
+    <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Ayikwazanga ukuxhumeka kunethiwekhi ye-Wi-Fi"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Thepha ukuze ubone onke amanethiwekhi"</string>
+    <string name="wifi_available_action_connect" msgid="2635699628459488788">"Xhuma"</string>
+    <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Onke amanethiwekhi"</string>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Ngena ngemvume kunethiwekhi ye-Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Ngena ngemvume kunethiwekhi"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 062da95..69bb0b9 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2980,4 +2980,10 @@
 
     <!-- An array of packages that need to be treated as type service in battery settings -->
     <string-array translatable="false" name="config_batteryPackageTypeService"/>
+
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">false</bool>
+
+    <!-- Enable the RingtonePickerActivity in 'com.android.providers.media'. -->
+    <bool name="config_defaultRingtonePickerEnabled">true</bool>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 5e2334d..fa33d56 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -67,6 +67,9 @@
     <!-- The amount to leave on-screen when the PIP is minimized. -->
     <dimen name="pip_minimized_visible_size">48dp</dimen>
 
+    <!-- The the PIP decelerates at while moving from a fling. -->
+    <dimen name="pip_fling_deceleration">-3000dp</dimen>
+
     <!-- Min width for a tablet device -->
     <dimen name="min_xlarge_screen_width">800dp</dimen>
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index ce701a7..bd8e14ea 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4713,6 +4713,9 @@
     <!-- Primary ETWS (Earthquake and Tsunami Warning System) default message for test -->
     <string name="etws_primary_default_message_test">Emergency messages test</string>
 
+    <!-- Content description for the reply button in the notification area [CHAR LIMIT=NONE]-->
+    <string name="notification_reply_button_accessibility">Reply</string>
+
     <!-- Primary ETWS (Earthquake and Tsunami Warning System) default message for others -->
     <string name="etws_primary_default_message_others"></string>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3b3879f..99807f9 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1583,6 +1583,7 @@
   <java-symbol type="dimen" name="docked_stack_divider_insets" />
   <java-symbol type="dimen" name="docked_stack_minimize_thickness" />
   <java-symbol type="dimen" name="pip_minimized_visible_size" />
+  <java-symbol type="dimen" name="pip_fling_deceleration" />
   <java-symbol type="integer" name="config_dockedStackDividerSnapMode" />
   <java-symbol type="integer" name="config_pictureInPictureSnapMode" />
   <java-symbol type="fraction" name="docked_stack_divider_fixed_ratio" />
@@ -3052,7 +3053,9 @@
 
   <java-symbol type="drawable" name="stat_sys_vitals" />
 
+  <java-symbol type="color" name="text_color_primary" />
+
   <java-symbol type="array" name="config_batteryPackageTypeSystem" />
   <java-symbol type="array" name="config_batteryPackageTypeService" />
-
+  <java-symbol type="bool" name="config_showAreaUpdateInfoSettings" />
 </resources>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 7dc72db7..f02c45c 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -17,24 +17,25 @@
 package android.provider;
 
 import static com.google.android.collect.Sets.newHashSet;
+
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.empty;
 import static org.hamcrest.Matchers.is;
+
 import static java.lang.reflect.Modifier.isFinal;
 import static java.lang.reflect.Modifier.isPublic;
 import static java.lang.reflect.Modifier.isStatic;
 
-import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.lang.reflect.Field;
 import java.util.HashSet;
 import java.util.Set;
 
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
 /** Tests that ensure appropriate settings are backed up. */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
@@ -446,6 +447,8 @@
                  Settings.Secure.MANAGED_PROFILE_CONTACT_REMOTE_SEARCH,
                  Settings.Secure.MULTI_PRESS_TIMEOUT,
                  Settings.Secure.NFC_PAYMENT_FOREGROUND,
+                 Settings.Secure.NIGHT_DISPLAY_ACTIVATED,
+                 Settings.Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
                  Settings.Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME,
                  Settings.Secure.PACKAGE_VERIFIER_STATE,
                  Settings.Secure.PACKAGE_VERIFIER_USER_CONSENT,
diff --git a/graphics/java/android/graphics/ColorFilter.java b/graphics/java/android/graphics/ColorFilter.java
index 0ca3729..b24b988 100644
--- a/graphics/java/android/graphics/ColorFilter.java
+++ b/graphics/java/android/graphics/ColorFilter.java
@@ -14,19 +14,22 @@
  * limitations under the License.
  */
 
-// This file was generated from the C++ include file: SkColorFilter.h
-// Any changes made to this file will be discarded by the build.
-// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, 
-// or one of the auxilary file specifications in device/tools/gluemaker.
-
 package android.graphics;
 
+import libcore.util.NativeAllocationRegistry;
+
 /**
  * A color filter can be used with a {@link Paint} to modify the color of
  * each pixel drawn with that paint. This is an abstract class that should
  * never be used directly.
  */
 public class ColorFilter {
+
+    private static class NoImagePreloadHolder {
+        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+                ColorFilter.class.getClassLoader(), nativeGetFinalizer(), 50);
+    }
+
     /**
      * @deprecated Use subclass constructors directly instead.
      */
@@ -34,9 +37,11 @@
     public ColorFilter() {}
 
     /**
-     * Holds the pointer to the native SkColorFilter instance.
+     * Current native SkColorFilter instance.
      */
     private long mNativeInstance;
+    // Runnable to do immediate destruction
+    private Runnable mCleaner;
 
     long createNativeInstance() {
         return 0;
@@ -44,35 +49,28 @@
 
     void discardNativeInstance() {
         if (mNativeInstance != 0) {
-            nSafeUnref(mNativeInstance);
+            mCleaner.run();
+            mCleaner = null;
             mNativeInstance = 0;
         }
     }
 
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            if (mNativeInstance != 0) {
-                nSafeUnref(mNativeInstance);
-            }
-            mNativeInstance = -1;
-        } finally {
-            super.finalize();
-        }
-    }
-
     /** @hide */
     public long getNativeInstance() {
-        if (mNativeInstance == -1) {
-            throw new IllegalStateException("attempting to use a finalized ColorFilter");
-        }
-
         if (mNativeInstance == 0) {
             mNativeInstance = createNativeInstance();
+
+            if (mNativeInstance != 0) {
+                // Note: we must check for null here, since it's possible for createNativeInstance()
+                // to return nullptr if the native SkColorFilter would be a no-op at draw time.
+                // See native implementations of subclass create methods for more info.
+                mCleaner = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
+                        this, mNativeInstance);
+            }
         }
         return mNativeInstance;
 
     }
 
-    static native void nSafeUnref(long native_instance);
+    private static native long nativeGetFinalizer();
 }
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index 8616d58..1d0cfa5 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -289,6 +289,9 @@
     }
 
     private void updateLayerBounds(Rect bounds) {
+        if (bounds.isEmpty()) {
+            return;
+        }
         try {
             suspendChildInvalidation();
             updateLayerBoundsInternal(bounds);
@@ -1109,4 +1112,4 @@
             mCheckedStateful = false;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index 2e9a6e8..c19c1a1 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -457,11 +457,13 @@
     return *this;
 }
 
-GlopBuilder& GlopBuilder::setFillExternalTexture(Texture& texture, Matrix4& textureTransform) {
+GlopBuilder& GlopBuilder::setFillExternalTexture(Texture& texture, Matrix4& textureTransform,
+        bool requiresFilter) {
     TRIGGER_STAGE(kFillStage);
     REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
 
-    mOutGlop->fill.texture = { &texture, GL_LINEAR, GL_CLAMP_TO_EDGE, &textureTransform };
+    GLenum filter = requiresFilter ? GL_LINEAR : GL_NEAREST;
+    mOutGlop->fill.texture = { &texture, filter, GL_CLAMP_TO_EDGE, &textureTransform };
 
     setFill(SK_ColorWHITE, 1.0f, SkBlendMode::kSrc, Blend::ModeOrderSwap::NoSwap,
             nullptr, nullptr);
diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h
index 87b1568..6d11da1 100644
--- a/libs/hwui/GlopBuilder.h
+++ b/libs/hwui/GlopBuilder.h
@@ -75,7 +75,8 @@
     GlopBuilder& setFillTextureLayer(GlLayer& layer, float alpha);
     // TODO: setFillLayer normally forces its own wrap & filter mode,
     // which isn't always correct.
-    GlopBuilder& setFillExternalTexture(Texture& texture, Matrix4& textureTransform);
+    GlopBuilder& setFillExternalTexture(Texture& texture, Matrix4& textureTransform,
+            bool requiresFilter);
 
     GlopBuilder& setTransform(const Matrix4& canvas, const int transformFlags);
 
diff --git a/libs/hwui/OpenGLReadback.cpp b/libs/hwui/OpenGLReadback.cpp
index b073070b..19d5d9d 100644
--- a/libs/hwui/OpenGLReadback.cpp
+++ b/libs/hwui/OpenGLReadback.cpp
@@ -199,6 +199,7 @@
             GL_TEXTURE_2D, texture, 0);
 
     {
+        bool requiresFilter;
         // Draw & readback
         renderState.setViewport(destWidth, destHeight);
         renderState.scissor().setEnabled(false);
@@ -216,12 +217,17 @@
             croppedTexTransform.scale(srcRect.getWidth() / sourceTexture.width(),
                     srcRect.getHeight() / sourceTexture.height(), 1);
             croppedTexTransform.multiply(sFlipV);
+            requiresFilter = srcRect.getWidth() != (float) destWidth
+                    || srcRect.getHeight() != (float) destHeight;
+        } else {
+            requiresFilter = sourceTexture.width() != (uint32_t) destWidth
+                    || sourceTexture.height() != (uint32_t) destHeight;
         }
         Glop glop;
         GlopBuilder(renderState, caches, &glop)
                 .setRoundRectClipState(nullptr)
                 .setMeshTexturedUnitQuad(nullptr)
-                .setFillExternalTexture(sourceTexture, croppedTexTransform)
+                .setFillExternalTexture(sourceTexture, croppedTexTransform, requiresFilter)
                 .setTransform(Matrix4::identity(), TransformFlags::None)
                 .setModelViewMapUnitToRect(Rect(destWidth, destHeight))
                 .build();
diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java
index 912551f..b2903c4 100644
--- a/location/java/android/location/GnssStatus.java
+++ b/location/java/android/location/GnssStatus.java
@@ -97,13 +97,12 @@
             CONSTELLATION_QZSS, CONSTELLATION_BEIDOU, CONSTELLATION_GALILEO})
     public @interface ConstellationType {}
 
-    /* These package private values are modified by the LocationManager class */
-    /* package */ int[] mSvidWithFlags;
-    /* package */ float[] mCn0DbHz;
-    /* package */ float[] mElevations;
-    /* package */ float[] mAzimuths;
-    /* package */ int mSvCount;
-    /* package */ float[] mCarrierFrequencies;
+    final int[] mSvidWithFlags;
+    final float[] mCn0DbHz;
+    final float[] mElevations;
+    final float[] mAzimuths;
+    final int mSvCount;
+    final float[] mCarrierFrequencies;
 
     GnssStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations,
             float[] azimuths, float[] carrierFrequencies) {
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 26ac2a2..968f596 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -74,7 +74,8 @@
             new HashMap<>();
     private final HashMap<OnNmeaMessageListener, GnssStatusListenerTransport> mGnssNmeaListeners =
             new HashMap<>();
-    private GnssStatus mGnssStatus;
+    // volatile + GnssStatus final-fields pattern to avoid a partially published object
+    private volatile GnssStatus mGnssStatus;
     private int mTimeToFirstFix;
 
     /**
@@ -1563,7 +1564,7 @@
                 float[] cn0s, float[] elevations, float[] azimuths, float[] carrierFreqs) {
             if (mGnssCallback != null) {
                 mGnssStatus = new GnssStatus(svCount, prnWithFlags, cn0s, elevations, azimuths,
-                    carrierFreqs);
+                        carrierFreqs);
 
                 Message msg = Message.obtain();
                 msg.what = GpsStatus.GPS_EVENT_SATELLITE_STATUS;
@@ -1949,7 +1950,7 @@
             status = new GpsStatus();
         }
         // When mGnssStatus is null, that means that this method is called outside
-        // onGpsStatusChanged().  Return an empty status  to maintain backwards compatibility.
+        // onGpsStatusChanged().  Return an empty status to maintain backwards compatibility.
         if (mGnssStatus != null) {
             status.setStatus(mGnssStatus, mTimeToFirstFix);
         }
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index c1e81c5..f403988 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -218,6 +218,7 @@
         SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_COMMUNICATION_DELAYED,SUPPRESSIBLE_NOTIFICATION);
         SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_EVENT,                SUPPRESSIBLE_NOTIFICATION);
         SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_ACCESSIBILITY,          SUPPRESSIBLE_NEVER);
+        SUPPRESSIBLE_USAGES.put(USAGE_VOICE_COMMUNICATION,               SUPPRESSIBLE_NEVER);
     }
 
     /**
diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
index 0a1de33..2b5ac5e 100644
--- a/media/java/android/media/AudioManagerInternal.java
+++ b/media/java/android/media/AudioManagerInternal.java
@@ -59,4 +59,15 @@
 
         int getRingerModeAffectedStreams(int streams);
     }
+
+    /**
+     * Disable or restore the ability to play audio for a given UID.
+     * When a UID isn't meant to be tracked anymore (e.g. client died), re-enable audio for this UID
+     * to prevent disabling audio for future UIDs that would reuse the same value.
+     * This operation is asynchronous.
+     * @param disable when true, prevents playback of audio streams from the given uid. If false,
+     *         restores the ability to play, or no-op if playback hadn't been disabled before.
+     * @param uid the client UID whose ability to play will be affected.
+     */
+    public abstract void disableAudioForUid(boolean disable, int uid);
 }
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 6ef3091..29fe275 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -424,7 +424,8 @@
                                                   DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
                                                   DEVICE_OUT_BLUETOOTH_SCO_CARKIT);
     public static final int DEVICE_OUT_ALL_USB = (DEVICE_OUT_USB_ACCESSORY |
-                                                  DEVICE_OUT_USB_DEVICE);
+                                                  DEVICE_OUT_USB_DEVICE |
+                                                  DEVICE_OUT_USB_HEADSET);
     public static final int DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO = (DEVICE_OUT_AUX_LINE |
                                                                 DEVICE_OUT_HDMI_ARC |
                                                                 DEVICE_OUT_SPDIF);
@@ -486,7 +487,8 @@
                                              DEVICE_IN_DEFAULT);
     public static final int DEVICE_IN_ALL_SCO = DEVICE_IN_BLUETOOTH_SCO_HEADSET;
     public static final int DEVICE_IN_ALL_USB = (DEVICE_IN_USB_ACCESSORY |
-                                                 DEVICE_IN_USB_DEVICE);
+                                                 DEVICE_IN_USB_DEVICE |
+                                                 DEVICE_IN_USB_HEADSET);
 
     // device states, must match AudioSystem::device_connection_state
     public static final int DEVICE_STATE_UNAVAILABLE = 0;
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index dfd2bb3..44bd252 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -43,6 +43,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.KeyEvent;
+import android.view.ViewConfiguration;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -200,8 +201,7 @@
                 return;
             }
             if (mCallback != null) {
-                // We're updating the callback, clear the session from the old
-                // one.
+                // We're updating the callback, clear the session from the old one.
                 mCallback.mCallback.mSession = null;
             }
             if (handler == null) {
@@ -735,6 +735,8 @@
      */
     public abstract static class Callback {
         private MediaSession mSession;
+        private CallbackMessageHandler mHandler;
+        private boolean mMediaPlayPauseKeyPending;
 
         public Callback() {
         }
@@ -766,13 +768,41 @@
          * @return True if the event was handled, false otherwise.
          */
         public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) {
-            if (mSession != null
+            if (mSession != null && mHandler != null
                     && Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) {
                 KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
                 if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) {
                     PlaybackState state = mSession.mPlaybackState;
                     long validActions = state == null ? 0 : state.getActions();
                     switch (ke.getKeyCode()) {
+                        case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+                        case KeyEvent.KEYCODE_HEADSETHOOK:
+                            if (ke.getRepeatCount() > 0) {
+                                // Consider long-press as a single tap.
+                                handleMediaPlayPauseKeySingleTapIfPending();
+                            } else if (mMediaPlayPauseKeyPending) {
+                                // Consider double tap as the next.
+                                mHandler.removeMessages(CallbackMessageHandler
+                                        .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT);
+                                mMediaPlayPauseKeyPending = false;
+                                if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) {
+                                    onSkipToNext();
+                                }
+                            } else {
+                                mMediaPlayPauseKeyPending = true;
+                                mHandler.sendEmptyMessageDelayed(CallbackMessageHandler
+                                        .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT,
+                                        ViewConfiguration.getDoubleTapTimeout());
+                            }
+                            return true;
+                        default:
+                            // If another key is pressed within double tap timeout, consider the
+                            // pending play/pause as a single tap to handle media keys in order.
+                            handleMediaPlayPauseKeySingleTapIfPending();
+                            break;
+                    }
+
+                    switch (ke.getKeyCode()) {
                         case KeyEvent.KEYCODE_MEDIA_PLAY:
                             if ((validActions & PlaybackState.ACTION_PLAY) != 0) {
                                 onPlay();
@@ -815,28 +845,33 @@
                                 return true;
                             }
                             break;
-                        case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
-                        case KeyEvent.KEYCODE_HEADSETHOOK:
-                            boolean isPlaying = state == null ? false
-                                    : state.getState() == PlaybackState.STATE_PLAYING;
-                            boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
-                                    | PlaybackState.ACTION_PLAY)) != 0;
-                            boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
-                                    | PlaybackState.ACTION_PAUSE)) != 0;
-                            if (isPlaying && canPause) {
-                                onPause();
-                                return true;
-                            } else if (!isPlaying && canPlay) {
-                                onPlay();
-                                return true;
-                            }
-                            break;
                     }
                 }
             }
             return false;
         }
 
+        private void handleMediaPlayPauseKeySingleTapIfPending() {
+            if (!mMediaPlayPauseKeyPending) {
+                return;
+            }
+            mMediaPlayPauseKeyPending = false;
+            mHandler.removeMessages(CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT);
+            PlaybackState state = mSession.mPlaybackState;
+            long validActions = state == null ? 0 : state.getActions();
+            boolean isPlaying = state != null
+                    && state.getState() == PlaybackState.STATE_PLAYING;
+            boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
+                        | PlaybackState.ACTION_PLAY)) != 0;
+            boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
+                        | PlaybackState.ACTION_PAUSE)) != 0;
+            if (isPlaying && canPause) {
+                onPause();
+            } else if (!isPlaying && canPlay) {
+                onPlay();
+            }
+        }
+
         /**
          * Override to handle requests to prepare playback. During the preparation, a session should
          * not hold audio focus in order to allow other sessions play seamlessly. The state of
@@ -1294,12 +1329,14 @@
         private static final int MSG_CUSTOM_ACTION = 20;
         private static final int MSG_ADJUST_VOLUME = 21;
         private static final int MSG_SET_VOLUME = 22;
+        private static final int MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT = 23;
 
         private MediaSession.Callback mCallback;
 
         public CallbackMessageHandler(Looper looper, MediaSession.Callback callback) {
             super(looper, null, true);
             mCallback = callback;
+            mCallback.mHandler = this;
         }
 
         public void post(int what, Object obj, Bundle bundle) {
@@ -1401,6 +1438,9 @@
                         vp.onSetVolumeTo((int) msg.obj);
                     }
                     break;
+                case MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT:
+                    mCallback.handleMediaPlayPauseKeySingleTapIfPending();
+                    break;
             }
         }
     }
diff --git a/media/jni/soundpool/SoundPoolThread.cpp b/media/jni/soundpool/SoundPoolThread.cpp
index 3d98877..ba3b482 100644
--- a/media/jni/soundpool/SoundPoolThread.cpp
+++ b/media/jni/soundpool/SoundPoolThread.cpp
@@ -20,8 +20,6 @@
 
 #include "SoundPoolThread.h"
 
-static const int kMaxWorkers = 3;
-
 namespace android {
 
 void SoundPoolThread::write(SoundPoolMsg msg) {
@@ -33,21 +31,14 @@
     // if thread is quitting, don't add to queue
     if (mRunning) {
         mMsgQueue.push(msg);
-        if (mNumWorkers < kMaxWorkers) {
-            if (createThreadEtc(beginThread, this, "SoundPoolThread")) {
-                mNumWorkers++;
-                ALOGV("created worker thread");
-            }
-        }
+        mCondition.signal();
     }
 }
 
 const SoundPoolMsg SoundPoolThread::read() {
     Mutex::Autolock lock(&mLock);
-    if (mMsgQueue.size() == 0) {
-        mNumWorkers--;
-        mCondition.signal();
-        return SoundPoolMsg(SoundPoolMsg::KILL, 0);
+    while (mMsgQueue.size() == 0) {
+        mCondition.wait(mLock);
     }
     SoundPoolMsg msg = mMsgQueue[0];
     mMsgQueue.removeAt(0);
@@ -60,20 +51,20 @@
     if (mRunning) {
         mRunning = false;
         mMsgQueue.clear();
-        mCondition.broadcast(); // wake up any blocked writers
-        while (mNumWorkers > 0) {
-            mCondition.wait(mLock);
-        }
+        mMsgQueue.push(SoundPoolMsg(SoundPoolMsg::KILL, 0));
+        mCondition.signal();
+        mCondition.wait(mLock);
     }
     ALOGV("return from quit");
 }
 
 SoundPoolThread::SoundPoolThread(SoundPool* soundPool) :
-    mSoundPool(soundPool),
-    mNumWorkers(0),
-    mRunning(true)
+    mSoundPool(soundPool)
 {
     mMsgQueue.setCapacity(maxMessages);
+    if (createThreadEtc(beginThread, this, "SoundPoolThread")) {
+        mRunning = true;
+    }
 }
 
 SoundPoolThread::~SoundPoolThread()
diff --git a/media/jni/soundpool/SoundPoolThread.h b/media/jni/soundpool/SoundPoolThread.h
index 5d7bf0c..7b3e1dd 100644
--- a/media/jni/soundpool/SoundPoolThread.h
+++ b/media/jni/soundpool/SoundPoolThread.h
@@ -58,7 +58,6 @@
     Condition               mCondition;
     Vector<SoundPoolMsg>    mMsgQueue;
     SoundPool*              mSoundPool;
-    int32_t                 mNumWorkers;
     bool                    mRunning;
 };
 
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index e38cca7..a487632 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -377,6 +377,9 @@
                 return;
             } else if (mPagesLoaded == 2) {
                 // Prevent going back to empty first page.
+                // Fix for missing focus, see b/62449959 for details. Remove it once we get a
+                // newer version of WebView (60.x.y).
+                view.requestFocus();
                 view.clearHistory();
             }
             testForCaptivePortal();
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index 3b29a6c..1e26231 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -77,7 +77,7 @@
 
     private BluetoothAdapter mBluetoothAdapter;
     private WifiManager mWifiManager;
-    private BluetoothLeScanner mBLEScanner;
+    @Nullable private BluetoothLeScanner mBLEScanner;
     private ScanSettings mDefaultScanSettings = new ScanSettings.Builder().build();
 
     private List<DeviceFilter<?>> mFilters;
@@ -185,7 +185,7 @@
             mBluetoothAdapter.startDiscovery();
         }
 
-        if (shouldScan(mBLEFilters)) {
+        if (shouldScan(mBLEFilters) && mBLEScanner != null) {
             mBLEScanCallback = new BLEScanCallback();
             mBLEScanner.startScan(mBLEScanFilters, mDefaultScanSettings, mBLEScanCallback);
         }
@@ -224,7 +224,7 @@
             unregisterReceiver(mBluetoothBroadcastReceiver);
             mBluetoothBroadcastReceiver = null;
         }
-        mBLEScanner.stopScan(mBLEScanCallback);
+        if (mBLEScanner != null) mBLEScanner.stopScan(mBLEScanCallback);
         if (mWifiBroadcastReceiver != null) {
             unregisterReceiver(mWifiBroadcastReceiver);
             mWifiBroadcastReceiver = null;
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 0484645..7f2d85a 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -110,7 +110,7 @@
     <string name="unknown" msgid="1592123443519355854">"Sconosciuta"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"Utente: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="313159469856372621">"Alcune opzioni predefinite impostate"</string>
-    <string name="launch_defaults_none" msgid="4241129108140034876">"Nessuna app predefinita impostata"</string>
+    <string name="launch_defaults_none" msgid="4241129108140034876">"Nessuna impostazione predefinita"</string>
     <string name="tts_settings" msgid="8186971894801348327">"Impostazioni di sintesi vocale"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"Output sintesi vocale"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Velocità voce"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index fd994b5..a430288 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -130,6 +130,15 @@
     <!-- Bluetooth settings.  Message when connected to a device, except for phone/media audio. [CHAR LIMIT=40] -->
     <string name="bluetooth_connected_no_headset_no_a2dp">Connected (no phone or media)</string>
 
+    <!-- Bluetooth settings.  Message when connected to a device, showing remote device battery level. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_connected_battery_level">Connected, battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
+    <!-- Bluetooth settings.  Message when connected to a device, except for phone audio, showing remote device battery level. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_connected_no_headset_battery_level">Connected (no phone), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
+    <!-- Bluetooth settings.  Message when connected to a device, except for media audio, showing remote device battery level. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_connected_no_a2dp_battery_level">Connected (no media), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
+    <!-- Bluetooth settings.  Message when connected to a device, except for phone/media audio, showing remote device battery level. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level">Connected (no phone or media), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
+
     <!-- Bluetooth settings.  The user-visible string that is used whenever referring to the A2DP profile. -->
     <string name="bluetooth_profile_a2dp">Media audio</string>
     <!-- Bluetooth settings.  The user-visible string that is used whenever referring to the headset or handsfree profile. -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/TronUtils.java b/packages/SettingsLib/src/com/android/settingslib/TronUtils.java
index bea6e8f..945cb57 100644
--- a/packages/SettingsLib/src/com/android/settingslib/TronUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/TronUtils.java
@@ -16,48 +16,18 @@
 package com.android.settingslib;
 
 import android.content.Context;
-import android.net.NetworkBadging;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.settingslib.wifi.AccessPoint.Speed;
 
 /** Utilites for Tron Logging. */
 public final class TronUtils {
 
+    private static final String TAG = "TronUtils";
+
     private TronUtils() {};
 
-    public static void logWifiSettingsBadge(Context context, int badgeEnum) {
-        logNetworkBadgeMetric(context, "settings_wifibadging", badgeEnum);
-    }
-
-    /**
-     * Logs an occurrence of the given network badge to a Histogram.
-     *
-     * @param context Context
-     * @param histogram the Tron histogram name to write to
-     * @param badgeEnum the {@link NetworkBadging.Badging} badge value
-     * @throws IllegalArgumentException if the given badge enum is not supported
-     */
-    private static void logNetworkBadgeMetric(
-            Context context, String histogram, int badgeEnum)
-            throws IllegalArgumentException {
-        int bucket;
-        switch (badgeEnum) {
-            case NetworkBadging.BADGING_NONE:
-                bucket = 0;
-                break;
-            case NetworkBadging.BADGING_SD:
-                bucket = 1;
-                break;
-            case NetworkBadging.BADGING_HD:
-                bucket = 2;
-                break;
-            case NetworkBadging.BADGING_4K:
-                bucket = 3;
-                break;
-            default:
-                throw new IllegalArgumentException("Unsupported badge enum: " + badgeEnum);
-        }
-
-        MetricsLogger.histogram(context, histogram, bucket);
+    public static void logWifiSettingsSpeed(Context context, @Speed int speedEnum) {
+        MetricsLogger.histogram(context, "settings_wifi_speed_labels", speedEnum);
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java b/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
index b06b032..7357fe6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
@@ -107,4 +107,20 @@
         return false;
     }
 
+    /** Returns the label for a given package. */
+    public static CharSequence getApplicationLabel(
+            PackageManager packageManager, String packageName) {
+        try {
+            final ApplicationInfo appInfo =
+                    packageManager.getApplicationInfo(
+                            packageName,
+                            PackageManager.MATCH_DISABLED_COMPONENTS
+                                    | PackageManager.MATCH_ANY_USER);
+            return appInfo.loadLabel(packageManager);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "Unable to find info for package: " + packageName);
+        }
+        return null;
+    }
+
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
index 1bb1417..426dc7c 100755
--- a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
@@ -28,6 +28,7 @@
 import android.graphics.Path;
 import android.graphics.Path.Direction;
 import android.graphics.Path.FillType;
+import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
@@ -82,6 +83,7 @@
     private final float[] mPlusPoints;
     private final Path mPlusPath = new Path();
 
+    private final Rect mPadding = new Rect();
     private final RectF mFrame = new RectF();
     private final RectF mButtonFrame = new RectF();
     private final RectF mBoltFrame = new RectF();
@@ -219,12 +221,40 @@
     @Override
     public void setBounds(int left, int top, int right, int bottom) {
         super.setBounds(left, top, right, bottom);
-        mHeight = bottom - top;
-        mWidth = right - left;
+        updateSize();
+    }
+
+    private void updateSize() {
+        final Rect bounds = getBounds();
+
+        mHeight = (bounds.bottom - mPadding.bottom) - (bounds.top + mPadding.top);
+        mWidth = (bounds.right - mPadding.right) - (bounds.left + mPadding.left);
         mWarningTextPaint.setTextSize(mHeight * 0.75f);
         mWarningTextHeight = -mWarningTextPaint.getFontMetrics().ascent;
     }
 
+    @Override
+    public boolean getPadding(Rect padding) {
+        if (mPadding.left == 0
+            && mPadding.top == 0
+            && mPadding.right == 0
+            && mPadding.bottom == 0) {
+            return super.getPadding(padding);
+        }
+
+        padding.set(mPadding);
+        return true;
+    }
+
+    public void setPadding(int left, int top, int right, int bottom) {
+        mPadding.left = left;
+        mPadding.top = top;
+        mPadding.right = right;
+        mPadding.bottom = bottom;
+
+        updateSize();
+    }
+
     private int getColorForLevel(int percent) {
         // If we are in power save mode, always use the normal color.
         if (mPowerSaveEnabled) {
@@ -251,10 +281,15 @@
         mIconTint = fillColor;
         mFramePaint.setColor(backgroundColor);
         mBoltPaint.setColor(fillColor);
+        mPlusPaint.setColor(fillColor);
         mChargeColor = fillColor;
         invalidateSelf();
     }
 
+    protected int batteryColorForLevel(int level) {
+        return mCharging ? mChargeColor : getColorForLevel(level);
+    }
+
     @Override
     public void draw(Canvas c) {
         final int level = mLevel;
@@ -264,11 +299,10 @@
         float drawFrac = (float) level / 100f;
         final int height = mHeight;
         final int width = (int) (ASPECT_RATIO * mHeight);
-        int px = (mWidth - width) / 2;
-
+        final int px = (mWidth - width) / 2;
         final int buttonHeight = Math.round(height * mButtonHeightFraction);
 
-        mFrame.set(0, 0, width, height);
+        mFrame.set(mPadding.left, mPadding.top, width + mPadding.left, height + mPadding.top);
         mFrame.offset(px, 0);
 
         // button-frame: area above the battery body
@@ -282,7 +316,7 @@
         mFrame.top += buttonHeight;
 
         // set the battery charging color
-        mBatteryPaint.setColor(mCharging ? mChargeColor : getColorForLevel(level));
+        mBatteryPaint.setColor(batteryColorForLevel(level));
 
         if (level >= FULL) {
             drawFrac = 1f;
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index d45ed19..4a54451 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -16,6 +16,7 @@
 
 package com.android.settingslib.wifi;
 
+import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.app.AppGlobals;
 import android.content.Context;
@@ -53,6 +54,8 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.R;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.concurrent.ConcurrentHashMap;
@@ -82,35 +85,30 @@
      */
     public static final int HIGHER_FREQ_5GHZ = 5900;
 
-    /**
-     * Constant value representing an unlabeled / unscored network.
-     */
-    @VisibleForTesting
-    static final int SPEED_NONE = 0;
-
-    /**
-     * Constant value representing a slow speed network connection.
-     */
-    @VisibleForTesting
-    static final int SPEED_SLOW = 5;
-
-    /**
-     * Constant value representing a medium speed network connection.
-     */
-    @VisibleForTesting
-    static final int SPEED_MEDIUM = 10;
-
-    /**
-     * Constant value representing a fast speed network connection.
-     */
-    @VisibleForTesting
-    static final int SPEED_FAST = 20;
-
-    /**
-     * Constant value representing a very fast speed network connection.
-     */
-    @VisibleForTesting
-    static final int SPEED_VERY_FAST = 30;
+    @IntDef({Speed.NONE, Speed.SLOW, Speed.MODERATE, Speed.FAST, Speed.VERY_FAST})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Speed {
+        /**
+         * Constant value representing an unlabeled / unscored network.
+         */
+        int NONE = 0;
+        /**
+         * Constant value representing a slow speed network connection.
+         */
+        int SLOW = 5;
+        /**
+         * Constant value representing a medium speed network connection.
+         */
+        int MODERATE = 10;
+        /**
+         * Constant value representing a fast speed network connection.
+         */
+        int FAST = 20;
+        /**
+         * Constant value representing a very fast speed network connection.
+         */
+        int VERY_FAST = 30;
+    }
 
     /**
      * Experimental: we should be able to show the user the list of BSSIDs and bands
@@ -177,7 +175,7 @@
     private Object mTag;
 
     private int mRankingScore = Integer.MIN_VALUE;
-    private int mSpeed = AccessPoint.SPEED_NONE;
+    private int mSpeed = Speed.NONE;
     private boolean mIsScoredNetworkMetered = false;
 
     // used to co-relate internal vs returned accesspoint.
@@ -322,8 +320,15 @@
         if (difference != 0) {
             return difference;
         }
+
         // Sort by ssid.
-        return getSsidStr().compareToIgnoreCase(other.getSsidStr());
+        difference = getSsidStr().compareToIgnoreCase(other.getSsidStr());
+        if (difference != 0) {
+            return difference;
+        }
+
+        // Do a case sensitive comparison to distinguish SSIDs that differ in case only
+        return getSsidStr().compareTo(other.getSsidStr());
     }
 
     @Override
@@ -368,7 +373,7 @@
         if (mRankingScore != Integer.MIN_VALUE) {
             builder.append(",rankingScore=").append(mRankingScore);
         }
-        if (mSpeed != SPEED_NONE) {
+        if (mSpeed != Speed.NONE) {
             builder.append(",speed=").append(mSpeed);
         }
         builder.append(",metered=").append(isMetered());
@@ -399,7 +404,7 @@
     private boolean updateScores(WifiNetworkScoreCache scoreCache) {
         int oldSpeed = mSpeed;
         int oldRankingScore = mRankingScore;
-        mSpeed = SPEED_NONE;
+        mSpeed = Speed.NONE;
         mRankingScore = Integer.MIN_VALUE;
 
         for (ScanResult result : mScanResultCache.values()) {
@@ -675,7 +680,7 @@
         // TODO(b/62354743): Standardize and international delimiter usage
         final String concatenator = " / ";
 
-        if (mSpeed != SPEED_NONE) {
+        if (mSpeed != Speed.NONE) {
             summary.append(getSpeedLabel() + concatenator);
         }
 
@@ -799,7 +804,7 @@
             if (mRankingScore != Integer.MIN_VALUE) {
                 visibility.append(" rankingScore=").append(getRankingScore());
             }
-            if (mSpeed != SPEED_NONE) {
+            if (mSpeed != Speed.NONE) {
                 visibility.append(" speed=").append(getSpeedLabel());
             }
             visibility.append(String.format(" tx=%.1f,", mInfo.txSuccessRate));
@@ -1053,6 +1058,12 @@
         final int oldLevel = getLevel();
         if (info != null && isInfoForThisAccessPoint(config, info)) {
             updated = (mInfo == null);
+            if (mConfig != config) {
+                // We do not set updated = true as we do not want to increase the amount of sorting
+                // and copying performed in WifiTracker at this time. If issues involving refresh
+                // are still seen, we will investigate further.
+                update(config); // Notifies the AccessPointListener of the change
+            }
             if (mRssi != info.getRssi()) {
                 mRssi = info.getRssi();
                 updated = true;
@@ -1104,15 +1115,15 @@
     @Nullable
     String getSpeedLabel() {
         switch (mSpeed) {
-            case SPEED_VERY_FAST:
+            case Speed.VERY_FAST:
                 return mContext.getString(R.string.speed_label_very_fast);
-            case SPEED_FAST:
+            case Speed.FAST:
                 return mContext.getString(R.string.speed_label_fast);
-            case SPEED_MEDIUM:
+            case Speed.MODERATE:
                 return mContext.getString(R.string.speed_label_okay);
-            case SPEED_SLOW:
+            case Speed.SLOW:
                 return mContext.getString(R.string.speed_label_slow);
-            case SPEED_NONE:
+            case Speed.NONE:
             default:
                 return null;
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
index e7525f3..92995a8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
@@ -70,6 +70,19 @@
             R.string.accessibility_wifi_signal_full
     };
 
+    public static String generatePreferenceKey(AccessPoint accessPoint) {
+        StringBuilder builder = new StringBuilder();
+
+        if (TextUtils.isEmpty(accessPoint.getBssid())) {
+            builder.append(accessPoint.getSsidStr());
+        } else {
+            builder.append(accessPoint.getBssid());
+        }
+
+        builder.append(',').append(accessPoint.getSecurity());
+        return builder.toString();
+    }
+
     // Used for dummy pref.
     public AccessPointPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -161,7 +174,7 @@
             safeSetDefaultIcon();
             return;
         }
-        TronUtils.logWifiSettingsBadge(context, mWifiSpeed);
+        TronUtils.logWifiSettingsSpeed(context, mWifiSpeed);
 
         // TODO(b/62355275): Revert this to N code after deleting NetworkBadging API
         Drawable drawable = NetworkBadging.getWifiIcon(
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/TestAccessPointBuilder.java b/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
similarity index 89%
rename from packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
rename to packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
index 2213ae6..4307cb0 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
@@ -26,9 +26,9 @@
 /**
 * Build and return a valid AccessPoint.
 *
-* Only intended for testing the AccessPoint class;
-* AccessPoints were designed to only be populated
-* by the mechanisms of scan results and wifi configurations.
+* Only intended for testing the AccessPoint class or creating Access points to be used in testing
+* applications. AccessPoints were designed to only be populated by the mechanisms of scan results
+* and wifi configurations.
 */
 public class TestAccessPointBuilder {
     // match the private values in WifiManager
@@ -36,12 +36,14 @@
     private static final int MAX_RSSI = -55;
 
     // set some sensible defaults
+    private String mBssid = null;
     private int mRssi = AccessPoint.UNREACHABLE_RSSI;
     private int mNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
     private String ssid = "TestSsid";
     private NetworkInfo mNetworkInfo = null;
     private String mFqdn = null;
     private String mProviderFriendlyName = null;
+    private int mSecurity = AccessPoint.SECURITY_NONE;
     private WifiConfiguration mWifiConfig;
     private WifiInfo mWifiInfo;
 
@@ -56,6 +58,7 @@
 
         WifiConfiguration wifiConfig = new WifiConfiguration();
         wifiConfig.networkId = mNetworkId;
+        wifiConfig.BSSID = mBssid;
 
         bundle.putString(AccessPoint.KEY_SSID, ssid);
         bundle.putParcelable(AccessPoint.KEY_CONFIG, wifiConfig);
@@ -67,6 +70,8 @@
         if (mProviderFriendlyName != null) {
             bundle.putString(AccessPoint.KEY_PROVIDER_FRIENDLY_NAME, mProviderFriendlyName);
         }
+        bundle.putInt(AccessPoint.KEY_SECURITY, mSecurity);
+
         AccessPoint ap = new AccessPoint(mContext, bundle);
         ap.setRssi(mRssi);
         return ap;
@@ -141,6 +146,11 @@
         return this;
     }
 
+    public TestAccessPointBuilder setSecurity(int security) {
+        mSecurity = security;
+        return this;
+    }
+
     public TestAccessPointBuilder setSsid(String newSsid) {
         ssid = newSsid;
         return this;
@@ -171,4 +181,9 @@
         mNetworkId = networkId;
         return this;
     }
+
+    public TestAccessPointBuilder setBssid(String bssid) {
+        mBssid = bssid;
+        return this;
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 9083d90..596eaef 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -16,6 +16,7 @@
 package com.android.settingslib.wifi;
 
 import android.annotation.MainThread;
+import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -36,7 +37,6 @@
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiNetworkScoreCache;
 import android.net.wifi.WifiNetworkScoreCache.CacheListener;
-import android.os.ConditionVariable;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -91,7 +91,7 @@
     private final boolean mIncludeScans;
     private final boolean mIncludePasspoints;
     @VisibleForTesting final MainHandler mMainHandler;
-    private final WorkHandler mWorkHandler;
+    @VisibleForTesting final WorkHandler mWorkHandler;
 
     private WifiTrackerNetworkCallback mNetworkCallback;
 
@@ -247,7 +247,10 @@
             mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
             mLastInfo = mWifiManager.getConnectionInfo();
             mLastNetworkInfo = mConnectivityManager.getNetworkInfo(mWifiManager.getCurrentNetwork());
-            updateAccessPointsLocked();
+
+            final List<ScanResult> newScanResults = mWifiManager.getScanResults();
+            List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+            updateAccessPointsLocked(newScanResults, configs);
 
             if (DBG) {
                 Log.d(TAG, "force update - internal access point list:\n" + mInternalAccessPoints);
@@ -377,7 +380,7 @@
         mNetworkScoreManager.unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI, mScoreCache);
         mScoreCache.clearScores();
 
-        // Synchronize on mLock to avoid concurrent modification during updateAccessPointsLocked
+        // Synchronize on mLock to avoid concurrent modification during updateAccessPoints
         synchronized (mLock) {
             mRequestedScores.clear();
         }
@@ -427,9 +430,8 @@
         mScanId = 0;
     }
 
-    private Collection<ScanResult> fetchScanResults() {
+    private Collection<ScanResult> updateScanResultCache(final List<ScanResult> newResults) {
         mScanId++;
-        final List<ScanResult> newResults = mWifiManager.getScanResults();
         for (ScanResult newResult : newResults) {
             if (newResult.SSID == null || newResult.SSID.isEmpty()) {
                 continue;
@@ -457,8 +459,8 @@
         return mScanResultCache.values();
     }
 
-    private WifiConfiguration getWifiConfigurationForNetworkId(int networkId) {
-        final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+    private WifiConfiguration getWifiConfigurationForNetworkId(
+            int networkId, final List<WifiConfiguration> configs) {
         if (configs != null) {
             for (WifiConfiguration config : configs) {
                 if (mLastInfo != null && networkId == config.networkId &&
@@ -470,20 +472,37 @@
         return null;
     }
 
-    /** Safely modify {@link #mInternalAccessPoints} by acquiring {@link #mLock} first. */
-    private void updateAccessPointsLocked() {
+    /**
+     * Safely modify {@link #mInternalAccessPoints} by acquiring {@link #mLock} first.
+     *
+     * <p>Will not perform the update if {@link #mStaleScanResults} is true
+     */
+    private void updateAccessPoints() {
+        List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+        final List<ScanResult> newScanResults = mWifiManager.getScanResults();
+
         synchronized (mLock) {
-            updateAccessPoints();
+            if(!mStaleScanResults) {
+                updateAccessPointsLocked(newScanResults, configs);
+            }
         }
     }
 
     /**
      * Update the internal list of access points.
      *
-     * <p>Should never be called directly, use {@link #updateAccessPointsLocked()} instead.
+     * <p>Do not called directly (except for forceUpdate), use {@link #updateAccessPoints()} which
+     * respects {@link #mStaleScanResults}.
      */
     @GuardedBy("mLock")
-    private void updateAccessPoints() {
+    private void updateAccessPointsLocked(final List<ScanResult> newScanResults,
+            List<WifiConfiguration> configs) {
+        WifiConfiguration connectionConfig = null;
+        if (mLastInfo != null) {
+            connectionConfig = getWifiConfigurationForNetworkId(
+                    mLastInfo.getNetworkId(), mWifiManager.getConfiguredNetworks());
+        }
+
         // Swap the current access points into a cached list.
         List<AccessPoint> cachedAccessPoints = new ArrayList<>(mInternalAccessPoints);
         ArrayList<AccessPoint> accessPoints = new ArrayList<>();
@@ -496,14 +515,9 @@
     /* Lookup table to more quickly update AccessPoints by only considering objects with the
      * correct SSID.  Maps SSID -> List of AccessPoints with the given SSID.  */
         Multimap<String, AccessPoint> apMap = new Multimap<String, AccessPoint>();
-        WifiConfiguration connectionConfig = null;
-        if (mLastInfo != null) {
-            connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId());
-        }
 
-        final Collection<ScanResult> results = fetchScanResults();
+        final Collection<ScanResult> results = updateScanResultCache(newScanResults);
 
-        final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
         if (configs != null) {
             for (WifiConfiguration config : configs) {
                 if (config.selfAdded && config.numAssociation == 0) {
@@ -653,6 +667,7 @@
         /* sticky broadcasts can call this when wifi is disabled */
         if (!mWifiManager.isWifiEnabled()) {
             mMainHandler.sendEmptyMessage(MainHandler.MSG_PAUSE_SCANNING);
+            clearAccessPointsAndConditionallyUpdate();
             return;
         }
 
@@ -670,7 +685,8 @@
         WifiConfiguration connectionConfig = null;
         mLastInfo = mWifiManager.getConnectionInfo();
         if (mLastInfo != null) {
-            connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId());
+            connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId(),
+                    mWifiManager.getConfiguredNetworks());
         }
 
         boolean updated = false;
@@ -696,6 +712,17 @@
         }
     }
 
+    private void clearAccessPointsAndConditionallyUpdate() {
+        synchronized (mLock) {
+            if (!mInternalAccessPoints.isEmpty()) {
+                mInternalAccessPoints.clear();
+                if (!mMainHandler.hasMessages(MainHandler.MSG_ACCESS_POINT_CHANGED)) {
+                    mMainHandler.sendEmptyMessage(MainHandler.MSG_ACCESS_POINT_CHANGED);
+                }
+            }
+        }
+    }
+
     /**
      * Update all the internal access points rankingScores, badge and metering.
      *
@@ -720,6 +747,9 @@
 
     private void updateWifiState(int state) {
         mWorkHandler.obtainMessage(WorkHandler.MSG_UPDATE_WIFI_STATE, state, 0).sendToTarget();
+        if (!mWifiManager.isWifiEnabled()) {
+            clearAccessPointsAndConditionallyUpdate();
+        }
     }
 
     public static List<AccessPoint> getCurrentAccessPoints(Context context, boolean includeSaved,
@@ -803,8 +833,15 @@
                     mListener.onWifiStateChanged(msg.arg1);
                     break;
                 case MSG_ACCESS_POINT_CHANGED:
-                    copyAndNotifyListeners(true /*notifyListeners*/);
-                    mListener.onAccessPointsChanged();
+                    // Only notify listeners of changes if we have fresh scan results, otherwise the
+                    // UI will be updated with stale results. We want to copy the APs regardless,
+                    // for instances where forceUpdate was invoked by the caller.
+                    if (mStaleScanResults) {
+                        copyAndNotifyListeners(false /*notifyListeners*/);
+                    } else {
+                        copyAndNotifyListeners(true /*notifyListeners*/);
+                        mListener.onAccessPointsChanged();
+                    }
                     break;
                 case MSG_RESUME_SCANNING:
                     if (mScanner != null) {
@@ -828,7 +865,8 @@
         }
     }
 
-    private final class WorkHandler extends Handler {
+    @VisibleForTesting
+    final class WorkHandler extends Handler {
         private static final int MSG_UPDATE_ACCESS_POINTS = 0;
         private static final int MSG_UPDATE_NETWORK_INFO = 1;
         private static final int MSG_RESUME = 2;
@@ -845,15 +883,12 @@
             }
         }
 
-        @GuardedBy("mLock")
         private void processMessage(Message msg) {
             if (!mRegistered) return;
 
             switch (msg.what) {
                 case MSG_UPDATE_ACCESS_POINTS:
-                    if (!mStaleScanResults) {
-                        updateAccessPointsLocked();
-                    }
+                    updateAccessPoints();
                     break;
                 case MSG_UPDATE_NETWORK_INFO:
                     updateNetworkInfo((NetworkInfo) msg.obj);
diff --git a/packages/SettingsLib/tests/integ/AndroidManifest.xml b/packages/SettingsLib/tests/integ/AndroidManifest.xml
index 0d5ff2c..e8e0b41 100644
--- a/packages/SettingsLib/tests/integ/AndroidManifest.xml
+++ b/packages/SettingsLib/tests/integ/AndroidManifest.xml
@@ -21,6 +21,7 @@
     <uses-permission android:name="android.permission.MANAGE_USERS" />
     <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY"/>
     <uses-permission android:name="android.permission.SET_TIME_ZONE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
index 83667ea..01df0ec 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
@@ -3,6 +3,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Canvas;
+import android.graphics.Rect;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -12,6 +13,7 @@
 import org.junit.runner.RunWith;
 
 import static com.google.common.truth.Truth.assertThat;
+import static junit.framework.Assert.assertTrue;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyFloat;
 import static org.mockito.Matchers.anyString;
@@ -68,4 +70,49 @@
             }
         }
     }
+
+    @Test
+    public void testPadding_returnsCorrectValues() {
+        // different pads on each side to differentiate
+        final int left = 1;
+        final int top = 2;
+        final int right = 3;
+        final int bottom = 4;
+
+        final Rect expected = new Rect(left, top, right, bottom);
+        final Rect padding = new Rect();
+
+        mBatteryDrawable.setPadding(left, top, right, bottom);
+
+        assertThat(mBatteryDrawable.getPadding(padding)).isEqualTo(true);
+        assertThat(padding).isEqualTo(expected);
+    }
+
+    @Test
+    public void testPadding_falseIfUnsetOrZero() {
+        final Rect padding = new Rect();
+        assertThat(mBatteryDrawable.getPadding(padding)).isEqualTo(false);
+        assertThat(isRectZero(padding)).isEqualTo(true);
+
+        mBatteryDrawable.setPadding(0, 0, 0, 0);
+        assertThat(mBatteryDrawable.getPadding(padding)).isEqualTo(false);
+        assertThat(isRectZero(padding)).isEqualTo(true);
+    }
+
+    private boolean isRectZero(Rect r) {
+        return r.left == 0 && r.top == 0 && r.right == 0 && r.bottom == 0;
+    }
+
+    @Test
+    public void testPlusPaint_isEqualToBoltPaint() {
+        // Before setting color
+        assertTrue(mBatteryDrawable.mPlusPaint.hasEqualAttributes(mBatteryDrawable.mBoltPaint));
+
+        final int fakeFillColor = 123;
+        final int fakeBackgrundColor = 456;
+
+        // After
+        mBatteryDrawable.setColors(fakeFillColor, fakeBackgrundColor);
+        assertTrue(mBatteryDrawable.mPlusPaint.hasEqualAttributes(mBatteryDrawable.mBoltPaint));
+    }
 }
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
index 89328ee..5c64cff 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
@@ -20,6 +20,8 @@
 
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -169,6 +171,21 @@
     }
 
     @Test
+    public void testCompareTo_GivesSsidCasePrecendenceAfterAlphabetical() {
+
+        final String firstName = "aaAaaa";
+        final String secondName = "aaaaaa";
+        final String thirdName = "BBBBBB";
+
+        AccessPoint firstAp = new TestAccessPointBuilder(mContext).setSsid(firstName).build();
+        AccessPoint secondAp = new TestAccessPointBuilder(mContext).setSsid(secondName).build();
+        AccessPoint thirdAp = new TestAccessPointBuilder(mContext).setSsid(thirdName).build();
+
+        assertSortingWorks(firstAp, secondAp);
+        assertSortingWorks(secondAp, thirdAp);
+    }
+
+    @Test
     public void testCompareTo_AllSortingRulesCombined() {
 
         AccessPoint active = new TestAccessPointBuilder(mContext).setActive(true).build();
@@ -334,11 +351,11 @@
 
         when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
                 .thenReturn(buildScoredNetworkWithMockBadgeCurve());
-        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.SPEED_VERY_FAST);
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST);
 
         ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
 
-        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.SPEED_VERY_FAST);
+        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.VERY_FAST);
         assertThat(ap.getSpeedLabel())
                 .isEqualTo(mContext.getString(R.string.speed_label_very_fast));
     }
@@ -349,11 +366,11 @@
 
         when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
                 .thenReturn(buildScoredNetworkWithMockBadgeCurve());
-        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.SPEED_FAST);
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.FAST);
 
         ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
 
-        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.SPEED_FAST);
+        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.FAST);
         assertThat(ap.getSpeedLabel())
                 .isEqualTo(mContext.getString(R.string.speed_label_fast));
     }
@@ -364,11 +381,11 @@
 
         when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
                 .thenReturn(buildScoredNetworkWithMockBadgeCurve());
-        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.SPEED_MEDIUM);
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.MODERATE);
 
         ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
 
-        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.SPEED_MEDIUM);
+        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.MODERATE);
         assertThat(ap.getSpeedLabel())
                 .isEqualTo(mContext.getString(R.string.speed_label_okay));
     }
@@ -379,11 +396,11 @@
 
         when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
                 .thenReturn(buildScoredNetworkWithMockBadgeCurve());
-        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.SPEED_SLOW);
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.SLOW);
 
         ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
 
-        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.SPEED_SLOW);
+        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.SLOW);
         assertThat(ap.getSpeedLabel())
                 .isEqualTo(mContext.getString(R.string.speed_label_slow));
     }
@@ -394,7 +411,7 @@
 
         when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
                 .thenReturn(buildScoredNetworkWithMockBadgeCurve());
-        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.SPEED_VERY_FAST);
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST);
 
         ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
 
@@ -408,7 +425,7 @@
 
         when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
                 .thenReturn(buildScoredNetworkWithMockBadgeCurve());
-        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.SPEED_VERY_FAST);
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST);
 
         ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
 
@@ -607,4 +624,36 @@
         NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
         assertThat(ap.update(config, wifiInfo, newInfo)).isFalse();
     }
+
+    @Test
+    public void testUpdateWithConfigChangeOnly_returnsFalseButInvokesListener() {
+        int networkId = 123;
+        int rssi = -55;
+        WifiConfiguration config = new WifiConfiguration();
+        config.networkId = networkId;
+        config.numNoInternetAccessReports = 1;
+
+        WifiInfo wifiInfo = new WifiInfo();
+        wifiInfo.setNetworkId(networkId);
+        wifiInfo.setRssi(rssi);
+
+        NetworkInfo networkInfo =
+                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
+        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", "");
+
+        AccessPoint ap = new TestAccessPointBuilder(mContext)
+                .setNetworkInfo(networkInfo)
+                .setNetworkId(networkId)
+                .setRssi(rssi)
+                .setWifiInfo(wifiInfo)
+                .build();
+
+        AccessPoint.AccessPointListener mockListener = mock(AccessPoint.AccessPointListener.class);
+        ap.setListener(mockListener);
+        WifiConfiguration newConfig = new WifiConfiguration(config);
+        config.validatedInternetAccess = true;
+
+        assertThat(ap.update(newConfig, wifiInfo, networkInfo)).isFalse();
+        verify(mockListener).onAccessPointChanged(ap);
+    }
 }
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index 340ef01..071f921 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -59,6 +59,7 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.FlakyTest;
 
 import org.junit.After;
 import org.junit.Before;
@@ -94,7 +95,7 @@
             new NetworkKey(new WifiKey('"' + SSID_1 + '"', BSSID_1));
     private static final int RSSI_1 = -30;
     private static final byte SCORE_1 = 10;
-    private static final int BADGE_1 = AccessPoint.SPEED_MEDIUM;
+    private static final int BADGE_1 = AccessPoint.Speed.MODERATE;
 
     private static final String SSID_2 = "ssid2";
     private static final String BSSID_2 = "AA:AA:AA:AA:AA:AA";
@@ -102,7 +103,7 @@
             new NetworkKey(new WifiKey('"' + SSID_2 + '"', BSSID_2));
     private static final int RSSI_2 = -30;
     private static final byte SCORE_2 = 15;
-    private static final int BADGE_2 = AccessPoint.SPEED_FAST;
+    private static final int BADGE_2 = AccessPoint.Speed.FAST;
 
     private static final int CONNECTED_NETWORK_ID = 123;
     private static final int CONNECTED_RSSI = -50;
@@ -256,6 +257,7 @@
         }
 
         sendScanResultsAndProcess(tracker);
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
 
         return tracker;
     }
@@ -341,6 +343,23 @@
         return createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(intent);
     }
 
+    private void waitForHandlersToProcessCurrentlyEnqueuedMessages(WifiTracker tracker)
+            throws InterruptedException {
+        CountDownLatch workerLatch = new CountDownLatch(1);
+        tracker.mWorkHandler.post(() -> {
+            workerLatch.countDown();
+        });
+        assertTrue("Latch timed out while waiting for WorkerHandler",
+                workerLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+
+        CountDownLatch mainLatch = new CountDownLatch(1);
+        tracker.mMainHandler.post(() -> {
+            mainLatch.countDown();
+        });
+        assertTrue("Latch timed out while waiting for MainHandler",
+                mainLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+    }
+
     @Test
     public void testAccessPointListenerSetWhenLookingUpUsingScanResults() {
         ScanResult scanResult = new ScanResult();
@@ -426,7 +445,7 @@
 
     @Test
     public void startTrackingShouldSetConnectedAccessPointAsActive() throws InterruptedException {
-        WifiTracker tracker =  createTrackerWithScanResultsAndAccessPoint1Connected();
+        WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
 
         List<AccessPoint> aps = tracker.getAccessPoints();
 
@@ -460,18 +479,21 @@
         startTracking(tracker);
         sendScanResultsAndProcess(tracker);
 
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
     }
 
-    private void updateScoresAndWaitForAccessPointsChangedCallback() throws InterruptedException {
+    private void updateScoresAndWaitForAccessPointsChangedCallback(WifiTracker tracker)
+            throws InterruptedException {
         // Updating scores can happen together or one after the other, so the latch countdown is set
         // to 2.
-        mAccessPointsChangedLatch = new CountDownLatch(2);
+        mAccessPointsChangedLatch = new CountDownLatch(1);
         updateScores();
-        assertTrue("onAccessPointChanged was not called twice",
+        assertTrue("onAccessPointChanged was not called after updating scores",
             mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
     }
 
+    @FlakyTest
     @Test
     public void scoreCacheUpdateScoresShouldChangeSortOrder() throws InterruptedException {
         WifiTracker tracker =  createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
@@ -480,7 +502,7 @@
         assertEquals(aps.get(0).getSsidStr(), SSID_1);
         assertEquals(aps.get(1).getSsidStr(), SSID_2);
 
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
 
         aps = tracker.getAccessPoints();
         assertTrue(aps.size() == 2);
@@ -502,7 +524,7 @@
         assertEquals(aps.get(0).getSsidStr(), SSID_1);
         assertEquals(aps.get(1).getSsidStr(), SSID_2);
 
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
 
         aps = tracker.getAccessPoints();
         assertTrue(aps.size() == 2);
@@ -510,11 +532,12 @@
         assertEquals(aps.get(1).getSsidStr(), SSID_2);
     }
 
+    @FlakyTest
     @Test
     public void scoreCacheUpdateScoresShouldInsertSpeedIntoAccessPoint()
             throws InterruptedException {
         WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
 
         List<AccessPoint> aps = tracker.getAccessPoints();
 
@@ -531,7 +554,7 @@
     public void scoreCacheUpdateMeteredShouldUpdateAccessPointMetering()
             throws InterruptedException {
         WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
 
         List<AccessPoint> aps = tracker.getAccessPoints();
 
@@ -553,15 +576,15 @@
                 0 /* disabled */);
 
         WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
 
         List<AccessPoint> aps = tracker.getAccessPoints();
 
         for (AccessPoint ap : aps) {
             if (ap.getSsidStr().equals(SSID_1)) {
-                assertEquals(AccessPoint.SPEED_NONE, ap.getSpeed());
+                assertEquals(AccessPoint.Speed.NONE, ap.getSpeed());
             } else if (ap.getSsidStr().equals(SSID_2)) {
-                assertEquals(AccessPoint.SPEED_NONE, ap.getSpeed());
+                assertEquals(AccessPoint.Speed.NONE, ap.getSpeed());
             }
         }
     }
@@ -754,13 +777,10 @@
             throws Exception {
         WifiTracker tracker = createMockedWifiTracker();
         startTracking(tracker);
-        tracker.stopTracking();
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
 
-        CountDownLatch latch1 = new CountDownLatch(1);
-        tracker.mMainHandler.post(() -> {
-                latch1.countDown();
-        });
-        assertTrue("Latch 1 timed out", latch1.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+        tracker.stopTracking();
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
 
         startTracking(tracker);
 
@@ -770,14 +790,24 @@
         tracker.mReceiver.onReceive(
                 mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION));
 
-        CountDownLatch latch2 = new CountDownLatch(1);
-        tracker.mMainHandler.post(() -> {
-            latch2.countDown();
-        });
-        assertTrue("Latch 2 timed out", latch2.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
 
         verify(mockWifiListener, never()).onAccessPointsChanged();
 
         sendScanResultsAndProcess(tracker); // verifies onAccessPointsChanged is invoked
     }
+
+    @Test
+    public void disablingWifiShouldClearExistingAccessPoints() throws Exception {
+        WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
+
+        when(mockWifiManager.isWifiEnabled()).thenReturn(false);
+        mAccessPointsChangedLatch = new CountDownLatch(1);
+        tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
+
+        mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
+
+        assertThat(tracker.getAccessPoints()).isEmpty();
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/AccessPointPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/AccessPointPreferenceTest.java
new file mode 100644
index 0000000..335653b
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/AccessPointPreferenceTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settingslib.wifi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import com.android.settingslib.SettingLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class AccessPointPreferenceTest {
+
+    private Context mContext = RuntimeEnvironment.application;
+
+    @Test
+    public void generatePreferenceKey_shouldReturnSsidPlusSecurity() {
+        String ssid = "ssid";
+        int security = AccessPoint.SECURITY_WEP;
+        String expectedKey = ssid + ',' + security;
+
+        TestAccessPointBuilder builder = new TestAccessPointBuilder(mContext);
+        builder.setSsid(ssid).setSecurity(security);
+
+        assertThat(AccessPointPreference.generatePreferenceKey(builder.build()))
+                .isEqualTo(expectedKey);
+    }
+
+    @Test
+    public void generatePreferenceKey_shouldReturnBssidPlusSecurity() {
+        String bssid = "bssid";
+        int security = AccessPoint.SECURITY_WEP;
+        String expectedKey = bssid + ',' + security;
+
+        TestAccessPointBuilder builder = new TestAccessPointBuilder(mContext);
+        builder.setBssid(bssid).setSecurity(security);
+
+        assertThat(AccessPointPreference.generatePreferenceKey(builder.build()))
+                .isEqualTo(expectedKey);
+    }
+}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 1e171d3..8abdc64 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -37,10 +37,12 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArraySet;
+import android.util.Slog;
 
 import java.util.Locale;
 
 public class SettingsHelper {
+    private static final String TAG = "SettingsHelper";
     private static final String SILENT_RINGTONE = "_silent";
     private Context mContext;
     private AudioManager mAudioManager;
@@ -324,11 +326,17 @@
      */
     void setLocaleData(byte[] data, int size) {
         // Check if locale was set by the user:
-        Configuration conf = mContext.getResources().getConfiguration();
-        // TODO: The following is not working as intended because the network is forcing a locale
-        // change after registering. Need to find some other way to detect if the user manually
-        // changed the locale
-        if (conf.userSetLocale) return; // Don't change if user set it in the SetupWizard
+        final ContentResolver cr = mContext.getContentResolver();
+        final boolean userSetLocale = mContext.getResources().getConfiguration().userSetLocale;
+        final boolean provisioned = Settings.Global.getInt(cr,
+                Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+        if (userSetLocale || provisioned) {
+            // Don't change if user set it in the SetupWizard, or if this is a post-setup
+            // deferred restore operation
+            Slog.i(TAG, "Not applying restored locale; "
+                    + (userSetLocale ? "user already specified" : "device already provisioned"));
+            return;
+        }
 
         final String[] availableLocales = mContext.getAssets().getLocales();
         // Replace "_" with "-" to deal with older backups.
diff --git a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java
index d9719f3..f59c4a5 100644
--- a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java
+++ b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java
@@ -29,6 +29,7 @@
 
 import com.google.android.colorextraction.ColorExtractor.GradientColors;
 
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -311,6 +312,12 @@
         final float maxHue;
 
         TonalPalette(float[] h, float[] s, float[] l) {
+            if (h.length != s.length || s.length != l.length) {
+                throw new IllegalArgumentException("All arrays should have the same size. h: "
+                        + Arrays.toString(h) + " s: " + Arrays.toString(s) + " l: "
+                        + Arrays.toString(l));
+            }
+
             this.h = h;
             this.s = s;
             this.l = l;
@@ -388,7 +395,7 @@
                     new float[] {0.70f, 0.72f, 0.69f, 0.6703296703296703f, 0.728813559322034f,
                             0.5657142857142856f, 0.5076923076923077f, 0.3944223107569721f,
                             0.6206896551724138f, 0.8931297709923666f, 1f, 1f, 1f},
-                    new float[] {0.05f, 0.08f, 0.1784313725490196f, 0.23137254901960785f,
+                    new float[] {0.05f, 0.08f, 0.14f, 0.1784313725490196f, 0.23137254901960785f,
                             0.3431372549019608f, 0.38235294117647056f, 0.49215686274509807f,
                             0.6588235294117647f, 0.7431372549019608f, 0.8176470588235294f,
                             0.8784313725490196f, 0.9294117647058824f}
@@ -442,7 +449,7 @@
                             0.8285256410256411f, 0.821522309711286f, 0.8083333333333333f,
                             0.8046594982078853f, 0.8005822416302766f, 0.7842377260981912f,
                             0.7771084337349398f, 0.7747747747747749f},
-                    new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f,
+                    new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f,
                             0.737142857142857f, 0.6434108527131781f, 0.46835443037974644f},
                     new float[] {0.05f, 0.08f, 0.12745098039215685f, 0.15490196078431373f,
                             0.20392156862745098f, 0.24901960784313726f, 0.3137254901960784f,
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java
new file mode 100644
index 0000000..925214e
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.plugins;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Bundle;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A PluginActivity is an activity that replaces another full activity (e.g. RecentsActivity)
+ * at runtime within the sysui process.
+ */
+@ProvidesInterface(version = PluginActivity.VERSION)
+public abstract class PluginActivity extends Activity implements Plugin {
+
+    public static final int VERSION = 1;
+
+    public static final String ACTION_RECENTS = "com.android.systemui.action.PLUGIN_RECENTS";
+
+    private Context mSysuiContext;
+    private boolean mSettingActionBar;
+
+    @Override
+    public final void onCreate(Context sysuiContext, Context pluginContext) {
+        mSysuiContext = sysuiContext;
+        super.attachBaseContext(pluginContext);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Theme theme = getClass().getDeclaredAnnotation(Theme.class);
+        if (theme != null && theme.value() != 0) {
+            setTheme(theme.value());
+        }
+        mSettingActionBar = true;
+        getActionBar();
+        mSettingActionBar = false;
+    }
+
+    @Override
+    public Resources getResources() {
+        return mSettingActionBar ? mSysuiContext.getResources() : super.getResources();
+    }
+
+    @Override
+    protected void attachBaseContext(Context newBase) {
+        mSysuiContext = newBase;
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+    }
+
+    public Context getSysuiContext() {
+        return mSysuiContext;
+    }
+
+    public Context getPluginContext() {
+        return getBaseContext();
+    }
+
+    /**
+     * Since PluginActivities are declared as services instead of activities (since they
+     * are plugins), they can't have a theme attached to them. Instead a PluginActivity
+     * can annotate itself with @Theme to specify the resource of the style it wants
+     * to be themed with.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface Theme {
+        int value();
+    }
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java
index 25ce3dd..db2e376 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java
@@ -21,6 +21,11 @@
     public static final int VERSION = 1;
     static DependencyProvider sProvider;
 
+    /**
+     * Allows a plugin to get a hold of static dependencies if they have declared dependence
+     * on their interface. For one-shot plugins this will only work during onCreate and will
+     * not work afterwards.
+     */
     public static <T> T get(Plugin p, Class<T> cls) {
         return sProvider.get(p, cls);
     }
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml
deleted file mode 100644
index b003e92..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="367"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml
deleted file mode 100644
index b003e92..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="367"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml
deleted file mode 100644
index 5c37479..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="117"
-            android:propertyName="scaleX"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="1"
-            android:valueTo="0.9"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="117"
-            android:propertyName="scaleY"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleY"
-            android:valueFrom="1"
-            android:valueTo="0.9"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <objectAnimator
-        android:duration="450"
-        android:propertyName="rotation"
-        android:valueFrom="0"
-        android:valueTo="-135"
-        android:interpolator="@interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml
deleted file mode 100644
index aa086c9..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="67"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="217"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml
deleted file mode 100644
index fa10b119..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml
deleted file mode 100644
index fa10b119..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml
deleted file mode 100644
index caae73a..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="333"
-        android:propertyName="scaleX"
-        android:valueFrom="0.9"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-    <objectAnimator
-        android:duration="333"
-        android:propertyName="scaleY"
-        android:valueFrom="0.9"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-    <objectAnimator
-        android:duration="450"
-        android:propertyName="rotation"
-        android:valueFrom="-135"
-        android:valueTo="0"
-        android:interpolator="@interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml
deleted file mode 100644
index aa22c3b..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="67"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="217"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml
deleted file mode 100644
index 2530f08..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="400"
-        android:propertyName="rotation"
-        android:valueFrom="-45"
-        android:valueTo="0"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml
similarity index 74%
copy from packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
copy to packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml
index 27fd653..8fdad80 100644
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
+++ b/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,11 +14,13 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
     <objectAnimator
-        android:duration="400"
+        android:duration="616"
         android:propertyName="rotation"
-        android:valueFrom="0"
-        android:valueTo="-45"
+        android:valueFrom="-90.0"
+        android:valueTo="0.0"
+        android:valueType="floatType"
         android:interpolator="@android:interpolator/fast_out_slow_in" />
 </set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml
similarity index 74%
rename from packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml
rename to packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml
index 682dcf3..3c3c131 100644
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml
+++ b/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,20 +14,23 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
             android:duration="50"
             android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="0"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
             android:duration="83"
             android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="1"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
     </set>
 </set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml
new file mode 100644
index 0000000..57132e1
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="466"
+        android:propertyName="scaleX"
+        android:valueFrom="1.0"
+        android:valueTo="0.909"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_landscape_to_rotate_animation_interpolator_0" />
+    <objectAnimator
+        android:duration="466"
+        android:propertyName="scaleY"
+        android:valueFrom="1.0"
+        android:valueTo="0.909"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_landscape_to_rotate_animation_interpolator_0" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="50"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="400"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="45.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml
deleted file mode 100644
index 4e20d81..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml
deleted file mode 100644
index 61bdfea..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="117"
-            android:propertyName="scaleX"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="1"
-            android:valueTo="0.9"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="117"
-            android:propertyName="scaleY"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleY"
-            android:valueFrom="1"
-            android:valueTo="0.9"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <objectAnimator
-        android:duration="617"
-        android:propertyName="rotation"
-        android:valueFrom="0"
-        android:valueTo="-221"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml
deleted file mode 100644
index 6a0a20b..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="400"
-        android:propertyName="rotation"
-        android:valueFrom="0"
-        android:valueTo="-135"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml
deleted file mode 100644
index 682dcf3..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml
similarity index 69%
rename from packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml
rename to packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml
index 9fa8ec0..ad2a5fa 100644
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml
+++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,41 +14,40 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="133"
+            android:duration="116"
             android:propertyName="scaleX"
-            android:valueFrom="0.9"
-            android:valueTo="0.9"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
             android:duration="333"
             android:propertyName="scaleX"
-            android:valueFrom="0.9"
-            android:valueTo="1"
+            android:valueFrom="1.0"
+            android:valueTo="0.9"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
     </set>
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="133"
+            android:duration="116"
             android:propertyName="scaleY"
-            android:valueFrom="0.9"
-            android:valueTo="0.9"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
             android:duration="333"
             android:propertyName="scaleY"
-            android:valueFrom="0.9"
-            android:valueTo="1"
+            android:valueFrom="1.0"
+            android:valueTo="0.9"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
     </set>
-    <objectAnimator
-        android:duration="617"
-        android:propertyName="rotation"
-        android:valueFrom="-221"
-        android:valueTo="0"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
 </set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml
similarity index 74%
copy from packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
copy to packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml
index 27fd653..cdb7890 100644
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
+++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,11 +14,13 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
     <objectAnimator
-        android:duration="400"
+        android:duration="616"
         android:propertyName="rotation"
-        android:valueFrom="0"
-        android:valueTo="-45"
+        android:valueFrom="0.0"
+        android:valueTo="-221.0"
+        android:valueType="floatType"
         android:interpolator="@android:interpolator/fast_out_slow_in" />
 </set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml
similarity index 74%
rename from packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml
rename to packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml
index 4e20d81..46100b4 100644
--- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml
+++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,20 +14,23 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
             android:duration="400"
             android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
             android:duration="83"
             android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
     </set>
 </set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml
similarity index 77%
rename from packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
rename to packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml
index 27fd653..8f6d24d 100644
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
+++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,11 +14,13 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
     <objectAnimator
         android:duration="400"
         android:propertyName="rotation"
-        android:valueFrom="0"
-        android:valueTo="-45"
+        android:valueFrom="0.0"
+        android:valueTo="-135.0"
+        android:valueType="floatType"
         android:interpolator="@android:interpolator/fast_out_slow_in" />
 </set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml
similarity index 94%
rename from packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml
rename to packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml
index 92b19ad..300ed53 100644
--- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml
+++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,18 +14,19 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="167"
+            android:duration="66"
             android:propertyName="pathData"
             android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
             android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
             android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
+            android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="217"
+            android:duration="216"
             android:propertyName="pathData"
             android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
             android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml
similarity index 69%
copy from packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml
copy to packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml
index 9fa8ec0..ad2a5fa 100644
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml
+++ b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,41 +14,40 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="133"
+            android:duration="116"
             android:propertyName="scaleX"
-            android:valueFrom="0.9"
-            android:valueTo="0.9"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
             android:duration="333"
             android:propertyName="scaleX"
-            android:valueFrom="0.9"
-            android:valueTo="1"
+            android:valueFrom="1.0"
+            android:valueTo="0.9"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
     </set>
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="133"
+            android:duration="116"
             android:propertyName="scaleY"
-            android:valueFrom="0.9"
-            android:valueTo="0.9"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
             android:duration="333"
             android:propertyName="scaleY"
-            android:valueFrom="0.9"
-            android:valueTo="1"
+            android:valueFrom="1.0"
+            android:valueTo="0.9"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
     </set>
-    <objectAnimator
-        android:duration="617"
-        android:propertyName="rotation"
-        android:valueFrom="-221"
-        android:valueTo="0"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
 </set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml
similarity index 74%
copy from packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
copy to packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml
index 27fd653..c152152 100644
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
+++ b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,11 +14,13 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
     <objectAnimator
-        android:duration="400"
+        android:duration="616"
         android:propertyName="rotation"
-        android:valueFrom="0"
-        android:valueTo="-45"
+        android:valueFrom="0.0"
+        android:valueTo="-180.0"
+        android:valueType="floatType"
         android:interpolator="@android:interpolator/fast_out_slow_in" />
 </set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml
similarity index 71%
copy from packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml
copy to packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml
index 682dcf3..b2c1eb8 100644
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml
+++ b/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,20 +14,23 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="50"
+            android:duration="200"
             android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="0"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
             android:duration="83"
             android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="1"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
     </set>
 </set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml
new file mode 100644
index 0000000..2a9bbe3
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="scaleX"
+            android:valueFrom="0.909"
+            android:valueTo="0.909"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="166"
+            android:propertyName="scaleX"
+            android:valueFrom="0.909"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_rotate_to_landscape_animation_interpolator_0" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="scaleY"
+            android:valueFrom="0.909"
+            android:valueTo="0.909"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="166"
+            android:propertyName="scaleY"
+            android:valueFrom="0.909"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_rotate_to_landscape_animation_interpolator_0" />
+    </set>
+    <objectAnimator
+        android:duration="616"
+        android:propertyName="rotation"
+        android:valueFrom="45.0"
+        android:valueTo="0.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml
new file mode 100644
index 0000000..ce26770
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="466"
+        android:propertyName="scaleX"
+        android:valueFrom="0.9"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_rotate_to_portrait_animation_interpolator_0" />
+    <objectAnimator
+        android:duration="466"
+        android:propertyName="scaleY"
+        android:valueFrom="0.9"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_rotate_to_portrait_animation_interpolator_0" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml
similarity index 74%
copy from packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
copy to packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml
index 27fd653..6e8941d 100644
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
+++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,11 +14,13 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
     <objectAnimator
-        android:duration="400"
+        android:duration="616"
         android:propertyName="rotation"
-        android:valueFrom="0"
-        android:valueTo="-45"
+        android:valueFrom="-221.0"
+        android:valueTo="0.0"
+        android:valueType="floatType"
         android:interpolator="@android:interpolator/fast_out_slow_in" />
 </set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml
similarity index 74%
copy from packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml
copy to packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml
index 682dcf3..3c3c131 100644
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml
+++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,20 +14,23 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
             android:duration="50"
             android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="0"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
             android:duration="83"
             android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="1"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
     </set>
 </set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml
similarity index 69%
rename from packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml
rename to packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml
index 3208eee..fd8e4f8 100644
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml
+++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,20 +14,23 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
             android:duration="50"
             android:propertyName="rotation"
-            android:valueFrom="-135"
-            android:valueTo="-135"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
+            android:valueFrom="-135.0"
+            android:valueTo="-135.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
         <objectAnimator
             android:duration="400"
             android:propertyName="rotation"
-            android:valueFrom="-135"
-            android:valueTo="0"
+            android:valueFrom="-135.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
             android:interpolator="@android:interpolator/fast_out_slow_in" />
     </set>
 </set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml
similarity index 95%
rename from packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml
rename to packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml
index c1124af..a77a536 100644
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml
+++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,7 +14,8 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
@@ -23,7 +24,7 @@
             android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
             android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
             android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
+            android:interpolator="@android:interpolator/linear" />
         <objectAnimator
             android:duration="500"
             android:propertyName="pathData"
diff --git a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml
index 8b2585b..061f9fe 100644
--- a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml
+++ b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,49 +14,52 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_rotate_to_landscape"
     android:height="48dp"
     android:width="48dp"
     android:viewportHeight="48"
     android:viewportWidth="48"
     android:tint="?android:attr/colorControlNormal" >
     <group
-        android:name="ic_screen_rotation_48px_outlines"
+        android:name="device"
         android:translateX="24"
         android:translateY="24" >
         <group
-            android:name="ic_screen_rotation_48px_outlines_pivot"
+            android:name="device_pivot"
             android:translateX="-24.15"
             android:translateY="-24.25" >
             <group
-                android:name="arrows"
-                android:translateX="24.1"
-                android:translateY="24.1" >
-                <group
-                    android:name="arrows_pivot"
-                    android:translateX="-24.1"
-                    android:translateY="-24.1" >
-                    <path
-                        android:name="arrow_top"
-                        android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                    <path
-                        android:name="arrow_bottom"
-                        android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                </group>
-            </group>
-            <group
-                android:name="device"
-                android:translateX="24.14999"
-                android:translateY="24.25" >
+                android:name="landscape"
+                android:translateX="24"
+                android:translateY="24"
+                android:scaleX="0.909"
+                android:scaleY="0.909"
+                android:rotation="45" >
                 <path
-                    android:name="body"
-                    android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
+                    android:name="device_merged"
+                    android:pathData="M -21.9799957275,-10.0 c 0.0,0.0 -0.0200042724609,20.0 -0.0200042724609,20.0 c 0.0,2.19999694824 1.80000305176,4.0 4.0,4.0 c 0.0,0.0 36.0,0.0 36.0,0.0 c 2.19999694824,0.0 4.0,-1.80000305176 4.0,-4.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,-2.19999694824 -1.80000305176,-4.0 -4.0,-4.0 c 0.0,0.0 -36.0,0.0 -36.0,0.0 c -2.19999694824,0.0 -3.97999572754,1.80000305176 -3.97999572754,4.0 Z M 14.0,10.0 c 0.0,0.0 -28.0,0.0 -28.0,0.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,0.0 28.0,0.0 28.0,0.0 c 0.0,0.0 0.0,20.0 0.0,20.0 Z"
+                    android:fillColor="#FFFFFFFF" />
+            </group>
+        </group>
+    </group>
+    <group
+        android:name="arrows"
+        android:translateX="24"
+        android:translateY="24" >
+        <group
+            android:name="arrows_pivot"
+            android:translateX="-24.0798"
+            android:translateY="-24.23" >
+            <group
+                android:name="arrows_0"
+                android:translateX="12.2505"
+                android:translateY="37.2145" >
+                <path
+                    android:name="bottom_merged"
+                    android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z"
+                    android:fillColor="#FFFFFFFF" />
             </group>
         </group>
     </group>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml
index 400a28b..00bcaf6 100644
--- a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,21 +14,19 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/ic_landscape_from_auto_rotate" >
     <target
+        android:name="landscape"
+        android:animation="@anim/ic_rotate_to_landscape_landscape_animation" />
+    <target
         android:name="arrows"
-        android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrows" />
+        android:animation="@anim/ic_rotate_to_landscape_arrows_animation" />
     <target
-        android:name="arrow_top"
-        android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrow_top" />
+        android:name="arrows_0"
+        android:animation="@anim/ic_rotate_to_landscape_arrows_0_animation" />
     <target
-        android:name="arrow_bottom"
-        android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrow_bottom" />
-    <target
-        android:name="device"
-        android:animation="@anim/ic_landscape_from_auto_rotate_animation_device" />
-    <target
-        android:name="body"
-        android:animation="@anim/ic_landscape_from_auto_rotate_animation_body" />
+        android:name="bottom_merged"
+        android:animation="@anim/ic_rotate_to_landscape_bottom_merged_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml
index 603d0bf..cde6797 100644
--- a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml
+++ b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,53 +14,51 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_landscape_to_rotate"
     android:height="48dp"
     android:width="48dp"
     android:viewportHeight="48"
     android:viewportWidth="48"
     android:tint="?android:attr/colorControlNormal" >
     <group
-        android:name="ic_screen_rotation_48px_outlines"
+        android:name="device"
         android:translateX="24"
         android:translateY="24" >
         <group
-            android:name="ic_screen_rotation_48px_outlines_pivot"
+            android:name="device_pivot"
             android:translateX="-24.15"
             android:translateY="-24.25" >
             <group
-                android:name="arrows"
-                android:translateX="24.1"
-                android:translateY="24.1"
-                android:scaleX="0.9"
-                android:scaleY="0.9"
-                android:rotation="-135" >
-                <group
-                    android:name="arrows_pivot"
-                    android:translateX="-24.1"
-                    android:translateY="-24.1" >
-                    <path
-                        android:name="arrow_top"
-                        android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="0" />
-                    <path
-                        android:name="arrow_bottom"
-                        android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="0" />
-                </group>
-            </group>
-            <group
-                android:name="device"
-                android:translateX="24.14999"
-                android:translateY="24.25"
-                android:rotation="-45" >
+                android:name="landscape"
+                android:translateX="24"
+                android:translateY="24" >
                 <path
-                    android:name="body"
-                    android:pathData="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+                    android:name="device_merged"
+                    android:pathData="M -21.9799957275,-10.0 c 0.0,0.0 -0.0200042724609,20.0 -0.0200042724609,20.0 c 0.0,2.19999694824 1.80000305176,4.0 4.0,4.0 c 0.0,0.0 36.0,0.0 36.0,0.0 c 2.19999694824,0.0 4.0,-1.80000305176 4.0,-4.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,-2.19999694824 -1.80000305176,-4.0 -4.0,-4.0 c 0.0,0.0 -36.0,0.0 -36.0,0.0 c -2.19999694824,0.0 -3.97999572754,1.80000305176 -3.97999572754,4.0 Z M 14.0,10.0 c 0.0,0.0 -28.0,0.0 -28.0,0.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,0.0 28.0,0.0 28.0,0.0 c 0.0,0.0 0.0,20.0 0.0,20.0 Z"
+                    android:fillColor="#FFFFFFFF" />
+            </group>
+        </group>
+    </group>
+    <group
+        android:name="arrows"
+        android:translateX="24"
+        android:translateY="24"
+        android:rotation="-90" >
+        <group
+            android:name="arrows_pivot"
+            android:translateX="-24.0798"
+            android:translateY="-24.23" >
+            <group
+                android:name="arrows_0"
+                android:translateX="12.2505"
+                android:translateY="37.2145" >
+                <path
+                    android:name="bottom_merged"
+                    android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z"
                     android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
+                    android:fillAlpha="0" />
             </group>
         </group>
     </group>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml
index 5263eb4..86dc6ce 100644
--- a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,21 +14,16 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/ic_landscape_to_auto_rotate" >
     <target
+        android:name="landscape"
+        android:animation="@anim/ic_landscape_to_rotate_landscape_animation" />
+    <target
         android:name="arrows"
-        android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrows" />
+        android:animation="@anim/ic_landscape_to_rotate_arrows_animation" />
     <target
-        android:name="arrow_top"
-        android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrow_top" />
-    <target
-        android:name="arrow_bottom"
-        android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrow_bottom" />
-    <target
-        android:name="device"
-        android:animation="@anim/ic_landscape_to_auto_rotate_animation_device" />
-    <target
-        android:name="body"
-        android:animation="@anim/ic_landscape_to_auto_rotate_animation_body" />
+        android:name="bottom_merged"
+        android:animation="@anim/ic_landscape_to_rotate_bottom_merged_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml
index 17185a7c..bce494c 100644
--- a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml
+++ b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,50 +14,51 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_portrait_to_rotate"
     android:height="48dp"
     android:width="48dp"
     android:viewportHeight="48"
     android:viewportWidth="48"
     android:tint="?android:attr/colorControlNormal" >
     <group
-        android:name="icon"
+        android:name="device"
         android:translateX="24"
         android:translateY="24" >
         <group
-            android:name="icon_pivot"
+            android:name="device_pivot"
             android:translateX="-24.15"
             android:translateY="-24.25" >
             <group
-                android:name="arrows"
-                android:translateX="24.1"
-                android:translateY="24.1" >
-                <group
-                    android:name="arrows_pivot"
-                    android:translateX="-24.1"
-                    android:translateY="-24.1" >
-                    <path
-                        android:name="arrow_top"
-                        android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                    <path
-                        android:name="arrow_bottom"
-                        android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                </group>
-            </group>
-            <group
-                android:name="device"
+                android:name="device_0"
                 android:translateX="24.14999"
                 android:translateY="24.25" >
                 <path
-                    android:name="device_1"
+                    android:name="device_merged"
                     android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
+                    android:fillColor="#FFFFFFFF" />
+            </group>
+        </group>
+    </group>
+    <group
+        android:name="arrows"
+        android:translateX="24"
+        android:translateY="24" >
+        <group
+            android:name="arrows_pivot"
+            android:translateX="-24.0798"
+            android:translateY="-24.23" >
+            <group
+                android:name="arrows_0"
+                android:translateX="12.2505"
+                android:translateY="37.2145" >
+                <path
+                    android:name="bottom_merged"
+                    android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z"
+                    android:fillColor="#FFFFFFFF" />
             </group>
         </group>
     </group>
 </vector>
+
diff --git a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml
index 565ef26..b8465f4 100644
--- a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,21 +14,22 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_portrait_from_auto_rotate" >
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_portrait_to_auto_rotate" >
+    <target
+        android:name="device_0"
+        android:animation="@anim/ic_portrait_to_rotate_device_0_animation" />
+    <target
+        android:name="device_merged"
+        android:animation="@anim/ic_portrait_to_rotate_device_merged_animation" />
     <target
         android:name="arrows"
-        android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrows" />
+        android:animation="@anim/ic_portrait_to_rotate_arrows_animation" />
     <target
-        android:name="arrow_top"
-        android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrow_top" />
+        android:name="arrows_0"
+        android:animation="@anim/ic_portrait_to_rotate_arrows_0_animation" />
     <target
-        android:name="arrow_bottom"
-        android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrow_bottom" />
-    <target
-        android:name="device"
-        android:animation="@anim/ic_portrait_from_auto_rotate_animation_device" />
-    <target
-        android:name="device_1"
-        android:animation="@anim/ic_portrait_from_auto_rotate_animation_device_1" />
+        android:name="bottom_merged"
+        android:animation="@anim/ic_portrait_to_rotate_bottom_merged_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml
index 88bf486..0ef15f0 100644
--- a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml
+++ b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,53 +14,54 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_rotate_to_portrait"
     android:height="48dp"
     android:width="48dp"
     android:viewportHeight="48"
     android:viewportWidth="48"
     android:tint="?android:attr/colorControlNormal" >
     <group
-        android:name="icon"
+        android:name="device"
         android:translateX="24"
         android:translateY="24" >
         <group
-            android:name="icon_pivot"
+            android:name="device_pivot"
             android:translateX="-24.15"
             android:translateY="-24.25" >
             <group
-                android:name="arrows"
-                android:translateX="24.1"
-                android:translateY="24.1"
-                android:scaleX="0.9"
-                android:scaleY="0.9"
-                android:rotation="-221" >
-                <group
-                    android:name="arrows_pivot"
-                    android:translateX="-24.1"
-                    android:translateY="-24.1" >
-                    <path
-                        android:name="arrow_top"
-                        android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="0" />
-                    <path
-                        android:name="arrow_bottom"
-                        android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="0" />
-                </group>
-            </group>
-            <group
-                android:name="device"
+                android:name="device_0"
                 android:translateX="24.14999"
                 android:translateY="24.25"
                 android:rotation="-135" >
                 <path
-                    android:name="device_1"
+                    android:name="device_merged"
                     android:pathData="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+                    android:fillColor="#FFFFFFFF" />
+            </group>
+        </group>
+    </group>
+    <group
+        android:name="arrows"
+        android:translateX="24"
+        android:translateY="24"
+        android:rotation="-221" >
+        <group
+            android:name="arrows_pivot"
+            android:translateX="-24.0798"
+            android:translateY="-24.23" >
+            <group
+                android:name="arrows_0"
+                android:translateX="12.2505"
+                android:translateY="37.2145"
+                android:scaleX="0.9"
+                android:scaleY="0.9" >
+                <path
+                    android:name="bottom_merged"
+                    android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z"
                     android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
+                    android:fillAlpha="0" />
             </group>
         </group>
     </group>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml
index f75617f..6d3fd37 100644
--- a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,21 +14,22 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_portrait_to_auto_rotate" >
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_portrait_from_auto_rotate" >
+    <target
+        android:name="device_0"
+        android:animation="@anim/ic_rotate_to_portrait_device_0_animation" />
+    <target
+        android:name="device_merged"
+        android:animation="@anim/ic_rotate_to_portrait_device_merged_animation" />
     <target
         android:name="arrows"
-        android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrows" />
+        android:animation="@anim/ic_rotate_to_portrait_arrows_animation" />
     <target
-        android:name="arrow_top"
-        android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrow_top" />
+        android:name="arrows_0"
+        android:animation="@anim/ic_rotate_to_portrait_arrows_0_animation" />
     <target
-        android:name="arrow_bottom"
-        android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrow_bottom" />
-    <target
-        android:name="device"
-        android:animation="@anim/ic_portrait_to_auto_rotate_animation_device" />
-    <target
-        android:name="device_1"
-        android:animation="@anim/ic_portrait_to_auto_rotate_animation_device_1" />
+        android:name="bottom_merged"
+        android:animation="@anim/ic_rotate_to_portrait_bottom_merged_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/recents_dismiss_dark.xml b/packages/SystemUI/res/drawable/recents_dismiss_dark.xml
index 951269b..b837ebe 100644
--- a/packages/SystemUI/res/drawable/recents_dismiss_dark.xml
+++ b/packages/SystemUI/res/drawable/recents_dismiss_dark.xml
@@ -14,11 +14,16 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48.0dp"
-        android:height="48.0dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-    <path
-        android:fillColor="@color/recents_task_bar_dark_icon_color"
-        android:pathData="M38.000000,12.800000l-2.799999,-2.800000 -11.200001,11.200001 -11.200000,-11.200001 -2.800000,2.800000 11.200001,11.200000 -11.200001,11.200001 2.800000,2.799999 11.200000,-11.200001 11.200001,11.200001 2.799999,-2.799999 -11.200001,-11.200001z"/>
+android:width="24dp"
+android:height="24dp"
+android:viewportWidth="24"
+android:viewportHeight="24">
+
+<path
+    android:fillColor="@color/recents_task_bar_dark_icon_color"
+    android:pathData="M18.3 5.71a.996 .996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996 .996 0 1 0 5.7
+7.11L10.59 12 5.7 16.89a.996 .996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996 .996 0
+1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38 .38 -1.02 0-1.4z" />
+<path
+    android:pathData="M0 0h24v24H0z" />
 </vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/recents_dismiss_light.xml b/packages/SystemUI/res/drawable/recents_dismiss_light.xml
index 1f44c1c..2b20814 100644
--- a/packages/SystemUI/res/drawable/recents_dismiss_light.xml
+++ b/packages/SystemUI/res/drawable/recents_dismiss_light.xml
@@ -14,11 +14,16 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48.0dp"
-        android:height="48.0dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-    <path
-        android:fillColor="@color/recents_task_bar_light_icon_color"
-        android:pathData="M38.000000,12.800000l-2.799999,-2.800000 -11.200001,11.200001 -11.200000,-11.200001 -2.800000,2.800000 11.200001,11.200000 -11.200001,11.200001 2.800000,2.799999 11.200000,-11.200001 11.200001,11.200001 2.799999,-2.799999 -11.200001,-11.200001z"/>
+android:width="24dp"
+android:height="24dp"
+android:viewportWidth="24"
+android:viewportHeight="24">
+
+<path
+    android:fillColor="@color/recents_task_bar_light_icon_color"
+    android:pathData="M18.3 5.71a.996 .996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996 .996 0 1 0 5.7
+7.11L10.59 12 5.7 16.89a.996 .996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996 .996 0
+1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38 .38 -1.02 0-1.4z" />
+<path
+    android:pathData="M0 0h24v24H0z" />
 </vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml b/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml
deleted file mode 100644
index 76f5667..0000000
--- a/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.458031162,0 0.299442342,0.748308635 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml b/packages/SystemUI/res/interpolator/ic_landscape_to_rotate_animation_interpolator_0.xml
similarity index 75%
rename from packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml
rename to packages/SystemUI/res/interpolator/ic_landscape_to_rotate_animation_interpolator_0.xml
index ac27e4d..793e7ff 100644
--- a/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml
+++ b/packages/SystemUI/res/interpolator/ic_landscape_to_rotate_animation_interpolator_0.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,5 +14,6 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.4,0.143709151 0.2,1 1,1" />
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml b/packages/SystemUI/res/interpolator/ic_rotate_to_landscape_animation_interpolator_0.xml
similarity index 75%
copy from packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml
copy to packages/SystemUI/res/interpolator/ic_rotate_to_landscape_animation_interpolator_0.xml
index ac27e4d..793e7ff 100644
--- a/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml
+++ b/packages/SystemUI/res/interpolator/ic_rotate_to_landscape_animation_interpolator_0.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,5 +14,6 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.4,0.143709151 0.2,1 1,1" />
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml b/packages/SystemUI/res/interpolator/ic_rotate_to_portrait_animation_interpolator_0.xml
similarity index 75%
copy from packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml
copy to packages/SystemUI/res/interpolator/ic_rotate_to_portrait_animation_interpolator_0.xml
index ac27e4d..793e7ff 100644
--- a/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml
+++ b/packages/SystemUI/res/interpolator/ic_rotate_to_portrait_animation_interpolator_0.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2014 The Android Open Source Project
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,5 +14,6 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.4,0.143709151 0.2,1 1,1" />
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/layout/back.xml b/packages/SystemUI/res/layout/back.xml
index 4e8726b..43bec91 100644
--- a/packages/SystemUI/res/layout/back.xml
+++ b/packages/SystemUI/res/layout/back.xml
@@ -22,8 +22,10 @@
     android:layout_height="match_parent"
     android:layout_weight="0"
     systemui:keyCode="4"
-    android:scaleType="center"
+    android:scaleType="fitCenter"
     android:contentDescription="@string/accessibility_back"
+    android:paddingTop="15dp"
+    android:paddingBottom="15dp"
     android:paddingStart="@dimen/navigation_key_padding"
     android:paddingEnd="@dimen/navigation_key_padding"
     />
diff --git a/packages/SystemUI/res/layout/home.xml b/packages/SystemUI/res/layout/home.xml
index 9586327..53ef2ab 100644
--- a/packages/SystemUI/res/layout/home.xml
+++ b/packages/SystemUI/res/layout/home.xml
@@ -21,8 +21,10 @@
     android:layout_height="match_parent"
     android:layout_weight="0"
     systemui:keyCode="3"
-    android:scaleType="center"
+    android:scaleType="fitCenter"
     android:contentDescription="@string/accessibility_home"
+    android:paddingTop="13dp"
+    android:paddingBottom="13dp"
     android:paddingStart="@dimen/navigation_key_padding"
     android:paddingEnd="@dimen/navigation_key_padding"
     />
diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml
index 2bf4d9c..a621c7c 100644
--- a/packages/SystemUI/res/layout/navigation_layout.xml
+++ b/packages/SystemUI/res/layout/navigation_layout.xml
@@ -18,7 +18,11 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:layout_marginStart="@dimen/rounded_corner_content_padding"
+    android:layout_marginEnd="@dimen/rounded_corner_content_padding"
+    android:paddingStart="8dp"
+    android:paddingEnd="8dp">
 
     <FrameLayout
         android:id="@+id/nav_buttons"
diff --git a/packages/SystemUI/res/layout/navigation_layout_rot90.xml b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
index 7601efc..bf48c7f 100644
--- a/packages/SystemUI/res/layout/navigation_layout_rot90.xml
+++ b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
@@ -18,7 +18,11 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:layout_marginTop="@dimen/rounded_corner_content_padding"
+    android:layout_marginBottom="@dimen/rounded_corner_content_padding"
+    android:paddingTop="8dp"
+    android:paddingBottom="8dp">
 
     <FrameLayout
         android:id="@+id/nav_buttons"
diff --git a/packages/SystemUI/res/layout/recent_apps.xml b/packages/SystemUI/res/layout/recent_apps.xml
index 870bcf7..c84d280 100644
--- a/packages/SystemUI/res/layout/recent_apps.xml
+++ b/packages/SystemUI/res/layout/recent_apps.xml
@@ -21,8 +21,10 @@
     android:layout_width="@dimen/navigation_key_width"
     android:layout_height="match_parent"
     android:layout_weight="0"
-    android:scaleType="center"
+    android:scaleType="fitCenter"
     android:contentDescription="@string/accessibility_recent"
+    android:paddingTop="15dp"
+    android:paddingBottom="15dp"
     android:paddingStart="@dimen/navigation_key_padding"
     android:paddingEnd="@dimen/navigation_key_padding"
     />
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 1b98510..652e35b 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -459,11 +459,11 @@
     <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
     <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"Άνοιγμα αξιόπιστων διαπιστευτηρίων"</string>
     <string name="monitoring_description_network_logging" msgid="7223505523384076027">"Ο διαχειριστής σας έχει ενεργοποιήσει την καταγραφή δικτύου, η οποία παρακολουθεί την επισκεψιμότητα στη συσκευή σας.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή σας."</string>
-    <string name="monitoring_description_vpn" msgid="4445150119515393526">"Παραχωρήσατε σε μια εφαρμογή άδεια για τη ρύθμιση σύνδεσης VPN.\n\nΑυτή η εφαρμογή μπορεί να παρακολουθεί τη δραστηριότητα της συσκευής και του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστότοπων."</string>
-    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"Η διαχείριση του προφίλ εργασίας γίνεται από τον οργανισμό <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nΟ διαχειριστής έχει τη δυνατότητα παρακολούθησης της δραστηριότητας του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστότοπων.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή.\n\nΕπίσης, είστε συνδεδεμένοι σε VPN, το οποίο μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου σας."</string>
+    <string name="monitoring_description_vpn" msgid="4445150119515393526">"Παραχωρήσατε σε μια εφαρμογή άδεια για τη ρύθμιση σύνδεσης VPN.\n\nΑυτή η εφαρμογή μπορεί να παρακολουθεί τη δραστηριότητα της συσκευής και του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"Η διαχείριση του προφίλ εργασίας γίνεται από τον οργανισμό <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nΟ διαχειριστής έχει τη δυνατότητα παρακολούθησης της δραστηριότητας του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή.\n\nΕπίσης, είστε συνδεδεμένοι σε VPN, το οποίο μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου σας."</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
     <string name="monitoring_description_app" msgid="1828472472674709532">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string>
-    <string name="monitoring_description_app_personal" msgid="484599052118316268">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του προσωπικού σας δικτύου, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστότοπων."</string>
+    <string name="monitoring_description_app_personal" msgid="484599052118316268">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του προσωπικού σας δικτύου, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string>
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του προσωπικού σας δικτύου, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Ο οργανισμός <xliff:g id="ORGANIZATION">%1$s</xliff:g> διαχειρίζεται το προφίλ εργασίας σας. Το προφίλ είναι συνδεδεμένο στην εφαρμογή <xliff:g id="APPLICATION">%2$s</xliff:g>, η οποία μπορεί να παρακολουθήσει τη δραστηριότητα του δικτύου εργασίας σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή σας."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Ο οργανισμός <xliff:g id="ORGANIZATION">%1$s</xliff:g> διαχειρίζεται το προφίλ εργασίας σας. Το προφίλ συνδέεται με την εφαρμογή <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου της εργασίας σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων.\n\nΕπίσης, είστε συνδεδεμένοι στην εφαρμογή <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, που έχει τη δυνατότητα παρακολούθησης της δραστηριότητας του προσωπικού σας δικτύου."</string>
diff --git a/packages/SystemUI/res/values-mcc311-mnc480/config.xml b/packages/SystemUI/res/values-mcc311-mnc480/config.xml
new file mode 100644
index 0000000..7dadae7
--- /dev/null
+++ b/packages/SystemUI/res/values-mcc311-mnc480/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources>
+    <!-- Enable 5 bar signal strength icon -->
+    <bool name="config_inflateSignalStrength">true</bool>
+</resources>
+
diff --git a/packages/SystemUI/res/values-sw372dp/config.xml b/packages/SystemUI/res/values-sw372dp/config.xml
new file mode 100644
index 0000000..07b797a
--- /dev/null
+++ b/packages/SystemUI/res/values-sw372dp/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources>
+    <!-- Nav bar button default ordering/layout -->
+    <string name="config_navBarLayout" translatable="false">left[.25W],back[.5WC];home;recent[.5WC],right[.25W]</string>
+</resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 74b0702..2ad6f2d 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -293,7 +293,7 @@
     <string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIFactory</string>
 
     <!-- Nav bar button default ordering/layout -->
-    <string name="config_navBarLayout" translatable="false">left,back;home;recent,right</string>
+    <string name="config_navBarLayout" translatable="false">left[.5W],back[1WC];home;recent[1WC],right[.5W]</string>
 
     <bool name="quick_settings_show_full_alarm">false</bool>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 93d2072..4a1d953 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -827,7 +827,4 @@
     <!-- How far to inset the rounded edges -->
     <dimen name="stat_sys_mobile_signal_circle_inset">0.9dp</dimen>
 
-    <!-- Width of the hollow triangle for empty signal state -->
-    <dimen name="mobile_signal_empty_strokewidth">2dp</dimen>
-
 </resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 570438a..7eabf39 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -741,6 +741,8 @@
     <string name="quick_settings_done">Done</string>
     <!-- QuickSettings: Control panel: Label for connected device. [CHAR LIMIT=NONE] -->
     <string name="quick_settings_connected">Connected</string>
+    <!-- QuickSettings: Control panel: Label for connected device, showing remote device battery level. [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_connected_battery_level">Connected, battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
     <!-- QuickSettings: Control panel: Label for connecting device. [CHAR LIMIT=NONE] -->
     <string name="quick_settings_connecting">Connecting...</string>
     <!-- QuickSettings: Tethering. [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
index d8bebab..12f75bb 100644
--- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
@@ -29,10 +29,8 @@
 import android.graphics.Typeface;
 import android.os.PowerManager;
 import android.os.SystemClock;
-import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.InputType;
-import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.View;
@@ -252,9 +250,9 @@
             mText = mText.substring(0, length - 1);
             CharState charState = mTextChars.get(length - 1);
             charState.startRemoveAnimation(0, 0);
+            sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0);
         }
         userActivity();
-        sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0);
     }
 
     public String getText() {
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 1b694b3..bb44123 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -31,6 +31,7 @@
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.fragments.FragmentService;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.PluginActivityManager;
 import com.android.systemui.plugins.PluginDependencyProvider;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.PluginManagerImpl;
@@ -276,6 +277,9 @@
 
         mProviders.put(UiOffloadThread.class, UiOffloadThread::new);
 
+        mProviders.put(PluginActivityManager.class,
+                () -> new PluginActivityManager(mContext, getDependency(PluginManager.class)));
+
         // Put all dependencies above here so the factory can override them if it wants.
         SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
index 6397eb5..74a1505 100644
--- a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
+++ b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
@@ -98,10 +98,6 @@
         TunablePadding.addTunablePadding(statusBar.findViewById(R.id.keyguard_header), PADDING,
                 padding, FLAG_END);
 
-        FragmentHostManager.get(sb.getNavigationBarWindow()).addTagListener(
-                NavigationBarFragment.TAG,
-                new TunablePaddingTagListener(padding, 0));
-
         FragmentHostManager fragmentHostManager = FragmentHostManager.get(statusBar);
         fragmentHostManager.addTagListener(CollapsedStatusBarFragment.TAG,
                 new TunablePaddingTagListener(padding, R.id.status_bar));
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 4a45997..fe6eb4b 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui;
 
+import android.app.Activity;
 import android.app.ActivityThread;
 import android.app.Application;
 import android.content.BroadcastReceiver;
@@ -39,6 +40,7 @@
 import com.android.systemui.plugins.GlobalActions;
 import com.android.systemui.plugins.OverlayPlugin;
 import com.android.systemui.plugins.Plugin;
+import com.android.systemui.plugins.PluginActivityManager;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.power.PowerUI;
@@ -266,4 +268,10 @@
     public SystemUI[] getServices() {
         return mServices;
     }
+
+    @Override
+    public Activity instantiateActivity(ClassLoader cl, String className, Intent intent) {
+        if (!mServicesStarted) return null;
+        return Dependency.get(PluginActivityManager.class).instantiate(cl, className, intent);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index ae936db..8d1d6e0 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -39,6 +39,7 @@
 import com.android.systemui.util.wakelock.WakeLock;
 
 import java.io.PrintWriter;
+import java.util.function.IntConsumer;
 
 /**
  * Handles triggers for ambient state changes.
@@ -98,18 +99,44 @@
         requestPulse(DozeLog.PULSE_REASON_NOTIFICATION, false /* performedProxCheck */);
     }
 
+    private void proximityCheckThenCall(IntConsumer callback,
+            boolean alreadyPerformedProxCheck,
+            int pulseReason) {
+        if (alreadyPerformedProxCheck) {
+            callback.accept(ProximityCheck.RESULT_NOT_CHECKED);
+        } else {
+            final long start = SystemClock.uptimeMillis();
+            new ProximityCheck() {
+                @Override
+                public void onProximityResult(int result) {
+                    final long end = SystemClock.uptimeMillis();
+                    DozeLog.traceProximityResult(mContext, result == RESULT_NEAR,
+                            end - start, pulseReason);
+                    callback.accept(result);
+                }
+            }.check();
+        }
+    }
+
     private void onSensor(int pulseReason, boolean sensorPerformedProxCheck,
             float screenX, float screenY) {
         boolean isDoubleTap = pulseReason == DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP;
         boolean isPickup = pulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP;
 
         if (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)) {
-            if (isDoubleTap) {
-                mDozeHost.onDoubleTap(screenX, screenY);
-                mMachine.wakeUp();
-            } else {
-                mDozeHost.extendPulse();
-            }
+            proximityCheckThenCall((result) -> {
+                if (result == ProximityCheck.RESULT_NEAR) {
+                    // In pocket, drop event.
+                    return;
+                }
+                if (isDoubleTap) {
+                    mDozeHost.onDoubleTap(screenX, screenY);
+                    mMachine.wakeUp();
+                } else {
+                    mDozeHost.extendPulse();
+                }
+            }, sensorPerformedProxCheck, pulseReason);
+            return;
         } else {
             requestPulse(pulseReason, sensorPerformedProxCheck);
         }
@@ -158,13 +185,16 @@
                 break;
             case DOZE:
             case DOZE_AOD:
-            case DOZE_AOD_PAUSED:
                 mDozeSensors.setProxListening(newState != DozeMachine.State.DOZE);
                 mDozeSensors.setListening(true);
                 if (oldState != DozeMachine.State.INITIALIZED) {
                     mDozeSensors.reregisterAllSensors();
                 }
                 break;
+            case DOZE_AOD_PAUSED:
+                mDozeSensors.setProxListening(true);
+                mDozeSensors.setListening(false);
+                break;
             case DOZE_PULSING:
                 mDozeSensors.setProxListening(true);
                 break;
@@ -199,33 +229,15 @@
         }
 
         mPulsePending = true;
-        if (!mDozeParameters.getProxCheckBeforePulse() || performedProxCheck) {
-            // skip proximity check
-            continuePulseRequest(reason);
-            return;
-        }
-
-        final long start = SystemClock.uptimeMillis();
-        new ProximityCheck() {
-            @Override
-            public void onProximityResult(int result) {
-                final long end = SystemClock.uptimeMillis();
-                DozeLog.traceProximityResult(mContext, result == RESULT_NEAR,
-                        end - start, reason);
-                if (performedProxCheck) {
-                    // we already continued
-                    return;
-                }
-                // avoid pulsing in pockets
-                if (result == RESULT_NEAR) {
-                    mPulsePending = false;
-                    return;
-                }
-
-                // not in-pocket, continue pulsing
+        proximityCheckThenCall((result) -> {
+            if (result == ProximityCheck.RESULT_NEAR) {
+                // in pocket, abort pulse
+                mPulsePending = false;
+            } else {
+                // not in pocket, continue pulsing
                 continuePulseRequest(reason);
             }
-        }.check();
+        }, !mDozeParameters.getProxCheckBeforePulse() || performedProxCheck, reason);
     }
 
     private boolean canPulse() {
@@ -259,6 +271,7 @@
         protected static final int RESULT_UNKNOWN = 0;
         protected static final int RESULT_NEAR = 1;
         protected static final int RESULT_FAR = 2;
+        protected static final int RESULT_NOT_CHECKED = 3;
 
         private boolean mRegistered;
         private boolean mFinished;
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 80a6418..1a8a474 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -339,6 +339,7 @@
                     long id) {
                 final Action action = mAdapter.getItem(position);
                 if (action instanceof LongPressAction) {
+                    mDialog.dismiss();
                     return ((LongPressAction) action).onLongPress();
                 }
                 return false;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index b8771d7..cebb22f 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -241,14 +241,14 @@
     /**
      * Flings the minimized PiP to the closest minimized snap target.
      */
-    Rect flingToMinimizedState(float velocityY, Rect movementBounds) {
+    Rect flingToMinimizedState(float velocityY, Rect movementBounds, Point dragStartPosition) {
         cancelAnimations();
         // We currently only allow flinging the minimized stack up and down, so just lock the
         // movement bounds to the current stack bounds horizontally
         movementBounds = new Rect(mBounds.left, movementBounds.top, mBounds.left,
                 movementBounds.bottom);
         Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds,
-                0 /* velocityX */, velocityY);
+                0 /* velocityX */, velocityY, dragStartPosition);
         if (!mBounds.equals(toBounds)) {
             mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN);
             mFlingAnimationUtils.apply(mBoundsAnimator, 0,
@@ -281,10 +281,11 @@
      * Flings the PiP to the closest snap target.
      */
     Rect flingToSnapTarget(float velocity, float velocityX, float velocityY, Rect movementBounds,
-            AnimatorUpdateListener updateListener, AnimatorListener listener) {
+            AnimatorUpdateListener updateListener, AnimatorListener listener,
+            Point startPosition) {
         cancelAnimations();
         Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds,
-                velocityX, velocityY);
+                velocityX, velocityY, startPosition);
         if (!mBounds.equals(toBounds)) {
             mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN);
             mFlingAnimationUtils.apply(mBoundsAnimator, 0,
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 3682ae6..9588b03 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -185,7 +185,7 @@
         mDismissViewController = new PipDismissViewController(context);
         mSnapAlgorithm = new PipSnapAlgorithm(mContext);
         mTouchState = new PipTouchState(mViewConfig);
-        mFlingAnimationUtils = new FlingAnimationUtils(context, 2f);
+        mFlingAnimationUtils = new FlingAnimationUtils(context, 2.5f);
         mGestures = new PipTouchGesture[] {
                 mDefaultMovementGesture
         };
@@ -534,6 +534,7 @@
     private PipTouchGesture mDefaultMovementGesture = new PipTouchGesture() {
         // Whether the PiP was on the left side of the screen at the start of the gesture
         private boolean mStartedOnLeft;
+        private Point mStartPosition;
 
         @Override
         public void onDown(PipTouchState touchState) {
@@ -541,7 +542,9 @@
                 return;
             }
 
-            mStartedOnLeft = mMotionHelper.getBounds().left < mMovementBounds.centerX();
+            Rect bounds = mMotionHelper.getBounds();
+            mStartPosition = new Point(bounds.left, bounds.top);
+            mStartedOnLeft = bounds.left < mMovementBounds.centerX();
             mMovementWithinMinimize = true;
             mMovementWithinDismiss = touchState.getDownTouchPosition().y >= mMovementBounds.bottom;
 
@@ -687,7 +690,8 @@
 
                 if (isFling) {
                     mMotionHelper.flingToSnapTarget(velocity, vel.x, vel.y, mMovementBounds,
-                            mUpdateScrimListener, postAnimationCallback);
+                            mUpdateScrimListener, postAnimationCallback,
+                            mStartPosition);
                 } else {
                     mMotionHelper.animateToClosestSnapTarget(mMovementBounds, mUpdateScrimListener,
                             postAnimationCallback);
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java
new file mode 100644
index 0000000..9becc38
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.plugins;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+
+public class PluginActivityManager {
+
+    private final Context mContext;
+    private final PluginManager mPluginManager;
+    private final ArrayMap<String, String> mActionLookup = new ArrayMap<>();
+
+    public PluginActivityManager(Context context, PluginManager pluginManager) {
+        mContext = context;
+        mPluginManager = pluginManager;
+    }
+
+    public void addActivityPlugin(String className, String action) {
+        mActionLookup.put(className, action);
+    }
+
+    public Activity instantiate(ClassLoader cl, String className, Intent intent) {
+        String action = mActionLookup.get(className);
+        if (TextUtils.isEmpty(action)) return null;
+        return mPluginManager.getOneShotPlugin(action, PluginActivity.class);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
index 493d244..a968399 100644
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
@@ -42,7 +42,6 @@
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.systemui.Dependency;
 import com.android.systemui.plugins.PluginInstanceManager.PluginContextWrapper;
-import com.android.systemui.plugins.PluginInstanceManager.PluginInfo;
 import com.android.systemui.plugins.annotations.ProvidesInterface;
 
 import dalvik.system.PathClassLoader;
@@ -120,14 +119,21 @@
         }
         PluginInstanceManager<T> p = mFactory.createPluginInstanceManager(mContext, action, null,
                 false, mLooper, cls, this);
+        PluginListener<Plugin> listener = new PluginListener<Plugin>() {
+            @Override
+            public void onPluginConnected(Plugin plugin, Context pluginContext) { }
+        };
+        mPluginMap.put(listener, p);
         mPluginPrefs.addAction(action);
-        PluginInfo<T> info = p.getPlugin();
+        PluginInstanceManager.PluginInfo<T> info = p.getPlugin();
         if (info != null) {
             mOneShotPackages.add(info.mPackage);
             mHasOneShot = true;
             startListening();
+            mPluginMap.remove(listener);
             return info.mPlugin;
         }
+        mPluginMap.remove(listener);
         return null;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 6b50764..8f18800 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -161,7 +161,8 @@
 
         QSTileLayout tileLayout = mQsPanel.getTileLayout();
         mAllViews.add((View) tileLayout);
-        int heightDiff = mQsPanel.getBottom() - mQs.getHeader().getBottom()
+        int height = mQs.getView() != null ? mQs.getView().getMeasuredHeight() : 0;
+        int heightDiff = height - mQs.getHeader().getBottom()
                 + mQs.getHeader().getPaddingBottom();
         firstPageBuilder.addFloat(tileLayout, "translationY", heightDiff, 0);
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 90275c5..bb36725 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -253,7 +253,8 @@
         }
         mHeader.setExpansion(mKeyguardShowing ? 1 : expansion);
         mFooter.setExpansion(mKeyguardShowing ? 1 : expansion);
-        int heightDiff = mQSPanel.getBottom() - mHeader.getBottom() + mHeader.getPaddingBottom();
+        int heightDiff = mQSPanel.getBottom() - mHeader.getBottom() + mHeader.getPaddingBottom()
+                + mFooter.getHeight();
         mQSPanel.setTranslationY(translationScaleY * heightDiff);
         mQSDetail.setFullyExpanded(expansion == 1);
 
@@ -262,7 +263,7 @@
         }
 
         // Set bounds on the QS panel so it doesn't run over the header.
-        mQsBounds.top = (int) (mQSPanel.getHeight() * (1 - expansion));
+        mQsBounds.top = (int) -mQSPanel.getTranslationY();
         mQsBounds.right = mQSPanel.getWidth();
         mQsBounds.bottom = mQSPanel.getHeight();
         mQSPanel.setClipBounds(mQsBounds);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index 918c00c..089d07a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -15,10 +15,13 @@
  */
 package com.android.systemui.qs.tiles;
 
+import android.content.Context;
 import android.content.Intent;
+import android.graphics.drawable.Drawable;
 import android.service.quicksettings.Tile;
 import android.widget.Switch;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settingslib.graph.BatteryMeterDrawableBase;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
@@ -79,7 +82,9 @@
     protected void handleUpdateState(BooleanState state, Object arg) {
         state.state = mCharging ? Tile.STATE_UNAVAILABLE
                 : mPowerSave ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
-        state.icon = ResourceIcon.get(R.drawable.ic_qs_battery_saver);
+        BatterySaverIcon bsi = new BatterySaverIcon();
+        bsi.mState = state.state;
+        state.icon = bsi;
         state.label = mContext.getString(R.string.battery_detail_switch_title);
         state.contentDescription = state.label;
         state.value = mPowerSave;
@@ -99,4 +104,41 @@
         mPowerSave = isPowerSave;
         refreshState(null);
     }
-}
\ No newline at end of file
+
+    public static class BatterySaverIcon extends Icon {
+        private int mState;
+
+        @Override
+        public Drawable getDrawable(Context context) {
+            BatterySaverDrawable b = new BatterySaverDrawable(context, 0);
+            b.mState = mState;
+            final int pad = context.getResources()
+                    .getDimensionPixelSize(R.dimen.qs_tile_divider_height);
+            b.setPadding(pad, pad, pad, pad);
+            return b;
+        }
+    }
+
+    private static class BatterySaverDrawable extends BatteryMeterDrawableBase {
+        private int mState;
+        private static final int MAX_BATTERY = 100;
+
+        BatterySaverDrawable(Context context, int frameColor) {
+            super(context, frameColor);
+            // Show as full so it's always uniform color
+            super.setBatteryLevel(MAX_BATTERY);
+            setPowerSave(true);
+            setCharging(false);
+        }
+
+        @Override
+        protected int batteryColorForLevel(int level) {
+            return QSTileImpl.getColorForState(mContext, mState);
+        }
+
+        @Override
+        public void setBatteryLevel(int val) {
+            // Don't change the actual level, otherwise this won't draw correctly
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 9ba32b3..de2ace4 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -43,11 +43,14 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
 import com.android.systemui.EventLogConstants;
 import com.android.systemui.EventLogTags;
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.SystemUI;
+import com.android.systemui.plugins.PluginActivity;
+import com.android.systemui.plugins.PluginActivityManager;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
 import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
@@ -234,6 +237,8 @@
             registerWithSystemUser();
         }
         putComponent(Recents.class, this);
+        Dependency.get(PluginActivityManager.class).addActivityPlugin(RecentsImpl.RECENTS_ACTIVITY,
+                PluginActivity.ACTION_RECENTS);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index eec818b..29b720c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -943,6 +943,10 @@
         }
     }
 
+    public boolean isDrawingAppearAnimation() {
+        return mDrawingAppearAnimation;
+    }
+
     @Override
     protected void dispatchDraw(Canvas canvas) {
         if (mDrawingAppearAnimation) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 6abf35f..ed4f685 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -756,6 +756,19 @@
         return getShowingLayout().getVisibleNotificationHeader();
     }
 
+
+    /**
+     * @return the contracted notification header. This can be different from
+     * {@link #getNotificationHeader()} and also {@link #getVisibleNotificationHeader()} and only
+     * returns the contracted version.
+     */
+    public NotificationHeaderView getContractedNotificationHeader() {
+        if (mIsSummaryWithChildren) {
+            return mChildrenContainer.getHeaderView();
+        }
+        return mPrivateLayout.getContractedNotificationHeader();
+    }
+
     public void setOnExpandClickListener(OnExpandClickListener onExpandClickListener) {
         mOnExpandClickListener = onExpandClickListener;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 75704b16..9e059c89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -1308,6 +1308,14 @@
         return header;
     }
 
+
+    public NotificationHeaderView getContractedNotificationHeader() {
+        if (mContractedChild != null) {
+            return mContractedWrapper.getNotificationHeader();
+        }
+        return null;
+    }
+
     public NotificationHeaderView getVisibleNotificationHeader() {
         NotificationViewWrapper wrapper = getVisibleWrapper(mVisibleType);
         return wrapper == null ? null : wrapper.getNotificationHeader();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index c0691c1..e5b1afe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -568,8 +568,6 @@
                 mTmpRanking.getImportance());
         pw.print(indent);
         pw.println("      notification=" + n.getNotification());
-        pw.print(indent);
-        pw.println("      tickerText=\"" + n.getNotification().tickerText + "\"");
     }
 
     private static boolean isSystemNotification(StatusBarNotification sbn) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
index 7f95d48..4301817 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
@@ -267,9 +267,10 @@
             if (!mApply) {
                 return;
             }
-            NotificationHeaderView header = row.getNotificationHeader();
+            NotificationHeaderView header = row.getContractedNotificationHeader();
             if (header == null) {
-                mApply = false;
+                // No header found. We still consider this to be the same to avoid weird flickering
+                // when for example showing an undo notification
                 return;
             }
             Object childData = mExtractor == null ? null : mExtractor.extractData(row);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
index 5a163d4..f859124 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
@@ -417,7 +417,7 @@
 
     @Override
     public void onHeightUpdate() {
-        if (mParent == null || mMenuItems.size() == 0) {
+        if (mParent == null || mMenuItems.size() == 0 || mMenuContainer == null) {
             return;
         }
         int parentHeight = mParent.getCollapsedHeight();
@@ -477,7 +477,7 @@
 
     private void setMenuLocation() {
         boolean showOnLeft = mTranslation > 0;
-        if ((mIconsPlaced && showOnLeft == mOnLeft) || mSnapping
+        if ((mIconsPlaced && showOnLeft == mOnLeft) || mSnapping || mMenuContainer == null
                 || !mMenuContainer.isAttachedToWindow()) {
             // Do nothing
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 97e2f6d..a601028 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -16,15 +16,18 @@
 
 package com.android.systemui.statusbar;
 
+import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE;
+import static com.android.systemui.statusbar.phone.NotificationIconContainer.OVERFLOW_EARLY_AMOUNT;
+
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.os.SystemProperties;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityNodeInfo;
+
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.ViewInvertHelper;
@@ -315,26 +318,65 @@
     private float updateIconAppearance(ExpandableNotificationRow row, float expandAmount,
             boolean scrolling, boolean scrollingFast, boolean expandingAnimated,
             boolean isLastChild) {
+        StatusBarIconView icon = row.getEntry().expandedIcon;
+        NotificationIconContainer.IconState iconState = getIconState(icon);
+        if (iconState == null) {
+            return 0.0f;
+        }
+
         // Let calculate how much the view is in the shelf
         float viewStart = row.getTranslationY();
         int fullHeight = row.getActualHeight() + mPaddingBetweenElements;
         float iconTransformDistance = getIntrinsicHeight() * 1.5f;
         iconTransformDistance *= NotificationUtils.interpolate(1.f, 1.5f, expandAmount);
+        iconTransformDistance = Math.min(iconTransformDistance, fullHeight);
         if (isLastChild) {
             fullHeight = Math.min(fullHeight, row.getMinHeight() - getIntrinsicHeight());
             iconTransformDistance = Math.min(iconTransformDistance, row.getMinHeight()
                     - getIntrinsicHeight());
         }
         float viewEnd = viewStart + fullHeight;
+        if (expandingAnimated && mAmbientState.getScrollY() == 0
+                && !mAmbientState.isOnKeyguard() && !iconState.isLastExpandIcon) {
+            // We are expanding animated. Because we switch to a linear interpolation in this case,
+            // the last icon may be stuck in between the shelf position and the notification
+            // position, which looks pretty bad. We therefore optimize this case by applying a
+            // shorter transition such that the icon is either fully in the notification or we clamp
+            // it into the shelf if it's close enough.
+            // We need to persist this, since after the expansion, the behavior should still be the
+            // same.
+            float position = mAmbientState.getIntrinsicPadding()
+                    + mHostLayout.getPositionInLinearLayout(row);
+            int maxShelfStart = mMaxLayoutHeight - getIntrinsicHeight();
+            if (position < maxShelfStart && position + row.getIntrinsicHeight() >= maxShelfStart
+                    && row.getTranslationY() < position) {
+                iconState.isLastExpandIcon = true;
+                iconState.customTransformHeight = NO_VALUE;
+                // Let's check if we're close enough to snap into the shelf
+                boolean forceInShelf = mMaxLayoutHeight - getIntrinsicHeight() - position
+                        < getIntrinsicHeight();
+                if (!forceInShelf) {
+                    // We are overlapping the shelf but not enough, so the icon needs to be
+                    // repositioned
+                    iconState.customTransformHeight = (int) (mMaxLayoutHeight
+                            - getIntrinsicHeight() - position);
+                }
+            }
+        }
         float fullTransitionAmount;
         float iconTransitionAmount;
         float shelfStart = getTranslationY();
+        if (iconState.hasCustomTransformHeight()) {
+            fullHeight = iconState.customTransformHeight;
+            iconTransformDistance = iconState.customTransformHeight;
+        }
+        boolean fullyInOrOut = true;
         if (viewEnd >= shelfStart && (!mAmbientState.isUnlockHintRunning() || row.isInShelf())
                 && (mAmbientState.isShadeExpanded()
                         || (!row.isPinned() && !row.isHeadsUpAnimatingAway()))) {
             if (viewStart < shelfStart) {
-
                 float fullAmount = (shelfStart - viewStart) / fullHeight;
+                fullAmount = Math.min(1.0f, fullAmount);
                 float interpolatedAmount =  Interpolators.ACCELERATE_DECELERATE.getInterpolation(
                         fullAmount);
                 interpolatedAmount = NotificationUtils.interpolate(
@@ -344,7 +386,7 @@
                 iconTransitionAmount = (shelfStart - viewStart) / iconTransformDistance;
                 iconTransitionAmount = Math.min(1.0f, iconTransitionAmount);
                 iconTransitionAmount = 1.0f - iconTransitionAmount;
-
+                fullyInOrOut = false;
             } else {
                 fullTransitionAmount = 1.0f;
                 iconTransitionAmount = 1.0f;
@@ -353,6 +395,10 @@
             fullTransitionAmount = 0.0f;
             iconTransitionAmount = 0.0f;
         }
+        if (fullyInOrOut && !expandingAnimated && iconState.isLastExpandIcon) {
+            iconState.isLastExpandIcon = false;
+            iconState.customTransformHeight = NO_VALUE;
+        }
         updateIconPositioning(row, iconTransitionAmount, fullTransitionAmount,
                 iconTransformDistance, scrolling, scrollingFast, expandingAnimated, isLastChild);
         return fullTransitionAmount;
@@ -366,9 +412,10 @@
         if (iconState == null) {
             return;
         }
+        boolean forceInShelf = iconState.isLastExpandIcon && !iconState.hasCustomTransformHeight();
         float clampedAmount = iconTransitionAmount > 0.5f ? 1.0f : 0.0f;
         if (clampedAmount == fullTransitionAmount) {
-            iconState.noAnimations = scrollingFast || expandingAnimated;
+            iconState.noAnimations = (scrollingFast || expandingAnimated) && !forceInShelf;
             iconState.useFullTransitionAmount = iconState.noAnimations
                 || (!ICON_ANMATIONS_WHILE_SCROLLING && fullTransitionAmount == 0.0f && scrolling);
             iconState.useLinearTransitionAmount = !ICON_ANMATIONS_WHILE_SCROLLING
@@ -376,12 +423,18 @@
             iconState.translateContent = mMaxLayoutHeight - getTranslationY()
                     - getIntrinsicHeight() > 0;
         }
-        if (scrollingFast || (expandingAnimated && iconState.useFullTransitionAmount
-                && !ViewState.isAnimatingY(icon))) {
+        if (!forceInShelf && (scrollingFast || (expandingAnimated
+                && iconState.useFullTransitionAmount && !ViewState.isAnimatingY(icon)))) {
             iconState.cancelAnimations(icon);
             iconState.useFullTransitionAmount = true;
             iconState.noAnimations = true;
         }
+        if (iconState.hasCustomTransformHeight()) {
+            iconState.useFullTransitionAmount = true;
+        }
+        if (iconState.isLastExpandIcon) {
+            iconState.translateContent = false;
+        }
         float transitionAmount;
         if (isLastChild || !USE_ANIMATIONS_WHEN_OPENING || iconState.useFullTransitionAmount
                 || iconState.useLinearTransitionAmount) {
@@ -452,6 +505,11 @@
             iconState.scaleX = newSize / icon.getHeight() / icon.getIconScale();
             iconState.scaleY = iconState.scaleX;
             iconState.hidden = transitionAmount == 0.0f && !iconState.isAnimating(icon);
+            boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf();
+            if (isAppearing) {
+                iconState.hidden = true;
+                iconState.iconAppearAmount = 0.0f;
+            }
             iconState.alpha = alpha;
             iconState.yTranslation = iconYTranslation;
             if (stayingInShelf) {
@@ -548,8 +606,7 @@
         if (!hasOverflow) {
             // we have to ensure that adding the low priority notification won't lead to an
             // overflow
-            collapsedPadding -= (1.0f + NotificationIconContainer.OVERFLOW_EARLY_AMOUNT)
-                    * mCollapsedIcons.getIconSize();
+            collapsedPadding -= (1.0f + OVERFLOW_EARLY_AMOUNT) * mCollapsedIcons.getIconSize();
         }
         float padding = NotificationUtils.interpolate(collapsedPadding,
                 mShelfIcons.getPaddingEnd(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index 720ca14..09ae521 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -19,9 +19,11 @@
 import android.content.res.Configuration;
 import android.graphics.drawable.Icon;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.Display.Mode;
+import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -35,6 +37,7 @@
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider;
+import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseFrameLayout;
 import com.android.systemui.statusbar.policy.KeyButtonView;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
@@ -43,6 +46,8 @@
 import java.util.List;
 import java.util.Objects;
 
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
 public class NavigationBarInflaterView extends FrameLayout
         implements Tunable, PluginListener<NavBarButtonProvider> {
 
@@ -71,6 +76,8 @@
     public static final String KEY_CODE_START = "(";
     public static final String KEY_IMAGE_DELIM = ":";
     public static final String KEY_CODE_END = ")";
+    private static final String WEIGHT_SUFFIX = "W";
+    private static final String WEIGHT_CENTERED_SUFFIX = "WC";
 
     private final List<NavBarButtonProvider> mPlugins = new ArrayList<>();
 
@@ -219,26 +226,27 @@
         String[] center = sets[1].split(BUTTON_SEPARATOR);
         String[] end = sets[2].split(BUTTON_SEPARATOR);
         // Inflate these in start to end order or accessibility traversal will be messed up.
-        inflateButtons(start, (ViewGroup) mRot0.findViewById(R.id.ends_group), isRot0Landscape);
-        inflateButtons(start, (ViewGroup) mRot90.findViewById(R.id.ends_group), !isRot0Landscape);
+        inflateButtons(start, mRot0.findViewById(R.id.ends_group), isRot0Landscape, true);
+        inflateButtons(start, mRot90.findViewById(R.id.ends_group), !isRot0Landscape, true);
 
-        inflateButtons(center, (ViewGroup) mRot0.findViewById(R.id.center_group), isRot0Landscape);
-        inflateButtons(center, (ViewGroup) mRot90.findViewById(R.id.center_group), !isRot0Landscape);
+        inflateButtons(center, mRot0.findViewById(R.id.center_group), isRot0Landscape, false);
+        inflateButtons(center, mRot90.findViewById(R.id.center_group), !isRot0Landscape, false);
 
-        addGravitySpacer((LinearLayout) mRot0.findViewById(R.id.ends_group));
-        addGravitySpacer((LinearLayout) mRot90.findViewById(R.id.ends_group));
+        addGravitySpacer(mRot0.findViewById(R.id.ends_group));
+        addGravitySpacer(mRot90.findViewById(R.id.ends_group));
 
-        inflateButtons(end, (ViewGroup) mRot0.findViewById(R.id.ends_group), isRot0Landscape);
-        inflateButtons(end, (ViewGroup) mRot90.findViewById(R.id.ends_group), !isRot0Landscape);
+        inflateButtons(end, mRot0.findViewById(R.id.ends_group), isRot0Landscape, false);
+        inflateButtons(end, mRot90.findViewById(R.id.ends_group), !isRot0Landscape, false);
     }
 
     private void addGravitySpacer(LinearLayout layout) {
         layout.addView(new Space(mContext), new LinearLayout.LayoutParams(0, 0, 1));
     }
 
-    private void inflateButtons(String[] buttons, ViewGroup parent, boolean landscape) {
+    private void inflateButtons(String[] buttons, ViewGroup parent, boolean landscape,
+            boolean start) {
         for (int i = 0; i < buttons.length; i++) {
-            inflateButton(buttons[i], parent, landscape);
+            inflateButton(buttons[i], parent, landscape, start);
         }
     }
 
@@ -251,16 +259,13 @@
     }
 
     @Nullable
-    protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape) {
+    protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape,
+            boolean start) {
         LayoutInflater inflater = landscape ? mLandscapeInflater : mLayoutInflater;
-        float size = extractSize(buttonSpec);
-        View v = createView(buttonSpec, parent, inflater, landscape);
+        View v = createView(buttonSpec, parent, inflater);
         if (v == null) return null;
 
-        if (size != 0) {
-            ViewGroup.LayoutParams params = v.getLayoutParams();
-            params.width = (int) (params.width * size);
-        }
+        v = applySize(v, buttonSpec, landscape, start);
         parent.addView(v);
         addToDispatchers(v);
         View lastView = landscape ? mLastLandscape : mLastPortrait;
@@ -275,16 +280,41 @@
         return v;
     }
 
-    private View createView(String buttonSpec, ViewGroup parent, LayoutInflater inflater,
-            boolean landscape) {
+    private View applySize(View v, String buttonSpec, boolean landscape, boolean start) {
+        String sizeStr = extractSize(buttonSpec);
+        if (sizeStr == null) return v;
+
+        if (sizeStr.contains(WEIGHT_SUFFIX)) {
+            float weight = Float.parseFloat(sizeStr.substring(0, sizeStr.indexOf(WEIGHT_SUFFIX)));
+            FrameLayout frame = new ReverseFrameLayout(mContext);
+            LayoutParams childParams = new LayoutParams(v.getLayoutParams());
+            if (sizeStr.endsWith(WEIGHT_CENTERED_SUFFIX)) {
+                childParams.gravity = Gravity.CENTER;
+            } else {
+                childParams.gravity = landscape ? (start ? Gravity.BOTTOM : Gravity.TOP)
+                        : (start ? Gravity.START : Gravity.END);
+            }
+            frame.addView(v, childParams);
+            frame.setLayoutParams(new LinearLayout.LayoutParams(0, MATCH_PARENT, weight));
+            frame.setClipChildren(false);
+            frame.setClipToPadding(false);
+            return frame;
+        }
+        float size = Float.parseFloat(sizeStr);
+        ViewGroup.LayoutParams params = v.getLayoutParams();
+        params.width = (int) (params.width * size);
+        return v;
+    }
+
+    private View createView(String buttonSpec, ViewGroup parent, LayoutInflater inflater) {
         View v = null;
         String button = extractButton(buttonSpec);
         if (LEFT.equals(button)) {
-            buttonSpec = Dependency.get(TunerService.class).getValue(NAV_BAR_LEFT, NAVSPACE);
-            button = extractButton(buttonSpec);
+            String s = Dependency.get(TunerService.class).getValue(NAV_BAR_LEFT, NAVSPACE);
+            button = extractButton(s);
         } else if (RIGHT.equals(button)) {
-            buttonSpec = Dependency.get(TunerService.class).getValue(NAV_BAR_RIGHT, MENU_IME);
-            button = extractButton(buttonSpec);
+            String s = Dependency.get(TunerService.class).getValue(NAV_BAR_RIGHT, MENU_IME);
+            button = extractButton(s);
         }
         // Let plugins go first so they can override a standard view if they want.
         for (NavBarButtonProvider provider : mPlugins) {
@@ -340,13 +370,12 @@
         return Integer.parseInt(subStr);
     }
 
-    public static float extractSize(String buttonSpec) {
+    public static String extractSize(String buttonSpec) {
         if (!buttonSpec.contains(SIZE_MOD_START)) {
-            return 1;
+            return null;
         }
         final int sizeStart = buttonSpec.indexOf(SIZE_MOD_START);
-        String sizeStr = buttonSpec.substring(sizeStart + 1, buttonSpec.indexOf(SIZE_MOD_END));
-        return Float.parseFloat(sizeStr);
+        return buttonSpec.substring(sizeStart + 1, buttonSpec.indexOf(SIZE_MOD_END));
     }
 
     public static String extractButton(String buttonSpec) {
@@ -379,8 +408,8 @@
                 mButtonDispatchers.valueAt(i).clear();
             }
         }
-        clearAllChildren((ViewGroup) mRot0.findViewById(R.id.nav_buttons));
-        clearAllChildren((ViewGroup) mRot90.findViewById(R.id.nav_buttons));
+        clearAllChildren(mRot0.findViewById(R.id.nav_buttons));
+        clearAllChildren(mRot90.findViewById(R.id.nav_buttons));
     }
 
     private void clearAllChildren(ViewGroup group) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index a6cd472..4264441 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -575,15 +575,17 @@
         mRotatedViews[Surface.ROTATION_270] =
                 mRotatedViews[Surface.ROTATION_90] = findViewById(R.id.rot90);
 
-        updateCurrentView();
+        mCurrentRotation = -1;
+        reorient();
     }
 
     public boolean needsReorient(int rotation) {
         return mCurrentRotation != rotation;
     }
 
-    private void updateCurrentView() {
+    private boolean updateCurrentView() {
         final int rot = mDisplay.getRotation();
+        if (rot == mCurrentRotation) return false;
         for (int i=0; i<4; i++) {
             mRotatedViews[i].setVisibility(View.GONE);
         }
@@ -595,6 +597,7 @@
         }
         updateLayoutTransitionsEnabled();
         mCurrentRotation = rot;
+        return true;
     }
 
     private void updateRecentsIcon() {
@@ -607,10 +610,14 @@
     }
 
     public void reorient() {
-        updateCurrentView();
+        if (!updateCurrentView()) {
+            return;
+        }
 
         mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone);
-        ((NavigationBarFrame) getRootView()).setDeadZone(mDeadZone);
+        if (getRootView() instanceof NavigationBarFrame) {
+            ((NavigationBarFrame) getRootView()).setDeadZone(mDeadZone);
+        }
         mDeadZone.setDisplayRotation(mCurrentRotation);
 
         // force the low profile & disabled states into compliance
@@ -644,6 +651,7 @@
             mVertical = newVertical;
             //Log.v(TAG, String.format("onSizeChanged: h=%d, w=%d, vert=%s", h, w, mVertical?"y":"n"));
             reorient();
+            getHomeButton().setVertical(mVertical);
             notifyVerticalChangedListener(newVertical);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 021e11a..6f5ad96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -526,6 +526,7 @@
     }
 
     public class IconState extends ViewState {
+        public static final int NO_VALUE = NotificationIconContainer.NO_VALUE;
         public float iconAppearAmount = 1.0f;
         public float clampedAppearAmount = 1.0f;
         public int visibleState;
@@ -538,6 +539,8 @@
         public boolean justUndarkened;
         public int iconColor = StatusBarIconView.NO_COLOR;
         public boolean noAnimations;
+        public boolean isLastExpandIcon;
+        public int customTransformHeight = NO_VALUE;
 
         @Override
         public void applyToView(View view) {
@@ -615,6 +618,10 @@
             justUndarkened = false;
         }
 
+        public boolean hasCustomTransformHeight() {
+            return isLastExpandIcon && customTransformHeight != NO_VALUE;
+        }
+
         @Override
         public void initFrom(View view) {
             super.initFrom(view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
index f45967a..bcbc345 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
@@ -16,10 +16,10 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
-import android.content.res.Configuration;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 
 import java.util.ArrayList;
@@ -48,7 +48,7 @@
 
     @Override
     public void addView(View child) {
-        reversParams(child.getLayoutParams());
+        reverseParams(child.getLayoutParams(), child);
         if (mIsLayoutReverse) {
             super.addView(child, 0);
         } else {
@@ -58,7 +58,7 @@
 
     @Override
     public void addView(View child, ViewGroup.LayoutParams params) {
-        reversParams(params);
+        reverseParams(params, child);
         if (mIsLayoutReverse) {
             super.addView(child, 0, params);
         } else {
@@ -100,7 +100,15 @@
         }
     }
 
-    private void reversParams(ViewGroup.LayoutParams params) {
+    private static void reverseParams(ViewGroup.LayoutParams params, View child) {
+        if (child instanceof Reversable) {
+            ((Reversable) child).reverse();
+        }
+        if (child.getPaddingLeft() == child.getPaddingRight()
+                && child.getPaddingTop() == child.getPaddingBottom()) {
+            child.setPadding(child.getPaddingTop(), child.getPaddingLeft(),
+                    child.getPaddingTop(), child.getPaddingLeft());
+        }
         if (params == null) {
             return;
         }
@@ -109,4 +117,23 @@
         params.height = width;
     }
 
+    public interface Reversable {
+        void reverse();
+    }
+
+    public static class ReverseFrameLayout extends FrameLayout implements Reversable {
+
+        public ReverseFrameLayout(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void reverse() {
+            for (int i = 0; i < getChildCount(); i++) {
+                View child = getChildAt(i);
+                reverseParams(child.getLayoutParams(), child);
+            }
+        }
+    }
+
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 419aefe..754c344 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -61,11 +61,11 @@
     public static final float GRADIENT_SCRIM_ALPHA = 0.45f;
     // A scrim varies its opacity based on a busyness factor, for example
     // how many notifications are currently visible.
-    public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.90f;
+    public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.70f;
     protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = GRADIENT_SCRIM_ALPHA;
     protected static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f;
-    private static final float SCRIM_IN_FRONT_ALPHA = GRADIENT_SCRIM_ALPHA;
-    private static final float SCRIM_IN_FRONT_ALPHA_LOCKED = GRADIENT_SCRIM_ALPHA;
+    private static final float SCRIM_IN_FRONT_ALPHA = GRADIENT_SCRIM_ALPHA_BUSY;
+    private static final float SCRIM_IN_FRONT_ALPHA_LOCKED = GRADIENT_SCRIM_ALPHA_BUSY;
     private static final int TAG_KEY_ANIM = R.id.scrim;
     private static final int TAG_KEY_ANIM_TARGET = R.id.scrim_target;
     private static final int TAG_START_ALPHA = R.id.scrim_alpha_start;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
index deea521..7a7efbd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
@@ -100,12 +100,8 @@
     // How far the circle defining the corners is inset from the edges
     private final float mAppliedCornerInset;
 
-    // The easiest way to understand this is as if we set Style.STROKE and draw the triangle,
-    // but that is only theoretically right. Instead, draw the triangle and clip out a smaller
-    // one inset by this amount.
-    private final float mEmptyStrokeWidth;
     private static final float INV_TAN = 1f / (float) Math.tan(Math.PI / 8f);
-    private final float mEmptyDiagInset;  // == mEmptyStrokeWidth * INV_TAN
+    private static final float CUT_WIDTH_DP = 1f / 12f;
 
     // Where the top and left points of the triangle would be if not for rounding
     private final PointF mVirtualTop  = new PointF();
@@ -145,11 +141,6 @@
                 Utils.getDefaultColor(context, R.color.light_mode_icon_color_dual_tone_fill);
         mIntrinsicSize = context.getResources().getDimensionPixelSize(R.dimen.signal_icon_size);
 
-        // mCutPath parameters
-        mEmptyStrokeWidth = context.getResources()
-                .getDimensionPixelSize(R.dimen.mobile_signal_empty_strokewidth);
-        mEmptyDiagInset = mEmptyStrokeWidth * INV_TAN;
-
         mHandler = new Handler();
         setDarkIntensity(0);
 
@@ -326,22 +317,20 @@
                     (padding + cornerRadius + mAppliedCornerInset) - (INV_TAN * cornerRadius),
                     height - padding);
 
+            final float cutWidth = CUT_WIDTH_DP * height;
+            final float cutDiagInset = cutWidth * INV_TAN;
+
             // Cut out a smaller triangle from the center of mFullPath
             mCutPath.reset();
             mCutPath.setFillType(FillType.WINDING);
-            mCutPath.moveTo(width - padding - mEmptyStrokeWidth,
-                    height - padding - mEmptyStrokeWidth);
-            mCutPath.lineTo(width - padding - mEmptyStrokeWidth,
-                    mVirtualTop.y + mEmptyDiagInset);
-            mCutPath.lineTo(mVirtualLeft.x + mEmptyDiagInset,
-                    height - padding - mEmptyStrokeWidth);
-            mCutPath.lineTo(width - padding - mEmptyStrokeWidth,
-                    height - padding - mEmptyStrokeWidth);
+            mCutPath.moveTo(width - padding - cutWidth, height - padding - cutWidth);
+            mCutPath.lineTo(width - padding - cutWidth, mVirtualTop.y + cutDiagInset);
+            mCutPath.lineTo(mVirtualLeft.x + cutDiagInset, height - padding - cutWidth);
+            mCutPath.lineTo(width - padding - cutWidth, height - padding - cutWidth);
 
-            // In empty state, draw the full path as the foreground paint
-            mForegroundPath.set(mFullPath);
-            mFullPath.reset();
-            mForegroundPath.op(mCutPath, Path.Op.DIFFERENCE);
+            // Draw empty state as only background
+            mForegroundPath.reset();
+            mFullPath.op(mCutPath, Path.Op.DIFFERENCE);
         } else if (mState == STATE_AIRPLANE) {
             // Airplane mode is slashed, full-signal
             mForegroundPath.set(mFullPath);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 14d0b7e..33d92fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -309,7 +309,7 @@
     public static final boolean DEBUG_GESTURES = false;
     public static final boolean DEBUG_MEDIA = false;
     public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
-    public static final boolean DEBUG_CAMERA_LIFT = true; // false once b/62623620 is fixed
+    public static final boolean DEBUG_CAMERA_LIFT = false;
 
     public static final boolean DEBUG_WINDOW_STATE = false;
 
@@ -425,6 +425,7 @@
     private boolean mWakeUpComingFromTouch;
     private PointF mWakeUpTouchLocation;
     private boolean mScreenTurningOn;
+    private boolean mScreenFullyOff;
 
     int mPixelFormat;
     Object mQueueLock = new Object();
@@ -2811,7 +2812,9 @@
     }
 
     public void onScreenTurnedOff() {
+        mScreenFullyOff = true;
         mFalsingManager.onScreenOff();
+        updateIsKeyguard();
     }
 
     public NotificationStackScrollLayout getNotificationScrollLayout() {
@@ -4188,8 +4191,11 @@
 
     private boolean updateIsKeyguard() {
         // For dozing, keyguard needs to be shown whenever the device is non-interactive. Otherwise
-        // there's no surface we can show to the user.
-        boolean keyguardForDozing = mDozingRequested && !mDeviceInteractive;
+        // there's no surface we can show to the user. Note that the device goes fully interactive
+        // late in the transition, so we also allow the device to start dozing once the screen has
+        // turned off fully.
+        boolean keyguardForDozing = mDozingRequested &&
+                (!mDeviceInteractive || mStartedGoingToSleep && (mScreenFullyOff || mIsKeyguard));
         boolean shouldBeKeyguard = mKeyguardRequested || keyguardForDozing;
         if (keyguardForDozing) {
             updatePanelExpansionForKeyguard();
@@ -5130,6 +5136,7 @@
     }
 
     public void onScreenTurningOn() {
+        mScreenFullyOff = false;
         mScreenTurningOn = true;
         mFalsingManager.onScreenTurningOn();
         mNotificationPanel.onScreenTurningOn();
@@ -5297,7 +5304,7 @@
                 mDozingRequested = true;
                 DozeLog.traceDozing(mContext, mDozing);
                 updateDozing();
-
+                updateIsKeyguard();
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 9b0307d..2833ff1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -152,7 +152,7 @@
      * {@link KeyguardBouncer#needsFullscreenBouncer()}.
      */
     protected void showBouncerOrKeyguard(boolean hideBouncerWhenShowing) {
-        if (mBouncer.needsFullscreenBouncer()) {
+        if (mBouncer.needsFullscreenBouncer() && !mDozing) {
 
             // The keyguard might be showing (already). So we need to hide it.
             mStatusBar.hideKeyguard();
@@ -258,8 +258,11 @@
     }
 
     public void setDozing(boolean dozing) {
-        mDozing = dozing;
-        updateStates();
+        if (mDozing != dozing) {
+            mDozing = dozing;
+            reset(dozing /* hideBouncerWhenShowing */);
+            updateStates();
+        }
     }
 
     public void onScreenTurnedOff() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index 93dc6de..6104bef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -138,7 +138,7 @@
     }
 
     private void adjustScreenOrientation(State state) {
-        if (state.isKeyguardShowingAndNotOccluded()) {
+        if (state.isKeyguardShowingAndNotOccluded() || state.dozing) {
             if (mKeyguardScreenRotation) {
                 mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index d777961..2d3e0b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -226,6 +226,9 @@
             case MotionEvent.ACTION_UP:
                 final boolean doIt = isPressed() && !mLongClicked;
                 setPressed(false);
+                // Always send a release ourselves because it doesn't seem to be sent elsewhere
+                // and it feels weird to sometimes get a release haptic and other times not.
+                performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);
                 if (mCode != 0) {
                     if (doIt) {
                         sendEvent(KeyEvent.ACTION_UP, 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index bd7fee0..b6c7655 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -341,6 +341,10 @@
     }
 
     private boolean isRoaming() {
+        // During a carrier change, roaming indications need to be supressed.
+        if (isCarrierNetworkChangeActive()) {
+            return false;
+        }
         if (isCdma()) {
             final int iconMode = mServiceState.getCdmaEriIconMode();
             return mServiceState.getCdmaEriIconIndex() != EriInfo.ROAMING_INDICATOR_OFF
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
index b7b991e..ba1e7c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
@@ -62,6 +62,7 @@
     private boolean mHasPulsingNotifications;
     private boolean mUnlockHintRunning;
     private boolean mQsCustomizerShowing;
+    private int mIntrinsicPadding;
 
     public AmbientState(Context context) {
         reload(context);
@@ -323,4 +324,12 @@
     public void setQsCustomizerShowing(boolean qsCustomizerShowing) {
         mQsCustomizerShowing = qsCustomizerShowing;
     }
+
+    public void setIntrinsicPadding(int intrinsicPadding) {
+        mIntrinsicPadding = intrinsicPadding;
+    }
+
+    public int getIntrinsicPadding() {
+        return mIntrinsicPadding;
+    }
 }
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 cbd315b..41cde9c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -2735,7 +2735,7 @@
         return view.getHeight();
     }
 
-    private int getPositionInLinearLayout(View requestedView) {
+    public int getPositionInLinearLayout(View requestedView) {
         ExpandableNotificationRow childInGroup = null;
         ExpandableNotificationRow requestedRow = null;
         if (isChildInGroup(requestedView)) {
@@ -3650,6 +3650,7 @@
 
     public void setIntrinsicPadding(int intrinsicPadding) {
         mIntrinsicPadding = intrinsicPadding;
+        mAmbientState.setIntrinsicPadding(intrinsicPadding);
     }
 
     public int getIntrinsicPadding() {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 5d51a33..eaad2f9 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -43,6 +43,7 @@
 import android.service.notification.Condition;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.view.accessibility.AccessibilityManager;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.systemui.Dumpable;
@@ -122,6 +123,12 @@
         mReceiver.init();
         mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
         mHasVibrator = mVibrator != null && mVibrator.hasVibrator();
+
+        boolean accessibilityVolumeStreamActive = context.getSystemService(
+                AccessibilityManager.class).isAccessibilityVolumeStreamActive();
+        mVolumeController.setA11yMode(accessibilityVolumeStreamActive ?
+                    VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME :
+                        VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME);
     }
 
     public AudioManager getAudioManager() {
@@ -210,6 +217,7 @@
 
     public void addCallback(Callbacks callback, Handler handler) {
         mCallbacks.add(callback, handler);
+        callback.onAccessibilityModeChanged(mShowA11yStream);
     }
 
     public void setUserActivityListener(UserActivityListener listener) {
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index b12fd1c..9bb2180 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -48,7 +48,7 @@
             android:process=":killable" />
     </application>
 
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+    <instrumentation android:name="android.testing.TestableInstrumentation"
         android:targetPackage="com.android.systemui.tests"
         android:label="Tests for SystemUI">
     </instrumentation>
diff --git a/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java b/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java
index 945af34..2a44771 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java
@@ -21,7 +21,6 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
@@ -30,7 +29,6 @@
 import static org.mockito.Mockito.when;
 
 import android.app.Fragment;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.view.Display;
@@ -48,12 +46,10 @@
 import com.android.systemui.tuner.TunerService;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidTestingRunner.class)
-@FlakyTest
 @SmallTest
 public class RoundedCornersTest extends SysuiTestCase {
 
@@ -72,6 +68,7 @@
         mWindowManager = mock(WindowManager.class);
         mView = spy(new StatusBarWindowView(mContext, null));
         when(mStatusBar.getStatusBarWindow()).thenReturn(mView);
+        when(mStatusBar.getNavigationBarWindow()).thenReturn(mView);
         mContext.putComponent(StatusBar.class, mStatusBar);
 
         Display display = mContext.getSystemService(WindowManager.class).getDefaultDisplay();
@@ -94,6 +91,8 @@
     @Test
     public void testNoRounding() {
         mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 0);
+        mContext.getOrCreateTestableResources()
+                .addOverride(dimen.rounded_corner_content_padding, 0);
 
         mRoundedCorners.start();
         // No views added.
@@ -107,13 +106,15 @@
     @Test
     public void testRounding() {
         mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 20);
+        mContext.getOrCreateTestableResources()
+                .addOverride(dimen.rounded_corner_content_padding, 20);
 
         mRoundedCorners.start();
         // Add 2 windows for rounded corners (top and bottom).
         verify(mWindowManager, times(2)).addView(any(), any());
 
-        // Add 3 tag listeners for each of the fragments that are needed.
-        verify(mFragmentHostManager, times(3)).addTagListener(any(), any());
+        // Add 2 tag listeners for each of the fragments that are needed.
+        verify(mFragmentHostManager, times(2)).addTagListener(any(), any());
         // One tunable.
         verify(mTunerService, times(1)).addTunable(any(), any());
         // One TunablePadding.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index 361a20f..66d00dd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -31,6 +31,8 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -56,10 +58,14 @@
 
         mRealInstrumentation = InstrumentationRegistry.getInstrumentation();
         Instrumentation inst = spy(mRealInstrumentation);
-        when(inst.getContext()).thenThrow(new RuntimeException(
-                "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"));
-        when(inst.getTargetContext()).thenThrow(new RuntimeException(
-                "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"));
+        when(inst.getContext()).thenAnswer(invocation -> {
+            throw new RuntimeException(
+                    "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext");
+        });
+        when(inst.getTargetContext()).thenAnswer(invocation -> {
+            throw new RuntimeException(
+                    "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext");
+        });
         InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments());
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index 2363b2a..8641fac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -27,7 +27,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
index b8e9fcd..bba982c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
@@ -26,8 +26,6 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.net.Uri;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -36,11 +34,10 @@
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.systemui.Dependency;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
 import com.android.systemui.plugins.PluginInstanceManager.PluginInfo;
+import com.android.systemui.plugins.annotations.ProvidesInterface;
 import com.android.systemui.plugins.PluginManagerImpl.PluginInstanceManagerFactory;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
index 6a85511..ed47fbb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
@@ -23,10 +23,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import org.junit.After;
-import org.junit.Ignore;
 import android.support.test.filters.SmallTest;
-import android.support.test.filters.FlakyTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
@@ -41,6 +38,7 @@
 import com.android.systemui.plugins.qs.DetailAdapter;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
index f4fda06..d25bbe1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
@@ -21,7 +21,6 @@
 import static org.mockito.Mockito.when;
 
 import android.support.test.filters.SmallTest;
-import android.support.test.filters.FlakyTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
index 637b244..85cdfcc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
@@ -20,7 +20,6 @@
 import static org.mockito.Mockito.when;
 
 import android.support.test.filters.SmallTest;
-import android.support.test.filters.FlakyTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
@@ -31,7 +30,6 @@
 import com.android.systemui.qs.customize.QSCustomizer;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -40,7 +38,6 @@
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 @SmallTest
-@FlakyTest
 public class QSPanelTest extends SysuiTestCase {
 
     private MetricsLogger mMetricsLogger;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
index 664ea71..2f6511c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
@@ -21,27 +21,21 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.View;
 
+import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
 import com.android.systemui.statusbar.stack.NotificationChildrenContainer;
-import com.android.systemui.SysuiTestCase;
 
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@FlakyTest
 public class ExpandableNotificationRowTest extends SysuiTestCase {
 
     private ExpandableNotificationRow mGroup;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
index 4dce2f5..436849c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
@@ -16,30 +16,25 @@
 
 package com.android.systemui.statusbar;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.view.View;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.View;
+
 import com.android.systemui.SysuiTestCase;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@FlakyTest
 public class NotificationContentViewTest extends SysuiTestCase {
 
     NotificationContentView mView;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
index d18e63b..6e59d10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
@@ -16,10 +16,7 @@
 
 package com.android.systemui.statusbar;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.View;
@@ -32,13 +29,11 @@
 
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@FlakyTest
 public class NotificationCustomViewWrapperTest extends SysuiTestCase {
 
     private ExpandableNotificationRow mRow;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
index 630da2e..2a2acab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
@@ -57,4 +57,10 @@
         row.createMenu(null, null);
         assertTrue(row.getMenuView() != null);
     }
+
+    @Test
+    public void testResetUncreatedMenu() {
+        NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
+        row.resetMenu();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index be3802b..cba9f77 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
@@ -494,6 +494,79 @@
               DEFAULT_ICON /* typeIcon */);
     }
 
+    @Test
+    public void testCarrierNetworkChange_roamingBeforeNetworkChange() {
+      int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
+
+      setupDefaultSignal();
+      setLevel(strength);
+      setGsmRoaming(true);
+
+      // Verify baseline
+      verifyLastMobileDataIndicators(true /* visible */,
+              strength /* strengthIcon */,
+              DEFAULT_ICON /* typeIcon */,
+              true /* roaming */);
+
+      // API call is made
+      setCarrierNetworkChange(true /* enabled */);
+
+      // Carrier network change is true, show special indicator, no roaming.
+      verifyLastMobileDataIndicators(true /* visible */,
+              SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+              0 /* typeIcon */,
+              false /* roaming */);
+
+      // Revert back
+      setCarrierNetworkChange(false /* enabled */);
+
+      // Verify back in previous state
+      verifyLastMobileDataIndicators(true /* visible */,
+              strength /* strengthIcon */,
+              DEFAULT_ICON /* typeIcon */,
+              true /* roaming */);
+    }
+
+    @Test
+    public void testCarrierNetworkChange_roamingAfterNetworkChange() {
+      int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
+
+      setupDefaultSignal();
+      setLevel(strength);
+
+      // Verify baseline
+      verifyLastMobileDataIndicators(true /* visible */,
+              strength /* strengthIcon */,
+              DEFAULT_ICON /* typeIcon */,
+              false /* roaming */);
+
+      // API call is made
+      setCarrierNetworkChange(true /* enabled */);
+
+      // Carrier network change is true, show special indicator, no roaming.
+      verifyLastMobileDataIndicators(true /* visible */,
+              SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+              0 /* typeIcon */,
+              false /* roaming */);
+
+      setGsmRoaming(true);
+
+      // Roaming should not show.
+      verifyLastMobileDataIndicators(true /* visible */,
+              SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+              0 /* typeIcon */,
+              false /* roaming */);
+
+      // Revert back
+      setCarrierNetworkChange(false /* enabled */);
+
+      // Verify back in previous state
+      verifyLastMobileDataIndicators(true /* visible */,
+              strength /* strengthIcon */,
+              DEFAULT_ICON /* typeIcon */,
+              true /* roaming */);
+    }
+
     private void verifyEmergencyOnly(boolean isEmergencyOnly) {
         ArgumentCaptor<Boolean> emergencyOnly = ArgumentCaptor.forClass(Boolean.class);
         Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setEmergencyCallsOnly(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
index bc6833d..5ac965c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
@@ -16,10 +16,6 @@
 
 package com.android.systemui.statusbar.stack;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.NotificationHeaderView;
@@ -31,13 +27,11 @@
 
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@FlakyTest
 public class NotificationChildrenContainerTest extends SysuiTestCase {
 
     private ExpandableNotificationRow mGroup;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java
index 0a83a89..d1b1c5b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java
@@ -14,7 +14,6 @@
 
 package com.android.systemui.utils.leaks;
 
-import android.content.Context;
 import android.testing.LeakCheck;
 
 import com.android.systemui.plugins.Plugin;
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 2edcd71..9aa58f5 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -4153,11 +4153,44 @@
     // OS: O DR
     FIELD_PLUG_BATTERY_PERCENTAGE = 1024;
 
+    // Device Headset battery level on Plug
+    // CATEGORY: OTHER
+    // FIELD - The battery percentage when the user decided to plug in
+    // Type: integer
+    // OS: O DR
+    FIELD_UNPLUG_BATTERY_PERCENTAGE = 1025;
+
     // Device Headset Pose status
     // CATEGORY: OTHER
     //  SUBTYPE: 1 is 6DOF, 2 is 3DOF
     // OS: O DR
-    ACTION_HEADSET_POSE_STATUS = 1025;
+    ACTION_HEADSET_POSE_STATUS = 1026;
+
+    // Device Headset Usage session time
+    // CATEGORY: OTHER
+    // FIELD - The time the headset was used in a session
+    // OS: O DR
+    FIELD_SESSION_TIME_MS = 1027;
+
+    // Device Headset Idle time
+    // CATEGORY: OTHER
+    // FIELD - The time in between each session
+    // OS: O DR
+    FIELD_TIME_ELAPSED_BETWEEN_SESSION_MS = 1028;
+
+    // Device Headset charge session time
+    // CATEGORY: OTHER
+    // FIELD - The time taken for each charge
+    // OS: O DR
+    FIELD_TIME_OF_CHARGE_MS = 1029;
+
+    // Device Headset time between charge
+    // CATEGORY: OTHER
+    // FIELD - The time in between each charge
+    // OS: O DR
+    FIELD_TIME_ELAPSED_BETWEEN_CHARGE_MS = 1030;
+
+    // ---- End O-DR1 Constants, all O-DR1 constants go above this line ----
 
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 9e4d89c..0e42e6d 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -271,6 +271,7 @@
 
     private void processKeyEvent(EventStreamState state, KeyEvent event, int policyFlags) {
         if (!state.shouldProcessKeyEvent(event)) {
+            super.onInputEvent(event, policyFlags);
             return;
         }
         mEventHandler.onKeyEvent(event, policyFlags);
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index f1f8757..e3da4eb 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -5688,13 +5688,15 @@
                 PerformFullTransportBackupTask pftbt = null;
                 synchronized (mQueueLock) {
                     if (mRunningFullBackupTask != null) {
-                        if (DEBUG_SCHEDULING) {
-                            Slog.i(TAG, "Telling running backup to stop");
-                        }
                         pftbt = mRunningFullBackupTask;
                     }
                 }
-                pftbt.handleCancel(true);
+                if (pftbt != null) {
+                    if (DEBUG_SCHEDULING) {
+                        Slog.i(TAG, "Telling running backup to stop");
+                    }
+                    pftbt.handleCancel(true);
+                }
             }
         };
         new Thread(endFullBackupRunnable, "end-full-backup").start();
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 4810f4f..f47b0d3 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -383,7 +383,7 @@
                                     findDeviceCallback,
                                     getServiceCallback());
                 } catch (RemoteException e) {
-                    throw new RuntimeException(e);
+                    Log.e(LOG_TAG, "Error while initiating device discovery", e);
                 }
             }
 
diff --git a/services/core/java/com/android/server/ContextHubSystemService.java b/services/core/java/com/android/server/ContextHubSystemService.java
index 5d4317c..110847d 100644
--- a/services/core/java/com/android/server/ContextHubSystemService.java
+++ b/services/core/java/com/android/server/ContextHubSystemService.java
@@ -16,17 +16,25 @@
 
 package com.android.server;
 
+import com.android.internal.util.ConcurrentUtils;
 import com.android.server.location.ContextHubService;
+import com.android.server.SystemServerInitThreadPool;
 import android.content.Context;
 import android.util.Log;
 
+import java.util.concurrent.Future;
+
 class ContextHubSystemService extends SystemService {
     private static final String TAG = "ContextHubSystemService";
-    private final ContextHubService mContextHubService;
+    private ContextHubService mContextHubService;
+
+    private Future<?> mInit;
 
     public ContextHubSystemService(Context context) {
         super(context);
-        mContextHubService = new ContextHubService(context);
+        mInit = SystemServerInitThreadPool.get().submit(() -> {
+            mContextHubService = new ContextHubService(context);
+        }, "Init ContextHubSystemService");
     }
 
     @Override
@@ -37,6 +45,9 @@
     public void onBootPhase(int phase) {
         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
             Log.d(TAG, "onBootPhase: PHASE_SYSTEM_SERVICES_READY");
+            ConcurrentUtils.waitForFutureNoInterrupt(mInit,
+                    "Wait for ContextHubSystemService init");
+            mInit = null;
             publishBinderService(Context.CONTEXTHUB_SERVICE, mContextHubService);
         }
     }
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index 4c9495a..a903f3d 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -57,7 +57,7 @@
  */
 public class GestureLauncherService extends SystemService {
     private static final boolean DBG = false;
-    private static final boolean DBG_CAMERA_LIFT = true; // false once b/62623620 is fixed
+    private static final boolean DBG_CAMERA_LIFT = false;
     private static final String TAG = "GestureLauncherService";
 
     /**
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index fd4f672..f106ca0 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -20,6 +20,7 @@
 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
 import static android.Manifest.permission.READ_FRAME_BUFFER;
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
@@ -10297,7 +10298,7 @@
 
     @Override
     public void moveStackToDisplay(int stackId, int displayId) {
-        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
+        enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
 
         synchronized (this) {
             final long ident = Binder.clearCallingIdentity();
@@ -12573,7 +12574,6 @@
                 Binder.restoreCallingIdentity(ident);
             }
         }
-        closeSystemDialogs("setLockScreenShown");
     }
 
     @Override
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 1ccac1b..e0f2a75 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
 import static android.Manifest.permission.START_ANY_ACTIVITY;
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
@@ -38,11 +39,13 @@
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.Process.SYSTEM_UID;
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.FLAG_PRIVATE;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
+import static android.view.Display.TYPE_VIRTUAL;
 
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
@@ -1694,6 +1697,24 @@
             return false;
         }
 
+        // Check if the caller can manage activity stacks.
+        final int startAnyPerm = mService.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid,
+                callingUid);
+        if (startAnyPerm == PERMISSION_GRANTED) {
+            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
+                    + " allow launch any on display");
+            return true;
+        }
+
+        if (activityDisplay.mDisplay.getType() == TYPE_VIRTUAL
+                && activityDisplay.mDisplay.getOwnerUid() != SYSTEM_UID) {
+            // Limit launching on virtual displays, because their contents can be read from Surface
+            // by apps that created them.
+            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
+                    + " disallow launch on virtual display for not-embedded activity");
+            return false;
+        }
+
         if (!activityDisplay.isPrivate()) {
             // Anyone can launch on a public display.
             if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
@@ -1715,15 +1736,6 @@
             return true;
         }
 
-        // Check if the caller can manage activity stacks.
-        final int startAnyPerm = mService.checkPermission(MANAGE_ACTIVITY_STACKS, callingPid,
-                callingUid);
-        if (startAnyPerm == PERMISSION_GRANTED) {
-            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
-                    + " allow launch any on display");
-            return true;
-        }
-
         Slog.w(TAG, "Launch on display check: denied");
         return false;
     }
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index a145435..a31c33e 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import static android.app.Activity.RESULT_CANCELED;
+import static android.app.ActivityManager.START_ABORTED;
 import static android.app.ActivityManager.START_CANCELED;
 import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
@@ -279,7 +280,9 @@
             // mLastStartActivityRecord[0] is set in the call to startActivity above.
             outActivity[0] = mLastStartActivityRecord[0];
         }
-        return mLastStartActivityResult;
+
+        // Aborted results are treated as successes externally, but we must track them internally.
+        return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
     }
 
     /** DO NOT call this method directly. Use {@link #startActivityLocked} instead. */
@@ -465,7 +468,7 @@
             // We pretend to the caller that it was really started, but
             // they will just get a cancel result.
             ActivityOptions.abort(options);
-            return START_SUCCESS;
+            return START_ABORTED;
         }
 
         // If permissions need a review before any of the app components can run, we
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index 2e0ec0b..a46c851 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
 import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
 import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
@@ -34,6 +35,7 @@
 
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.Trace;
 import android.util.Slog;
 
 import com.android.internal.policy.IKeyguardDismissCallback;
@@ -111,22 +113,28 @@
      *              etc.
      */
     void keyguardGoingAway(int flags) {
-        if (mKeyguardShowing) {
-            mWindowManager.deferSurfaceLayout();
-            try {
-                setKeyguardGoingAway(true);
-                mWindowManager.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
-                        false /* alwaysKeepCurrent */, convertTransitFlags(flags),
-                        false /* forceOverride */);
-                mService.updateSleepIfNeededLocked();
+        if (!mKeyguardShowing) {
+            return;
+        }
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "keyguardGoingAway");
+        mWindowManager.deferSurfaceLayout();
+        try {
+            setKeyguardGoingAway(true);
+            mWindowManager.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
+                    false /* alwaysKeepCurrent */, convertTransitFlags(flags),
+                    false /* forceOverride */);
+            mService.updateSleepIfNeededLocked();
 
-                // Some stack visibility might change (e.g. docked stack)
-                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
-                mStackSupervisor.addStartingWindowsForVisibleActivities(true /* taskSwitch */);
-                mWindowManager.executeAppTransition();
-            } finally {
-                mWindowManager.continueSurfaceLayout();
-            }
+            // Some stack visibility might change (e.g. docked stack)
+            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+            mStackSupervisor.addStartingWindowsForVisibleActivities(true /* taskSwitch */);
+            mWindowManager.executeAppTransition();
+        } finally {
+            Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "keyguardGoingAway: surfaceLayout");
+            mWindowManager.continueSurfaceLayout();
+            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+
+            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
         }
     }
 
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index e5ab784..2199bba 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -239,6 +239,7 @@
     private static final int MSG_SET_A2DP_SRC_CONNECTION_STATE = 101;
     private static final int MSG_SET_A2DP_SINK_CONNECTION_STATE = 102;
     private static final int MSG_A2DP_DEVICE_CONFIG_CHANGE = 103;
+    private static final int MSG_DISABLE_AUDIO_FOR_UID = 104;
     // end of messages handled under wakelock
 
     private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000;
@@ -4871,6 +4872,12 @@
                     mAudioEventWakeLock.release();
                     break;
 
+                case MSG_DISABLE_AUDIO_FOR_UID:
+                    mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */,
+                            msg.arg2 /* uid */);
+                    mAudioEventWakeLock.release();
+                    break;
+
                 case MSG_REPORT_NEW_ROUTES: {
                     int N = mRoutesObservers.beginBroadcast();
                     if (N > 0) {
@@ -6591,6 +6598,13 @@
                 }
             }
         }
+
+        @Override
+        public void disableAudioForUid(boolean disable, int uid) {
+            queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID,
+                    disable ? 1 : 0 /* arg1 */,  uid /* arg2 */,
+                    null /* obj */,  0 /* delay */);
+        }
     }
 
     //==========================================================================================
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 702cbbe..663559f 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -29,6 +29,8 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import com.android.internal.util.ArrayUtils;
+
 import java.io.PrintWriter;
 import java.text.DateFormat;
 import java.util.ArrayList;
@@ -67,6 +69,12 @@
                     .createIfNeeded()
                     .build();
 
+    // TODO support VolumeShaper on those players
+    private static final int[] UNDUCKABLE_PLAYER_TYPES = {
+            AudioPlaybackConfiguration.PLAYER_TYPE_AAUDIO,
+            AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL,
+    };
+
     // like a PLAY_CREATE_IF_NEEDED operation but with a skip to the end of the ramp
     private static final VolumeShaper.Operation PLAY_SKIP_RAMP =
             new VolumeShaper.Operation.Builder(PLAY_CREATE_IF_NEEDED).setXOffset(1.0f).build();
@@ -87,6 +95,43 @@
     }
 
     //=================================================================
+    private final ArrayList<Integer> mBannedUids = new ArrayList<Integer>();
+
+    // see AudioManagerInternal.disableAudioForUid(boolean disable, int uid)
+    public void disableAudioForUid(boolean disable, int uid) {
+        synchronized(mPlayerLock) {
+            final int index = mBannedUids.indexOf(new Integer(uid));
+            if (index >= 0) {
+                if (!disable) {
+                    mBannedUids.remove(index);
+                    // nothing else to do, future playback requests from this uid are ok
+                } // no else to handle, uid already present, so disabling again is no-op
+            } else {
+                if (disable) {
+                    for (AudioPlaybackConfiguration apc : mPlayers.values()) {
+                        checkBanPlayer(apc, uid);
+                    }
+                    mBannedUids.add(new Integer(uid));
+                } // no else to handle, uid already not in list, so enabling again is no-op
+            }
+        }
+    }
+
+    private boolean checkBanPlayer(@NonNull AudioPlaybackConfiguration apc, int uid) {
+        final boolean toBan = (apc.getClientUid() == uid);
+        if (toBan) {
+            final int piid = apc.getPlayerInterfaceId();
+            try {
+                Log.v(TAG, "banning player " + piid + " uid:" + uid);
+                apc.getPlayerProxy().pause();
+            } catch (Exception e) {
+                Log.e(TAG, "error banning player " + piid + " uid:" + uid, e);
+            }
+        }
+        return toBan;
+    }
+
+    //=================================================================
     // Track players and their states
     // methods playerAttributes, playerEvent, releasePlayer are all oneway calls
     //  into AudioService. They trigger synchronous dispatchPlaybackChange() which updates
@@ -129,6 +174,14 @@
             if (apc == null) {
                 return;
             }
+            if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
+                for (Integer uidInteger: mBannedUids) {
+                    if (checkBanPlayer(apc, uidInteger.intValue())) {
+                        // player was banned, do not update its state
+                        return;
+                    }
+                }
+            }
             if (apc.getPlayerType() == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
                 // FIXME SoundPool not ready for state reporting
                 return;
@@ -178,10 +231,17 @@
             pw.println("\n  ducked players:");
             mDuckingManager.dump(pw);
             // players muted due to the device ringing or being in a call
-            pw.println("\n  muted player piids:");
+            pw.print("\n  muted player piids:");
             for (int piid : mMutedPlayers) {
-                pw.println(" " + piid);
+                pw.print(" " + piid);
             }
+            pw.println();
+            // banned players:
+            pw.print("\n  banned uids:");
+            for (int uid : mBannedUids) {
+                pw.print(" " + uid);
+            }
+            pw.println();
         }
     }
 
@@ -298,12 +358,12 @@
                                 + " uid:" + apc.getClientUid() + " pid:" + apc.getClientPid()
                                 + " - SPEECH");
                         return false;
-                    } else if (apc.getPlayerType()
-                            == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
-                        // TODO support ducking of SoundPool players
+                    } else if (ArrayUtils.contains(UNDUCKABLE_PLAYER_TYPES, apc.getPlayerType())) {
                         Log.v(TAG, "not ducking player " + apc.getPlayerInterfaceId()
                                 + " uid:" + apc.getClientUid() + " pid:" + apc.getClientPid()
-                                + " - SoundPool");
+                                + " due to type:"
+                                + AudioPlaybackConfiguration.toLogFriendlyPlayerType(
+                                        apc.getPlayerType()));
                         return false;
                     }
                     apcsToDuck.add(apc);
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 13054a6..ad74ff8 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -60,6 +60,7 @@
 import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
@@ -101,6 +102,22 @@
             }
         }
 
+
+        @Override
+        public void onStartUser(int userHandle) {
+            mService.onStartUser(userHandle);
+        }
+
+        @Override
+        public void onUnlockUser(int userHandle) {
+            mService.onUnlockUser(userHandle);
+        }
+
+        @Override
+        public void onStopUser(int userHandle) {
+            mService.onStopUser(userHandle);
+        }
+
         @Override
         public void onCleanupUser(int userHandle) {
             synchronized (mService.mCache) {
@@ -161,11 +178,25 @@
         }
     }
 
+    void onStartUser(int userHandle) {
+        if (mSyncManager != null) mSyncManager.onStartUser(userHandle);
+    }
+
+    void onUnlockUser(int userHandle) {
+        if (mSyncManager != null) mSyncManager.onUnlockUser(userHandle);
+    }
+
+    void onStopUser(int userHandle) {
+        if (mSyncManager != null) mSyncManager.onStopUser(userHandle);
+    }
+
     @Override
     protected synchronized void dump(FileDescriptor fd, PrintWriter pw_, String[] args) {
         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw_)) return;
         final IndentingPrintWriter pw = new IndentingPrintWriter(pw_, "  ");
 
+        final boolean dumpAll = ArrayUtils.contains(args, "-a");
+
         // This makes it so that future permission checks will be in the context of this
         // process rather than the caller's process. We will restore this before returning.
         final long identityToken = clearCallingIdentity();
@@ -173,7 +204,7 @@
             if (mSyncManager == null) {
                 pw.println("No SyncManager created!  (Disk full?)");
             } else {
-                mSyncManager.dump(fd, pw);
+                mSyncManager.dump(fd, pw, dumpAll);
             }
             pw.println();
             pw.println("Observer tree:");
@@ -603,7 +634,7 @@
                 SyncStorageEngine.EndPoint info;
                 info = new SyncStorageEngine.EndPoint(account, authority, userId);
                 syncManager.clearScheduledSyncOperations(info);
-                syncManager.cancelActiveSync(info, null /* all syncs for this adapter */);
+                syncManager.cancelActiveSync(info, null /* all syncs for this adapter */, "API");
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -631,7 +662,7 @@
             }
             // Cancel active syncs and clear pending syncs from the queue.
             syncManager.cancelScheduledSyncOperation(info, extras);
-            syncManager.cancelActiveSync(info, extras);
+            syncManager.cancelActiveSync(info, extras, "API");
         } finally {
             restoreCallingIdentity(identityToken);
         }
diff --git a/services/core/java/com/android/server/content/SyncJobService.java b/services/core/java/com/android/server/content/SyncJobService.java
index a621d73..1f02ebf 100644
--- a/services/core/java/com/android/server/content/SyncJobService.java
+++ b/services/core/java/com/android/server/content/SyncJobService.java
@@ -34,6 +34,8 @@
     private Messenger mMessenger;
     private SparseArray<JobParameters> jobParamsMap = new SparseArray<JobParameters>();
 
+    private final SyncLogger mLogger = SyncLogger.getInstance();
+
     /**
      * This service is started by the SyncManager which passes a messenger object to
      * communicate back with it. It never stops while the device is running.
@@ -63,6 +65,9 @@
 
     @Override
     public boolean onStartJob(JobParameters params) {
+
+        mLogger.purgeOldLogs();
+
         boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
         synchronized (jobParamsMap) {
             jobParamsMap.put(params.getJobId(), params);
@@ -70,6 +75,9 @@
         Message m = Message.obtain();
         m.what = SyncManager.SyncHandler.MESSAGE_START_SYNC;
         SyncOperation op = SyncOperation.maybeCreateFromJobExtras(params.getExtras());
+
+        mLogger.log("onStopJob() jobid=", params.getJobId(), " op=", op);
+
         if (op == null) {
             Slog.e(TAG, "Got invalid job " + params.getJobId());
             return false;
@@ -88,7 +96,7 @@
             Slog.v(TAG, "onStopJob called " + params.getJobId() + ", reason: "
                     + params.getStopReason());
         }
-
+        mLogger.log("onStopJob() ", mLogger.jobParametersToString(params));
         synchronized (jobParamsMap) {
             jobParamsMap.remove(params.getJobId());
         }
@@ -108,9 +116,13 @@
         return false;
     }
 
-    public void callJobFinished(int jobId, boolean needsReschedule) {
+    public void callJobFinished(int jobId, boolean needsReschedule, String why) {
         synchronized (jobParamsMap) {
             JobParameters params = jobParamsMap.get(jobId);
+            mLogger.log("callJobFinished()",
+                    " needsReschedule=", needsReschedule,
+                    " ", mLogger.jobParametersToString(params),
+                    " why=", why);
             if (params != null) {
                 jobFinished(params, needsReschedule);
                 jobParamsMap.remove(jobId);
diff --git a/services/core/java/com/android/server/content/SyncLogger.java b/services/core/java/com/android/server/content/SyncLogger.java
new file mode 100644
index 0000000..db79464
--- /dev/null
+++ b/services/core/java/com/android/server/content/SyncLogger.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.content;
+
+import android.app.job.JobParameters;
+import android.os.Build;
+import android.os.Environment;
+import android.os.FileUtils;
+import android.os.SystemProperties;
+import android.text.format.DateUtils;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+
+import libcore.io.IoUtils;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Implements a rotating file logger for the sync manager, which is enabled only on userdebug/eng
+ * builds (unless debug.synclog is set to 1).
+ *
+ * Note this class could be used for other purposes too, but in general we don't want various
+ * system components to log to files, so it's put in a local package here.
+ */
+public class SyncLogger {
+    private static final String TAG = "SyncLogger";
+
+    private static SyncLogger sInstance;
+
+    SyncLogger() {
+    }
+
+    /**
+     * @return the singleton instance.
+     */
+    public static synchronized SyncLogger getInstance() {
+        if (sInstance == null) {
+            final boolean enable = "1".equals(SystemProperties.get("debug.synclog",
+                    Build.IS_DEBUGGABLE ? "1" : "0"));
+            if (enable) {
+                sInstance = new RotatingFileLogger();
+            } else {
+                sInstance = new SyncLogger();
+            }
+        }
+        return sInstance;
+    }
+
+    /**
+     * Write strings to the log file.
+     */
+    public void log(Object... message) {
+    }
+
+    /**
+     * Remove old log files.
+     */
+    public void purgeOldLogs() {
+        // The default implementation is no-op.
+    }
+
+    public String jobParametersToString(JobParameters params) {
+        // The default implementation is no-op.
+        return "";
+    }
+
+    /**
+     * Dump all existing log files into a given writer.
+     */
+    public void dumpAll(PrintWriter pw) {
+    }
+
+    /**
+     * Actual implementation which is only used on userdebug/eng builds (by default).
+     */
+    private static class RotatingFileLogger extends SyncLogger {
+        private final Object mLock = new Object();
+
+        private final long mKeepAgeMs = TimeUnit.DAYS.toMillis(7);
+
+        private static final SimpleDateFormat sTimestampFormat
+                = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+        private static final SimpleDateFormat sFilenameDateFormat
+                = new SimpleDateFormat("yyyy-MM-dd");
+
+        @GuardedBy("mLock")
+        private final Date mCachedDate = new Date();
+
+        @GuardedBy("mLock")
+        private final StringBuilder mStringBuilder = new StringBuilder();
+
+        private final File mLogPath;
+
+        @GuardedBy("mLock")
+        private long mCurrentLogFileDayTimestamp;
+
+        @GuardedBy("mLock")
+        private Writer mLogWriter;
+
+        @GuardedBy("mLock")
+        private boolean mErrorShown;
+
+        RotatingFileLogger() {
+            mLogPath = new File(Environment.getDataSystemDirectory(), "syncmanager-log");
+        }
+
+        private void handleException(String message, Exception e) {
+            if (!mErrorShown) {
+                Slog.e(TAG, message, e);
+                mErrorShown = true;
+            }
+        }
+
+        @Override
+        public void log(Object... message) {
+            if (message == null) {
+                return;
+            }
+            synchronized (mLock) {
+                final long now = System.currentTimeMillis();
+                openLogLocked(now);
+                if (mLogWriter == null) {
+                    return; // Couldn't open log file?
+                }
+
+                mStringBuilder.setLength(0);
+                mCachedDate.setTime(now);
+                mStringBuilder.append(sTimestampFormat.format(mCachedDate));
+                mStringBuilder.append(' ');
+
+                mStringBuilder.append(android.os.Process.myTid());
+                mStringBuilder.append(' ');
+
+                for (Object o : message) {
+                    mStringBuilder.append(o);
+                }
+                mStringBuilder.append('\n');
+
+                try {
+                    mLogWriter.append(mStringBuilder);
+                    mLogWriter.flush();
+                } catch (IOException e) {
+                    handleException("Failed to write log", e);
+                }
+            }
+        }
+
+        private void openLogLocked(long now) {
+            // If we already have a log file opened and the date has't changed, just use it.
+            final long day = now % DateUtils.DAY_IN_MILLIS;
+            if ((mLogWriter != null) && (day == mCurrentLogFileDayTimestamp)) {
+                return;
+            }
+
+            // Otherwise create a new log file.
+            closeCurrentLogLocked();
+
+            mCurrentLogFileDayTimestamp = day;
+
+            mCachedDate.setTime(now);
+            final String filename = "synclog-" + sFilenameDateFormat.format(mCachedDate) + ".log";
+            final File file = new File(mLogPath, filename);
+
+            file.getParentFile().mkdirs();
+
+            try {
+                mLogWriter = new FileWriter(file, /* append= */ true);
+            } catch (IOException e) {
+                handleException("Failed to open log file: " + file, e);
+            }
+        }
+
+        private void closeCurrentLogLocked() {
+            IoUtils.closeQuietly(mLogWriter);
+            mLogWriter = null;
+        }
+
+        @Override
+        public void purgeOldLogs() {
+            synchronized (mLock) {
+                FileUtils.deleteOlderFiles(mLogPath, /* keepCount= */ 1, mKeepAgeMs);
+            }
+        }
+
+        @Override
+        public String jobParametersToString(JobParameters params) {
+            if (params == null) {
+                return "job:null";
+            } else {
+                return "job:#" + params.getJobId() + ":"
+                        + SyncOperation.maybeCreateFromJobExtras(params.getExtras());
+            }
+        }
+
+        @Override
+        public void dumpAll(PrintWriter pw) {
+            synchronized (mLock) {
+                final String[] files = mLogPath.list();
+                if (files == null || (files.length == 0)) {
+                    return;
+                }
+                Arrays.sort(files);
+
+                for (String file : files) {
+                    dumpFile(pw, new File(mLogPath, file));
+                }
+            }
+        }
+
+        private void dumpFile(PrintWriter pw, File file) {
+            Slog.w(TAG, "Dumping " + file);
+            final char[] buffer = new char[32 * 1024];
+
+            try (Reader in = new BufferedReader(new FileReader(file))) {
+                int read;
+                while ((read = in.read(buffer)) >= 0) {
+                    if (read > 0) {
+                        pw.write(buffer, 0, read);
+                    }
+                }
+            } catch (IOException e) {
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index e3e2658..c250005 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -241,6 +241,8 @@
 
     private final Random mRand;
 
+    private final SyncLogger mLogger;
+
     private boolean isJobIdInUseLockedH(int jobId, List<JobInfo> pendingJobs) {
         for (JobInfo job: pendingJobs) {
             if (job.getId() == jobId) {
@@ -289,13 +291,15 @@
                         mStorageIsLow = true;
                         cancelActiveSync(
                                 SyncStorageEngine.EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL,
-                                null /* any sync */);
+                                null /* any sync */,
+                                "storage low");
                     } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Slog.v(TAG, "Internal storage is ok.");
                         }
                         mStorageIsLow = false;
-                        rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL);
+                        rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL,
+                                "storage ok");
                     }
                 }
             };
@@ -378,15 +382,16 @@
                             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                                 Slog.v(TAG, "Reconnection detected: clearing all backoffs");
                             }
+                            // Note the location of this code was wrong from nyc to oc; fixed in DR.
+                            clearAllBackoffs("network reconnect");
                         }
-                        clearAllBackoffs();
                     }
                 }
             };
 
-    private void clearAllBackoffs() {
+    private void clearAllBackoffs(String why) {
         mSyncStorageEngine.clearAllBackoffsLocked();
-        rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL);
+        rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL, why);
     }
 
     private boolean readDataConnectionState() {
@@ -400,6 +405,7 @@
                 public void onReceive(Context context, Intent intent) {
                     Log.w(TAG, "Writing sync state before shutdown...");
                     getSyncStorageEngine().writeAllState();
+                    mLogger.log("Shutting down.");
                 }
             };
 
@@ -502,6 +508,8 @@
         // and creating threads and so on; it may fail if the disk is full.
         mContext = context;
 
+        mLogger = SyncLogger.getInstance();
+
         SyncStorageEngine.init(context);
         mSyncStorageEngine = SyncStorageEngine.getSingleton();
         mSyncStorageEngine.setOnSyncRequestListener(new OnSyncRequestListener() {
@@ -667,8 +675,23 @@
         // before we started checking for account access because they already know
         // the account (they run before) which is the genie is out of the bottle.
         whiteListExistingSyncAdaptersIfNeeded();
+
+        mLogger.log("Sync manager initialized.");
     }
 
+    public void onStartUser(int userHandle) {
+        mLogger.log("onStartUser: user=", userHandle);
+    }
+
+    public void onUnlockUser(int userHandle) {
+        mLogger.log("onUnlockUser: user=", userHandle);
+    }
+
+    public void onStopUser(int userHandle) {
+        mLogger.log("onStopUser: user=", userHandle);
+    }
+
+
     private void whiteListExistingSyncAdaptersIfNeeded() {
         if (!mSyncStorageEngine.shouldGrantSyncAdaptersAccountAccess()) {
             return;
@@ -1145,8 +1168,12 @@
         mSyncHandler.sendMessage(msg);
     }
 
-    private void sendCancelSyncsMessage(final SyncStorageEngine.EndPoint info, Bundle extras) {
+    private void sendCancelSyncsMessage(final SyncStorageEngine.EndPoint info, Bundle extras,
+            String why) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) Slog.v(TAG, "sending MESSAGE_CANCEL");
+
+        mLogger.log("sendCancelSyncsMessage() ep=", info, " why=", why);
+
         Message msg = mSyncHandler.obtainMessage();
         msg.what = SyncHandler.MESSAGE_CANCEL;
         msg.setData(extras);
@@ -1227,7 +1254,7 @@
         }
     }
 
-    private void clearBackoffSetting(EndPoint target) {
+    private void clearBackoffSetting(EndPoint target, String why) {
         Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(target);
         if (backoff != null && backoff.first == SyncStorageEngine.NOT_IN_BACKOFF_MODE &&
                 backoff.second == SyncStorageEngine.NOT_IN_BACKOFF_MODE) {
@@ -1240,7 +1267,7 @@
                 SyncStorageEngine.NOT_IN_BACKOFF_MODE,
                 SyncStorageEngine.NOT_IN_BACKOFF_MODE);
 
-        rescheduleSyncs(target);
+        rescheduleSyncs(target, why);
     }
 
     private void increaseBackoffSetting(EndPoint target) {
@@ -1281,14 +1308,16 @@
             Slog.v(TAG, "Backoff until: " + backoff + ", delayTime: " + newDelayInMs);
         }
         mSyncStorageEngine.setBackoff(target, backoff, newDelayInMs);
-        rescheduleSyncs(target);
+        rescheduleSyncs(target, "increaseBackoffSetting");
     }
 
     /**
      * Reschedule all scheduled syncs for this EndPoint. The syncs will be scheduled according
      * to current backoff and delayUntil values of this EndPoint.
      */
-    private void rescheduleSyncs(EndPoint target) {
+    private void rescheduleSyncs(EndPoint target, String why) {
+        mLogger.log("rescheduleSyncs() ep=", target, " why=", why);
+
         List<SyncOperation> ops = getAllPendingSyncs();
         int count = 0;
         for (SyncOperation op: ops) {
@@ -1316,7 +1345,7 @@
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Slog.v(TAG, "Delay Until time set to " + newDelayUntilTime + " for " + target);
         }
-        rescheduleSyncs(target);
+        rescheduleSyncs(target, "delayUntil newDelayUntilTime: " + newDelayUntilTime);
     }
 
     private boolean isAdapterDelayed(EndPoint target) {
@@ -1338,8 +1367,8 @@
      * have null account/provider info to specify all accounts/providers.
      * @param extras if non-null, specifies the exact sync to remove.
      */
-    public void cancelActiveSync(SyncStorageEngine.EndPoint info, Bundle extras) {
-        sendCancelSyncsMessage(info, extras);
+    public void cancelActiveSync(SyncStorageEngine.EndPoint info, Bundle extras, String why) {
+        sendCancelSyncsMessage(info, extras, why);
     }
 
     /**
@@ -1599,7 +1628,8 @@
                         null /* any account */,
                         null /* any authority */,
                         userId),
-                null /* any sync. */
+                null /* any sync. */,
+                "onUserStopped"
         );
     }
 
@@ -1759,10 +1789,15 @@
         }
     }
 
-    protected void dump(FileDescriptor fd, PrintWriter pw) {
+    protected void dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
         dumpSyncState(ipw);
         dumpSyncAdapters(ipw);
+
+        if (dumpAll) {
+            ipw.println("Detailed Sync History");
+            mLogger.dumpAll(pw);
+        }
     }
 
     static String formatTime(long time) {
@@ -2644,7 +2679,7 @@
                             Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_CANCEL: "
                                     + endpoint + " bundle: " + extras);
                         }
-                        cancelActiveSyncH(endpoint, extras);
+                        cancelActiveSyncH(endpoint, extras, "MESSAGE_CANCEL");
                         break;
 
                     case SyncHandler.MESSAGE_SYNC_FINISHED:
@@ -2660,7 +2695,8 @@
                             Slog.v(TAG, "syncFinished" + payload.activeSyncContext.mSyncOperation);
                         }
                         mSyncJobService.callJobFinished(
-                                payload.activeSyncContext.mSyncOperation.jobId, false);
+                                payload.activeSyncContext.mSyncOperation.jobId, false,
+                                "sync finished");
                         runSyncFinishedOrCanceledH(payload.syncResult,
                                 payload.activeSyncContext);
                         break;
@@ -2704,7 +2740,8 @@
                             SyncResult syncResult = new SyncResult();
                             syncResult.stats.numIoExceptions++;
                             mSyncJobService.callJobFinished(
-                                    currentSyncContext.mSyncOperation.jobId, false);
+                                    currentSyncContext.mSyncOperation.jobId, false,
+                                    "service disconnected");
                             runSyncFinishedOrCanceledH(syncResult, currentSyncContext);
                         }
                         break;
@@ -2722,7 +2759,8 @@
                                     "Detected sync making no progress for %s. cancelling.",
                                     monitoredSyncContext));
                             mSyncJobService.callJobFinished(
-                                    monitoredSyncContext.mSyncOperation.jobId, false);
+                                    monitoredSyncContext.mSyncOperation.jobId, false,
+                                    "no network activity");
                             runSyncFinishedOrCanceledH(
                                     null /* cancel => no result */, monitoredSyncContext);
                         } else {
@@ -2754,8 +2792,10 @@
          * delay. This is equivalent to a failure. If this is a periodic sync, a delayed one-off
          * sync will be scheduled.
          */
-        private void deferSyncH(SyncOperation op, long delay) {
-            mSyncJobService.callJobFinished(op.jobId, false);
+        private void deferSyncH(SyncOperation op, long delay, String why) {
+            mLogger.log("deferSyncH() ", (op.isPeriodic ? "periodic " : ""),
+                    "sync.  op=", op, " delay=", delay, " why=", why);
+            mSyncJobService.callJobFinished(op.jobId, false, why);
             if (op.isPeriodic) {
                 scheduleSyncOperationH(op.createOneTimeSyncOperation(), delay);
             } else {
@@ -2779,10 +2819,10 @@
         /**
          * Cancel an active sync and reschedule it on the JobScheduler with some delay.
          */
-        private void deferActiveSyncH(ActiveSyncContext asc) {
+        private void deferActiveSyncH(ActiveSyncContext asc, String why) {
             SyncOperation op = asc.mSyncOperation;
             runSyncFinishedOrCanceledH(null, asc);
-            deferSyncH(op, SYNC_DELAY_ON_CONFLICT);
+            deferSyncH(op, SYNC_DELAY_ON_CONFLICT, why);
         }
 
         private void startSyncH(SyncOperation op) {
@@ -2790,7 +2830,7 @@
             if (isLoggable) Slog.v(TAG, op.toString());
 
             if (mStorageIsLow) {
-                deferSyncH(op, SYNC_DELAY_ON_LOW_STORAGE);
+                deferSyncH(op, SYNC_DELAY_ON_LOW_STORAGE, "storage low");
                 return;
             }
 
@@ -2800,7 +2840,8 @@
                 List<SyncOperation> ops = getAllPendingSyncs();
                 for (SyncOperation syncOperation: ops) {
                     if (syncOperation.sourcePeriodicId == op.jobId) {
-                        mSyncJobService.callJobFinished(op.jobId, false);
+                        mSyncJobService.callJobFinished(op.jobId, false,
+                                "periodic sync, pending");
                         return;
                     }
                 }
@@ -2808,13 +2849,14 @@
                 // executing according to some backoff criteria.
                 for (ActiveSyncContext asc: mActiveSyncContexts) {
                     if (asc.mSyncOperation.sourcePeriodicId == op.jobId) {
-                        mSyncJobService.callJobFinished(op.jobId, false);
+                        mSyncJobService.callJobFinished(op.jobId, false,
+                                "periodic sync, already running");
                         return;
                     }
                 }
                 // Check for adapter delays.
                 if (isAdapterDelayed(op.target)) {
-                    deferSyncH(op, 0 /* No minimum delay */);
+                    deferSyncH(op, 0 /* No minimum delay */, "backing off");
                     return;
                 }
             }
@@ -2828,13 +2870,13 @@
                         if (isLoggable) {
                             Slog.v(TAG, "Rescheduling sync due to conflict " + op.toString());
                         }
-                        deferSyncH(op, SYNC_DELAY_ON_CONFLICT);
+                        deferSyncH(op, SYNC_DELAY_ON_CONFLICT, "delay on conflict");
                         return;
                     } else {
                         if (isLoggable) {
                             Slog.v(TAG, "Pushing back running sync due to a higher priority sync");
                         }
-                        deferActiveSyncH(asc);
+                        deferActiveSyncH(asc, "preempted");
                         break;
                     }
                 }
@@ -2844,12 +2886,13 @@
             switch (syncOpState) {
                 case SYNC_OP_STATE_INVALID_NO_ACCOUNT_ACCESS:
                 case SYNC_OP_STATE_INVALID: {
-                    mSyncJobService.callJobFinished(op.jobId, false);
+                    mSyncJobService.callJobFinished(op.jobId, false,
+                            "invalid op state: " + syncOpState);
                 } return;
             }
 
             if (!dispatchSyncOperation(op)) {
-                mSyncJobService.callJobFinished(op.jobId, false);
+                mSyncJobService.callJobFinished(op.jobId, false, "dispatchSyncOperation() failed");
             }
 
             setAuthorityPendingState(op.target);
@@ -3019,7 +3062,8 @@
                 if (op.sourcePeriodicId == syncOperation.jobId || op.jobId == syncOperation.jobId) {
                     ActiveSyncContext asc = findActiveSyncContextH(syncOperation.jobId);
                     if (asc != null) {
-                        mSyncJobService.callJobFinished(syncOperation.jobId, false);
+                        mSyncJobService.callJobFinished(syncOperation.jobId, false,
+                                "removePeriodicSyncInternalH");
                         runSyncFinishedOrCanceledH(null, asc);
                     }
                     getJobScheduler().cancel(op.jobId);
@@ -3131,6 +3175,8 @@
             final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
             syncAdapterInfo = mSyncAdapters.getServiceInfo(syncAdapterType, info.userId);
             if (syncAdapterInfo == null) {
+                mLogger.log("dispatchSyncOperation() failed: no sync adapter info for ",
+                        syncAdapterType);
                 Log.d(TAG, "can't find a sync adapter for " + syncAdapterType
                         + ", removing settings for it");
                 mSyncStorageEngine.removeAuthority(info);
@@ -3151,6 +3197,8 @@
             postMonitorSyncProgressMessage(activeSyncContext);
 
             if (!activeSyncContext.bindToSyncAdapter(targetComponent, info.userId)) {
+                mLogger.log("dispatchSyncOperation() failed: bind failed. target: ",
+                        targetComponent);
                 Slog.e(TAG, "Bind attempt failed - target: " + targetComponent);
                 closeActiveSyncContext(activeSyncContext);
                 return false;
@@ -3166,16 +3214,25 @@
                 activeSyncContext.mIsLinkedToDeath = true;
                 syncAdapter.linkToDeath(activeSyncContext, 0);
 
+                mLogger.log("Sync start: account=" + syncOperation.target.account,
+                        " authority=", syncOperation.target.provider,
+                        " reason=", SyncOperation.reasonToString(null, syncOperation.reason),
+                        " extras=", SyncOperation.extrasToString(syncOperation.extras));
+
                 activeSyncContext.mSyncAdapter = ISyncAdapter.Stub.asInterface(syncAdapter);
                 activeSyncContext.mSyncAdapter
                         .startSync(activeSyncContext, syncOperation.target.provider,
                                 syncOperation.target.account, syncOperation.extras);
+
+                mLogger.log("Sync finish");
             } catch (RemoteException remoteExc) {
+                mLogger.log("Sync failed with RemoteException: ", remoteExc.toString());
                 Log.d(TAG, "maybeStartNextSync: caught a RemoteException, rescheduling", remoteExc);
                 closeActiveSyncContext(activeSyncContext);
                 increaseBackoffSetting(syncOperation.target);
                 scheduleSyncOperationH(syncOperation);
             } catch (RuntimeException exc) {
+                mLogger.log("Sync failed with RuntimeException: ", exc.toString());
                 closeActiveSyncContext(activeSyncContext);
                 Slog.e(TAG, "Caught RuntimeException while starting the sync " + syncOperation, exc);
             }
@@ -3186,7 +3243,8 @@
          * @param info Can have null fields to indicate all the active syncs for that field.
          * @param extras Can be null to indicate <strong>all</strong> syncs for the given endpoint.
          */
-        private void cancelActiveSyncH(SyncStorageEngine.EndPoint info, Bundle extras) {
+        private void cancelActiveSyncH(SyncStorageEngine.EndPoint info, Bundle extras,
+                String why) {
             ArrayList<ActiveSyncContext> activeSyncs =
                     new ArrayList<ActiveSyncContext>(mActiveSyncContexts);
             for (ActiveSyncContext activeSyncContext : activeSyncs) {
@@ -3202,7 +3260,8 @@
                                     false /* no config settings */)) {
                         continue;
                     }
-                    mSyncJobService.callJobFinished(activeSyncContext.mSyncOperation.jobId, false);
+                    mSyncJobService.callJobFinished(activeSyncContext.mSyncOperation.jobId, false,
+                            why);
                     runSyncFinishedOrCanceledH(null /* cancel => no result */, activeSyncContext);
                 }
             }
@@ -3250,6 +3309,7 @@
                 // potentially rescheduling all pending jobs to respect new backoff values.
                 getJobScheduler().cancel(syncOperation.jobId);
             }
+            mLogger.log("runSyncFinishedOrCanceledH() op=", syncOperation, " result=", syncResult);
 
             if (syncResult != null) {
                 if (isLoggable) {
@@ -3262,7 +3322,7 @@
                     // TODO: set these correctly when the SyncResult is extended to include it
                     downstreamActivity = 0;
                     upstreamActivity = 0;
-                    clearBackoffSetting(syncOperation.target);
+                    clearBackoffSetting(syncOperation.target, "sync success");
 
                     // If the operation completes successfully and it was scheduled due to
                     // a periodic operation failing, we reschedule the periodic operation to
diff --git a/services/core/java/com/android/server/content/SyncOperation.java b/services/core/java/com/android/server/content/SyncOperation.java
index b46426c..7d2cc00 100644
--- a/services/core/java/com/android/server/content/SyncOperation.java
+++ b/services/core/java/com/android/server/content/SyncOperation.java
@@ -237,6 +237,9 @@
      * contain a valid sync operation.
      */
     static SyncOperation maybeCreateFromJobExtras(PersistableBundle jobExtras) {
+        if (jobExtras == null) {
+            return null;
+        }
         String accountName, accountType;
         String provider;
         int userId, owningUid;
@@ -445,6 +448,10 @@
     }
 
     static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) {
+        if (bundle == null) {
+            sb.append("null");
+            return;
+        }
         sb.append("[");
         for (String key : bundle.keySet()) {
             sb.append(key).append("=").append(bundle.get(key)).append(" ");
@@ -452,6 +459,12 @@
         sb.append("]");
     }
 
+    static String extrasToString(Bundle bundle) {
+        final StringBuilder sb = new StringBuilder();
+        extrasToStringBuilder(bundle, sb);
+        return sb.toString();
+    }
+
     String wakeLockName() {
         if (wakeLockName != null) {
             return wakeLockName;
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 8129f45..8269042 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -132,7 +132,7 @@
 
     private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;
 
-    private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER = 1;
+    private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
     private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2;
     private static final int MSG_DELIVER_DISPLAY_EVENT = 3;
     private static final int MSG_REQUEST_TRAVERSAL = 4;
@@ -266,7 +266,6 @@
 
         PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
-
     }
 
     public void setupSchedulerPolicies() {
@@ -284,9 +283,9 @@
         // We need to pre-load the persistent data store so it's ready before the default display
         // adapter is up so that we have it's configuration. We could load it lazily, but since
         // we're going to have to read it in eventually we may as well do it here rather than after
-        // we've waited for the diplay to register itself with us.
+        // we've waited for the display to register itself with us.
         mPersistentDataStore.loadIfNeeded();
-        mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
+        mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
 
         publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
                 true /*allowIsolated*/);
@@ -298,12 +297,16 @@
     public void onBootPhase(int phase) {
         if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) {
             synchronized (mSyncRoot) {
-                long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
-                while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) {
+                long timeout = SystemClock.uptimeMillis()
+                        + mInjector.getDefaultDisplayDelayTimeout();
+                while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null ||
+                        mVirtualDisplayAdapter == null) {
                     long delay = timeout - SystemClock.uptimeMillis();
                     if (delay <= 0) {
                         throw new RuntimeException("Timeout waiting for default display "
-                                + "to be initialized.");
+                                + "to be initialized. DefaultDisplay="
+                                + mLogicalDisplays.get(Display.DEFAULT_DISPLAY)
+                                + ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter);
                     }
                     if (DEBUG) {
                         Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
@@ -685,11 +688,23 @@
         }
     }
 
-    private void registerDefaultDisplayAdapter() {
-        // Register default display adapter.
+    private void registerDefaultDisplayAdapters() {
+        // Register default display adapters.
         synchronized (mSyncRoot) {
+            // main display adapter
             registerDisplayAdapterLocked(new LocalDisplayAdapter(
                     mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
+
+            // Standalone VR devices rely on a virtual display as their primary display for
+            // 2D UI. We register virtual display adapter along side the main display adapter
+            // here so that it is ready by the time the system sends the home Intent for
+            // early apps like SetupWizard/Launcher. In particular, SUW is displayed using
+            // the virtual display inside VR before any VR-specific apps even run.
+            mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
+                    mHandler, mDisplayAdapterListener);
+            if (mVirtualDisplayAdapter != null) {
+                registerDisplayAdapterLocked(mVirtualDisplayAdapter);
+            }
         }
     }
 
@@ -698,7 +713,6 @@
             if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
                 registerOverlayDisplayAdapterLocked();
                 registerWifiDisplayAdapterLocked();
-                registerVirtualDisplayAdapterLocked();
             }
         }
     }
@@ -719,12 +733,6 @@
         }
     }
 
-    private void registerVirtualDisplayAdapterLocked() {
-        mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext, mHandler,
-                mDisplayAdapterListener);
-        registerDisplayAdapterLocked(mVirtualDisplayAdapter);
-    }
-
     private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() {
         // In safe mode, we disable non-essential display adapters to give the user
         // an opportunity to fix broken settings or other problems that might affect
@@ -1219,6 +1227,22 @@
                 Handler handler, DisplayAdapter.Listener displayAdapterListener) {
             return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener);
         }
+
+        long getDefaultDisplayDelayTimeout() {
+            return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
+        }
+    }
+
+    @VisibleForTesting
+    DisplayDeviceInfo getDisplayDeviceInfoInternal(int displayId) {
+        synchronized (mSyncRoot) {
+            LogicalDisplay display = mLogicalDisplays.get(displayId);
+            if (display != null) {
+                DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
+                return displayDevice.getDisplayDeviceInfoLocked();
+            }
+            return null;
+        }
     }
 
     private final class DisplayManagerHandler extends Handler {
@@ -1229,8 +1253,8 @@
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-                case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER:
-                    registerDefaultDisplayAdapter();
+                case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS:
+                    registerDefaultDisplayAdapters();
                     break;
 
                 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS:
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 9d3021a..d6ab888 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -23,6 +23,7 @@
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
 
 import android.content.Context;
 import android.hardware.display.IVirtualDisplayCallback;
@@ -359,6 +360,10 @@
                 if ((mFlags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
                     mInfo.flags |= DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
                 }
+                if ((mFlags & VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT) != 0) {
+                    mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
+                }
+
                 mInfo.type = Display.TYPE_VIRTUAL;
                 mInfo.touch = ((mFlags & VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH) == 0) ?
                         DisplayDeviceInfo.TOUCH_NONE : DisplayDeviceInfo.TOUCH_VIRTUAL;
diff --git a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
index 5339bac..370e569 100644
--- a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
+++ b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
@@ -79,7 +79,7 @@
         }
         if (!authenticated) {
             if (receiver != null) {
-                FingerprintUtils.vibrateFingerprintError(getContext());
+                vibrateError();
             }
             // allow system-defined limit of number of attempts before giving up
             int lockoutMode =  handleFailedAttempt();
@@ -99,7 +99,7 @@
             result |= lockoutMode != LOCKOUT_NONE; // in a lockout mode
         } else {
             if (receiver != null) {
-                FingerprintUtils.vibrateFingerprintSuccess(getContext());
+                vibrateSuccess();
             }
             result |= true; // we have a valid fingerprint, done
             resetFailedAttempts();
diff --git a/services/core/java/com/android/server/fingerprint/ClientMonitor.java b/services/core/java/com/android/server/fingerprint/ClientMonitor.java
index 1a2e144..3eae157 100644
--- a/services/core/java/com/android/server/fingerprint/ClientMonitor.java
+++ b/services/core/java/com/android/server/fingerprint/ClientMonitor.java
@@ -23,6 +23,8 @@
 import android.hardware.fingerprint.IFingerprintServiceReceiver;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
 import android.util.Slog;
 
 import java.util.NoSuchElementException;
@@ -36,14 +38,18 @@
     protected static final String TAG = FingerprintService.TAG; // TODO: get specific name
     protected static final int ERROR_ESRCH = 3; // Likely fingerprint HAL is dead. See errno.h.
     protected static final boolean DEBUG = FingerprintService.DEBUG;
+    private static final long[] DEFAULT_SUCCESS_VIBRATION_PATTERN = new long[] {0, 30};
+    private final Context mContext;
+    private final long mHalDeviceId;
+    private final int mTargetUserId;
+    private final int mGroupId;
+    // True if client does not have MANAGE_FINGERPRINT permission
+    private final boolean mIsRestricted;
+    private final String mOwner;
+    private final VibrationEffect mSuccessVibrationEffect;
+    private final VibrationEffect mErrorVibrationEffect;
     private IBinder mToken;
     private IFingerprintServiceReceiver mReceiver;
-    private int mTargetUserId;
-    private int mGroupId;
-    private boolean mIsRestricted; // True if client does not have MANAGE_FINGERPRINT permission
-    private String mOwner;
-    private Context mContext;
-    private long mHalDeviceId;
     protected boolean mAlreadyCancelled;
 
     /**
@@ -68,6 +74,8 @@
         mGroupId = groupId;
         mIsRestricted = restricted;
         mOwner = owner;
+        mSuccessVibrationEffect = getSuccessVibrationEffect(context);
+        mErrorVibrationEffect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
         try {
             if (token != null) {
                 token.linkToDeath(this, 0);
@@ -79,7 +87,7 @@
 
     /**
      * Contacts fingerprint HAL to start the client.
-     * @return 0 on succes, errno from driver on failure
+     * @return 0 on success, errno from driver on failure
      */
     public abstract int start();
 
@@ -211,4 +219,39 @@
     public final IBinder getToken() {
         return mToken;
     }
+
+    public final void vibrateSuccess() {
+        Vibrator vibrator = mContext.getSystemService(Vibrator.class);
+        if (vibrator != null) {
+            vibrator.vibrate(mSuccessVibrationEffect);
+        }
+    }
+
+    public final void vibrateError() {
+        Vibrator vibrator = mContext.getSystemService(Vibrator.class);
+        if (vibrator != null) {
+            vibrator.vibrate(mErrorVibrationEffect);
+        }
+    }
+
+    private static VibrationEffect getSuccessVibrationEffect(Context ctx) {
+        int[] arr = ctx.getResources().getIntArray(
+                com.android.internal.R.array.config_longPressVibePattern);
+        final long[] vibePattern;
+        if (arr == null || arr.length == 0) {
+            vibePattern = DEFAULT_SUCCESS_VIBRATION_PATTERN;
+        } else {
+            vibePattern = new long[arr.length];
+            for (int i = 0; i < arr.length; i++) {
+                vibePattern[i] = arr[i];
+            }
+        }
+        if (vibePattern.length == 1) {
+            return VibrationEffect.createOneShot(
+                    vibePattern[0], VibrationEffect.DEFAULT_AMPLITUDE);
+        } else {
+            return VibrationEffect.createWaveform(vibePattern, -1);
+        }
+    }
+
 }
diff --git a/services/core/java/com/android/server/fingerprint/EnrollClient.java b/services/core/java/com/android/server/fingerprint/EnrollClient.java
index 6170894..c9efcf2 100644
--- a/services/core/java/com/android/server/fingerprint/EnrollClient.java
+++ b/services/core/java/com/android/server/fingerprint/EnrollClient.java
@@ -65,7 +65,7 @@
         if (receiver == null)
             return true; // client not listening
 
-        FingerprintUtils.vibrateFingerprintSuccess(getContext());
+        vibrateSuccess();
         MetricsLogger.action(getContext(), MetricsEvent.ACTION_FINGERPRINT_ENROLL);
         try {
             receiver.onEnrollResult(getHalDeviceId(), fpId, groupId, remaining);
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintUtils.java b/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
index 49dc8e4..5fbd735 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.hardware.fingerprint.Fingerprint;
-import android.os.Vibrator;
 import android.text.TextUtils;
 import android.util.SparseArray;
 
@@ -31,9 +30,6 @@
  */
 public class FingerprintUtils {
 
-    private static final long[] FP_ERROR_VIBRATE_PATTERN = new long[] {0, 30, 100, 30};
-    private static final long[] FP_SUCCESS_VIBRATE_PATTERN = new long[] {0, 30};
-
     private static final Object sInstanceLock = new Object();
     private static FingerprintUtils sInstance;
 
@@ -72,20 +68,6 @@
         getStateForUser(ctx, userId).renameFingerprint(fingerId, name);
     }
 
-    public static void vibrateFingerprintError(Context context) {
-        Vibrator vibrator = context.getSystemService(Vibrator.class);
-        if (vibrator != null) {
-            vibrator.vibrate(FP_ERROR_VIBRATE_PATTERN, -1);
-        }
-    }
-
-    public static void vibrateFingerprintSuccess(Context context) {
-        Vibrator vibrator = context.getSystemService(Vibrator.class);
-        if (vibrator != null) {
-            vibrator.vibrate(FP_SUCCESS_VIBRATE_PATTERN, -1);
-        }
-    }
-
     private FingerprintsUserState getStateForUser(Context ctx, int userId) {
         synchronized (this) {
             FingerprintsUserState state = mUsers.get(userId);
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index fe2c5bd..c1e820c 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -142,6 +142,7 @@
     private static final int SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT = 1;
 
     // Order of holding lock: mSeparateChallengeLock -> mSpManager -> this
+    // Do not call into ActivityManager while holding mSpManager lock.
     private final Object mSeparateChallengeLock = new Object();
 
     private final DeviceProvisionedObserver mDeviceProvisionedObserver =
@@ -1434,16 +1435,14 @@
             Slog.e(TAG, "FRP credential can only be verified prior to provisioning.");
             return VerifyCredentialResponse.ERROR;
         }
-        synchronized (mSpManager) {
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                VerifyCredentialResponse response = spBasedDoVerifyCredentialLocked(credential,
-                        credentialType, hasChallenge, challenge, userId, progressCallback);
-                if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-                    mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
-                }
-                return response;
-            }
+        VerifyCredentialResponse response = null;
+        response = spBasedDoVerifyCredential(credential, credentialType, hasChallenge, challenge,
+                userId, progressCallback);
+        // The user employs synthetic password based credential.
+        if (response != null) {
+            return response;
         }
+
         final CredentialHash storedHash;
         if (userId == USER_FRP) {
             PersistentData data = mStorage.readPersistentDataBlock();
@@ -1472,7 +1471,7 @@
             credentialToVerify = credential;
         }
 
-        VerifyCredentialResponse response = verifyCredential(userId, storedHash, credentialToVerify,
+        response = verifyCredential(userId, storedHash, credentialToVerify,
                 hasChallenge, challenge, progressCallback);
 
         if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
@@ -1995,33 +1994,46 @@
         setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
     }
 
-    private VerifyCredentialResponse spBasedDoVerifyCredentialLocked(String userCredential, int
+    private VerifyCredentialResponse spBasedDoVerifyCredential(String userCredential, int
             credentialType, boolean hasChallenge, long challenge, int userId,
             ICheckCredentialProgressCallback progressCallback) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredentialLocked: user=" + userId);
+        if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredential: user=" + userId);
         if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
             userCredential = null;
         }
-        if (userId == USER_FRP) {
-            return mSpManager.verifyFrpCredential(getGateKeeperService(),
-                    userCredential, credentialType, progressCallback);
+
+        final AuthenticationResult authResult;
+        VerifyCredentialResponse response;
+        synchronized (mSpManager) {
+            if (!isSyntheticPasswordBasedCredentialLocked(userId)) {
+                return null;
+            }
+            if (userId == USER_FRP) {
+                return mSpManager.verifyFrpCredential(getGateKeeperService(),
+                        userCredential, credentialType, progressCallback);
+            }
+
+            long handle = getSyntheticPasswordHandleLocked(userId);
+            authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
+                    getGateKeeperService(), handle, userCredential, userId);
+
+            response = authResult.gkResponse;
+            // credential has matched
+            if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+                // perform verifyChallenge with synthetic password which generates the real GK auth
+                // token and response for the current user
+                response = mSpManager.verifyChallenge(getGateKeeperService(), authResult.authToken,
+                        challenge, userId);
+                if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+                    // This shouldn't really happen: the unwrapping of SP succeeds, but SP doesn't
+                    // match the recorded GK password handle.
+                    Slog.wtf(TAG, "verifyChallenge with SP failed.");
+                    return VerifyCredentialResponse.ERROR;
+                }
+            }
         }
 
-        long handle = getSyntheticPasswordHandleLocked(userId);
-        AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
-                getGateKeeperService(), handle, userCredential, userId);
-
-        VerifyCredentialResponse response = authResult.gkResponse;
         if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-            // credential has matched
-            // perform verifyChallenge with synthetic password which generates the real auth
-            // token for the current user
-            response = mSpManager.verifyChallenge(getGateKeeperService(), authResult.authToken,
-                    challenge, userId);
-            if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
-                Slog.wtf(TAG, "verifyChallenge with SP failed.");
-                return VerifyCredentialResponse.ERROR;
-            }
             if (progressCallback != null) {
                 progressCallback.onCredentialVerified();
             }
@@ -2032,12 +2044,14 @@
             Slog.i(TAG, "Unlocking user " + userId + " with secret only, length " + secret.length);
             unlockUser(userId, null, secret);
 
+            activateEscrowTokens(authResult.authToken, userId);
+
             if (isManagedProfileWithSeparatedLock(userId)) {
                 TrustManager trustManager =
                         (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
                 trustManager.setDeviceLockedForUser(userId, false);
             }
-            activateEscrowTokens(authResult.authToken, userId);
+            mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
         } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
             if (response.getTimeout() > 0) {
                 requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
@@ -2184,8 +2198,8 @@
 
     private void activateEscrowTokens(AuthenticationToken auth, int userId) throws RemoteException {
         if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId);
-        disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
         synchronized (mSpManager) {
+            disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
             for (long handle : mSpManager.getPendingTokensForUser(userId)) {
                 Slog.i(TAG, String.format("activateEscrowTokens: %x %d ", handle, userId));
                 mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 5ee7ac4..038e47e 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -4004,16 +4004,19 @@
             }
             int indexBefore = findNotificationRecordIndexLocked(record);
             boolean interceptBefore = record.isIntercepted();
+            float contactAffinityBefore = record.getContactAffinity();
             int visibilityBefore = record.getPackageVisibilityOverride();
             recon.applyChangesLocked(record);
             applyZenModeLocked(record);
             mRankingHelper.sort(mNotificationList);
             int indexAfter = findNotificationRecordIndexLocked(record);
             boolean interceptAfter = record.isIntercepted();
+            float contactAffinityAfter = record.getContactAffinity();
             int visibilityAfter = record.getPackageVisibilityOverride();
             changed = indexBefore != indexAfter || interceptBefore != interceptAfter
                     || visibilityBefore != visibilityAfter;
-            if (interceptBefore && !interceptAfter) {
+            if (interceptBefore && !interceptAfter
+                    && Float.compare(contactAffinityBefore, contactAffinityAfter) != 0) {
                 buzzBeepBlinkLocked(record);
             }
         }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 5501ef1..1242daa 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7205,12 +7205,15 @@
                     // load resources from the correct package
                     installerInfo.resolvePackageName = info.getComponentInfo().packageName;
                     resolveInfos.set(i, installerInfo);
+                    continue;
                 }
-                continue;
             }
             // caller is a full app, don't need to apply any other filtering
             if (ephemeralPkgName == null) {
                 continue;
+            } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
+                // caller is same app; don't need to apply any other filtering
+                continue;
             }
             // allow activities that have been explicitly exposed to ephemeral apps
             if (!isEphemeralApp
@@ -20029,7 +20032,7 @@
         // Queue up an async operation since the package deletion may take a little while.
         mHandler.post(new Runnable() {
             public void run() {
-                final PackageSetting ps = (PackageSetting) pkg.mExtras;
+                final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
                 boolean doClearData = true;
                 if (ps != null) {
                     final boolean targetIsInstantApp =
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index f3a292b..20d7b28 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1018,7 +1018,7 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            ResolveInfo ri = mInterface.resolveIntent(intent, null, 0, mTargetUser);
+            ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), 0, mTargetUser);
             PrintWriter pw = getOutPrintWriter();
             if (ri == null) {
                 pw.println("No activity found");
@@ -1040,7 +1040,7 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            List<ResolveInfo> result = mInterface.queryIntentActivities(intent, null, 0,
+            List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(), 0,
                     mTargetUser).getList();
             PrintWriter pw = getOutPrintWriter();
             if (result == null || result.size() <= 0) {
@@ -1074,7 +1074,7 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            List<ResolveInfo> result = mInterface.queryIntentServices(intent, null, 0,
+            List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(), 0,
                     mTargetUser).getList();
             PrintWriter pw = getOutPrintWriter();
             if (result == null || result.size() <= 0) {
@@ -1108,7 +1108,7 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, null, 0,
+            List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(), 0,
                     mTargetUser).getList();
             PrintWriter pw = getOutPrintWriter();
             if (result == null || result.size() <= 0) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 89dbc2a..5d2d4b6 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1677,8 +1677,17 @@
     }
 
     boolean isUserSetupComplete() {
-        return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+        boolean isSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(),
                 Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
+        if (mHasFeatureLeanback) {
+            isSetupComplete &= isTvUserSetupComplete();
+        }
+        return isSetupComplete;
+    }
+
+    private boolean isTvUserSetupComplete() {
+        return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.TV_USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
     }
 
     private void handleShortPressOnHome() {
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 32871bb..984b40f 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -783,7 +783,7 @@
             mHandler.post(() -> {
                 // ShutdownThread displays UI, so give it a UI context.
                 if (safeMode) {
-                    ShutdownThread.rebootSafeMode(getUiContext(), false);
+                    ShutdownThread.rebootSafeMode(getUiContext(), true);
                 } else {
                     ShutdownThread.reboot(getUiContext(),
                             PowerManager.SHUTDOWN_USER_REQUESTED, false);
diff --git a/services/core/java/com/android/server/vr/Vr2dDisplay.java b/services/core/java/com/android/server/vr/Vr2dDisplay.java
index 4a1297f..b1c1df1 100644
--- a/services/core/java/com/android/server/vr/Vr2dDisplay.java
+++ b/services/core/java/com/android/server/vr/Vr2dDisplay.java
@@ -35,7 +35,6 @@
     private final static String TAG = "Vr2dDisplay";
     private final static boolean DEBUG = false;
 
-    // TODO: Go over these values and figure out what is best
     private int mVirtualDisplayHeight;
     private int mVirtualDisplayWidth;
     private int mVirtualDisplayDpi;
@@ -55,17 +54,17 @@
     /**
      * The default width of the VR virtual display
      */
-    public static final int DEFAULT_VR_DISPLAY_WIDTH = 1400;
+    public static final int DEFAULT_VIRTUAL_DISPLAY_WIDTH = 1400;
 
     /**
      * The default height of the VR virtual display
      */
-    public static final int DEFAULT_VR_DISPLAY_HEIGHT = 1800;
+    public static final int DEFAULT_VIRTUAL_DISPLAY_HEIGHT = 1400;
 
     /**
      * The default height of the VR virtual dpi.
      */
-    public static final int DEFAULT_VR_DISPLAY_DPI = 320;
+    public static final int DEFAULT_VIRTUAL_DISPLAY_DPI = 320;
 
     /**
      * The minimum height, width and dpi of VR virtual display.
@@ -87,8 +86,8 @@
             new IPersistentVrStateCallbacks.Stub() {
         @Override
         public void onPersistentVrStateChanged(boolean enabled) {
-            if (enabled != mIsVrModeEnabled) {
-                mIsVrModeEnabled = enabled;
+            if (enabled != mIsPersistentVrModeEnabled) {
+                mIsPersistentVrModeEnabled = enabled;
                 updateVirtualDisplay();
             }
         }
@@ -98,25 +97,33 @@
     private Surface mSurface;
     private ImageReader mImageReader;
     private Runnable mStopVDRunnable;
-    private boolean mIsVrModeOverrideEnabled;
-    private boolean mIsVrModeEnabled;
+    private boolean mIsVrModeOverrideEnabled;  // debug override to set vr mode.
+    private boolean mIsVirtualDisplayAllowed = true;  // Virtual-display feature toggle
+    private boolean mIsPersistentVrModeEnabled;  // indicates we are in vr persistent mode.
+    private boolean mBootsToVr = false;  // The device boots into VR (standalone VR device)
 
     public Vr2dDisplay(DisplayManager displayManager,
            ActivityManagerInternal activityManagerInternal, IVrManager vrManager) {
         mDisplayManager = displayManager;
         mActivityManagerInternal = activityManagerInternal;
         mVrManager = vrManager;
-        mVirtualDisplayWidth = DEFAULT_VR_DISPLAY_WIDTH;
-        mVirtualDisplayHeight = DEFAULT_VR_DISPLAY_HEIGHT;
-        mVirtualDisplayDpi = DEFAULT_VR_DISPLAY_DPI;
+        mVirtualDisplayWidth = DEFAULT_VIRTUAL_DISPLAY_WIDTH;
+        mVirtualDisplayHeight = DEFAULT_VIRTUAL_DISPLAY_HEIGHT;
+        mVirtualDisplayDpi = DEFAULT_VIRTUAL_DISPLAY_DPI;
     }
 
     /**
      * Initializes the compabilitiy display by listening to VR mode changes.
      */
-    public void init(Context context) {
+    public void init(Context context, boolean bootsToVr) {
         startVrModeListener();
         startDebugOnlyBroadcastReceiver(context);
+        mBootsToVr = bootsToVr;
+        if (mBootsToVr) {
+          // If we are booting into VR, we need to start the virtual display immediately. This
+          // ensures that the virtual display is up by the time Setup Wizard is started.
+          updateVirtualDisplay();
+        }
     }
 
     /**
@@ -124,10 +131,13 @@
      */
     private void updateVirtualDisplay() {
         if (DEBUG) {
-            Log.i(TAG, "isVrMode: " + mIsVrModeEnabled + ", override: " + mIsVrModeOverrideEnabled);
+            Log.i(TAG, "isVrMode: " + mIsPersistentVrModeEnabled + ", override: "
+                    + mIsVrModeOverrideEnabled + ", isAllowed: " + mIsVirtualDisplayAllowed
+                    + ", bootsToVr: " + mBootsToVr);
         }
 
-        if (mIsVrModeEnabled || mIsVrModeOverrideEnabled) {
+        if (shouldRunVirtualDisplay()) {
+            Log.i(TAG, "Attempting to start virtual display");
             // TODO: Consider not creating the display until ActivityManager needs one on
             // which to display a 2D application.
             startVirtualDisplay();
@@ -190,33 +200,43 @@
      *
      * <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
      *
-     * @param compatDisplayProperties Properties of the virtual display for 2D applications
+     * @param displayProperties Properties of the virtual display for 2D applications
      * in VR mode.
      */
-    public void setVirtualDisplayProperties(Vr2dDisplayProperties compatDisplayProperties) {
+    public void setVirtualDisplayProperties(Vr2dDisplayProperties displayProperties) {
         synchronized(mVdLock) {
             if (DEBUG) {
-                Log.i(TAG, "VD setVirtualDisplayProperties: res = "
-                        + compatDisplayProperties.getWidth() + "X"
-                        + compatDisplayProperties.getHeight() + ", dpi = "
-                        + compatDisplayProperties.getDpi());
+                Log.i(TAG, "VD setVirtualDisplayProperties: " +
+                        displayProperties.toString());
             }
 
-            if (compatDisplayProperties.getWidth() < MIN_VR_DISPLAY_WIDTH ||
-                compatDisplayProperties.getHeight() < MIN_VR_DISPLAY_HEIGHT ||
-                compatDisplayProperties.getDpi() < MIN_VR_DISPLAY_DPI) {
-                throw new IllegalArgumentException (
-                        "Illegal argument: height, width, dpi cannot be negative. res = "
-                        + compatDisplayProperties.getWidth() + "X"
-                        + compatDisplayProperties.getHeight()
-                        + ", dpi = " + compatDisplayProperties.getDpi());
+            int width = displayProperties.getWidth();
+            int height = displayProperties.getHeight();
+            int dpi = displayProperties.getDpi();
+            boolean resized = false;
+
+            if (width < MIN_VR_DISPLAY_WIDTH || height < MIN_VR_DISPLAY_HEIGHT ||
+                    dpi < MIN_VR_DISPLAY_DPI) {
+                Log.i(TAG, "Ignoring Width/Height/Dpi values of " + width + "," + height + ","
+                        + dpi);
+            } else {
+                Log.i(TAG, "Setting width/height/dpi to " + width + "," + height + "," + dpi);
+                mVirtualDisplayWidth = width;
+                mVirtualDisplayHeight = height;
+                mVirtualDisplayDpi = dpi;
+                resized = true;
             }
 
-            mVirtualDisplayWidth = compatDisplayProperties.getWidth();
-            mVirtualDisplayHeight = compatDisplayProperties.getHeight();
-            mVirtualDisplayDpi = compatDisplayProperties.getDpi();
+            if ((displayProperties.getFlags() & Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED)
+                    == Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED) {
+                mIsVirtualDisplayAllowed = true;
+            } else if ((displayProperties.getRemovedFlags() &
+                    Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED)
+                    == Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED) {
+                mIsVirtualDisplayAllowed = false;
+            }
 
-            if (mVirtualDisplay != null) {
+            if (mVirtualDisplay != null && resized && mIsVirtualDisplayAllowed) {
                 mVirtualDisplay.resize(mVirtualDisplayWidth, mVirtualDisplayHeight,
                     mVirtualDisplayDpi);
                 ImageReader oldImageReader = mImageReader;
@@ -224,6 +244,9 @@
                 startImageReader();
                 oldImageReader.close();
             }
+
+            // Start/Stop the virtual display in case the updates indicated that we should.
+            updateVirtualDisplay();
         }
     }
 
@@ -266,6 +289,7 @@
             }
 
             int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
+            flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
             mVirtualDisplay = mDisplayManager.createVirtualDisplay(null /* projection */,
                     DISPLAY_NAME, mVirtualDisplayWidth, mVirtualDisplayHeight, mVirtualDisplayDpi,
                     null /* surface */, flags, null /* callback */, null /* handler */,
@@ -296,7 +320,7 @@
            mStopVDRunnable = new Runnable() {
                @Override
                public void run() {
-                    if (mIsVrModeEnabled) {
+                    if (shouldRunVirtualDisplay()) {
                         Log.i(TAG, "Virtual Display destruction stopped: VrMode is back on.");
                     } else {
                         Log.i(TAG, "Stopping Virtual Display");
@@ -365,4 +389,14 @@
             mImageReader = null;
         }
     }
+
+    private boolean shouldRunVirtualDisplay() {
+        // Virtual Display should run whenever:
+        // * Virtual Display is allowed/enabled AND
+        // (1) BootsToVr is set indicating the device never leaves VR
+        // (2) VR (persistent) mode is enabled
+        // (3) VR mode is overridden to be enabled.
+        return mIsVirtualDisplayAllowed &&
+                (mBootsToVr || mIsPersistentVrModeEnabled || mIsVrModeOverrideEnabled);
+    }
 }
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index 55d4719..f13cc76 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -619,7 +619,7 @@
                     (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE);
             ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class);
             mVr2dDisplay = new Vr2dDisplay(dm, ami, mVrManager);
-            mVr2dDisplay.init(getContext());
+            mVr2dDisplay.init(getContext(), mBootsToVr);
 
             IntentFilter intentFilter = new IntentFilter();
             intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index fe74947..4e4398e 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -614,8 +614,8 @@
             return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
         } else if (taskSwitch && allowTaskSnapshot) {
             return snapshot == null ? STARTING_WINDOW_TYPE_NONE
-                    : snapshotFillsWidth(snapshot) || fromRecents ? STARTING_WINDOW_TYPE_SNAPSHOT
-                    : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
+                    : snapshotOrientationSameAsTask(snapshot) || fromRecents
+                            ? STARTING_WINDOW_TYPE_SNAPSHOT : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
         } else {
             return STARTING_WINDOW_TYPE_NONE;
         }
@@ -640,22 +640,11 @@
         return true;
     }
 
-    private boolean snapshotFillsWidth(TaskSnapshot snapshot) {
+    private boolean snapshotOrientationSameAsTask(TaskSnapshot snapshot) {
         if (snapshot == null) {
             return false;
         }
-        final Rect rect = new Rect(0, 0, snapshot.getSnapshot().getWidth(),
-                snapshot.getSnapshot().getHeight());
-        rect.inset(snapshot.getContentInsets());
-        final Rect taskBoundsWithoutInsets = new Rect();
-        mContainer.getTask().getBounds(taskBoundsWithoutInsets);
-        final DisplayInfo di = mContainer.getDisplayContent().getDisplayInfo();
-        final Rect displayBounds = new Rect(0, 0, di.logicalWidth, di.logicalHeight);
-        final Rect stableInsets = new Rect();
-        mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
-                stableInsets);
-        displayBounds.inset(stableInsets);
-        return rect.width() >= displayBounds.width();
+        return mContainer.getTask().getConfiguration().orientation == snapshot.getOrientation();
     }
 
     public void removeStartingWindow() {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index bd37934..8afc4fd 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -937,8 +937,6 @@
             // Update keyguard flags upon finishing relaunch.
             checkKeyguardFlagsChanged();
         }
-
-        updateAllDrawn();
     }
 
     void clearRelaunching() {
@@ -1344,6 +1342,10 @@
         }
     }
 
+    /**
+     *  Determines if the token has finished drawing. This should only be called from
+     *  {@link DisplayContent#applySurfaceChangesTransaction}
+     */
     void updateAllDrawn() {
         if (!allDrawn) {
             // Number of drawn windows can be less when a window is being relaunched, wait for
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index c98d60d..9fe7381 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1183,6 +1183,8 @@
         final int dh = displayInfo.logicalHeight;
         config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
                 Configuration.ORIENTATION_LANDSCAPE;
+        config.setRotation(displayInfo.rotation);
+
         config.screenWidthDp =
                 (int)(mService.mPolicy.getConfigDisplayWidth(dw, dh, displayInfo.rotation,
                         config.uiMode, mDisplayId) / mDisplayMetrics.density);
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index 297e288..b628869 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -25,6 +25,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.CompressFormat;
 import android.graphics.Bitmap.Config;
+import android.graphics.GraphicBuffer;
 import android.os.Process;
 import android.os.SystemClock;
 import android.util.ArraySet;
@@ -325,6 +326,15 @@
             final File file = getBitmapFile(mTaskId, mUserId);
             final File reducedFile = getReducedResolutionBitmapFile(mTaskId, mUserId);
             final Bitmap bitmap = Bitmap.createHardwareBitmap(mSnapshot.getSnapshot());
+            if (bitmap == null) {
+                Slog.e(TAG, "Invalid task snapshot");
+                return false;
+            } else if (bitmap.getWidth() == 0 || bitmap.getHeight() == 0) {
+                Slog.e(TAG, "Invalid task snapshot dimensions " + bitmap.getWidth() + "x"
+                        + bitmap.getHeight());
+                return false;
+            }
+
             final Bitmap swBitmap = bitmap.copy(Config.ARGB_8888, false /* isMutable */);
             final Bitmap reduced = Bitmap.createScaledBitmap(swBitmap,
                     (int) (bitmap.getWidth() * REDUCED_SCALE),
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f9d7c37..613c830 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -19,16 +19,17 @@
 import static android.Manifest.permission.MANAGE_APP_TOKENS;
 import static android.Manifest.permission.READ_FRAME_BUFFER;
 import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
+import static android.Manifest.permission.RESTRICTED_VR_ACCESS;
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
 import static android.app.StatusBarManager.DISABLE_MASK;
 import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
 import static android.content.Intent.ACTION_USER_REMOVED;
 import static android.content.Intent.EXTRA_USER_HANDLE;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Process.ROOT_UID;
 import static android.os.Process.SHELL_UID;
 import static android.os.Process.SYSTEM_UID;
-import static android.os.Process.THREAD_PRIORITY_DISPLAY;
 import static android.os.Process.myPid;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.os.UserHandle.USER_NULL;
@@ -48,7 +49,6 @@
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TASK_SNAPSHOT;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
@@ -231,7 +231,6 @@
 import com.android.server.EventLogTags;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
-import com.android.server.ThreadPriorityBooster;
 import com.android.server.UiThread;
 import com.android.server.Watchdog;
 import com.android.server.input.InputManagerService;
@@ -2018,8 +2017,7 @@
                     win.setDisplayLayoutNeeded();
                     mWindowPlacerLocked.performSurfacePlacement(true);
                 }
-                result = win.relayoutVisibleWindow(mergedConfiguration, result, attrChanges,
-                        oldVisibility);
+                result = win.relayoutVisibleWindow(result, attrChanges, oldVisibility);
 
                 try {
                     result = createSurfaceControl(outSurface, result, win, winAnimator);
@@ -2157,6 +2155,15 @@
             if (!win.isGoneForLayoutLw()) {
                 win.mResizedWhileGone = false;
             }
+
+            // We must always send the latest {@link MergedConfiguration}, regardless of whether we
+            // have already reported it. The client might not have processed the previous value yet
+            // and needs process it before handling the corresponding window frame. the variable
+            // {@code mergedConfiguration} is an out parameter that will be passed back to the
+            // client over IPC and checked there.
+            win.getMergedConfiguration(mergedConfiguration);
+            win.setReportedConfiguration(mergedConfiguration);
+
             outFrame.set(win.mCompatFrame);
             outOverscanInsets.set(win.mOverscanInsets);
             outContentInsets.set(win.mContentInsets);
@@ -2948,9 +2955,10 @@
     }
 
     public void setKeyguardGoingAway(boolean keyguardGoingAway) {
-        synchronized (mWindowMap) {
-            mKeyguardGoingAway = keyguardGoingAway;
-        }
+// TODO: Use of this can be removed. Revert ag/I8369723d6a77f2c602f1ef080371fa7cd9ee094e
+//        synchronized (mWindowMap) {
+//            mKeyguardGoingAway = keyguardGoingAway;
+//        }
     }
 
     // -------------------------------------------------------------
@@ -6304,6 +6312,9 @@
 
     @Override
     public Region getCurrentImeTouchRegion() {
+        if (mContext.checkCallingOrSelfPermission(RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
+            throw new SecurityException("getCurrentImeTouchRegion is restricted to VR services");
+        }
         synchronized (mWindowMap) {
             final Region r = new Region();
             if (mInputMethodWindow != null) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index f74948f..d1fbf90 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2207,8 +2207,7 @@
         }
     }
 
-    void prepareWindowToDisplayDuringRelayout(MergedConfiguration mergedConfiguration,
-            boolean wasVisible) {
+    void prepareWindowToDisplayDuringRelayout(boolean wasVisible) {
         // We need to turn on screen regardless of visibility.
         if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) {
             if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this);
@@ -2230,16 +2229,16 @@
         if (isDrawnLw() && mService.okToDisplay()) {
             mWinAnimator.applyEnterAnimationLocked();
         }
+    }
 
-        if (isConfigChanged()) {
-            final Configuration globalConfig = mService.mRoot.getConfiguration();
-            final Configuration overrideConfig = getMergedOverrideConfiguration();
-            mergedConfiguration.setConfiguration(globalConfig, overrideConfig);
-            if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this
-                    + " visible with new global config: " + globalConfig
-                    + " merged override config: " + overrideConfig);
-            mLastReportedConfiguration.setTo(getConfiguration());
-        }
+    void getMergedConfiguration(MergedConfiguration outConfiguration) {
+        final Configuration globalConfig = mService.mRoot.getConfiguration();
+        final Configuration overrideConfig = getMergedOverrideConfiguration();
+        outConfiguration.setConfiguration(globalConfig, overrideConfig);
+    }
+
+    void setReportedConfiguration(MergedConfiguration config) {
+        mLastReportedConfiguration.setTo(config.getMergedConfiguration());
     }
 
     void adjustStartingWindowFlags() {
@@ -3005,14 +3004,12 @@
         try {
             if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this
                     + ": " + mCompatFrame);
-            final MergedConfiguration mergedConfiguration;
-            if (isConfigChanged()) {
-                mergedConfiguration = new MergedConfiguration(mService.mRoot.getConfiguration(),
-                        getMergedOverrideConfiguration());
-                mLastReportedConfiguration.setTo(mergedConfiguration.getMergedConfiguration());
-            } else {
-                mergedConfiguration = null;
-            }
+            final MergedConfiguration mergedConfiguration =
+                    new MergedConfiguration(mService.mRoot.getConfiguration(),
+                    getMergedOverrideConfiguration());
+
+            setReportedConfiguration(mergedConfiguration);
+
             if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == DRAW_PENDING)
                 Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING");
 
@@ -4342,8 +4339,7 @@
         return !mLastSurfaceInsets.equals(mAttrs.surfaceInsets);
     }
 
-    int relayoutVisibleWindow(MergedConfiguration mergedConfiguration, int result, int attrChanges,
-            int oldVisibility) {
+    int relayoutVisibleWindow(int result, int attrChanges, int oldVisibility) {
         final boolean wasVisible = isVisibleLw();
 
         result |= (!wasVisible || !isDrawnLw()) ? RELAYOUT_RES_FIRST_TIME : 0;
@@ -4366,7 +4362,7 @@
 
         mWinAnimator.mEnteringAnimation = true;
 
-        prepareWindowToDisplayDuringRelayout(mergedConfiguration, wasVisible);
+        prepareWindowToDisplayDuringRelayout(wasVisible);
 
         if ((attrChanges & FORMAT_CHANGED) != 0) {
             // If the format can't be changed in place, preserve the old surface until the app draws
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index a3d28bb..e2a82b7 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -33,6 +33,7 @@
     $(LOCAL_REL_DIR)/com_android_server_tv_TvInputHal.cpp \
     $(LOCAL_REL_DIR)/com_android_server_vr_VrManagerService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_UsbDeviceManager.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_UsbDescriptorParser.cpp \
     $(LOCAL_REL_DIR)/com_android_server_UsbMidiDevice.cpp \
     $(LOCAL_REL_DIR)/com_android_server_UsbHostManager.cpp \
     $(LOCAL_REL_DIR)/com_android_server_VibratorService.cpp \
diff --git a/services/core/jni/com_android_server_UsbDescriptorParser.cpp b/services/core/jni/com_android_server_UsbDescriptorParser.cpp
new file mode 100644
index 0000000..98c5ec1
--- /dev/null
+++ b/services/core/jni/com_android_server_UsbDescriptorParser.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "UsbHostManagerJNI"
+#include "utils/Log.h"
+
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include <usbhost/usbhost.h>
+
+#define MAX_DESCRIPTORS_LENGTH 16384
+
+// com.android.server.usb.descriptors
+extern "C" {
+jbyteArray JNICALL Java_com_android_server_usb_descriptors_UsbDescriptorParser_getRawDescriptors(
+        JNIEnv* env, jobject thiz, jstring deviceAddr) {
+    const char *deviceAddrStr = env->GetStringUTFChars(deviceAddr, NULL);
+    struct usb_device* device = usb_device_open(deviceAddrStr);
+    env->ReleaseStringUTFChars(deviceAddr, deviceAddrStr);
+
+    if (!device) {
+        ALOGE("usb_device_open failed");
+        return NULL;
+    }
+
+    int fd = usb_device_get_fd(device);
+    if (fd < 0) {
+        return NULL;
+    }
+
+    // from android_hardware_UsbDeviceConnection_get_desc()
+    jbyte buffer[MAX_DESCRIPTORS_LENGTH];
+    lseek(fd, 0, SEEK_SET);
+    int numBytes = read(fd, buffer, sizeof(buffer));
+
+    usb_device_close(device);
+
+    jbyteArray ret = NULL;
+    if (numBytes != 0) {
+        ret = env->NewByteArray(numBytes);
+        env->SetByteArrayRegion(ret, 0, numBytes, buffer);
+    }
+    return ret;
+}
+
+} // extern "C"
+
+
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index 804cd17..cb8416b 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -42,107 +42,121 @@
 namespace android
 {
 
-static sp<IVibrator> mHal;
+static constexpr int NUM_TRIES = 2;
+
+// Creates a Return<R> with STATUS::EX_NULL_POINTER.
+template<class R>
+inline Return<R> NullptrStatus() {
+    using ::android::hardware::Status;
+    return Return<R>{Status::fromExceptionCode(Status::EX_NULL_POINTER)};
+}
+
+// Helper used to transparently deal with the vibrator HAL becoming unavailable.
+template<class R, class I, class... Args0, class... Args1>
+Return<R> halCall(Return<R> (I::* fn)(Args0...), Args1&&... args1) {
+    // Assume that if getService returns a nullptr, HAL is not available on the
+    // device.
+    static sp<I> sHal = I::getService();
+    static bool sAvailable = sHal != nullptr;
+
+    if (!sAvailable) {
+        return NullptrStatus<R>();
+    }
+
+    // Return<R> doesn't have a default constructor, so make a Return<R> with
+    // STATUS::EX_NONE.
+    using ::android::hardware::Status;
+    Return<R> ret{Status::fromExceptionCode(Status::EX_NONE)};
+
+    // Note that ret is guaranteed to be changed after this loop.
+    for (int i = 0; i < NUM_TRIES; ++i) {
+        ret = (sHal == nullptr) ? NullptrStatus<R>()
+                : (*sHal.*fn)(std::forward<Args1>(args1)...);
+
+        if (!ret.isOk()) {
+            ALOGE("Failed to issue command to vibrator HAL. Retrying.");
+            // Restoring connection to the HAL.
+            sHal = I::tryGetService();
+        }
+    }
+    return ret;
+}
 
 static void vibratorInit(JNIEnv /* env */, jobject /* clazz */)
 {
-    /* TODO(b/31632518) */
-    if (mHal != nullptr) {
-        return;
-    }
-    mHal = IVibrator::getService();
+    halCall(&IVibrator::ping).isOk();
 }
 
 static jboolean vibratorExists(JNIEnv* /* env */, jobject /* clazz */)
 {
-    if (mHal != nullptr) {
-        return JNI_TRUE;
-    } else {
-        return JNI_FALSE;
-    }
+    return halCall(&IVibrator::ping).isOk() ? JNI_TRUE : JNI_FALSE;
 }
 
 static void vibratorOn(JNIEnv* /* env */, jobject /* clazz */, jlong timeout_ms)
 {
-    if (mHal != nullptr) {
-        Status retStatus = mHal->on(timeout_ms);
-        if (retStatus != Status::OK) {
-            ALOGE("vibratorOn command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
-        }
-    } else {
-        ALOGW("Tried to vibrate but there is no vibrator device.");
+    Status retStatus = halCall(&IVibrator::on, timeout_ms).withDefault(Status::UNKNOWN_ERROR);
+    if (retStatus != Status::OK) {
+        ALOGE("vibratorOn command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
     }
 }
 
 static void vibratorOff(JNIEnv* /* env */, jobject /* clazz */)
 {
-    if (mHal != nullptr) {
-        Status retStatus = mHal->off();
-        if (retStatus != Status::OK) {
-            ALOGE("vibratorOff command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
-        }
-    } else {
-        ALOGW("Tried to stop vibrating but there is no vibrator device.");
+    Status retStatus = halCall(&IVibrator::off).withDefault(Status::UNKNOWN_ERROR);
+    if (retStatus != Status::OK) {
+        ALOGE("vibratorOff command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
     }
 }
 
 static jlong vibratorSupportsAmplitudeControl(JNIEnv*, jobject) {
-    if (mHal != nullptr) {
-        return mHal->supportsAmplitudeControl();
-    } else {
-        ALOGW("Unable to get max vibration amplitude, there is no vibrator device.");
-    }
-    return false;
+    return halCall(&IVibrator::supportsAmplitudeControl).withDefault(false);
 }
 
 static void vibratorSetAmplitude(JNIEnv*, jobject, jint amplitude) {
-    if (mHal != nullptr) {
-        Status status = mHal->setAmplitude(static_cast<uint32_t>(amplitude));
-        if (status != Status::OK) {
-            ALOGE("Failed to set vibrator amplitude (%" PRIu32 ").",
-                    static_cast<uint32_t>(status));
-        }
-    } else {
-        ALOGW("Unable to set vibration amplitude, there is no vibrator device.");
+    Status status = halCall(&IVibrator::setAmplitude, static_cast<uint32_t>(amplitude))
+        .withDefault(Status::UNKNOWN_ERROR);
+    if (status != Status::OK) {
+      ALOGE("Failed to set vibrator amplitude (%" PRIu32 ").",
+            static_cast<uint32_t>(status));
     }
 }
 
 static jlong vibratorPerformEffect(JNIEnv*, jobject, jlong effect, jint strength) {
-    if (mHal != nullptr) {
-        Status status;
-        uint32_t lengthMs;
-        auto callback = [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) {
-            status = retStatus;
-            lengthMs = retLengthMs;
-        };
-        EffectStrength effectStrength(static_cast<EffectStrength>(strength));
+    Status status;
+    uint32_t lengthMs;
+    auto callback = [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) {
+        status = retStatus;
+        lengthMs = retLengthMs;
+    };
+    EffectStrength effectStrength(static_cast<EffectStrength>(strength));
 
-        if (effect < 0  || effect > static_cast<uint32_t>(Effect_1_1::TICK)) {
-            ALOGW("Unable to perform haptic effect, invalid effect ID (%" PRId32 ")",
+    if (effect < 0  || effect > static_cast<uint32_t>(Effect_1_1::TICK)) {
+        ALOGW("Unable to perform haptic effect, invalid effect ID (%" PRId32 ")",
+                static_cast<int32_t>(effect));
+    } else if (effect == static_cast<uint32_t>(Effect_1_1::TICK)) {
+        auto ret = halCall(&IVibrator_1_1::perform_1_1, static_cast<Effect_1_1>(effect),
+                           effectStrength, callback);
+        if (!ret.isOk()) {
+            ALOGW("Failed to perform effect (%" PRId32 "), insufficient HAL version",
                     static_cast<int32_t>(effect));
-        } else if (effect == static_cast<uint32_t>(Effect_1_1::TICK)) {
-            sp<IVibrator_1_1> hal_1_1 = IVibrator_1_1::castFrom(mHal);
-            if (hal_1_1 != nullptr) {
-                hal_1_1->perform_1_1(static_cast<Effect_1_1>(effect), effectStrength, callback);
-            } else {
-                ALOGW("Failed to perform effect (%" PRId32 "), insufficient HAL version",
-                        static_cast<int32_t>(effect));
-            }
-        } else {
-            mHal->perform(static_cast<Effect>(effect), effectStrength, callback);
-        }
-        if (status == Status::OK) {
-            return lengthMs;
-        } else if (status != Status::UNSUPPORTED_OPERATION) {
-            // Don't warn on UNSUPPORTED_OPERATION, that's a normal even and just means the motor
-            // doesn't have a pre-defined waveform to perform for it, so we should just fall back
-            // to the framework waveforms.
-            ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32
-                    ", error=%" PRIu32 ").", static_cast<int64_t>(effect),
-                    static_cast<int32_t>(strength), static_cast<uint32_t>(status));
         }
     } else {
-        ALOGW("Unable to perform haptic effect, there is no vibrator device.");
+        auto ret = halCall(&IVibrator::perform, static_cast<Effect>(effect), effectStrength,
+                           callback);
+        if (!ret.isOk()) {
+            ALOGW("Failed to perform effect (%" PRId32 ")", static_cast<int32_t>(effect));
+        }
+    }
+
+    if (status == Status::OK) {
+        return lengthMs;
+    } else if (status != Status::UNSUPPORTED_OPERATION) {
+        // Don't warn on UNSUPPORTED_OPERATION, that's a normal even and just means the motor
+        // doesn't have a pre-defined waveform to perform for it, so we should just fall back
+        // to the framework waveforms.
+        ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32
+                ", error=%" PRIu32 ").", static_cast<int64_t>(effect),
+                static_cast<int32_t>(strength), static_cast<uint32_t>(status));
     }
     return -1;
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 136d335..8cac6e0 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -43,6 +43,7 @@
 import static android.app.admin.DevicePolicyManager.DELEGATION_PERMISSION_GRANT;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
 import static android.app.admin.DevicePolicyManager.PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER;
+import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
 import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE;
 import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA;
 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
@@ -1691,9 +1692,9 @@
             mContext.getSystemService(PowerManager.class).reboot(reason);
         }
 
-        void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force)
-                throws IOException {
-            RecoverySystem.rebootWipeUserData(mContext, shutdown, reason, force);
+        void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force,
+                boolean wipeEuicc) throws IOException {
+            RecoverySystem.rebootWipeUserData(mContext, shutdown, reason, force, wipeEuicc);
         }
 
         boolean systemPropertiesGetBoolean(String key, boolean def) {
@@ -5302,7 +5303,7 @@
         }
     }
 
-    private void forceWipeDeviceNoLock(boolean wipeExtRequested, String reason) {
+    private void forceWipeDeviceNoLock(boolean wipeExtRequested, String reason, boolean wipeEuicc) {
         wtfIfInLock();
 
         if (wipeExtRequested) {
@@ -5312,7 +5313,7 @@
         }
         try {
             mInjector.recoverySystemRebootWipeUserData(
-                    /*shutdown=*/ false, reason, /*force=*/ true);
+                    /*shutdown=*/ false, reason, /*force=*/ true, /*wipeEuicc=*/ wipeEuicc);
         } catch (IOException | SecurityException e) {
             Slog.w(LOG_TAG, "Failed requesting data wipe", e);
         }
@@ -5389,7 +5390,7 @@
             // removes that user (but still clears FRP...)
             if (userId == UserHandle.USER_SYSTEM) {
                 forceWipeDeviceNoLock(/*wipeExtRequested=*/ (flags & WIPE_EXTERNAL_STORAGE) != 0,
-                        reason);
+                        reason, /*wipeEuicc=*/ (flags & WIPE_EUICC) != 0);
             } else {
                 forceWipeUser(userId);
             }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
index 70c7e58..6086354 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
@@ -25,8 +25,8 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.SystemClock;
-import android.util.Log;
 import android.util.LongSparseArray;
+import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 
@@ -60,16 +60,21 @@
     /** Delay after which older batches get discarded after a retrieval. */
     private static final long RETRIEVED_BATCH_DISCARD_DELAY_MS = 5 * 60 * 1000; // 5m
 
+    /** Do not call into mDpm with locks held */
     private final DevicePolicyManagerService mDpm;
     private final AlarmManager mAlarmManager;
 
     private final OnAlarmListener mBatchTimeoutAlarmListener = new OnAlarmListener() {
         @Override
         public void onAlarm() {
-            Log.d(TAG, "Received a batch finalization timeout alarm, finalizing "
+            Slog.d(TAG, "Received a batch finalization timeout alarm, finalizing "
                     + mNetworkEvents.size() + " pending events.");
+            Bundle notificationExtras = null;
             synchronized (NetworkLoggingHandler.this) {
-                finalizeBatchAndNotifyDeviceOwnerLocked();
+                notificationExtras = finalizeBatchAndBuildDeviceOwnerMessageLocked();
+            }
+            if (notificationExtras != null) {
+                notifyDeviceOwner(notificationExtras);
             }
         }
     };
@@ -110,17 +115,21 @@
             case LOG_NETWORK_EVENT_MSG: {
                 final NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY);
                 if (networkEvent != null) {
+                    Bundle notificationExtras = null;
                     synchronized (NetworkLoggingHandler.this) {
                         mNetworkEvents.add(networkEvent);
                         if (mNetworkEvents.size() >= MAX_EVENTS_PER_BATCH) {
-                            finalizeBatchAndNotifyDeviceOwnerLocked();
+                            notificationExtras = finalizeBatchAndBuildDeviceOwnerMessageLocked();
                         }
                     }
+                    if (notificationExtras != null) {
+                        notifyDeviceOwner(notificationExtras);
+                    }
                 }
                 break;
             }
             default: {
-                Log.d(TAG, "NetworkLoggingHandler received an unknown of message.");
+                Slog.d(TAG, "NetworkLoggingHandler received an unknown of message.");
                 break;
             }
         }
@@ -133,40 +142,48 @@
         mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, when,
                 BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS, NETWORK_LOGGING_TIMEOUT_ALARM_TAG,
                 mBatchTimeoutAlarmListener, this);
-        Log.d(TAG, "Scheduled a new batch finalization alarm " + BATCH_FINALIZATION_TIMEOUT_MS
+        Slog.d(TAG, "Scheduled a new batch finalization alarm " + BATCH_FINALIZATION_TIMEOUT_MS
                 + "ms from now.");
     }
 
     synchronized void pause() {
-        Log.d(TAG, "Paused network logging");
+        Slog.d(TAG, "Paused network logging");
         mPaused = true;
     }
 
-    synchronized void resume() {
-        if (!mPaused) {
-            Log.d(TAG, "Attempted to resume network logging, but logging is not paused.");
-            return;
+    void resume() {
+        Bundle notificationExtras = null;
+        synchronized (this) {
+            if (!mPaused) {
+                Slog.d(TAG, "Attempted to resume network logging, but logging is not paused.");
+                return;
+            }
+
+            Slog.d(TAG, "Resumed network logging. Current batch=" + mCurrentBatchToken
+                    + ", LastRetrievedBatch=" + mLastRetrievedBatchToken);
+            mPaused = false;
+
+            // If there is a batch ready that the device owner hasn't been notified about, do it now.
+            if (mBatches.size() > 0 && mLastRetrievedBatchToken != mCurrentBatchToken) {
+                scheduleBatchFinalization();
+                notificationExtras = buildDeviceOwnerMessageLocked();
+            }
         }
-
-        Log.d(TAG, "Resumed network logging. Current batch=" + mCurrentBatchToken
-                + ", LastRetrievedBatch=" + mLastRetrievedBatchToken);
-        mPaused = false;
-
-        // If there is a batch ready that the device owner hasn't been notified about, do it now.
-        if (mBatches.size() > 0 && mLastRetrievedBatchToken != mCurrentBatchToken) {
-            scheduleBatchFinalization();
-            notifyDeviceOwnerLocked();
+        if (notificationExtras != null) {
+            notifyDeviceOwner(notificationExtras);
         }
     }
 
     synchronized void discardLogs() {
         mBatches.clear();
         mNetworkEvents = new ArrayList<>();
-        Log.d(TAG, "Discarded all network logs");
+        Slog.d(TAG, "Discarded all network logs");
     }
 
     @GuardedBy("this")
-    private void finalizeBatchAndNotifyDeviceOwnerLocked() {
+    /** @returns extras if a message should be sent to the device owner */
+    private Bundle finalizeBatchAndBuildDeviceOwnerMessageLocked() {
+        Bundle notificationExtras = null;
         if (mNetworkEvents.size() > 0) {
             // Finalize the batch and start a new one from scratch.
             if (mBatches.size() >= MAX_BATCHES) {
@@ -177,27 +194,39 @@
             mBatches.append(mCurrentBatchToken, mNetworkEvents);
             mNetworkEvents = new ArrayList<>();
             if (!mPaused) {
-                notifyDeviceOwnerLocked();
+                notificationExtras = buildDeviceOwnerMessageLocked();
             }
         } else {
             // Don't notify the DO, since there are no events; DPC can still retrieve
             // the last full batch if not paused.
-            Log.d(TAG, "Was about to finalize the batch, but there were no events to send to"
+            Slog.d(TAG, "Was about to finalize the batch, but there were no events to send to"
                     + " the DPC, the batchToken of last available batch: " + mCurrentBatchToken);
         }
         // Regardless of whether the batch was non-empty schedule a new finalization after timeout.
         scheduleBatchFinalization();
+        return notificationExtras;
     }
 
-    /** Sends a notification to the DO. Should only be called when there is a batch available. */
     @GuardedBy("this")
-    private void notifyDeviceOwnerLocked() {
+    /** Build extras notification to the DO. Should only be called when there
+        is a batch available. */
+    private Bundle buildDeviceOwnerMessageLocked() {
         final Bundle extras = new Bundle();
         final int lastBatchSize = mBatches.valueAt(mBatches.size() - 1).size();
         extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentBatchToken);
         extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, lastBatchSize);
-        Log.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: "
-                + mCurrentBatchToken);
+        return extras;
+    }
+
+    /** Sends a notification to the DO. Should not hold locks as DevicePolicyManagerService may
+        call into NetworkLoggingHandler. */
+    private void notifyDeviceOwner(Bundle extras) {
+        Slog.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: "
+                + extras.getLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, -1));
+        if (Thread.holdsLock(this)) {
+            Slog.wtfStack(TAG, "Shouldn't be called with NetworkLoggingHandler lock held");
+            return;
+        }
         mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras);
     }
 
diff --git a/services/tests/notification/AndroidManifest.xml b/services/tests/notification/AndroidManifest.xml
index 99d9c7b..c20020a 100644
--- a/services/tests/notification/AndroidManifest.xml
+++ b/services/tests/notification/AndroidManifest.xml
@@ -31,7 +31,7 @@
     </application>
 
     <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:name="android.testing.TestableInstrumentation"
         android:targetPackage="com.android.frameworks.tests.notification"
         android:label="Notification Tests" />
 </manifest>
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
index a33153e..5471715 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -269,9 +269,9 @@
         }
 
         @Override
-        void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force)
-                throws IOException {
-            services.recoverySystem.rebootWipeUserData(shutdown, reason, force);
+        void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force,
+                boolean wipeEuicc) throws IOException {
+            services.recoverySystem.rebootWipeUserData(shutdown, reason, force, wipeEuicc);
         }
 
         @Override
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 6393b0b..c58b733 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -17,6 +17,7 @@
 
 import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS;
 import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL;
+import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
 import static android.os.UserManagerInternal.CAMERA_DISABLED_GLOBALLY;
 import static android.os.UserManagerInternal.CAMERA_DISABLED_LOCALLY;
 import static android.os.UserManagerInternal.CAMERA_NOT_DISABLED;
@@ -3451,7 +3452,21 @@
 
         dpm.wipeData(0);
         verify(getServices().recoverySystem).rebootWipeUserData(
-                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true));
+                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true),
+                /*wipeEuicc=*/ eq(false));
+    }
+
+    public void testWipeEuiccDataEnabled() throws Exception {
+        setDeviceOwner();
+        when(getServices().userManager.getUserRestrictionSource(
+            UserManager.DISALLOW_FACTORY_RESET,
+            UserHandle.SYSTEM))
+            .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
+
+        dpm.wipeData(WIPE_EUICC);
+        verify(getServices().recoverySystem).rebootWipeUserData(
+                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true),
+                /*wipeEuicc=*/ eq(true));
     }
 
     public void testWipeDataDeviceOwnerDisallowed() throws Exception {
@@ -3549,7 +3564,8 @@
         // The device should be wiped even if DISALLOW_FACTORY_RESET is enabled, because both the
         // user restriction and the policy were set by the DO.
         verify(getServices().recoverySystem).rebootWipeUserData(
-                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true));
+                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true),
+                /*wipeEuicc=*/ eq(false));
     }
 
     public void testMaximumFailedPasswordAttemptsReachedDeviceOwnerDisallowed() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
index ed8de05..8121bcf 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -314,8 +314,8 @@
     }
 
     public static class RecoverySystemForMock {
-        public void rebootWipeUserData(
-                boolean shutdown, String reason, boolean force) throws IOException {
+        public void rebootWipeUserData(boolean shutdown, String reason, boolean force,
+                boolean wipeEuicc) throws IOException {
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index c399a5d..61df22e 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -29,8 +29,11 @@
 import android.view.WindowManagerInternal;
 
 import com.android.server.LocalServices;
+import com.android.server.SystemService;
+import com.android.server.display.DisplayDeviceInfo;
 import com.android.server.display.DisplayManagerService.SyncRoot;
 import com.android.server.display.VirtualDisplayAdapter.SurfaceControlDisplayFactory;
+import com.android.server.lights.LightsManager;
 
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
@@ -44,35 +47,51 @@
 
 @SmallTest
 public class DisplayManagerServiceTest extends AndroidTestCase {
-    private Handler mHandler;
-    private DisplayManagerService mDisplayManager;
+    private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
+    private static final long SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS = 10;
+
+    private final DisplayManagerService.Injector mShortMockedInjector =
+            new DisplayManagerService.Injector() {
+                @Override
+                VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
+                        Context context, Handler handler, DisplayAdapter.Listener listener) {
+                    return mMockVirtualDisplayAdapter;
+                }
+
+                @Override
+                long getDefaultDisplayDelayTimeout() {
+                    return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS;
+                }
+            };
+    private final DisplayManagerService.Injector mBasicInjector =
+            new DisplayManagerService.Injector() {
+                @Override
+                VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
+                        Context context, Handler handler,
+                        DisplayAdapter.Listener displayAdapterListener) {
+                    return new VirtualDisplayAdapter(syncRoot, context, handler,
+                            displayAdapterListener,
+                            (String name, boolean secure) -> mMockDisplayToken);
+                }
+            };
+
     @Mock InputManagerInternal mMockInputManagerInternal;
     @Mock IVirtualDisplayCallback.Stub mMockAppToken;
     @Mock WindowManagerInternal mMockWindowManagerInternal;
+    @Mock LightsManager mMockLightsManager;
     @Mock VirtualDisplayAdapter mMockVirtualDisplayAdapter;
     @Mock IBinder mMockDisplayToken;
 
     @Override
     protected void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mDisplayManager = new DisplayManagerService(mContext,
-        new DisplayManagerService.Injector() {
-            @Override
-            VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context,
-                    Handler handler, DisplayAdapter.Listener displayAdapterListener) {
-                return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener,
-                        (String name, boolean secure) -> mMockDisplayToken);
-            }
-        });
-        mHandler = mDisplayManager.getDisplayHandler();
 
         LocalServices.removeServiceForTest(InputManagerInternal.class);
         LocalServices.addService(InputManagerInternal.class, mMockInputManagerInternal);
         LocalServices.removeServiceForTest(WindowManagerInternal.class);
         LocalServices.addService(WindowManagerInternal.class, mMockWindowManagerInternal);
-
-        mDisplayManager.systemReady(false /* safeMode */, false /* onlyCore */);
-        mDisplayManager.windowManagerAndInputReady();
+        LocalServices.removeServiceForTest(LightsManager.class);
+        LocalServices.addService(LightsManager.class, mMockLightsManager);
         super.setUp();
     }
 
@@ -82,8 +101,14 @@
     }
 
     public void testCreateVirtualDisplay_sentToInputManager() throws Exception {
+        DisplayManagerService displayManager =
+                new DisplayManagerService(mContext, mBasicInjector);
+        registerDefaultDisplays(displayManager);
+        displayManager.systemReady(false /* safeMode */, true /* onlyCore */);
+        displayManager.windowManagerAndInputReady();
+
         // This is effectively the DisplayManager service published to ServiceManager.
-        DisplayManagerService.BinderService bs = mDisplayManager.new BinderService();
+        DisplayManagerService.BinderService bs = displayManager.new BinderService();
 
         String uniqueId = "uniqueId --- Test";
         String uniqueIdPrefix = "virtual:" + mContext.getPackageName() + ":";
@@ -98,10 +123,10 @@
                 "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */,
                 uniqueId);
 
-        mDisplayManager.performTraversalInTransactionFromWindowManagerInternal();
+        displayManager.performTraversalInTransactionFromWindowManagerInternal();
 
         // flush the handler
-        mHandler.runWithScissors(() -> {}, 0 /* now */);
+        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
 
         ArgumentCaptor<List<DisplayViewport>> virtualViewportCaptor =
                 ArgumentCaptor.forClass(List.class);
@@ -115,4 +140,97 @@
         assertEquals(uniqueIdPrefix + uniqueId, dv.uniqueId);
         assertEquals(displayId, dv.displayId);
     }
+
+    public void testCreateVirtualDisplayRotatesWithContent() throws Exception {
+        DisplayManagerService displayManager =
+                new DisplayManagerService(mContext, mBasicInjector);
+        registerDefaultDisplays(displayManager);
+
+        // This is effectively the DisplayManager service published to ServiceManager.
+        DisplayManagerService.BinderService bs = displayManager.new BinderService();
+
+        String uniqueId = "uniqueId --- Rotates With Content Test";
+        int width = 600;
+        int height = 800;
+        int dpi = 320;
+        int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
+
+        when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+        int displayId = bs.createVirtualDisplay(mMockAppToken /* callback */,
+                null /* projection */, "com.android.frameworks.servicestests",
+                "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */,
+                uniqueId);
+
+        displayManager.performTraversalInTransactionFromWindowManagerInternal();
+
+        // flush the handler
+        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
+
+        DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
+        assertNotNull(ddi);
+        assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0);
+    }
+
+    /**
+     * Tests that the virtual display is created along-side the default display.
+     */
+    public void testStartVirtualDisplayWithDefaultDisplay_Succeeds() throws Exception {
+        DisplayManagerService displayManager =
+                new DisplayManagerService(mContext, mShortMockedInjector);
+        registerDefaultDisplays(displayManager);
+        displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
+    }
+
+    /**
+     * Tests that we get a Runtime exception when we cannot initialize the default display.
+     */
+    public void testStartVirtualDisplayWithDefDisplay_NoDefaultDisplay() throws Exception {
+        DisplayManagerService displayManager =
+                new DisplayManagerService(mContext, mShortMockedInjector);
+        Handler handler = displayManager.getDisplayHandler();
+        handler.runWithScissors(() -> {}, 0 /* now */);
+
+        try {
+            displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
+        } catch (RuntimeException e) {
+            return;
+        }
+        fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the"
+                + " default display");
+    }
+
+    /**
+     * Tests that we get a Runtime exception when we cannot initialize the virtual display.
+     */
+    public void testStartVirtualDisplayWithDefDisplay_NoVirtualDisplayAdapter() throws Exception {
+        DisplayManagerService displayManager = new DisplayManagerService(mContext,
+                new DisplayManagerService.Injector() {
+                    @Override
+                    VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
+                            Context context, Handler handler, DisplayAdapter.Listener listener) {
+                        return null;  // return null for the adapter.  This should cause a failure.
+                    }
+
+                    @Override
+                    long getDefaultDisplayDelayTimeout() {
+                        return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS;
+                    }
+                });
+        try {
+            displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
+        } catch (RuntimeException e) {
+            return;
+        }
+        fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the"
+                + " virtual display adapter");
+    }
+
+    private void registerDefaultDisplays(DisplayManagerService displayManager) {
+        Handler handler = displayManager.getDisplayHandler();
+        // Would prefer to call displayManager.onStart() directly here but it performs binderService
+        // registration which triggers security exceptions when running from a test.
+        handler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
+        // flush the handler
+        handler.runWithScissors(() -> {}, 0 /* now */);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
index c809c32..67db5f4 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -218,8 +218,7 @@
         root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
         root.mTurnOnScreen = false;
 
-        root.prepareWindowToDisplayDuringRelayout(new MergedConfiguration(),
-                wasVisible /*wasVisible*/);
+        root.prepareWindowToDisplayDuringRelayout(wasVisible /*wasVisible*/);
         assertTrue(root.mTurnOnScreen);
     }
 }
diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
index d315b18..68c1d5f 100644
--- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java
+++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
@@ -65,6 +65,9 @@
     private final HashMap<UsbDevice,UsbAudioDevice>
         mAudioDevices = new HashMap<UsbDevice,UsbAudioDevice>();
 
+    private boolean mIsInputHeadset; // as reported by UsbDescriptorParser
+    private boolean mIsOutputHeadset; // as reported by UsbDescriptorParser
+
     private final HashMap<UsbDevice,UsbMidiDevice>
         mMidiDevices = new HashMap<UsbDevice,UsbMidiDevice>();
 
@@ -184,9 +187,14 @@
         try {
             // Playback Device
             if (audioDevice.mHasPlayback) {
-                int device = (audioDevice == mAccessoryAudioDevice ?
-                        AudioSystem.DEVICE_OUT_USB_ACCESSORY :
-                        AudioSystem.DEVICE_OUT_USB_DEVICE);
+                int device;
+                if (mIsOutputHeadset) {
+                    device = AudioSystem.DEVICE_OUT_USB_HEADSET;
+                } else {
+                    device = (audioDevice == mAccessoryAudioDevice
+                        ? AudioSystem.DEVICE_OUT_USB_ACCESSORY
+                        : AudioSystem.DEVICE_OUT_USB_DEVICE);
+                }
                 if (DEBUG) {
                     Slog.i(TAG, "pre-call device:0x" + Integer.toHexString(device) +
                             " addr:" + address + " name:" + audioDevice.getDeviceName());
@@ -197,9 +205,14 @@
 
             // Capture Device
             if (audioDevice.mHasCapture) {
-               int device = (audioDevice == mAccessoryAudioDevice ?
-                        AudioSystem.DEVICE_IN_USB_ACCESSORY :
-                        AudioSystem.DEVICE_IN_USB_DEVICE);
+                int device;
+                if (mIsInputHeadset) {
+                    device = AudioSystem.DEVICE_IN_USB_HEADSET;
+                } else {
+                    device = (audioDevice == mAccessoryAudioDevice
+                        ? AudioSystem.DEVICE_IN_USB_ACCESSORY
+                        : AudioSystem.DEVICE_IN_USB_DEVICE);
+                }
                 mAudioService.setWiredDeviceConnectionState(
                         device, state, address, audioDevice.getDeviceName(), TAG);
             }
@@ -343,12 +356,16 @@
         return selectAudioCard(mCardsParser.getDefaultCard());
     }
 
-    /* package */ void usbDeviceAdded(UsbDevice usbDevice) {
-       if (DEBUG) {
-          Slog.d(TAG, "deviceAdded(): " + usbDevice.getManufacturerName() +
-                  " nm:" + usbDevice.getProductName());
+    /* package */ void usbDeviceAdded(UsbDevice usbDevice,
+            boolean isInputHeadset, boolean isOutputHeadset) {
+        if (DEBUG) {
+            Slog.d(TAG, "deviceAdded(): " + usbDevice.getManufacturerName()
+                    + " nm:" + usbDevice.getProductName());
         }
 
+        mIsInputHeadset = isInputHeadset;
+        mIsOutputHeadset = isOutputHeadset;
+
         // Is there an audio interface in there?
         boolean isAudioDevice = false;
 
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index af78c05..40aadbb 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -16,7 +16,6 @@
 
 package com.android.server.usb;
 
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
@@ -32,6 +31,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.usb.descriptors.UsbDescriptorParser;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -259,7 +259,14 @@
                     getCurrentUserSettings().deviceAttachedForFixedHandler(mNewDevice,
                             usbDeviceConnectionHandler);
                 }
-                mUsbAlsaManager.usbDeviceAdded(mNewDevice);
+                // deviceName is something like: "/dev/bus/usb/001/001"
+                UsbDescriptorParser parser = new UsbDescriptorParser();
+                if (parser.parseDevice(mNewDevice.getDeviceName())) {
+                    Slog.i(TAG, "---- isHeadset[in:" + parser.isInputHeadset()
+                            + " , out:" + parser.isOutputHeadset() + "]");
+                    mUsbAlsaManager.usbDeviceAdded(mNewDevice,
+                            parser.isInputHeadset(), parser.isOutputHeadset());
+                }
             } else {
                 Slog.e(TAG, "mNewDevice is null in endUsbDeviceAdded");
             }
diff --git a/services/usb/java/com/android/server/usb/descriptors/ByteStream.java b/services/usb/java/com/android/server/usb/descriptors/ByteStream.java
new file mode 100644
index 0000000..d678931
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/ByteStream.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+import android.annotation.NonNull;
+
+/**
+ * @hide
+ * A stream interface wrapping a byte array. Very much like a java.io.ByteArrayInputStream
+ * but with the capability to "back up" in situations where the parser discovers that a
+ * UsbDescriptor has overrun its length.
+ */
+public class ByteStream {
+    private static final String TAG = "ByteStream";
+
+    /** The byte array being wrapped */
+    @NonNull
+    private final byte[] mBytes; // this is never null.
+
+    /**
+     * The index into the byte array to be read next.
+     * This value is altered by reading data out of the stream
+     * (using either the getByte() or unpack*() methods), or alternatively
+     * by explicitly offseting the stream position with either
+     * advance() or reverse().
+     */
+    private int mIndex;
+
+    /*
+     * This member used with resetReadCount() & getReadCount() can be used to determine how many
+     * bytes a UsbDescriptor subclass ACTUALLY reads (as opposed to what its length field says).
+     * using this info, the parser can mark a descriptor as valid or invalid and correct the stream
+     * position with advance() & reverse() to keep from "getting lost" in the descriptor stream.
+     */
+    private int mReadCount;
+
+    /**
+     * Create a ByteStream object wrapping the specified byte array.
+     *
+     * @param bytes The byte array containing the raw descriptor information retrieved from
+     *              the USB device.
+     * @throws IllegalArgumentException
+     */
+    public ByteStream(@NonNull byte[] bytes) {
+        if (bytes == null) {
+            throw new IllegalArgumentException();
+        }
+        mBytes = bytes;
+    }
+
+    /**
+     * Resets the running count of bytes read so that later we can see how much more has been read.
+     */
+    public void resetReadCount() {
+        mReadCount = 0;
+    }
+
+    /**
+     * Retrieves the running count of bytes read from the stream.
+     */
+    public int getReadCount() {
+        return mReadCount;
+    }
+
+    /**
+     * @return The value of the next byte in the stream without advancing the stream.
+     * Does not affect the running count as the byte hasn't been "consumed".
+     * @throws IndexOutOfBoundsException
+     */
+    public byte peekByte() {
+        if (available() > 0) {
+            return mBytes[mIndex + 1];
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * @return the next byte from the stream and advances the stream and the read count. Note
+     * that this is a signed byte (as is the case of byte in Java). The user may need to understand
+     * from context if it should be interpreted as an unsigned value.
+     * @throws IndexOutOfBoundsException
+     */
+    public byte getByte() {
+        if (available() > 0) {
+            mReadCount++;
+            return mBytes[mIndex++];
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Reads 2 bytes in *little endian format* from the stream and composes a 16-bit integer.
+     * As we are storing the 2-byte value in a 4-byte integer, the upper 2 bytes are always
+     * 0, essentially making the returned value *unsigned*.
+     * @return The 16-bit integer (packed into the lower 2 bytes of an int) encoded by the
+     * next 2 bytes in the stream.
+     * @throws IndexOutOfBoundsException
+     */
+    public int unpackUsbWord() {
+        if (available() >= 2) {
+            int b0 = getByte();
+            int b1 = getByte();
+            return ((b1 << 8) & 0x0000FF00) | (b0 & 0x000000FF);
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Reads 3 bytes in *little endian format* from the stream and composes a 24-bit integer.
+     * As we are storing the 3-byte value in a 4-byte integer, the upper byte is always
+     * 0, essentially making the returned value *unsigned*.
+     * @return The 24-bit integer (packed into the lower 3 bytes of an int) encoded by the
+     * next 3 bytes in the stream.
+     * @throws IndexOutOfBoundsException
+     */
+    public int unpackUsbTriple() {
+        if (available() >= 3) {
+            int b0 = getByte();
+            int b1 = getByte();
+            int b2 = getByte();
+            return ((b2 << 16) & 0x00FF0000) | ((b1 << 8) & 0x0000FF00) | (b0 & 0x000000FF);
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Advances the logical position in the stream. Affects the running count also.
+     * @param numBytes The number of bytes to advance.
+     * @throws IndexOutOfBoundsException
+     * @throws IllegalArgumentException
+     */
+    public void advance(int numBytes) {
+        if (numBytes < 0) {
+            // Positive offsets only
+            throw new IllegalArgumentException();
+        }
+        // do arithmetic and comparison in long to ovoid potention integer overflow
+        long longNewIndex = (long) mIndex + (long) numBytes;
+        if (longNewIndex < (long) mBytes.length) {
+            mReadCount += numBytes;
+            mIndex += numBytes;
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Reverse the logical position in the stream. Affects the running count also.
+     * @param numBytes The (positive) number of bytes to reverse.
+     * @throws IndexOutOfBoundsException
+     * @throws IllegalArgumentException
+     */
+    public void reverse(int numBytes) {
+        if (numBytes < 0) {
+            // Positive (reverse) offsets only
+            throw new IllegalArgumentException();
+        }
+        if (mIndex >= numBytes) {
+            mReadCount -= numBytes;
+            mIndex -= numBytes;
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * @return The number of bytes available to be read in the stream.
+     */
+    public int available() {
+        return mBytes.length - mIndex;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACAudioControlEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACAudioControlEndpoint.java
new file mode 100644
index 0000000..96fcc6a
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACAudioControlEndpoint.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Audio Control Endpoint.
+ * audio10.pdf section 4.4.2.1
+ */
+public class UsbACAudioControlEndpoint extends UsbACEndpoint {
+    private static final String TAG = "ACAudioControlEndpoint";
+
+    private byte mAddress;  // 2:1 The address of the endpoint on the USB device.
+                            // D7: Direction. 1 = IN endpoint
+                            // D6..4: Reserved, reset to zero
+                            // D3..0: The endpoint number.
+    private byte mAttribs;  // 3:1 (see ATTRIBSMASK_* below
+    private int mMaxPacketSize; // 4:2 Maximum packet size this endpoint is capable of sending
+                                // or receiving when this configuration is selected.
+    private byte mInterval; // 6:1
+
+    static final byte ADDRESSMASK_DIRECTION = (byte) 0x80;
+    static final byte ADDRESSMASK_ENDPOINT  = 0x0F;
+
+    static final byte ATTRIBSMASK_SYNC  = 0x0C;
+    static final byte ATTRIBMASK_TRANS  = 0x03;
+
+    public UsbACAudioControlEndpoint(int length, byte type, byte subclass) {
+        super(length, type, subclass);
+    }
+
+    public byte getAddress() {
+        return mAddress;
+    }
+
+    public byte getAttribs() {
+        return mAttribs;
+    }
+
+    public int getMaxPacketSize() {
+        return mMaxPacketSize;
+    }
+
+    public byte getInterval() {
+        return mInterval;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        super.parseRawDescriptors(stream);
+
+        mAddress = stream.getByte();
+        mAttribs = stream.getByte();
+        mMaxPacketSize = stream.unpackUsbWord();
+        mInterval = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACAudioStreamEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACAudioStreamEndpoint.java
new file mode 100644
index 0000000..d387883
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACAudioStreamEndpoint.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Streaming Endpoint
+ * see audio10.pdf section 3.7.2
+ */
+public class UsbACAudioStreamEndpoint extends UsbACEndpoint {
+    private static final String TAG = "ACAudioStreamEndpoint";
+
+    //TODO data fields...
+    public UsbACAudioStreamEndpoint(int length, byte type, byte subclass) {
+        super(length, type, subclass);
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        super.parseRawDescriptors(stream);
+
+        //TODO Read fields
+        stream.advance(mLength - stream.getReadCount());
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java
new file mode 100644
index 0000000..223496ab
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+import android.util.Log;
+
+/**
+ * @hide
+ * An audio class-specific Endpoint
+ * see audio10.pdf section 4.4.1.2
+ */
+abstract class UsbACEndpoint extends UsbDescriptor {
+    private static final String TAG = "ACEndpoint";
+
+    protected final byte mSubclass; // from the mSubclass member of the "enclosing"
+                                    // Interface Descriptor, not the stream.
+    protected byte mSubtype;        // 2:1 HEADER descriptor subtype
+
+    UsbACEndpoint(int length, byte type, byte subclass) {
+        super(length, type);
+        mSubclass = subclass;
+    }
+
+    public byte getSubclass() {
+        return mSubclass;
+    }
+
+    public byte getSubtype() {
+        return mSubtype;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mSubtype = stream.getByte();
+
+        return mLength;
+    }
+
+    public static UsbDescriptor allocDescriptor(UsbDescriptorParser parser,
+            int length, byte type) {
+        UsbInterfaceDescriptor interfaceDesc = parser.getCurInterface();
+        byte subClass = interfaceDesc.getUsbSubclass();
+        switch (subClass) {
+            case AUDIO_AUDIOCONTROL:
+                return new UsbACAudioControlEndpoint(length, type, subClass);
+
+            case AUDIO_AUDIOSTREAMING:
+                return new UsbACAudioStreamEndpoint(length, type, subClass);
+
+            case AUDIO_MIDISTREAMING:
+                return new UsbACMidiEndpoint(length, type, subClass);
+
+            default:
+                Log.w(TAG, "Unknown Audio Class Endpoint id:0x" + Integer.toHexString(subClass));
+                return null;
+        }
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACFeatureUnit.java b/services/usb/java/com/android/server/usb/descriptors/UsbACFeatureUnit.java
new file mode 100644
index 0000000..739fe55
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACFeatureUnit.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Feature Unit Interface
+ * see audio10.pdf section 3.5.5
+ */
+public class UsbACFeatureUnit extends UsbACInterface {
+    private static final String TAG = "ACFeatureUnit";
+
+    // audio10.pdf section 4.3.2.5
+    public static final int CONTROL_MASK_MUTE =    0x0001;
+    public static final int CONTROL_MASK_VOL =     0x0002;
+    public static final int CONTROL_MASK_BASS =    0x0004;
+    public static final int CONTROL_MASK_MID =     0x0008;
+    public static final int CONTROL_MASK_TREB =    0x0010;
+    public static final int CONTROL_MASK_EQ =      0x0020;
+    public static final int CONTROL_MASK_AGC =     0x0040;
+    public static final int CONTROL_MASK_DELAY =   0x0080;
+    public static final int CONTROL_MASK_BOOST =   0x0100; // BASS boost
+    public static final int CONTROL_MASK_LOUD =    0x0200; // LOUDNESS
+
+    private int mNumChannels;
+
+    private byte mUnitID;   // 3:1 Constant uniquely identifying the Unit within the audio function.
+                            // This value is used in all requests to address this Unit
+    private byte mSourceID; // 4:1 ID of the Unit or Terminal to which this Feature Unit
+                            // is connected.
+    private byte mControlSize;  // 5:1 Size in bytes of an element of the mControls array: n
+    private int[] mControls;    // 6:? bitmask (see above) of supported controls in a given
+                                // logical channel
+    private byte mUnitName;     // ?:1 Index of a string descriptor, describing this Feature Unit.
+
+    public UsbACFeatureUnit(int length, byte type, byte subtype, byte subClass) {
+        super(length, type, subtype, subClass);
+    }
+
+    public int getNumChannels() {
+        return mNumChannels;
+    }
+
+    public byte getUnitID() {
+        return mUnitID;
+    }
+
+    public byte getSourceID() {
+        return mSourceID;
+    }
+
+    public byte getControlSize() {
+        return mControlSize;
+    }
+
+    public int[] getControls() {
+        return mControls;
+    }
+
+    public byte getUnitName() {
+        return mUnitName;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACHeader.java b/services/usb/java/com/android/server/usb/descriptors/UsbACHeader.java
new file mode 100644
index 0000000..e31438c
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACHeader.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Interface Header.
+ * see audio10.pdf section 4.3.2
+ */
+public class UsbACHeader extends UsbACInterface {
+    private static final String TAG = "ACHeader";
+
+    private int mADCRelease;    // 3:2 Audio Device Class Specification Release (BCD).
+    private int mTotalLength;   // 5:2 Total number of bytes returned for the class-specific
+                                // AudioControl interface descriptor. Includes the combined length
+                                // of this descriptor header and all Unit and Terminal descriptors.
+    private byte mNumInterfaces = 0; // 7:1 The number of AudioStreaming and MIDIStreaming
+                                     // interfaces in the Audio Interface Collection to which this
+                                     // AudioControl interface belongs: n
+    private byte[] mInterfaceNums = null;   // 8:n List of Audio/MIDI streaming interface
+                                            // numbers associate with this endpoint
+    private byte mControls;                 // Vers 2.0 thing
+
+    public UsbACHeader(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    public int getADCRelease() {
+        return mADCRelease;
+    }
+
+    public int getTotalLength() {
+        return mTotalLength;
+    }
+
+    public byte getNumInterfaces() {
+        return mNumInterfaces;
+    }
+
+    public byte[] getInterfaceNums() {
+        return mInterfaceNums;
+    }
+
+    public byte getControls() {
+        return mControls;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mADCRelease = stream.unpackUsbWord();
+
+        mTotalLength = stream.unpackUsbWord();
+        if (mADCRelease >= 0x200) {
+            mControls = stream.getByte();
+        } else {
+            mNumInterfaces = stream.getByte();
+            mInterfaceNums = new byte[mNumInterfaces];
+            for (int index = 0; index < mNumInterfaces; index++) {
+                mInterfaceNums[index] = stream.getByte();
+            }
+        }
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACInputTerminal.java b/services/usb/java/com/android/server/usb/descriptors/UsbACInputTerminal.java
new file mode 100644
index 0000000..653a7de
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACInputTerminal.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Input Terminal interface.
+ * see audio10.pdf section 4.3.2.1
+ */
+public class UsbACInputTerminal extends UsbACTerminal {
+    private static final String TAG = "ACInputTerminal";
+
+    private byte mNrChannels;       // 7:1 1 Channel (0x01)
+                                    // Number of logical output channels in the
+                                    // Terminal’s output audio channel cluster
+    private int mChannelConfig;     // 8:2 Mono (0x0000)
+    private byte mChannelNames;     // 10:1 Unused (0x00)
+    private byte mTerminal;         // 11:1 Unused (0x00)
+
+    public UsbACInputTerminal(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    public byte getNrChannels() {
+        return mNrChannels;
+    }
+
+    public int getChannelConfig() {
+        return mChannelConfig;
+    }
+
+    public byte getChannelNames() {
+        return mChannelNames;
+    }
+
+    public byte getTerminal() {
+        return mTerminal;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        super.parseRawDescriptors(stream);
+
+        mNrChannels = stream.getByte();
+        mChannelConfig = stream.unpackUsbWord();
+        mChannelNames = stream.getByte();
+        mTerminal = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java b/services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java
new file mode 100644
index 0000000..0ab7fcc
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+import android.util.Log;
+
+/**
+ * @hide
+ * An audio class-specific Interface.
+ * see audio10.pdf section 4.3.2
+ */
+public abstract class UsbACInterface extends UsbDescriptor {
+    private static final String TAG = "ACInterface";
+
+    // Audio Control Subtypes
+    public static final byte ACI_UNDEFINED = 0;
+    public static final byte ACI_HEADER = 1;
+    public static final byte ACI_INPUT_TERMINAL = 2;
+    public static final byte ACI_OUTPUT_TERMINAL = 3;
+    public static final byte ACI_MIXER_UNIT = 4;
+    public static final byte ACI_SELECTOR_UNIT = 5;
+    public static final byte ACI_FEATURE_UNIT = 6;
+    public static final byte ACI_PROCESSING_UNIT = 7;
+    public static final byte ACI_EXTENSION_UNIT = 8;
+
+    // Audio Streaming Subtypes
+    public static final byte ASI_UNDEFINED = 0;
+    public static final byte ASI_GENERAL = 1;
+    public static final byte ASI_FORMAT_TYPE = 2;
+    public static final byte ASI_FORMAT_SPECIFIC = 3;
+
+    // MIDI Streaming Subtypes
+    public static final byte MSI_UNDEFINED = 0;
+    public static final byte MSI_HEADER = 1;
+    public static final byte MSI_IN_JACK = 2;
+    public static final byte MSI_OUT_JACK = 3;
+    public static final byte MSI_ELEMENT = 4;
+
+    // Sample format IDs (encodings)
+    // FORMAT_I
+    public static final int FORMAT_I_UNDEFINED     = 0x0000;
+    public static final int FORMAT_I_PCM           = 0x0001;
+    public static final int FORMAT_I_PCM8          = 0x0002;
+    public static final int FORMAT_I_IEEE_FLOAT    = 0x0003;
+    public static final int FORMAT_I_ALAW          = 0x0004;
+    public static final int FORMAT_I_MULAW         = 0x0005;
+    // FORMAT_II
+    public static final int FORMAT_II_UNDEFINED    = 0x1000;
+    public static final int FORMAT_II_MPEG         = 0x1001;
+    public static final int FORMAT_II_AC3          = 0x1002;
+    // FORMAT_III
+    public static final int FORMAT_III_UNDEFINED              = 0x2000;
+    public static final int FORMAT_III_IEC1937AC3             = 0x2001;
+    public static final int FORMAT_III_IEC1937_MPEG1_Layer1   = 0x2002;
+    public static final int FORMAT_III_IEC1937_MPEG1_Layer2   = 0x2003;
+    public static final int FORMAT_III_IEC1937_MPEG2_EXT      = 0x2004;
+    public static final int FORMAT_III_IEC1937_MPEG2_Layer1LS = 0x2005;
+
+    protected final byte mSubtype;  // 2:1 HEADER descriptor subtype
+    protected final byte mSubclass; // from the mSubclass member of the
+                                    // "enclosing" Interface Descriptor
+
+    public UsbACInterface(int length, byte type, byte subtype, byte subclass) {
+        super(length, type);
+        mSubtype = subtype;
+        mSubclass = subclass;
+    }
+
+    public byte getSubtype() {
+        return mSubtype;
+    }
+
+    public byte getSubclass() {
+        return mSubclass;
+    }
+
+    private static UsbDescriptor allocAudioControlDescriptor(ByteStream stream,
+            int length, byte type, byte subtype, byte subClass) {
+        switch (subtype) {
+            case ACI_HEADER:
+                return new UsbACHeader(length, type, subtype, subClass);
+
+            case ACI_INPUT_TERMINAL:
+                return new UsbACInputTerminal(length, type, subtype, subClass);
+
+            case ACI_OUTPUT_TERMINAL:
+                return new UsbACOutputTerminal(length, type, subtype, subClass);
+
+            case ACI_SELECTOR_UNIT:
+                return new UsbACSelectorUnit(length, type, subtype, subClass);
+
+            case ACI_FEATURE_UNIT:
+                return new UsbACFeatureUnit(length, type, subtype, subClass);
+
+            case ACI_MIXER_UNIT:
+                return new UsbACMixerUnit(length, type, subtype, subClass);
+
+            case ACI_PROCESSING_UNIT:
+            case ACI_EXTENSION_UNIT:
+            case ACI_UNDEFINED:
+                // break; Fall through until we implement this descriptor
+            default:
+                Log.w(TAG, "Unknown Audio Class Interface subtype:0x"
+                        + Integer.toHexString(subtype));
+                return null;
+        }
+    }
+
+    private static UsbDescriptor allocAudioStreamingDescriptor(ByteStream stream,
+            int length, byte type, byte subtype, byte subClass) {
+        switch (subtype) {
+            case ASI_GENERAL:
+                return new UsbASGeneral(length, type, subtype, subClass);
+
+            case ASI_FORMAT_TYPE:
+                return UsbASFormat.allocDescriptor(stream, length, type, subtype, subClass);
+
+            case ASI_FORMAT_SPECIFIC:
+            case ASI_UNDEFINED:
+                // break; Fall through until we implement this descriptor
+            default:
+                Log.w(TAG, "Unknown Audio Streaming Interface subtype:0x"
+                        + Integer.toHexString(subtype));
+                return null;
+        }
+    }
+
+    private static UsbDescriptor allocMidiStreamingDescriptor(int length, byte type,
+            byte subtype, byte subClass) {
+        switch (subtype) {
+            case MSI_HEADER:
+                return new UsbMSMidiHeader(length, type, subtype, subClass);
+
+            case MSI_IN_JACK:
+                return new UsbMSMidiInputJack(length, type, subtype, subClass);
+
+            case MSI_OUT_JACK:
+                return new UsbMSMidiOutputJack(length, type, subtype, subClass);
+
+            case MSI_ELEMENT:
+                // break;
+                // Fall through until we implement that descriptor
+
+            case MSI_UNDEFINED:
+                // break; Fall through until we implement this descriptor
+            default:
+                Log.w(TAG, "Unknown MIDI Streaming Interface subtype:0x"
+                        + Integer.toHexString(subtype));
+                return null;
+        }
+    }
+
+    /**
+     * Allocates an audio class interface subtype based on subtype and subclass.
+     */
+    public static UsbDescriptor allocDescriptor(UsbDescriptorParser parser, ByteStream stream,
+            int length, byte type) {
+        byte subtype = stream.getByte();
+        UsbInterfaceDescriptor interfaceDesc = parser.getCurInterface();
+        byte subClass = interfaceDesc.getUsbSubclass();
+        switch (subClass) {
+            case AUDIO_AUDIOCONTROL:
+                return allocAudioControlDescriptor(stream, length, type, subtype, subClass);
+
+            case AUDIO_AUDIOSTREAMING:
+                return allocAudioStreamingDescriptor(stream, length, type, subtype, subClass);
+
+            case AUDIO_MIDISTREAMING:
+                return allocMidiStreamingDescriptor(length, type, subtype, subClass);
+
+            default:
+                Log.w(TAG, "Unknown Audio Class Interface Subclass: 0x"
+                        + Integer.toHexString(subClass));
+                return null;
+        }
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACMidiEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACMidiEndpoint.java
new file mode 100644
index 0000000..9c07242
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACMidiEndpoint.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Midi Endpoint.
+ * see midi10.pdf section 6.2.2
+ */
+public class UsbACMidiEndpoint extends UsbACEndpoint {
+    private static final String TAG = "ACMidiEndpoint";
+
+    private byte mNumJacks;
+    private byte[] mJackIds;
+
+    public UsbACMidiEndpoint(int length, byte type, byte subclass) {
+        super(length, type, subclass);
+    }
+
+    public byte getNumJacks() {
+        return mNumJacks;
+    }
+
+    public byte[] getJackIds() {
+        return mJackIds;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        super.parseRawDescriptors(stream);
+
+        mNumJacks = stream.getByte();
+        mJackIds = new byte[mNumJacks];
+        for (int jack = 0; jack < mNumJacks; jack++) {
+            mJackIds[jack] = stream.getByte();
+        }
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACMixerUnit.java b/services/usb/java/com/android/server/usb/descriptors/UsbACMixerUnit.java
new file mode 100644
index 0000000..552b5ae
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACMixerUnit.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Mixer Interface.
+ * see audio10.pdf section 4.3.2.3
+ */
+public class UsbACMixerUnit extends UsbACInterface {
+    private static final String TAG = "ACMixerUnit";
+
+    private byte mUnitID;       // 3:1
+    private byte mNumInputs;    // 4:1 Number of Input Pins of this Unit.
+    private byte[] mInputIDs;   // 5...:1 ID of the Unit or Terminal to which the Input Pins
+                                // are connected.
+    private byte mNumOutputs;   // The number of output channels
+    private int mChannelConfig; // Spacial location of output channels
+    private byte mChanNameID;   // First channel name string descriptor ID
+    private byte[] mControls;   // bitmasks of which controls are present for each channel
+    private byte mNameID;       // string descriptor ID of mixer name
+
+    public UsbACMixerUnit(int length, byte type, byte subtype, byte subClass) {
+        super(length, type, subtype, subClass);
+    }
+
+    public byte getUnitID() {
+        return mUnitID;
+    }
+
+    public byte getNumInputs() {
+        return mNumInputs;
+    }
+
+    public byte[] getInputIDs() {
+        return mInputIDs;
+    }
+
+    public byte getNumOutputs() {
+        return mNumOutputs;
+    }
+
+    public int getChannelConfig() {
+        return mChannelConfig;
+    }
+
+    public byte getChanNameID() {
+        return mChanNameID;
+    }
+
+    public byte[] getControls() {
+        return mControls;
+    }
+
+    public byte getNameID() {
+        return mNameID;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mUnitID = stream.getByte();
+        mNumInputs = stream.getByte();
+        mInputIDs = new byte[mNumInputs];
+        for (int input = 0; input < mNumInputs; input++) {
+            mInputIDs[input] = stream.getByte();
+        }
+        mNumOutputs = stream.getByte();
+        mChannelConfig = stream.unpackUsbWord();
+        mChanNameID = stream.getByte();
+
+        int controlArraySize;
+        int totalChannels = mNumInputs * mNumOutputs;
+        if (totalChannels % 8 == 0) {
+            controlArraySize = totalChannels / 8;
+        } else {
+            controlArraySize = totalChannels / 8 + 1;
+        }
+        mControls = new byte[controlArraySize];
+        for (int index = 0; index < controlArraySize; index++) {
+            mControls[index] = stream.getByte();
+        }
+
+        mNameID = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACOutputTerminal.java b/services/usb/java/com/android/server/usb/descriptors/UsbACOutputTerminal.java
new file mode 100644
index 0000000..f957e3d
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACOutputTerminal.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Output Terminal Interface.
+ * see audio10.pdf section 4.3.2.2
+ */
+public class UsbACOutputTerminal extends UsbACTerminal {
+    private static final String TAG = "ACOutputTerminal";
+
+    private byte mSourceID;         // 7:1 From Input Terminal. (0x01)
+    private byte mTerminal;         // 8:1 Unused.
+
+    public UsbACOutputTerminal(int length, byte type, byte subtype, byte subClass) {
+        super(length, type, subtype, subClass);
+    }
+
+    public byte getSourceID() {
+        return mSourceID;
+    }
+
+    public byte getTerminal() {
+        return mTerminal;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        super.parseRawDescriptors(stream);
+
+        mSourceID = stream.getByte();
+        mTerminal = stream.getByte();
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACSelectorUnit.java b/services/usb/java/com/android/server/usb/descriptors/UsbACSelectorUnit.java
new file mode 100644
index 0000000..b1f60bd
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACSelectorUnit.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Selector Unit Interface.
+ * see audio10.pdf section 4.3.2.4
+ */
+public class UsbACSelectorUnit extends UsbACInterface {
+    private static final String TAG = "ACSelectorUnit";
+
+    private byte mUnitID;   // 3:1 Constant uniquely identifying the Unit within the audio function.
+                            // This value is used in all requests to address this Unit.
+    private byte mNumPins;  // 4:1 Number of input pins in this unit
+    private byte[] mSourceIDs;  // 5+mNumPins:1 ID of the Unit or Terminal to which the first
+                                // Input Pin of this Selector Unit is connected.
+    private byte mNameIndex;    // Index of a string descriptor, describing the Selector Unit.
+
+    public UsbACSelectorUnit(int length, byte type, byte subtype, byte subClass) {
+        super(length, type, subtype, subClass);
+    }
+
+    public byte getUnitID() {
+        return mUnitID;
+    }
+
+    public byte getNumPins() {
+        return mNumPins;
+    }
+
+    public byte[] getSourceIDs() {
+        return mSourceIDs;
+    }
+
+    public byte getNameIndex() {
+        return mNameIndex;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mUnitID = stream.getByte();
+        mNumPins = stream.getByte();
+        mSourceIDs = new byte[mNumPins];
+        for (int index = 0; index < mNumPins; index++) {
+            mSourceIDs[index] = stream.getByte();
+        }
+        mNameIndex = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java b/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java
new file mode 100644
index 0000000..ea80208
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ */
+public abstract class UsbACTerminal extends UsbACInterface {
+    // Note that these fields are the same for both the
+    // audio class-specific Output Terminal Interface.(audio10.pdf section 4.3.2.2)
+    // and audio class-specific Input Terminal interface.(audio10.pdf section 4.3.2.1)
+    // so we may as well unify the parsing here.
+    protected byte mTerminalID;       // 3:1 ID of this Output Terminal. (0x02)
+    protected int mTerminalType;      // 4:2 USB Streaming. (0x0101)
+    protected byte mAssocTerminal;    // 6:1 Unused (0x00)
+
+    public UsbACTerminal(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    public byte getTerminalID() {
+        return mTerminalID;
+    }
+
+    public int getTerminalType() {
+        return mTerminalType;
+    }
+
+    public byte getAssocTerminal() {
+        return mAssocTerminal;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mTerminalID = stream.getByte();
+        mTerminalType = stream.unpackUsbWord();
+        mAssocTerminal = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbASFormat.java b/services/usb/java/com/android/server/usb/descriptors/UsbASFormat.java
new file mode 100644
index 0000000..d7c84c6
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbASFormat.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Format Interface.
+ *   Subclasses: UsbACFormatI and UsbACFormatII.
+ * see audio10.pdf section 4.5.3 & & Frmts10.pdf
+ */
+public abstract class UsbASFormat extends UsbACInterface {
+    private static final String TAG = "ASFormat";
+
+    private final byte mFormatType;   // 3:1 FORMAT_TYPE_*
+
+    public static final byte FORMAT_TYPE_I = 1;
+    public static final byte FORMAT_TYPE_II = 2;
+
+    public UsbASFormat(int length, byte type, byte subtype, byte formatType, byte mSubclass) {
+        super(length, type, subtype, mSubclass);
+        mFormatType = formatType;
+    }
+
+    public byte getFormatType() {
+        return mFormatType;
+    }
+
+    /**
+     * Allocates the audio-class format subtype associated with the format type read from the
+     * stream.
+     */
+    public static UsbDescriptor allocDescriptor(ByteStream stream, int length, byte type,
+            byte subtype, byte subclass) {
+
+        byte formatType = stream.getByte();
+        //TODO
+        // There is an issue parsing format descriptors on (some) USB 2.0 pro-audio interfaces
+        // Since we don't need this info for headset detection, just skip these descriptors
+        // for now to avoid the (low) possibility of an IndexOutOfBounds exception.
+        switch (formatType) {
+//            case FORMAT_TYPE_I:
+//                return new UsbASFormatI(length, type, subtype, formatType, subclass);
+//
+//            case FORMAT_TYPE_II:
+//                return new UsbASFormatII(length, type, subtype, formatType, subclass);
+
+            default:
+                return null;
+        }
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbASFormatI.java b/services/usb/java/com/android/server/usb/descriptors/UsbASFormatI.java
new file mode 100644
index 0000000..347a6cf
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbASFormatI.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Format I interface.
+ * see Frmts10.pdf section 2.2
+ */
+public class UsbASFormatI extends UsbASFormat {
+    private static final String TAG = "ASFormatI";
+
+    private byte mNumChannels;      // 4:1
+    private byte mSubframeSize;     // 5:1 frame size in bytes
+    private byte mBitResolution;    // 6:1 sample size in bits
+    private byte mSampleFreqType;   // 7:1
+    private int[] mSampleRates;     // if mSamFreqType == 0, there will be 2 values: the
+                                    // min & max rates otherwise mSamFreqType rates.
+                                    // All 3-byte values. All rates in Hz
+
+    public UsbASFormatI(int length, byte type, byte subtype, byte formatType, byte subclass) {
+        super(length, type, subtype, formatType, subclass);
+    }
+
+    public byte getNumChannels() {
+        return mNumChannels;
+    }
+
+    public byte getSubframeSize() {
+        return mSubframeSize;
+    }
+
+    public byte getBitResolution() {
+        return mBitResolution;
+    }
+
+    public byte getSampleFreqType() {
+        return mSampleFreqType;
+    }
+
+    public int[] getSampleRates() {
+        return mSampleRates;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mNumChannels = stream.getByte();
+        mSubframeSize = stream.getByte();
+        mBitResolution = stream.getByte();
+        mSampleFreqType = stream.getByte();
+        if (mSampleFreqType == 0) {
+            mSampleRates = new int[2];
+            mSampleRates[0] = stream.unpackUsbTriple();
+            mSampleRates[1] = stream.unpackUsbTriple();
+        } else {
+            mSampleRates = new int[mSampleFreqType];
+            for (int index = 0; index < mSampleFreqType; index++) {
+                mSampleRates[index] = stream.unpackUsbTriple();
+            }
+        }
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbASFormatII.java b/services/usb/java/com/android/server/usb/descriptors/UsbASFormatII.java
new file mode 100644
index 0000000..abdc621
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbASFormatII.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Format II interface.
+ * see Frmts10.pdf section 2.3
+ */
+public class UsbASFormatII extends UsbASFormat {
+    private static final String TAG = "ASFormatII";
+
+    private int mMaxBitRate; // 4:2 Indicates the maximum number of bits per second this
+                            // interface can handle. Expressed in kbits/s.
+    private int mSamplesPerFrame;   // 6:2 Indicates the number of PCM audio samples contained
+                                    // in one encoded audio frame.
+    private byte mSamFreqType;  // Indicates how the sampling frequency can be programmed:
+                                // 0: Continuous sampling frequency
+                                // 1..255: The number of discrete sampling frequencies supported
+                                // by the isochronous data endpoint of the AudioStreaming
+                                // interface (ns)
+    private int[] mSampleRates; // if mSamFreqType == 0, there will be 2 values:
+                                // the min & max rates. otherwise mSamFreqType rates.
+                                // All 3-byte values. All rates in Hz
+
+    public UsbASFormatII(int length, byte type, byte subtype, byte formatType, byte subclass) {
+        super(length, type, subtype, formatType, subclass);
+    }
+
+    public int getMaxBitRate() {
+        return mMaxBitRate;
+    }
+
+    public int getSamplesPerFrame() {
+        return mSamplesPerFrame;
+    }
+
+    public byte getSamFreqType() {
+        return mSamFreqType;
+    }
+
+    public int[] getSampleRates() {
+        return mSampleRates;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mMaxBitRate = stream.unpackUsbWord();
+        mSamplesPerFrame = stream.unpackUsbWord();
+        mSamFreqType = stream.getByte();
+        int numFreqs = mSamFreqType == 0 ? 2 : mSamFreqType;
+        mSampleRates = new int[numFreqs];
+        for (int index = 0; index < numFreqs; index++) {
+            mSampleRates[index] = stream.unpackUsbTriple();
+        }
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbASGeneral.java b/services/usb/java/com/android/server/usb/descriptors/UsbASGeneral.java
new file mode 100644
index 0000000..c4f42d3
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbASGeneral.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific General interface.
+ * see audio10.pdf section 4.5.2
+ */
+public class UsbASGeneral extends UsbACInterface {
+    private static final String TAG = "ACGeneral";
+
+    // audio10.pdf - section 4.5.2
+    private byte mTerminalLink; // 3:1 The Terminal ID of the Terminal to which the endpoint
+                                // of this interface is connected.
+    private byte mDelay;        // 4:1 Delay introduced by the data path (see Section 3.4,
+                                // “Inter Channel Synchronization”). Expressed in number of frames.
+    private int mFormatTag;     // 5:2 The Audio Data Format that has to be used to communicate
+                                // with this interface.
+
+    public UsbASGeneral(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    public byte getTerminalLink() {
+        return mTerminalLink;
+    }
+
+    public byte getDelay() {
+        return mDelay;
+    }
+
+    public int getFormatTag() {
+        return mFormatTag;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mTerminalLink = stream.getByte();
+        mDelay = stream.getByte();
+        mFormatTag = stream.unpackUsbWord();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbBinaryParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbBinaryParser.java
new file mode 100644
index 0000000..185cee2
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbBinaryParser.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+import android.hardware.usb.UsbDeviceConnection;
+import android.util.Log;
+
+import com.android.server.usb.descriptors.report.UsbStrings;
+
+/**
+ * @hide
+ * A class that just walks the descriptors and does a hex dump of the contained values.
+ * Usefull as a debugging tool.
+ */
+public class UsbBinaryParser {
+    private static final String TAG = "UsbBinaryParser";
+    private static final boolean LOGGING = false;
+
+    private void dumpDescriptor(ByteStream stream, int length, byte type, StringBuilder builder) {
+
+        // Log
+        if (LOGGING) {
+            Log.i(TAG, "l:" + length + " t:" + Integer.toHexString(type) + " "
+                    + UsbStrings.getDescriptorName(type));
+            StringBuilder sb = new StringBuilder();
+            for (int index = 2; index < length; index++) {
+                sb.append("0x" + Integer.toHexString(stream.getByte() & 0xFF) + " ");
+            }
+            Log.i(TAG, sb.toString());
+        } else {
+            // Screen Dump
+            builder.append("<p>");
+            builder.append("<b> l:" + length
+                    + " t:0x" + Integer.toHexString(type) + " "
+                    + UsbStrings.getDescriptorName(type) + "</b><br>");
+            for (int index = 2; index < length; index++) {
+                builder.append("0x" + Integer.toHexString(stream.getByte() & 0xFF) + " ");
+            }
+            builder.append("</p>");
+        }
+    }
+
+    /**
+     * Walk through descriptor stream and generate an HTML text report of the contents.
+     * TODO: This should be done in the model of UsbDescriptorsParser/Reporter model.
+     */
+    public void parseDescriptors(UsbDeviceConnection connection, byte[] descriptors,
+                                 StringBuilder builder) {
+
+        builder.append("<tt>");
+        ByteStream stream = new ByteStream(descriptors);
+        while (stream.available() > 0) {
+            int length = (int) stream.getByte() & 0x000000FF;
+            byte type = stream.getByte();
+            dumpDescriptor(stream, length, type, builder);
+        }
+        builder.append("</tt>");
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java
new file mode 100644
index 0000000..8ae6d0f
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An USB Config Descriptor.
+ * see usb11.pdf section 9.6.2
+ */
+public class UsbConfigDescriptor extends UsbDescriptor {
+    private static final String TAG = "Config";
+
+    private int mTotalLength;   // 2:2 Total length in bytes of data returned
+    private byte mNumInterfaces; // 4:1 Number of Interfaces
+    private byte mConfigValue;  // 5:1 Value to use as an argument to select this configuration
+    private byte mConfigIndex;  // 6:1 Index of String Descriptor describing this configuration
+    private byte mAttribs;      // 7:1 D7 Reserved, set to 1. (USB 1.0 Bus Powered)
+                                //     D6 Self Powered
+                                //     D5 Remote Wakeup
+                                //     D4..0 Reserved, set to 0.
+    private byte mMaxPower;     // 8:1 Maximum Power Consumption in 2mA units
+
+    UsbConfigDescriptor(int length, byte type) {
+        super(length, type);
+    }
+
+    public int getTotalLength() {
+        return mTotalLength;
+    }
+
+    public byte getNumInterfaces() {
+        return mNumInterfaces;
+    }
+
+    public byte getConfigValue() {
+        return mConfigValue;
+    }
+
+    public byte getConfigIndex() {
+        return mConfigIndex;
+    }
+
+    public byte getAttribs() {
+        return mAttribs;
+    }
+
+    public byte getMaxPower() {
+        return mMaxPower;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mTotalLength = stream.unpackUsbWord();
+        mNumInterfaces = stream.getByte();
+        mConfigValue = stream.getByte();
+        mConfigIndex = stream.getByte();
+        mAttribs = stream.getByte();
+        mMaxPower = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java
new file mode 100644
index 0000000..63b2d7f
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDeviceConnection;
+import android.util.Log;
+
+/*
+ * Some notes about UsbDescriptor and its subclasses.
+ *
+ * It is assumed that the user of the UsbDescriptorParser knows what they are doing
+ * so NO PROTECTION is implemented against "improper" use. Such uses are specifically:
+ * allocating a UsbDescriptor (subclass) object outside of the context of parsing/reading
+ * a rawdescriptor stream and perhaps accessing fields which have not been inialized (by
+ * parsing/reading or course).
+ */
+
+/**
+ * @hide
+ * Common superclass for all USB Descriptors.
+ */
+public abstract class UsbDescriptor {
+    private static final String TAG = "Descriptor";
+
+    protected final int mLength;    // 0:1 bLength Number Size of the Descriptor in Bytes (18 bytes)
+                                    // we store this as an int because Java bytes are SIGNED.
+    protected final byte mType;     // 1:1 bDescriptorType Constant Device Descriptor (0x01)
+
+    private byte[] mRawData;
+
+    private static final int SIZE_STRINGBUFFER = 256;
+    private static byte[] sStringBuffer = new byte[SIZE_STRINGBUFFER];
+
+    // Status
+    public static final int STATUS_UNPARSED         = 0;
+    public static final int STATUS_PARSED_OK        = 1;
+    public static final int STATUS_PARSED_UNDERRUN  = 2;
+    public static final int STATUS_PARSED_OVERRUN   = 3;
+    private int mStatus = STATUS_UNPARSED;
+
+    private static String[] sStatusStrings = {
+            "UNPARSED", "PARSED - OK", "PARSED - UNDERRUN", "PARSED - OVERRUN"};
+
+    // Descriptor Type IDs
+    public static final byte DESCRIPTORTYPE_DEVICE = 0x01;            // 1
+    public static final byte DESCRIPTORTYPE_CONFIG = 0x02;            // 2
+    public static final byte DESCRIPTORTYPE_STRING = 0x03;            // 3
+    public static final byte DESCRIPTORTYPE_INTERFACE = 0x04;         // 4
+    public static final byte DESCRIPTORTYPE_ENDPOINT = 0x05;          // 5
+    public static final byte DESCRIPTORTYPE_INTERFACEASSOC = 0x0B;    // 11
+    public static final byte DESCRIPTORTYPE_BOS = 0x0F;               // 15
+    public static final byte DESCRIPTORTYPE_CAPABILITY = 0x10;        // 16
+
+    public static final byte DESCRIPTORTYPE_HID = 0x21;                // 33
+    public static final byte DESCRIPTORTYPE_REPORT = 0x22;             // 34
+    public static final byte DESCRIPTORTYPE_PHYSICAL = 0x23;           // 35
+    public static final byte DESCRIPTORTYPE_AUDIO_INTERFACE = 0x24;    // 36
+    public static final byte DESCRIPTORTYPE_AUDIO_ENDPOINT = 0x25;     // 37
+    public static final byte DESCRIPTORTYPE_HUB = 0x29;                // 41
+    public static final byte DESCRIPTORTYPE_SUPERSPEED_HUB = 0x2A;     // 42
+    public static final byte DESCRIPTORTYPE_ENDPOINT_COMPANION = 0x30; // 48
+
+    // Class IDs
+    public static final byte CLASSID_DEVICE  =      0x00;
+    public static final byte CLASSID_AUDIO =        0x01;
+    public static final byte CLASSID_COM =          0x02;
+    public static final byte CLASSID_HID =          0x03;
+    // public static final byte CLASSID_??? =       0x04;
+    public static final byte CLASSID_PHYSICAL =     0x05;
+    public static final byte CLASSID_IMAGE =        0x06;
+    public static final byte CLASSID_PRINTER =      0x07;
+    public static final byte CLASSID_STORAGE =      0x08;
+    public static final byte CLASSID_HUB =          0x09;
+    public static final byte CLASSID_CDC_CONTROL =  0x0A;
+    public static final byte CLASSID_SMART_CARD =   0x0B;
+    //public static final byte CLASSID_??? =        0x0C;
+    public static final byte CLASSID_SECURITY =     0x0D;
+    public static final byte CLASSID_VIDEO =        0x0E;
+    public static final byte CLASSID_HEALTHCARE =   0x0F;
+    public static final byte CLASSID_AUDIOVIDEO =   0x10;
+    public static final byte CLASSID_BILLBOARD =    0x11;
+    public static final byte CLASSID_TYPECBRIDGE =  0x12;
+    public static final byte CLASSID_DIAGNOSTIC =   (byte) 0xDC;
+    public static final byte CLASSID_WIRELESS =     (byte) 0xE0;
+    public static final byte CLASSID_MISC =         (byte) 0xEF;
+    public static final byte CLASSID_APPSPECIFIC =  (byte) 0xFE;
+    public static final byte CLASSID_VENDSPECIFIC = (byte) 0xFF;
+
+    // Audio Subclass codes
+    public static final byte AUDIO_SUBCLASS_UNDEFINED   = 0x00;
+    public static final byte AUDIO_AUDIOCONTROL         = 0x01;
+    public static final byte AUDIO_AUDIOSTREAMING       = 0x02;
+    public static final byte AUDIO_MIDISTREAMING        = 0x03;
+
+    // Request IDs
+    public static final int REQUEST_GET_STATUS         = 0x00;
+    public static final int REQUEST_CLEAR_FEATURE      = 0x01;
+    public static final int REQUEST_SET_FEATURE        = 0x03;
+    public static final int REQUEST_GET_ADDRESS        = 0x05;
+    public static final int REQUEST_GET_DESCRIPTOR     = 0x06;
+    public static final int REQUEST_SET_DESCRIPTOR     = 0x07;
+    public static final int REQUEST_GET_CONFIGURATION  = 0x08;
+    public static final int REQUEST_SET_CONFIGURATION  = 0x09;
+
+    /**
+     * @throws IllegalArgumentException
+     */
+    UsbDescriptor(int length, byte type) {
+        // a descriptor has at least a length byte and type byte
+        // one could imagine an empty one otherwise
+        if (length < 2) {
+            // huh?
+            throw new IllegalArgumentException();
+        }
+
+        mLength = length;
+        mType = type;
+    }
+
+    public int getLength() {
+        return mLength;
+    }
+
+    public byte getType() {
+        return mType;
+    }
+
+    public int getStatus() {
+        return mStatus;
+    }
+
+    public void setStatus(int status) {
+        mStatus = status;
+    }
+
+    public String getStatusString() {
+        return sStatusStrings[mStatus];
+    }
+
+    public byte[] getRawData() {
+        return mRawData;
+    }
+
+    /**
+     * Called by the parser for any necessary cleanup.
+     */
+    public void postParse(ByteStream stream) {
+        // Status
+        int bytesRead = stream.getReadCount();
+        if (bytesRead < mLength) {
+            // Too cold...
+            stream.advance(mLength - bytesRead);
+            mStatus = STATUS_PARSED_UNDERRUN;
+            Log.w(TAG, "UNDERRUN t:0x" + Integer.toHexString(mType)
+                    + " r:" + bytesRead + " < l:" + mLength);
+        } else if (bytesRead > mLength) {
+            // Too hot...
+            stream.reverse(bytesRead - mLength);
+            mStatus = STATUS_PARSED_OVERRUN;
+            Log.w(TAG, "OVERRRUN t:0x" + Integer.toHexString(mType)
+                    + " r:" + bytesRead + " > l:" + mLength);
+        } else {
+            // Just right!
+            mStatus = STATUS_PARSED_OK;
+        }
+    }
+
+    /**
+     * Reads data fields from specified raw-data stream.
+     */
+    public int parseRawDescriptors(ByteStream stream) {
+        int numRead = stream.getReadCount();
+        int dataLen = mLength - numRead;
+        if (dataLen > 0) {
+            mRawData = new byte[dataLen];
+            for (int index = 0; index < dataLen; index++) {
+                mRawData[index] = stream.getByte();
+            }
+        }
+        return mLength;
+    }
+
+    /**
+     * Gets a string for the specified index from the USB Device's string descriptors.
+     */
+    public static String getUsbDescriptorString(UsbDeviceConnection connection, byte strIndex) {
+        String usbStr = "";
+        if (strIndex != 0) {
+            try {
+                int rdo = connection.controlTransfer(
+                        UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_STANDARD,
+                        REQUEST_GET_DESCRIPTOR,
+                        (DESCRIPTORTYPE_STRING << 8) | strIndex,
+                        0,
+                        sStringBuffer,
+                        0xFF,
+                        0);
+                if (rdo >= 0) {
+                    usbStr = new String(sStringBuffer, 2, rdo - 2, "UTF-16LE");
+                } else {
+                    usbStr = "?";
+                }
+            } catch (Exception e) {
+                Log.e(TAG, "Can not communicate with USB device", e);
+            }
+        }
+        return usbStr;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
new file mode 100644
index 0000000..7c074da
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+import android.util.Log;
+
+import java.util.ArrayList;
+
+/**
+ * @hide
+ * Class for parsing a binary stream of USB Descriptors.
+ */
+public class UsbDescriptorParser {
+    private static final String TAG = "DescriptorParser";
+
+    // Descriptor Objects
+    private ArrayList<UsbDescriptor> mDescriptors = new ArrayList<UsbDescriptor>();
+
+    private UsbDeviceDescriptor mDeviceDescriptor;
+    private UsbInterfaceDescriptor mCurInterfaceDescriptor;
+
+    public UsbDescriptorParser() {}
+
+    /**
+     * The probability (as returned by getHeadsetProbability() at which we conclude
+     * the peripheral is a headset.
+     */
+    private static final float IN_HEADSET_TRIGGER = 0.75f;
+    private static final float OUT_HEADSET_TRIGGER = 0.75f;
+
+    private UsbDescriptor allocDescriptor(ByteStream stream) {
+        stream.resetReadCount();
+
+        int length = (int) stream.getByte() & 0x000000FF;
+        byte type = stream.getByte();
+
+        UsbDescriptor descriptor = null;
+        switch (type) {
+            /*
+             * Standard
+             */
+            case UsbDescriptor.DESCRIPTORTYPE_DEVICE:
+                descriptor = mDeviceDescriptor = new UsbDeviceDescriptor(length, type);
+                break;
+
+            case UsbDescriptor.DESCRIPTORTYPE_CONFIG:
+                descriptor = new UsbConfigDescriptor(length, type);
+                break;
+
+            case UsbDescriptor.DESCRIPTORTYPE_INTERFACE:
+                descriptor = mCurInterfaceDescriptor = new UsbInterfaceDescriptor(length, type);
+                break;
+
+            case UsbDescriptor.DESCRIPTORTYPE_ENDPOINT:
+                descriptor = new UsbEndpointDescriptor(length, type);
+                break;
+
+            /*
+             * HID
+             */
+            case UsbDescriptor.DESCRIPTORTYPE_HID:
+                descriptor = new UsbHIDDescriptor(length, type);
+                break;
+
+            /*
+             * Other
+             */
+            case UsbDescriptor.DESCRIPTORTYPE_INTERFACEASSOC:
+                descriptor = new UsbInterfaceAssoc(length, type);
+                break;
+
+            /*
+             * Audio Class Specific
+             */
+            case UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE:
+                descriptor = UsbACInterface.allocDescriptor(this, stream, length, type);
+                break;
+
+            case UsbDescriptor.DESCRIPTORTYPE_AUDIO_ENDPOINT:
+                descriptor = UsbACEndpoint.allocDescriptor(this, length, type);
+                break;
+
+            default:
+                break;
+        }
+
+        if (descriptor == null) {
+            // Unknown Descriptor
+            Log.i(TAG, "Unknown Descriptor len:" + length + " type:0x"
+                    + Integer.toHexString(type));
+            descriptor = new UsbUnknown(length, type);
+        }
+
+        return descriptor;
+    }
+
+    public UsbDeviceDescriptor getDeviceDescriptor() {
+        return mDeviceDescriptor;
+    }
+
+    public UsbInterfaceDescriptor getCurInterface() {
+        return mCurInterfaceDescriptor;
+    }
+
+    /**
+     * @hide
+     */
+    public boolean parseDescriptors(byte[] descriptors) {
+        try {
+            mDescriptors.clear();
+
+            ByteStream stream = new ByteStream(descriptors);
+            while (stream.available() > 0) {
+                UsbDescriptor descriptor = allocDescriptor(stream);
+                if (descriptor != null) {
+                    // Parse
+                    descriptor.parseRawDescriptors(stream);
+                    mDescriptors.add(descriptor);
+
+                    // Clean up
+                    descriptor.postParse(stream);
+                }
+            }
+            return true;
+        } catch (Exception ex) {
+            Log.e(TAG, "Exception parsing USB descriptors.", ex);
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    public boolean parseDevice(String deviceAddr) {
+        byte[] rawDescriptors = getRawDescriptors(deviceAddr);
+        return rawDescriptors != null && parseDescriptors(rawDescriptors);
+    }
+
+    private native byte[] getRawDescriptors(String deviceAddr);
+
+    public int getParsingSpec() {
+        return mDeviceDescriptor != null ? mDeviceDescriptor.getSpec() : 0;
+    }
+
+    public ArrayList<UsbDescriptor> getDescriptors() {
+        return mDescriptors;
+    }
+
+    /**
+     * @hide
+     */
+    public ArrayList<UsbDescriptor> getDescriptors(byte type) {
+        ArrayList<UsbDescriptor> list = new ArrayList<UsbDescriptor>();
+        for (UsbDescriptor descriptor : mDescriptors) {
+            if (descriptor.getType() == type) {
+                list.add(descriptor);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * @hide
+     */
+    public ArrayList<UsbDescriptor> getInterfaceDescriptorsForClass(byte usbClass) {
+        ArrayList<UsbDescriptor> list = new ArrayList<UsbDescriptor>();
+        for (UsbDescriptor descriptor : mDescriptors) {
+            // ensure that this isn't an unrecognized DESCRIPTORTYPE_INTERFACE
+            if (descriptor.getType() == UsbDescriptor.DESCRIPTORTYPE_INTERFACE) {
+                if (descriptor instanceof UsbInterfaceDescriptor) {
+                    UsbInterfaceDescriptor intrDesc = (UsbInterfaceDescriptor) descriptor;
+                    if (intrDesc.getUsbClass() == usbClass) {
+                        list.add(descriptor);
+                    }
+                } else {
+                    Log.w(TAG, "Unrecognized Interface l:" + descriptor.getLength()
+                            + " t:0x" + Integer.toHexString(descriptor.getType()));
+                }
+            }
+        }
+        return list;
+    }
+
+    /**
+     * @hide
+     */
+    public ArrayList<UsbDescriptor> getACInterfaceDescriptors(byte subtype, byte subclass) {
+        ArrayList<UsbDescriptor> list = new ArrayList<UsbDescriptor>();
+        for (UsbDescriptor descriptor : mDescriptors) {
+            if (descriptor.getType() == UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE) {
+                // ensure that this isn't an unrecognized DESCRIPTORTYPE_AUDIO_INTERFACE
+                if (descriptor instanceof UsbACInterface) {
+                    UsbACInterface acDescriptor = (UsbACInterface) descriptor;
+                    if (acDescriptor.getSubtype() == subtype
+                            && acDescriptor.getSubclass() == subclass) {
+                        list.add(descriptor);
+                    }
+                } else {
+                    Log.w(TAG, "Unrecognized Audio Interface l:" + descriptor.getLength()
+                            + " t:0x" + Integer.toHexString(descriptor.getType()));
+                }
+            }
+        }
+        return list;
+    }
+
+    /**
+     * @hide
+     */
+    public boolean hasHIDDescriptor() {
+        ArrayList<UsbDescriptor> descriptors =
+                getInterfaceDescriptorsForClass(UsbDescriptor.CLASSID_HID);
+        return !descriptors.isEmpty();
+    }
+
+    /**
+     * @hide
+     */
+    public boolean hasMIDIInterface() {
+        ArrayList<UsbDescriptor> descriptors =
+                getInterfaceDescriptorsForClass(UsbDescriptor.CLASSID_AUDIO);
+        for (UsbDescriptor descriptor : descriptors) {
+            // enusure that this isn't an unrecognized interface descriptor
+            if (descriptor instanceof UsbInterfaceDescriptor) {
+                UsbInterfaceDescriptor interfaceDescr = (UsbInterfaceDescriptor) descriptor;
+                if (interfaceDescr.getUsbSubclass() == UsbDescriptor.AUDIO_MIDISTREAMING) {
+                    return true;
+                }
+            } else {
+                Log.w(TAG, "Undefined Audio Class Interface l:" + descriptor.getLength()
+                        + " t:0x" + Integer.toHexString(descriptor.getType()));
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    public float getInputHeadsetProbability() {
+        if (hasMIDIInterface()) {
+            return 0.0f;
+        }
+
+        float probability = 0.0f;
+        ArrayList<UsbDescriptor> acDescriptors;
+
+        // Look for a microphone
+        boolean hasMic = false;
+        acDescriptors = getACInterfaceDescriptors(UsbACInterface.ACI_INPUT_TERMINAL,
+                UsbACInterface.AUDIO_AUDIOCONTROL);
+        for (UsbDescriptor descriptor : acDescriptors) {
+            if (descriptor instanceof UsbACInputTerminal) {
+                UsbACInputTerminal inDescr = (UsbACInputTerminal) descriptor;
+                if (inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_IN_MIC
+                        || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_HEADSET
+                        || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_UNDEFINED
+                        || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_EXTERN_LINE) {
+                    hasMic = true;
+                    break;
+                }
+            } else {
+                Log.w(TAG, "Undefined Audio Input terminal l:" + descriptor.getLength()
+                        + " t:0x" + Integer.toHexString(descriptor.getType()));
+            }
+        }
+
+        // Look for a "speaker"
+        boolean hasSpeaker = false;
+        acDescriptors =
+                getACInterfaceDescriptors(UsbACInterface.ACI_OUTPUT_TERMINAL,
+                        UsbACInterface.AUDIO_AUDIOCONTROL);
+        for (UsbDescriptor descriptor : acDescriptors) {
+            if (descriptor instanceof UsbACOutputTerminal) {
+                UsbACOutputTerminal outDescr = (UsbACOutputTerminal) descriptor;
+                if (outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_OUT_SPEAKER
+                        || outDescr.getTerminalType()
+                            == UsbTerminalTypes.TERMINAL_OUT_HEADPHONES
+                        || outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_HEADSET) {
+                    hasSpeaker = true;
+                    break;
+                }
+            } else {
+                Log.w(TAG, "Undefined Audio Output terminal l:" + descriptor.getLength()
+                        + " t:0x" + Integer.toHexString(descriptor.getType()));
+            }
+        }
+
+        if (hasMic && hasSpeaker) {
+            probability += 0.75f;
+        }
+
+        if (hasMic && hasHIDDescriptor()) {
+            probability += 0.25f;
+        }
+
+        return probability;
+    }
+
+    /**
+     * getInputHeadsetProbability() reports a probability of a USB Input peripheral being a
+     * headset. The probability range is between 0.0f (definitely NOT a headset) and
+     * 1.0f (definitely IS a headset). A probability of 0.75f seems sufficient
+     * to count on the peripheral being a headset.
+     */
+    public boolean isInputHeadset() {
+        return getInputHeadsetProbability() >= IN_HEADSET_TRIGGER;
+    }
+
+    /**
+     * @hide
+     */
+    public float getOutputHeadsetProbability() {
+        if (hasMIDIInterface()) {
+            return 0.0f;
+        }
+
+        float probability = 0.0f;
+        ArrayList<UsbDescriptor> acDescriptors;
+
+        // Look for a "speaker"
+        boolean hasSpeaker = false;
+        acDescriptors =
+                getACInterfaceDescriptors(UsbACInterface.ACI_OUTPUT_TERMINAL,
+                        UsbACInterface.AUDIO_AUDIOCONTROL);
+        for (UsbDescriptor descriptor : acDescriptors) {
+            if (descriptor instanceof UsbACOutputTerminal) {
+                UsbACOutputTerminal outDescr = (UsbACOutputTerminal) descriptor;
+                if (outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_OUT_SPEAKER
+                        || outDescr.getTerminalType()
+                            == UsbTerminalTypes.TERMINAL_OUT_HEADPHONES
+                        || outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_HEADSET) {
+                    hasSpeaker = true;
+                    break;
+                }
+            } else {
+                Log.w(TAG, "Undefined Audio Output terminal l:" + descriptor.getLength()
+                        + " t:0x" + Integer.toHexString(descriptor.getType()));
+            }
+        }
+
+        if (hasSpeaker) {
+            probability += 0.75f;
+        }
+
+        if (hasSpeaker && hasHIDDescriptor()) {
+            probability += 0.25f;
+        }
+
+        return probability;
+    }
+
+    /**
+     * getOutputHeadsetProbability() reports a probability of a USB Output peripheral being a
+     * headset. The probability range is between 0.0f (definitely NOT a headset) and
+     * 1.0f (definitely IS a headset). A probability of 0.75f seems sufficient
+     * to count on the peripheral being a headset.
+     */
+    public boolean isOutputHeadset() {
+        return getOutputHeadsetProbability() >= OUT_HEADSET_TRIGGER;
+    }
+
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
new file mode 100644
index 0000000..90848ca
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * A USB Device Descriptor.
+ * see usb11.pdf section 9.6.1
+ */
+/* public */ public class UsbDeviceDescriptor extends UsbDescriptor {
+    private static final String TAG = "Device";
+
+    private int mSpec;          // 2:2 bcdUSB 2 BCD USB Specification Number - BCD
+    private byte mDevClass;     // 4:1 class code
+    private byte mDevSubClass;  // 5:1 subclass code
+    private byte mProtocol;     // 6:1 protocol
+    private byte mPacketSize;   // 7:1 Maximum Packet Size for Zero Endpoint.
+                                // Valid Sizes are 8, 16, 32, 64
+    private int mVendorID;      // 8:2 vendor ID
+    private int mProductID;     // 10:2 product ID
+    private int mDeviceRelease; // 12:2 Device Release number - BCD
+    private byte mMfgIndex;     // 14:1 Index of Manufacturer String Descriptor
+    private byte mProductIndex; // 15:1 Index of Product String Descriptor
+    private byte mSerialNum;    // 16:1 Index of Serial Number String Descriptor
+    private byte mNumConfigs;   // 17:1 Number of Possible Configurations
+
+    UsbDeviceDescriptor(int length, byte type) {
+        super(length, type);
+    }
+
+    public int getSpec() {
+        return mSpec;
+    }
+
+    public byte getDevClass() {
+        return mDevClass;
+    }
+
+    public byte getDevSubClass() {
+        return mDevSubClass;
+    }
+
+    public byte getProtocol() {
+        return mProtocol;
+    }
+
+    public byte getPacketSize() {
+        return mPacketSize;
+    }
+
+    public int getVendorID() {
+        return mVendorID;
+    }
+
+    public int getProductID() {
+        return mProductID;
+    }
+
+    public int getDeviceRelease() {
+        return mDeviceRelease;
+    }
+
+    public byte getMfgIndex() {
+        return mMfgIndex;
+    }
+
+    public byte getProductIndex() {
+        return mProductIndex;
+    }
+
+    public byte getSerialNum() {
+        return mSerialNum;
+    }
+
+    public byte getNumConfigs() {
+        return mNumConfigs;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mSpec = stream.unpackUsbWord();
+        mDevClass = stream.getByte();
+        mDevSubClass = stream.getByte();
+        mProtocol = stream.getByte();
+        mPacketSize = stream.getByte();
+        mVendorID = stream.unpackUsbWord();
+        mProductID = stream.unpackUsbWord();
+        mDeviceRelease = stream.unpackUsbWord();
+        mMfgIndex = stream.getByte();
+        mProductIndex = stream.getByte();
+        mSerialNum = stream.getByte();
+        mNumConfigs = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java
new file mode 100644
index 0000000..def6700
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * A Usb Endpoint Descriptor.
+ * see usb11.pdf section 9.6.4
+ */
+public class UsbEndpointDescriptor extends UsbDescriptor {
+    private static final String TAG = "EndPoint";
+
+    public static final byte MASK_ENDPOINT_ADDRESS     = 0b0001111;
+    public static final byte MASK_ENDPOINT_DIRECTION   = (byte) 0b10000000;
+    public static final byte DIRECTION_OUTPUT          = 0x00;
+    public static final byte DIRECTION_INPUT           = (byte) 0x80;
+
+    public static final byte MASK_ATTRIBS_TRANSTYPE = 0b00000011;
+    public static final byte TRANSTYPE_CONTROL     = 0x00;
+    public static final byte TRANSTYPE_ISO         = 0x01;
+    public static final byte TRANSTYPE_BULK        = 0x02;
+    public static final byte TRANSTYPE_INTERRUPT   = 0x03;
+
+    public static final byte MASK_ATTRIBS_SYNCTYPE  = 0b00001100;
+    public static final byte SYNCTYPE_NONE          = 0b00000000;
+    public static final byte SYNCTYPE_ASYNC         = 0b00000100;
+    public static final byte SYNCTYPE_ADAPTSYNC     = 0b00001000;
+    public static final byte SYNCTYPE_RESERVED      = 0b00001100;
+
+    public static final byte MASK_ATTRIBS_USEAGE    = 0b00110000;
+    public static final byte USEAGE_DATA            = 0b00000000;
+    public static final byte USEAGE_FEEDBACK        = 0b00010000;
+    public static final byte USEAGE_EXPLICIT        = 0b00100000;
+    public static final byte USEAGE_RESERVED        = 0b00110000;
+
+    private byte mEndpointAddress;  // 2:1 Endpoint Address
+                                    // Bits 0..3b Endpoint Number.
+                                    // Bits 4..6b Reserved. Set to Zero
+                                    // Bits 7 Direction 0 = Out, 1 = In
+                                    // (Ignored for Control Endpoints)
+    private byte mAttributes;   // 3:1 Various flags
+                                // Bits 0..1 Transfer Type:
+                                //     00 = Control, 01 = Isochronous, 10 = Bulk, 11 = Interrupt
+                                // Bits 2..7 are reserved. If Isochronous endpoint,
+                                // Bits 3..2 = Synchronisation Type (Iso Mode)
+                                //  00 = No Synchonisation
+                                //  01 = Asynchronous
+                                //  10 = Adaptive
+                                //  11 = Synchronous
+                                // Bits 5..4 = Usage Type (Iso Mode)
+                                //  00: Data Endpoint
+                                //  01:Feedback Endpoint 10
+                                //  Explicit Feedback Data Endpoint
+                                //  11: Reserved
+    private int mPacketSize;    // 4:2 Maximum Packet Size this endpoint is capable of
+                                // sending or receiving
+    private byte mInterval;     // 6:1 Interval for polling endpoint data transfers. Value in
+                                // frame counts.
+                                // Ignored for Bulk & Control Endpoints. Isochronous must equal
+                                // 1 and field may range from 1 to 255 for interrupt endpoints.
+    private byte mRefresh;
+    private byte mSyncAddress;
+
+    public UsbEndpointDescriptor(int length, byte type) {
+        super(length, type);
+    }
+
+    public byte getEndpointAddress() {
+        return mEndpointAddress;
+    }
+
+    public byte getAttributes() {
+        return mAttributes;
+    }
+
+    public int getPacketSize() {
+        return mPacketSize;
+    }
+
+    public byte getInterval() {
+        return mInterval;
+    }
+
+    public byte getRefresh() {
+        return mRefresh;
+    }
+
+    public byte getSyncAddress() {
+        return mSyncAddress;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mEndpointAddress = stream.getByte();
+        mAttributes = stream.getByte();
+        mPacketSize = stream.unpackUsbWord();
+        mInterval = stream.getByte();
+        if (mLength == 9) {
+            mRefresh = stream.getByte();
+            mSyncAddress = stream.getByte();
+        }
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbHIDDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbHIDDescriptor.java
new file mode 100644
index 0000000..56c07ec
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbHIDDescriptor.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * A USB HID (Human Interface Descriptor).
+ * see HID1_11.pdf - 6.2.1
+ */
+public class UsbHIDDescriptor extends UsbDescriptor {
+    private static final String TAG = "HID";
+
+    private int mRelease;           // 2:2 the HID Class Specification release.
+    private byte mCountryCode;      // 4:1 country code of the localized hardware.
+    private byte mNumDescriptors;   // number of descriptors (always at least one
+                                    // i.e. Report descriptor.)
+    private byte mDescriptorType;   // 6:1 type of class descriptor.
+                                    // See Section 7.1.2: Set_Descriptor
+                                    // Request for a table of class descriptor constants.
+    private int mDescriptorLen;     // 7:2 Numeric expression that is the total size of
+                                    // the Report descriptor.
+
+    public UsbHIDDescriptor(int length, byte type) {
+        super(length, type);
+    }
+
+    public int getRelease() {
+        return mRelease;
+    }
+
+    public byte getCountryCode() {
+        return mCountryCode;
+    }
+
+    public byte getNumDescriptors() {
+        return mNumDescriptors;
+    }
+
+    public byte getDescriptorType() {
+        return mDescriptorType;
+    }
+
+    public int getDescriptorLen() {
+        return mDescriptorLen;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mRelease = stream.unpackUsbWord();
+        mCountryCode = stream.getByte();
+        mNumDescriptors = stream.getByte();
+        mDescriptorType = stream.getByte();
+        mDescriptorLen = stream.unpackUsbWord();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceAssoc.java b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceAssoc.java
new file mode 100644
index 0000000..4b18a01
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceAssoc.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * A USB Interface Association Descriptor.
+ * found this one here: http://www.usb.org/developers/docs/whitepapers/iadclasscode_r10.pdf
+ * also: https://msdn.microsoft.com/en-us/library/windows/hardware/ff540054(v=vs.85).aspx
+ */
+public class UsbInterfaceAssoc extends UsbDescriptor {
+    private static final String TAG = "InterfaceAssoc";
+
+    private byte mFirstInterface;
+    private byte mInterfaceCount;
+    private byte mFunctionClass;
+    private byte mFunctionSubClass;
+    private byte mFunctionProtocol;
+    private byte mFunction;
+
+    public UsbInterfaceAssoc(int length, byte type) {
+        super(length, type);
+    }
+
+    public byte getFirstInterface() {
+        return mFirstInterface;
+    }
+
+    public byte getInterfaceCount() {
+        return mInterfaceCount;
+    }
+
+    public byte getFunctionClass() {
+        return mFunctionClass;
+    }
+
+    public byte getFunctionSubClass() {
+        return mFunctionSubClass;
+    }
+
+    public byte getFunctionProtocol() {
+        return mFunctionProtocol;
+    }
+
+    public byte getFunction() {
+        return mFunction;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mFirstInterface = stream.getByte();
+        mInterfaceCount = stream.getByte();
+        mFunctionClass = stream.getByte();
+        mFunctionSubClass = stream.getByte();
+        mFunctionProtocol = stream.getByte();
+        mFunction = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java
new file mode 100644
index 0000000..21b5e0c
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * A common super-class for all USB Interface Descritor subtypes.
+ * see usb11.pdf section 9.6.3
+ */
+public class UsbInterfaceDescriptor extends UsbDescriptor {
+    private static final String TAG = "Interface";
+
+    protected byte mInterfaceNumber;  // 2:1 Number of Interface
+    protected byte mAlternateSetting; // 3:1 Value used to select alternative setting
+    protected byte mNumEndpoints;     // 4:1 Number of Endpoints used for this interface
+    protected byte mUsbClass;         // 5:1 Class Code
+    protected byte mUsbSubclass;      // 6:1 Subclass Code
+    protected byte mProtocol;         // 7:1 Protocol Code
+    protected byte mDescrIndex;       // 8:1 Index of String Descriptor Describing this interface
+
+    UsbInterfaceDescriptor(int length, byte type) {
+        super(length, type);
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mInterfaceNumber = stream.getByte();
+        mAlternateSetting = stream.getByte();
+        mNumEndpoints = stream.getByte();
+        mUsbClass = stream.getByte();
+        mUsbSubclass = stream.getByte();
+        mProtocol = stream.getByte();
+        mDescrIndex = stream.getByte();
+
+        return mLength;
+    }
+
+    public byte getInterfaceNumber() {
+        return mInterfaceNumber;
+    }
+
+    public byte getAlternateSetting() {
+        return mAlternateSetting;
+    }
+
+    public byte getNumEndpoints() {
+        return mNumEndpoints;
+    }
+
+    public byte getUsbClass() {
+        return mUsbClass;
+    }
+
+    public byte getUsbSubclass() {
+        return mUsbSubclass;
+    }
+
+    public byte getProtocol() {
+        return mProtocol;
+    }
+
+    public byte getDescrIndex() {
+        return mDescrIndex;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiHeader.java b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiHeader.java
new file mode 100644
index 0000000..4452b23
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiHeader.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Midi Streaming Interface.
+ * see midi10.pdf section 6.1.2.1
+ */
+public class UsbMSMidiHeader extends UsbACInterface {
+    private static final String TAG = "MSMidiHeader";
+
+    public UsbMSMidiHeader(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        // TODO - read data memebers
+        stream.advance(mLength - stream.getReadCount());
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiInputJack.java b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiInputJack.java
new file mode 100644
index 0000000..2d33ba7
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiInputJack.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Midi Input Jack Interface.
+ * see midi10.pdf section B.4.3
+ */
+public class UsbMSMidiInputJack extends UsbACInterface {
+    private static final String TAG = "MSMidiInputJack";
+
+    UsbMSMidiInputJack(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        // TODO - read data memebers
+        stream.advance(mLength - stream.getReadCount());
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiOutputJack.java b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiOutputJack.java
new file mode 100644
index 0000000..bd2dc11
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiOutputJack.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Midi Output Jack Interface.
+ * see midi10.pdf section B.4.4
+ */
+public class UsbMSMidiOutputJack extends UsbACInterface {
+    private static final String TAG = "MSMidiOutputJack";
+
+    public UsbMSMidiOutputJack(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        // TODO - read data memebers
+        stream.advance(mLength - stream.getReadCount());
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbTerminalTypes.java b/services/usb/java/com/android/server/usb/descriptors/UsbTerminalTypes.java
new file mode 100644
index 0000000..b521462
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbTerminalTypes.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * A class for decoding information in Terminal Descriptors.
+ * see termt10.pdf
+ */
+public class UsbTerminalTypes {
+    private static final String TAG = "TerminalTypes";
+
+    // USB
+    public static final int TERMINAL_USB_STREAMING   = 0x0101;
+
+    // Inputs
+    public static final int TERMINAL_IN_UNDEFINED    = 0x0200;
+    public static final int TERMINAL_IN_MIC          = 0x0201;
+    public static final int TERMINAL_IN_DESKTOP_MIC  = 0x0202;
+    public static final int TERMINAL_IN_PERSONAL_MIC = 0x0203;
+    public static final int TERMINAL_IN_OMNI_MIC     = 0x0204;
+    public static final int TERMINAL_IN_MIC_ARRAY    = 0x0205;
+    public static final int TERMINAL_IN_PROC_MIC_ARRAY = 0x0206;
+
+    // Outputs
+    public static final int TERMINAL_OUT_UNDEFINED       = 0x0300;
+    public static final int TERMINAL_OUT_SPEAKER         = 0x0301;
+    public static final int TERMINAL_OUT_HEADPHONES      = 0x0302;
+    public static final int TERMINAL_OUT_HEADMOUNTED     = 0x0303;
+    public static final int TERMINAL_OUT_DESKTOPSPEAKER  = 0x0304;
+    public static final int TERMINAL_OUT_ROOMSPEAKER     = 0x0305;
+    public static final int TERMINAL_OUT_COMSPEAKER      = 0x0306;
+    public static final int TERMINAL_OUT_LFSPEAKER       = 0x0307;
+
+    // Bi-directional
+    public static final int TERMINAL_BIDIR_UNDEFINED    = 0x0400;
+    public static final int TERMINAL_BIDIR_HANDSET      = 0x0401;
+    public static final int TERMINAL_BIDIR_HEADSET      = 0x0402;
+    public static final int TERMINAL_BIDIR_SKRPHONE     = 0x0403;
+    public static final int TERMINAL_BIDIR_SKRPHONE_SUPRESS = 0x0404;
+    public static final int TERMINAL_BIDIR_SKRPHONE_CANCEL = 0x0405;
+
+    // Telephony
+    public static final int TERMINAL_TELE_UNDEFINED     = 0x0500;
+    public static final int TERMINAL_TELE_PHONELINE     = 0x0501;
+    public static final int TERMINAL_TELE_PHONE         = 0x0502;
+    public static final int TERMINAL_TELE_DOWNLINEPHONE = 0x0503;
+
+    // External
+    public static final int TERMINAL_EXTERN_UNDEFINED   = 0x0600;
+    public static final int TERMINAL_EXTERN_ANALOG      = 0x0601;
+    public static final int TERMINAL_EXTERN_DIGITAL     = 0x0602;
+    public static final int TERMINAL_EXTERN_LINE        = 0x0603;
+    public static final int TERMINAL_EXTERN_LEGACY      = 0x0604;
+    public static final int TERMINAL_EXTERN_SPIDF       = 0x0605;
+    public static final int TERMINAL_EXTERN_1394DA      = 0x0606;
+    public static final int TERMINAL_EXTERN_1394DV      = 0x0607;
+
+    public static final int TERMINAL_EMBED_UNDEFINED    = 0x0700;
+    public static final int TERMINAL_EMBED_CALNOISE     = 0x0701;
+    public static final int TERMINAL_EMBED_EQNOISE      = 0x0702;
+    public static final int TERMINAL_EMBED_CDPLAYER     = 0x0703;
+    public static final int TERMINAL_EMBED_DAT          = 0x0704;
+    public static final int TERMINAL_EMBED_DCC          = 0x0705;
+    public static final int TERMINAL_EMBED_MINIDISK     = 0x0706;
+    public static final int TERMINAL_EMBED_ANALOGTAPE   = 0x0707;
+    public static final int TERMINAL_EMBED_PHONOGRAPH   = 0x0708;
+    public static final int TERMINAL_EMBED_VCRAUDIO     = 0x0709;
+    public static final int TERMINAL_EMBED_VIDDISKAUDIO = 0x070A;
+    public static final int TERMINAL_EMBED_DVDAUDIO     = 0x070B;
+    public static final int TERMINAL_EMBED_TVAUDIO      = 0x070C;
+    public static final int TERMINAL_EMBED_SATELLITEAUDIO = 0x070D;
+    public static final int TERMINAL_EMBED_CABLEAUDIO   = 0x070E;
+    public static final int TERMINAL_EMBED_DSSAUDIO     = 0x070F;
+    public static final int TERMINAL_EMBED_RADIOAUDIO   = 0x0710;
+    public static final int TERMINAL_EMBED_RADIOTRANSMITTER = 0x0711;
+    public static final int TERMINAL_EMBED_MULTITRACK   = 0x0712;
+    public static final int TERMINAL_EMBED_SYNTHESIZER  = 0x0713;
+
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbUnknown.java b/services/usb/java/com/android/server/usb/descriptors/UsbUnknown.java
new file mode 100644
index 0000000..a6fe8bb
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbUnknown.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * A holder for any unrecognized descriptor encountered in the descriptor stream.
+ */
+public class UsbUnknown extends UsbDescriptor {
+    static final String TAG = "Unknown";
+
+    public UsbUnknown(int length, byte type) {
+        super(length, type);
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/report/HTMLReporter.java b/services/usb/java/com/android/server/usb/descriptors/report/HTMLReporter.java
new file mode 100644
index 0000000..c98789d
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/report/HTMLReporter.java
@@ -0,0 +1,572 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors.report;
+
+import android.hardware.usb.UsbDeviceConnection;
+
+import com.android.server.usb.descriptors.UsbACAudioControlEndpoint;
+import com.android.server.usb.descriptors.UsbACAudioStreamEndpoint;
+import com.android.server.usb.descriptors.UsbACFeatureUnit;
+import com.android.server.usb.descriptors.UsbACHeader;
+import com.android.server.usb.descriptors.UsbACInputTerminal;
+import com.android.server.usb.descriptors.UsbACInterface;
+import com.android.server.usb.descriptors.UsbACMidiEndpoint;
+import com.android.server.usb.descriptors.UsbACMixerUnit;
+import com.android.server.usb.descriptors.UsbACOutputTerminal;
+import com.android.server.usb.descriptors.UsbACSelectorUnit;
+import com.android.server.usb.descriptors.UsbACTerminal;
+import com.android.server.usb.descriptors.UsbASFormat;
+import com.android.server.usb.descriptors.UsbASFormatI;
+import com.android.server.usb.descriptors.UsbASFormatII;
+import com.android.server.usb.descriptors.UsbASGeneral;
+import com.android.server.usb.descriptors.UsbConfigDescriptor;
+import com.android.server.usb.descriptors.UsbDescriptor;
+import com.android.server.usb.descriptors.UsbDeviceDescriptor;
+import com.android.server.usb.descriptors.UsbEndpointDescriptor;
+import com.android.server.usb.descriptors.UsbHIDDescriptor;
+import com.android.server.usb.descriptors.UsbInterfaceAssoc;
+import com.android.server.usb.descriptors.UsbInterfaceDescriptor;
+import com.android.server.usb.descriptors.UsbMSMidiHeader;
+import com.android.server.usb.descriptors.UsbMSMidiInputJack;
+import com.android.server.usb.descriptors.UsbMSMidiOutputJack;
+import com.android.server.usb.descriptors.UsbUnknown;
+
+/**
+ * Implements the Reporter inteface to provide HTML reporting for UsbDescriptor subclasses.
+ */
+public class HTMLReporter implements Reporter {
+    private final StringBuilder mStringBuilder;
+    private final UsbDeviceConnection mConnection;
+
+    public HTMLReporter(StringBuilder stringBuilder, UsbDeviceConnection connection) {
+        mStringBuilder = stringBuilder;
+        mConnection = connection;
+    }
+
+    /*
+     * HTML Helpers
+     */
+    private void writeHeader(int level, String text) {
+        mStringBuilder
+                .append("<h").append(level).append('>')
+                .append(text)
+                .append("</h").append(level).append('>');
+    }
+
+    private void openParagraph() {
+        mStringBuilder.append("<p>");
+    }
+
+    private void closeParagraph() {
+        mStringBuilder.append("</p>");
+    }
+
+    private void writeParagraph(String text) {
+        openParagraph();
+        mStringBuilder.append(text);
+        closeParagraph();
+    }
+
+    private void openList() {
+        mStringBuilder.append("<ul>");
+    }
+
+    private void closeList() {
+        mStringBuilder.append("</ul>");
+    }
+
+    private void openListItem() {
+        mStringBuilder.append("<li>");
+    }
+
+    private void closeListItem() {
+        mStringBuilder.append("</li>");
+    }
+
+    private void writeListItem(String text) {
+        openListItem();
+        mStringBuilder.append(text);
+        closeListItem();
+    }
+
+    /*
+     * Data Formating Helpers
+     */
+    private static String getHexString(byte value) {
+        return "0x" + Integer.toHexString(((int) value) & 0xFF).toUpperCase();
+    }
+
+    private static String getBCDString(int value) {
+        int major = value >> 8;
+        int minor = (value >> 4) & 0x0F;
+        int subminor = value & 0x0F;
+
+        return "" + major + "." + minor + subminor;
+    }
+
+    private static String getHexString(int value) {
+        int intValue = value & 0xFFFF;
+        return "0x" + Integer.toHexString(intValue).toUpperCase();
+    }
+
+    private void dumpHexArray(byte[] rawData, StringBuilder builder) {
+        if (rawData != null) {
+            // Assume the type and Length and perhaps sub-type have been displayed
+            openParagraph();
+            for (int index = 0; index < rawData.length; index++) {
+                builder.append(getHexString(rawData[index]) + " ");
+            }
+            closeParagraph();
+        }
+    }
+
+    /**
+     * Decode ACTUAL UsbDescriptor sub classes and call type-specific report methods.
+     */
+    @Override
+    public void report(UsbDescriptor descriptor) {
+        if (descriptor instanceof UsbDeviceDescriptor) {
+            tsReport((UsbDeviceDescriptor) descriptor);
+        } else if (descriptor instanceof UsbConfigDescriptor) {
+            tsReport((UsbConfigDescriptor) descriptor);
+        } else if (descriptor instanceof UsbInterfaceDescriptor) {
+            tsReport((UsbInterfaceDescriptor) descriptor);
+        } else if (descriptor instanceof UsbEndpointDescriptor) {
+            tsReport((UsbEndpointDescriptor) descriptor);
+        } else if (descriptor instanceof UsbHIDDescriptor) {
+            tsReport((UsbHIDDescriptor) descriptor);
+        } else if (descriptor instanceof UsbACAudioControlEndpoint) {
+            tsReport((UsbACAudioControlEndpoint) descriptor);
+        } else if (descriptor instanceof UsbACAudioStreamEndpoint) {
+            tsReport((UsbACAudioStreamEndpoint) descriptor);
+        } else if (descriptor instanceof UsbACHeader) {
+            tsReport((UsbACHeader) descriptor);
+        } else if (descriptor instanceof UsbACFeatureUnit) {
+            tsReport((UsbACFeatureUnit) descriptor);
+        } else if (descriptor instanceof UsbACInputTerminal) {
+            tsReport((UsbACInputTerminal) descriptor);
+        } else if (descriptor instanceof UsbACOutputTerminal) {
+            tsReport((UsbACOutputTerminal) descriptor);
+        } else if (descriptor instanceof UsbACMidiEndpoint) {
+            tsReport((UsbACMidiEndpoint) descriptor);
+        } else if (descriptor instanceof UsbACMixerUnit) {
+            tsReport((UsbACMixerUnit) descriptor);
+        } else if (descriptor instanceof UsbACSelectorUnit) {
+            tsReport((UsbACSelectorUnit) descriptor);
+        } else if (descriptor instanceof UsbASFormatI) {
+            tsReport((UsbASFormatI) descriptor);
+        } else if (descriptor instanceof UsbASFormatII) {
+            tsReport((UsbASFormatII) descriptor);
+        } else if (descriptor instanceof UsbASFormat) {
+            tsReport((UsbASFormat) descriptor);
+        } else if (descriptor instanceof UsbASGeneral) {
+            tsReport((UsbASGeneral) descriptor);
+        } else if (descriptor instanceof UsbInterfaceAssoc) {
+            tsReport((UsbInterfaceAssoc) descriptor);
+        } else if (descriptor instanceof UsbMSMidiHeader) {
+            tsReport((UsbMSMidiHeader) descriptor);
+        } else if (descriptor instanceof UsbMSMidiInputJack) {
+            tsReport((UsbMSMidiInputJack) descriptor);
+        } else if (descriptor instanceof UsbMSMidiOutputJack) {
+            tsReport((UsbMSMidiOutputJack) descriptor);
+        } else if (descriptor instanceof UsbUnknown) {
+            tsReport((UsbUnknown) descriptor);
+        } else if (descriptor instanceof UsbACInterface) {
+            tsReport((UsbACInterface) descriptor);
+        } else if (descriptor instanceof UsbDescriptor) {
+            tsReport((UsbDescriptor) descriptor);
+        }
+    }
+
+    //
+    // Type-specific report() implementations
+    //
+    private void tsReport(UsbDescriptor descriptor) {
+        int length = descriptor.getLength();
+        byte type = descriptor.getType();
+        int status = descriptor.getStatus();
+
+        String descTypeStr = UsbStrings.getDescriptorName(type);
+        writeParagraph(descTypeStr + ":" + type + " l:" + length + " s:" + status);
+    }
+
+    private void tsReport(UsbDeviceDescriptor descriptor) {
+        writeHeader(1, "Device len:" + descriptor.getLength());
+        openList();
+
+        int spec = descriptor.getSpec();
+        writeListItem("spec:" + getBCDString(spec));
+
+        byte devClass = descriptor.getDevClass();
+        String classStr = UsbStrings.getClassName(devClass);
+        byte devSubClass = descriptor.getDevSubClass();
+        String subClasStr = UsbStrings.getClassName(devSubClass);
+        writeListItem("class " + devClass + ":" + classStr + " subclass"
+                + devSubClass + ":" + subClasStr);
+        writeListItem("vendorID:" + descriptor.getVendorID()
+                + " prodID:" + descriptor.getProductID()
+                + " prodRel:" + getBCDString(descriptor.getDeviceRelease()));
+
+        byte mfgIndex = descriptor.getMfgIndex();
+        String manufacturer = UsbDescriptor.getUsbDescriptorString(mConnection, mfgIndex);
+        byte productIndex = descriptor.getProductIndex();
+        String product = UsbDescriptor.getUsbDescriptorString(mConnection, productIndex);
+
+        writeListItem("mfg " + mfgIndex + ":" + manufacturer
+                + " prod " + productIndex + ":" + product);
+        closeList();
+    }
+
+    private void tsReport(UsbConfigDescriptor descriptor) {
+        writeHeader(2, "Config #" + descriptor.getConfigValue()
+                + " len:" + descriptor.getLength());
+
+        openList();
+        writeListItem(descriptor.getNumInterfaces() + " interfaces.");
+        writeListItem("attribs:" + getHexString(descriptor.getAttribs()));
+        closeList();
+    }
+
+    private void tsReport(UsbInterfaceDescriptor descriptor) {
+        byte usbClass = descriptor.getUsbClass();
+        byte usbSubclass = descriptor.getUsbSubclass();
+        String descr = UsbStrings.getDescriptorName(descriptor.getType());
+        String className = UsbStrings.getClassName(usbClass);
+        String subclassName = "";
+        if (usbClass == UsbDescriptor.CLASSID_AUDIO) {
+            subclassName = UsbStrings.getAudioSubclassName(usbSubclass);
+        }
+
+        writeHeader(2, descr + " #" + descriptor.getInterfaceNumber()
+                        + " len:" + descriptor.getLength());
+        String descrStr =
+                UsbDescriptor.getUsbDescriptorString(mConnection, descriptor.getDescrIndex());
+        if (descrStr.length() > 0) {
+            mStringBuilder.append("<br>" + descrStr);
+        }
+        openList();
+        writeListItem("class " + getHexString(usbClass) + ":" + className
+                + " subclass " + getHexString(usbSubclass) + ":" + subclassName);
+        writeListItem(""  + descriptor.getNumEndpoints() + " endpoints");
+        closeList();
+    }
+
+    private void tsReport(UsbEndpointDescriptor descriptor) {
+        writeHeader(3, "Endpoint " + getHexString(descriptor.getType())
+                + " len:" + descriptor.getLength());
+        openList();
+
+        byte address = descriptor.getEndpointAddress();
+        writeListItem("address:"
+                + getHexString(address & UsbEndpointDescriptor.MASK_ENDPOINT_ADDRESS)
+                + ((address & UsbEndpointDescriptor.MASK_ENDPOINT_DIRECTION)
+                        == UsbEndpointDescriptor.DIRECTION_OUTPUT ? " [out]" : " [in]"));
+
+        byte attributes = descriptor.getAttributes();
+        openListItem();
+        mStringBuilder.append("attribs:" + getHexString(attributes) + " ");
+        switch (attributes & UsbEndpointDescriptor.MASK_ATTRIBS_TRANSTYPE) {
+            case UsbEndpointDescriptor.TRANSTYPE_CONTROL:
+                mStringBuilder.append("Control");
+                break;
+            case UsbEndpointDescriptor.TRANSTYPE_ISO:
+                mStringBuilder.append("Iso");
+                break;
+            case UsbEndpointDescriptor.TRANSTYPE_BULK:
+                mStringBuilder.append("Bulk");
+                break;
+            case UsbEndpointDescriptor.TRANSTYPE_INTERRUPT:
+                mStringBuilder.append("Interrupt");
+                break;
+        }
+        closeListItem();
+
+        // These flags are only relevant for ISO transfer type
+        if ((attributes & UsbEndpointDescriptor.MASK_ATTRIBS_TRANSTYPE)
+                == UsbEndpointDescriptor.TRANSTYPE_ISO) {
+            openListItem();
+            mStringBuilder.append("sync:");
+            switch (attributes & UsbEndpointDescriptor.MASK_ATTRIBS_SYNCTYPE) {
+                case UsbEndpointDescriptor.SYNCTYPE_NONE:
+                    mStringBuilder.append("NONE");
+                    break;
+                case UsbEndpointDescriptor.SYNCTYPE_ASYNC:
+                    mStringBuilder.append("ASYNC");
+                    break;
+                case UsbEndpointDescriptor.SYNCTYPE_ADAPTSYNC:
+                    mStringBuilder.append("ADAPTIVE ASYNC");
+                    break;
+            }
+            closeListItem();
+
+            openListItem();
+            mStringBuilder.append("useage:");
+            switch (attributes & UsbEndpointDescriptor.MASK_ATTRIBS_USEAGE) {
+                case UsbEndpointDescriptor.USEAGE_DATA:
+                    mStringBuilder.append("DATA");
+                    break;
+                case UsbEndpointDescriptor.USEAGE_FEEDBACK:
+                    mStringBuilder.append("FEEDBACK");
+                    break;
+                case UsbEndpointDescriptor.USEAGE_EXPLICIT:
+                    mStringBuilder.append("EXPLICIT FEEDBACK");
+                    break;
+                case UsbEndpointDescriptor.USEAGE_RESERVED:
+                    mStringBuilder.append("RESERVED");
+                    break;
+            }
+            closeListItem();
+        }
+        writeListItem("package size:" + descriptor.getPacketSize());
+        writeListItem("interval:" + descriptor.getInterval());
+        closeList();
+    }
+
+    private void tsReport(UsbHIDDescriptor descriptor) {
+        String descr = UsbStrings.getDescriptorName(descriptor.getType());
+        writeHeader(2, descr + " len:" + descriptor.getLength());
+        openList();
+        writeListItem("spec:" + getBCDString(descriptor.getRelease()));
+        writeListItem("type:" + getBCDString(descriptor.getDescriptorType()));
+        writeListItem("descriptor.getNumDescriptors()  descriptors len:"
+                + descriptor.getDescriptorLen());
+        closeList();
+    }
+
+    private void tsReport(UsbACAudioControlEndpoint descriptor) {
+        writeHeader(3, "AC Audio Control Endpoint:" + getHexString(descriptor.getType())
+                + " length:" + descriptor.getLength());
+    }
+
+    private void tsReport(UsbACAudioStreamEndpoint descriptor) {
+        writeHeader(3, "AC Audio Streaming Endpoint:"
+                + getHexString(descriptor.getType())
+                + " length:" + descriptor.getLength());
+    }
+
+    private void tsReport(UsbACHeader descriptor) {
+        tsReport((UsbACInterface) descriptor);
+
+        openList();
+        writeListItem("spec:" + getBCDString(descriptor.getADCRelease()));
+        int numInterfaces = descriptor.getNumInterfaces();
+        writeListItem("" + numInterfaces + " interfaces");
+        if (numInterfaces > 0) {
+            openListItem();
+            mStringBuilder.append("[");
+            byte[] interfaceNums = descriptor.getInterfaceNums();
+            if (numInterfaces != 0 && interfaceNums != null) {
+                for (int index = 0; index < numInterfaces; index++) {
+                    mStringBuilder.append("" + interfaceNums[index]);
+                    if (index < numInterfaces - 1) {
+                        mStringBuilder.append(" ");
+                    }
+                }
+            }
+            mStringBuilder.append("]");
+            closeListItem();
+        }
+        writeListItem("controls:" + getHexString(descriptor.getControls()));
+        closeList();
+    }
+
+    private void tsReport(UsbACFeatureUnit descriptor) {
+        tsReport((UsbACInterface) descriptor);
+    }
+
+    private void tsReport(UsbACInterface descriptor) {
+        String subClassName =
+                descriptor.getSubclass() == UsbDescriptor.AUDIO_AUDIOCONTROL
+                        ? "AC Control"
+                        : "AC Streaming";
+        byte subtype = descriptor.getSubtype();
+        String subTypeStr = UsbStrings.getACControlInterfaceName(subtype);
+        writeHeader(4, subClassName + " - " + getHexString(subtype)
+                + ":" + subTypeStr + " len:" + descriptor.getLength());
+    }
+
+    private void tsReport(UsbACTerminal descriptor) {
+        tsReport((UsbACInterface) descriptor);
+    }
+
+    private void tsReport(UsbACInputTerminal descriptor) {
+        tsReport((UsbACTerminal) descriptor);
+
+        openList();
+        writeListItem("ID:" + getHexString(descriptor.getTerminalID()));
+        int terminalType = descriptor.getTerminalType();
+        writeListItem("Type:<b>" + getHexString(terminalType) + ":"
+                + UsbStrings.getTerminalName(terminalType) + "</b>");
+        writeListItem("AssocTerminal:" + getHexString(descriptor.getAssocTerminal()));
+        writeListItem("" + descriptor.getNrChannels() + " chans. config:"
+                + getHexString(descriptor.getChannelConfig()));
+        closeList();
+    }
+
+    private void tsReport(UsbACOutputTerminal descriptor) {
+        tsReport((UsbACTerminal) descriptor);
+
+        openList();
+        writeListItem("ID:" + getHexString(descriptor.getTerminalID()));
+        int terminalType = descriptor.getTerminalType();
+        writeListItem("Type:<b>" + getHexString(terminalType) + ":"
+                + UsbStrings.getTerminalName(terminalType) + "</b>");
+        writeListItem("AssocTerminal:" + getHexString(descriptor.getAssocTerminal()));
+        writeListItem("Source:" + getHexString(descriptor.getSourceID()));
+        closeList();
+    }
+
+    private void tsReport(UsbACMidiEndpoint descriptor) {
+        writeHeader(3, "AC Midi Endpoint:" + getHexString(descriptor.getType())
+                + " length:" + descriptor.getLength());
+        openList();
+        writeListItem("" + descriptor.getNumJacks() + " jacks.");
+        closeList();
+    }
+
+    private void tsReport(UsbACMixerUnit descriptor) {
+        tsReport((UsbACInterface) descriptor);
+        openList();
+
+        writeListItem("Unit ID:" + getHexString(descriptor.getUnitID()));
+        byte numInputs = descriptor.getNumInputs();
+        byte[] inputIDs = descriptor.getInputIDs();
+        openListItem();
+        mStringBuilder.append("Num Inputs:" + numInputs + " [");
+        for (int input = 0; input < numInputs; input++) {
+            mStringBuilder.append("" + getHexString(inputIDs[input]));
+            if (input < numInputs - 1) {
+                mStringBuilder.append(" ");
+            }
+        }
+        mStringBuilder.append("]");
+        closeListItem();
+
+        writeListItem("Num Outputs:" + descriptor.getNumOutputs());
+        writeListItem("Chan Config:" + getHexString(descriptor.getChannelConfig()));
+
+        byte[] controls = descriptor.getControls();
+        openListItem();
+        mStringBuilder.append("controls:" + controls.length + " [");
+        for (int ctrl = 0; ctrl < controls.length; ctrl++) {
+            mStringBuilder.append("" + controls[ctrl]);
+            if (ctrl < controls.length - 1) {
+                mStringBuilder.append(" ");
+            }
+        }
+        mStringBuilder.append("]");
+        closeListItem();
+        closeList();
+        // byte mChanNameID; // First channel name string descriptor ID
+        // byte mNameID;       // string descriptor ID of mixer name
+    }
+
+    private void tsReport(UsbACSelectorUnit descriptor) {
+        tsReport((UsbACInterface) descriptor);
+    }
+
+    private void tsReport(UsbASFormat descriptor) {
+        writeHeader(4, "AC Streaming Format "
+                + (descriptor.getFormatType() ==  UsbASFormat.FORMAT_TYPE_I  ? "I" : "II")
+                + " - " + getHexString(descriptor.getSubtype()) + ":"
+                + " len:" + descriptor.getLength());
+    }
+
+    private void tsReport(UsbASFormatI descriptor) {
+        tsReport((UsbASFormat) descriptor);
+        openList();
+        writeListItem("chans:" + descriptor.getNumChannels());
+        writeListItem("subframe size:" + descriptor.getSubframeSize());
+        writeListItem("bit resolution:" + descriptor.getBitResolution());
+        byte sampleFreqType = descriptor.getSampleFreqType();
+        int[] sampleRates = descriptor.getSampleRates();
+        writeListItem("sample freq type:" + sampleFreqType);
+        if (sampleFreqType == 0) {
+            openList();
+            writeListItem("min:" + sampleRates[0]);
+            writeListItem("max:" + sampleRates[1]);
+            closeList();
+        } else {
+            openList();
+            for (int index = 0; index < sampleFreqType; index++) {
+                writeListItem("" + sampleRates[index]);
+            }
+            closeList();
+        }
+        closeList();
+    }
+
+    private void tsReport(UsbASFormatII descriptor) {
+        tsReport((UsbASFormat) descriptor);
+        openList();
+        writeListItem("max bit rate:" + descriptor.getMaxBitRate());
+        writeListItem("samples per frame:" + descriptor.getMaxBitRate());
+        byte sampleFreqType = descriptor.getSamFreqType();
+        int[] sampleRates = descriptor.getSampleRates();
+        writeListItem("sample freq type:" + sampleFreqType);
+        if (sampleFreqType == 0) {
+            openList();
+            writeListItem("min:" + sampleRates[0]);
+            writeListItem("max:" + sampleRates[1]);
+            closeList();
+        } else {
+            openList();
+            for (int index = 0; index < sampleFreqType; index++) {
+                writeListItem("" + sampleRates[index]);
+            }
+            closeList();
+        }
+
+        closeList();
+    }
+
+    private void tsReport(UsbASGeneral descriptor) {
+        tsReport((UsbACInterface) descriptor);
+        openList();
+        int formatTag = descriptor.getFormatTag();
+        writeListItem("fmt:" + UsbStrings.getAudioFormatName(formatTag) + " - "
+                + getHexString(formatTag));
+        closeList();
+    }
+
+    private void tsReport(UsbInterfaceAssoc descriptor) {
+        tsReport((UsbDescriptor) descriptor);
+    }
+
+    private void tsReport(UsbMSMidiHeader descriptor) {
+        writeHeader(3, "MS Midi Header:" + getHexString(descriptor.getType())
+                + " subType:" + getHexString(descriptor.getSubclass())
+                + " length:" + descriptor.getSubclass());
+    }
+
+    private void tsReport(UsbMSMidiInputJack descriptor) {
+        writeHeader(3, "MS Midi Input Jack:" + getHexString(descriptor.getType())
+                + " subType:" + getHexString(descriptor.getSubclass())
+                + " length:" + descriptor.getSubclass());
+    }
+
+    private void tsReport(UsbMSMidiOutputJack descriptor) {
+        writeHeader(3, "MS Midi Output Jack:" + getHexString(descriptor.getType())
+                + " subType:" + getHexString(descriptor.getSubclass())
+                + " length:" + descriptor.getSubclass());
+    }
+
+    private void tsReport(UsbUnknown descriptor) {
+        writeParagraph("<i><b>Unknown Descriptor " + getHexString(descriptor.getType())
+                + " len:" + descriptor.getLength() + "</b></i>");
+        dumpHexArray(descriptor.getRawData(), mStringBuilder);
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/report/Reporter.java b/services/usb/java/com/android/server/usb/descriptors/report/Reporter.java
new file mode 100644
index 0000000..2944c10
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/report/Reporter.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors.report;
+
+import com.android.server.usb.descriptors.UsbDescriptor;
+
+/**
+ * Declares the Reporter interface to provide HTML reporting for UsbDescriptor (sub)classes.
+ *
+ * NOTE: It is the responsibility of the implementor of this interface to correctly
+ * interpret/decode the SPECIFIC UsbDescriptor subclass (perhaps with 'instanceof') that is
+ * passed and handle that in the appropriate manner. This appears to be a
+ * not very object-oriented approach, and that is true. This approach DOES however move the
+ * complexity and 'plumbing' of reporting into the Reporter implementation and avoids needing
+ * a (trivial) type-specific call to 'report()' in each UsbDescriptor (sub)class, instead
+ * having just one in the top-level UsbDescriptor class. It also removes the need to add new
+ * type-specific 'report()' methods to be added to Reporter interface whenever a
+ * new UsbDescriptor subclass is defined. This seems like a pretty good trade-off.
+ *
+ * See HTMLReporter.java in this package for an example of type decoding.
+ */
+public interface Reporter {
+    /**
+     * Generate report for this UsbDescriptor descriptor
+     */
+    void report(UsbDescriptor descriptor);
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/report/Reporting.java b/services/usb/java/com/android/server/usb/descriptors/report/Reporting.java
new file mode 100644
index 0000000..c13111b
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/report/Reporting.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors.report;
+
+/**
+ * Declares the interface for classes that provide reporting functionality.
+ * (This is the double-indirection aspect of the "Visitor" pattern.
+ */
+public interface Reporting {
+    /**
+     * Declares the report method that UsbDescriptor subclasses call.
+     */
+    void report(Reporter reporter);
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java b/services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java
new file mode 100644
index 0000000..0461150
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.descriptors.report;
+
+import com.android.server.usb.descriptors.UsbACInterface;
+import com.android.server.usb.descriptors.UsbDescriptor;
+import com.android.server.usb.descriptors.UsbTerminalTypes;
+
+import java.util.HashMap;
+
+/**
+ * @hide
+ * A class to provide human-readable strings for various USB constants.
+ */
+public class UsbStrings {
+    private static final String TAG = "UsbStrings";
+
+    private static HashMap<Byte, String> sDescriptorNames;
+    private static HashMap<Byte, String> sACControlInterfaceNames;
+    private static HashMap<Byte, String> sACStreamingInterfaceNames;
+    private static HashMap<Byte, String> sClassNames;
+    private static HashMap<Byte, String> sAudioSubclassNames;
+    private static HashMap<Integer, String> sAudioEncodingNames;
+    private static HashMap<Integer, String> sTerminalNames;
+
+    private static void initDescriptorNames() {
+        sDescriptorNames = new HashMap<Byte, String>();
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_DEVICE, "Device");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_CONFIG, "Config");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_STRING, "String");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_INTERFACE, "Interface");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_ENDPOINT, "Endpoint");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_BOS, "BOS (whatever that means)");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_INTERFACEASSOC,
+                "Interface Association");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_CAPABILITY, "Capability");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_HID, "HID");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_REPORT, "Report");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_PHYSICAL, "Physical");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE,
+                "Audio Class Interface");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_AUDIO_ENDPOINT, "Audio Class Endpoint");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_HUB, "Hub");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_SUPERSPEED_HUB, "Superspeed Hub");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_ENDPOINT_COMPANION,
+                "Endpoint Companion");
+    }
+
+    private static void initACControlInterfaceNames() {
+        sACControlInterfaceNames = new HashMap<Byte, String>();
+        sACControlInterfaceNames.put(UsbACInterface.ACI_UNDEFINED, "Undefined");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_HEADER, "Header");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_INPUT_TERMINAL, "Input Terminal");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_OUTPUT_TERMINAL, "Output Terminal");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_MIXER_UNIT, "Mixer Unit");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_SELECTOR_UNIT, "Selector Unit");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_FEATURE_UNIT, "Feature Unit");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_PROCESSING_UNIT, "Processing Unit");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_EXTENSION_UNIT, "Extension Unit");
+    }
+
+    private static void initACStreamingInterfaceNames() {
+        sACStreamingInterfaceNames = new HashMap<Byte, String>();
+        sACStreamingInterfaceNames.put(UsbACInterface.ASI_UNDEFINED, "Undefined");
+        sACStreamingInterfaceNames.put(UsbACInterface.ASI_GENERAL, "General");
+        sACStreamingInterfaceNames.put(UsbACInterface.ASI_FORMAT_TYPE, "Format Type");
+        sACStreamingInterfaceNames.put(UsbACInterface.ASI_FORMAT_SPECIFIC, "Format Specific");
+    }
+
+    private static void initClassNames() {
+        sClassNames = new HashMap<Byte, String>();
+        sClassNames.put(UsbDescriptor.CLASSID_DEVICE, "Device");
+        sClassNames.put(UsbDescriptor.CLASSID_AUDIO, "Audio");
+        sClassNames.put(UsbDescriptor.CLASSID_COM, "Communications");
+        sClassNames.put(UsbDescriptor.CLASSID_HID, "HID");
+        sClassNames.put(UsbDescriptor.CLASSID_PHYSICAL, "Physical");
+        sClassNames.put(UsbDescriptor.CLASSID_IMAGE, "Image");
+        sClassNames.put(UsbDescriptor.CLASSID_PRINTER, "Printer");
+        sClassNames.put(UsbDescriptor.CLASSID_STORAGE, "Storage");
+        sClassNames.put(UsbDescriptor.CLASSID_HUB, "Hub");
+        sClassNames.put(UsbDescriptor.CLASSID_CDC_CONTROL, "CDC Control");
+        sClassNames.put(UsbDescriptor.CLASSID_SMART_CARD, "Smart Card");
+        sClassNames.put(UsbDescriptor.CLASSID_SECURITY, "Security");
+        sClassNames.put(UsbDescriptor.CLASSID_VIDEO, "Video");
+        sClassNames.put(UsbDescriptor.CLASSID_HEALTHCARE, "Healthcare");
+        sClassNames.put(UsbDescriptor.CLASSID_AUDIOVIDEO, "Audio/Video");
+        sClassNames.put(UsbDescriptor.CLASSID_BILLBOARD, "Billboard");
+        sClassNames.put(UsbDescriptor.CLASSID_TYPECBRIDGE, "Type C Bridge");
+        sClassNames.put(UsbDescriptor.CLASSID_DIAGNOSTIC, "Diagnostic");
+        sClassNames.put(UsbDescriptor.CLASSID_WIRELESS, "Wireless");
+        sClassNames.put(UsbDescriptor.CLASSID_MISC, "Misc");
+        sClassNames.put(UsbDescriptor.CLASSID_APPSPECIFIC, "Application Specific");
+        sClassNames.put(UsbDescriptor.CLASSID_VENDSPECIFIC, "Vendor Specific");
+    }
+
+    private static void initAudioSubclassNames() {
+        sAudioSubclassNames = new HashMap<Byte, String>();
+        sAudioSubclassNames.put(UsbDescriptor.AUDIO_SUBCLASS_UNDEFINED, "Undefinded");
+        sAudioSubclassNames.put(UsbDescriptor.AUDIO_AUDIOCONTROL, "Audio Control");
+        sAudioSubclassNames.put(UsbDescriptor.AUDIO_AUDIOSTREAMING, "Audio Streaming");
+        sAudioSubclassNames.put(UsbDescriptor.AUDIO_MIDISTREAMING, "MIDI Streaming");
+    }
+
+    private static void initAudioEncodingNames() {
+        sAudioEncodingNames = new HashMap<Integer, String>();
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_UNDEFINED, "Format I Undefined");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_PCM, "Format I PCM");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_PCM8, "Format I PCM8");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_IEEE_FLOAT, "Format I FLOAT");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_ALAW, "Format I ALAW");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_MULAW, "Format I MuLAW");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_II_UNDEFINED, "FORMAT_II Undefined");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_II_MPEG, "FORMAT_II MPEG");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_II_AC3, "FORMAT_II AC3");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_UNDEFINED, "FORMAT_III Undefined");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937AC3, "FORMAT_III IEC1937 AC3");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937_MPEG1_Layer1,
+                "FORMAT_III MPEG1 Layer 1");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937_MPEG1_Layer2,
+                "FORMAT_III MPEG1 Layer 2");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937_MPEG2_EXT,
+                "FORMAT_III MPEG2 EXT");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937_MPEG2_Layer1LS,
+                "FORMAT_III MPEG2 Layer1LS");
+    }
+
+    private static void initTerminalNames() {
+        sTerminalNames = new HashMap<Integer, String>();
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_USB_STREAMING, "USB Streaming");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_MIC, "Microphone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_DESKTOP_MIC, "Desktop Microphone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_PERSONAL_MIC,
+                "Personal (headset) Microphone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_OMNI_MIC, "Omni Microphone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_MIC_ARRAY, "Microphone Array");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_PROC_MIC_ARRAY,
+                "Proecessing Microphone Array");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_SPEAKER, "Speaker");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_HEADPHONES, "Headphones");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_HEADMOUNTED, "Head Mounted Speaker");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_DESKTOPSPEAKER, "Desktop Speaker");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_ROOMSPEAKER, "Room Speaker");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_COMSPEAKER, "Communications Speaker");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_LFSPEAKER, "Low Frequency Speaker");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_HANDSET, "Handset");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_HEADSET, "Headset");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_SKRPHONE, "Speaker Phone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_SKRPHONE_SUPRESS,
+                "Speaker Phone (echo supressing)");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_SKRPHONE_CANCEL,
+                "Speaker Phone (echo canceling)");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_TELE_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_TELE_PHONELINE, "Phone Line");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_TELE_PHONE, "Telephone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_TELE_DOWNLINEPHONE, "Down Line Phone");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_ANALOG, "Analog Connector");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_DIGITAL, "Digital Connector");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_LINE, "Line Connector");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_LEGACY, "Legacy Audio Connector");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_SPIDF, "S/PIDF Interface");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_1394DA, "1394 Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_1394DV, "1394 Audio/Video");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_CALNOISE, "Calibration Nose");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_EQNOISE, "EQ Noise");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_CDPLAYER, "CD Player");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_DAT, "DAT");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_DCC, "DCC");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_MINIDISK, "Mini Disk");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_ANALOGTAPE, "Analog Tap");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_PHONOGRAPH, "Phonograph");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_VCRAUDIO, "VCR Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_VIDDISKAUDIO, "Video Disk Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_DVDAUDIO, "DVD Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_TVAUDIO, "TV Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_SATELLITEAUDIO, "Satellite Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_CABLEAUDIO, "Cable Tuner Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_DSSAUDIO, "DSS Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_RADIOTRANSMITTER, "Radio Transmitter");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_MULTITRACK, "Multitrack Recorder");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_SYNTHESIZER, "Synthesizer");
+    }
+
+    /**
+     * Retrieves the terminal name for the specified terminal type ID.
+     */
+    public static String getTerminalName(int terminalType) {
+        String name = sTerminalNames.get(terminalType);
+        return name != null
+                ? name
+                : "Unknown Terminal Type 0x" + Integer.toHexString(terminalType);
+    }
+    /**
+     * Initializes string tables.
+     */
+    public static void allocUsbStrings() {
+        initDescriptorNames();
+        initACControlInterfaceNames();
+        initACStreamingInterfaceNames();
+        initClassNames();
+        initAudioSubclassNames();
+        initAudioEncodingNames();
+        initTerminalNames();
+    }
+
+    /**
+     * Initializes string tables.
+     */
+    public static void releaseUsbStrings() {
+        sDescriptorNames = null;
+        sACControlInterfaceNames = null;
+        sACStreamingInterfaceNames = null;
+        sClassNames = null;
+        sAudioSubclassNames = null;
+        sAudioEncodingNames = null;
+        sTerminalNames = null;
+    }
+
+    /**
+     * Retrieves the name for the specified descriptor ID.
+     */
+    public static String getDescriptorName(byte descriptorID) {
+        String name = sDescriptorNames.get(descriptorID);
+        int iDescriptorID = descriptorID & 0xFF;
+        return name != null
+            ? name
+            : "Unknown Descriptor [0x" + Integer.toHexString(iDescriptorID)
+                + ":" + iDescriptorID + "]";
+    }
+
+    /**
+     * Retrieves the audio-class control interface name for the specified audio-class subtype.
+     */
+    public static String getACControlInterfaceName(byte subtype) {
+        String name = sACControlInterfaceNames.get(subtype);
+        int iSubType = subtype & 0xFF;
+        return name != null
+                ? name
+                : "Unknown subtype [0x" + Integer.toHexString(iSubType)
+                    + ":" + iSubType + "]";
+    }
+
+    /**
+     * Retrieves the audio-class streaming interface name for the specified audio-class subtype.
+     */
+    public static String getACStreamingInterfaceName(byte subtype) {
+        String name = sACStreamingInterfaceNames.get(subtype);
+        int iSubType = subtype & 0xFF;
+        return name != null
+                ? name
+                : "Unknown Subtype [0x" + Integer.toHexString(iSubType) + ":"
+                    + iSubType + "]";
+    }
+
+    /**
+     * Retrieves the name for the specified USB class ID.
+     */
+    public static String getClassName(byte classID) {
+        String name = sClassNames.get(classID);
+        int iClassID = classID & 0xFF;
+        return name != null
+                ? name
+                : "Unknown Class ID [0x" + Integer.toHexString(iClassID) + ":"
+                    + iClassID + "]";
+    }
+
+    /**
+     * Retrieves the name for the specified USB audio subclass ID.
+     */
+    public static String getAudioSubclassName(byte subClassID) {
+        String name = sAudioSubclassNames.get(subClassID);
+        int iSubclassID = subClassID & 0xFF;
+        return name != null
+                ? name
+                : "Unknown Audio Subclass [0x" + Integer.toHexString(iSubclassID) + ":"
+                    + iSubclassID + "]";
+    }
+
+    /**
+     * Retrieves the name for the specified USB audio format ID.
+     */
+    public static String getAudioFormatName(int formatID) {
+        String name = sAudioEncodingNames.get(formatID);
+        return name != null
+                ? name
+                : "Unknown Format (encoding) ID [0x" + Integer.toHexString(formatID) + ":"
+                    + formatID + "]";
+    }
+}
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index a6bfbad..e8e0680 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -189,6 +189,19 @@
      */
     public static final String EVENT_HANDOVER_COMPLETE =
             "android.telecom.event.HANDOVER_COMPLETE";
+
+    /**
+     * Call event sent from Telecom to the handover destination {@link ConnectionService} via
+     * {@link Connection#onCallEvent(String, Bundle)} to inform the handover destination that the
+     * source connection has disconnected.  The {@link Bundle} parameter for the call event will be
+     * {@code null}.
+     * <p>
+     * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
+     * @hide
+     */
+    public static final String EVENT_HANDOVER_SOURCE_DISCONNECTED =
+            "android.telecom.event.HANDOVER_SOURCE_DISCONNECTED";
+
     /**
      * Call event sent from Telecom to the handover {@link ConnectionService} via
      * {@link Connection#onCallEvent(String, Bundle)} to inform a {@link Connection} that a handover
diff --git a/telephony/java/android/telephony/ImsiEncryptionInfo.java b/telephony/java/android/telephony/ImsiEncryptionInfo.java
index ecb9d25..d2680ad 100644
--- a/telephony/java/android/telephony/ImsiEncryptionInfo.java
+++ b/telephony/java/android/telephony/ImsiEncryptionInfo.java
@@ -17,6 +17,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import java.util.Date;
 import android.util.Log;
 
 import java.security.KeyFactory;
@@ -34,7 +35,6 @@
 public final class ImsiEncryptionInfo implements Parcelable {
 
     private static final String LOG_TAG = "ImsiEncryptionInfo";
-    private static final boolean DBG = false;
 
 
     private final String mcc;
@@ -42,14 +42,25 @@
     private final PublicKey publicKey;
     private final String keyIdentifier;
     private final int keyType;
+    //Date-Time in UTC when the key will expire.
+    private final Date expirationTime;
 
     public ImsiEncryptionInfo(String mcc, String mnc, int keyType, String keyIdentifier,
-                              PublicKey publicKey) {
+                              byte[] key, Date expirationTime) {
+        this(mcc, mnc, keyType, keyIdentifier, makeKeyObject(key), expirationTime);
+    }
+
+    public ImsiEncryptionInfo(String mcc, String mnc, int keyType, String keyIdentifier,
+                              PublicKey publicKey, Date expirationTime) {
+        // todo need to validate that ImsiEncryptionInfo is being created with the correct params.
+        //      Including validating that the public key is in "X.509" format. This will be done in
+        //      a subsequent CL.
         this.mcc = mcc;
         this.mnc = mnc;
         this.keyType = keyType;
         this.publicKey = publicKey;
         this.keyIdentifier = keyIdentifier;
+        this.expirationTime = expirationTime;
     }
 
     public ImsiEncryptionInfo(Parcel in) {
@@ -61,7 +72,7 @@
         mnc = in.readString();
         keyIdentifier = in.readString();
         keyType = in.readInt();
-
+        expirationTime = new Date(in.readLong());
     }
 
     public String getMnc() {
@@ -84,6 +95,10 @@
         return this.publicKey;
     }
 
+    public Date getExpirationTime() {
+        return this.expirationTime;
+    }
+
     private static PublicKey makeKeyObject(byte[] publicKeyBytes) {
         try {
             X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(publicKeyBytes);
@@ -91,7 +106,7 @@
         } catch (InvalidKeySpecException | NoSuchAlgorithmException ex) {
             Log.e(LOG_TAG, "Error makeKeyObject: unable to convert into PublicKey", ex);
         }
-     return null;
+        throw new IllegalArgumentException();
     }
 
     /** Implement the Parcelable interface */
@@ -122,6 +137,7 @@
         dest.writeString(mnc);
         dest.writeString(keyIdentifier);
         dest.writeInt(keyType);
+        dest.writeLong(expirationTime.getTime());
     }
 
     @Override
@@ -132,6 +148,7 @@
                 + "publicKey=" + publicKey
                 + ", keyIdentifier=" + keyIdentifier
                 + ", keyType=" + keyType
+                + ", expirationTime=" + expirationTime
                 + "]";
     }
 }
diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java
index c905d3a..92a21b6 100644
--- a/telephony/java/android/telephony/TelephonyScanManager.java
+++ b/telephony/java/android/telephony/TelephonyScanManager.java
@@ -20,15 +20,18 @@
 
 import android.content.Context;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Messenger;
+import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Log;
 import android.util.SparseArray;
+import java.util.Arrays;
 import java.util.List;
 
 import com.android.internal.telephony.ITelephony;
@@ -42,6 +45,9 @@
     private static final String TAG = "TelephonyScanManager";
 
     /** @hide */
+    public static final String SCAN_RESULT_KEY = "scanResult";
+
+    /** @hide */
     public static final int CALLBACK_SCAN_RESULTS = 1;
     /** @hide */
     public static final int CALLBACK_SCAN_ERROR = 2;
@@ -112,7 +118,13 @@
                 switch (message.what) {
                     case CALLBACK_SCAN_RESULTS:
                         try {
-                            callback.onResults((List<CellInfo>) message.obj);
+                            final Bundle b = message.getData();
+                            final Parcelable[] parcelables = b.getParcelableArray(SCAN_RESULT_KEY);
+                            CellInfo[] ci = new CellInfo[parcelables.length];
+                            for (int i = 0; i < parcelables.length; i++) {
+                                ci[i] = (CellInfo) parcelables[i];
+                            }
+                            callback.onResults((List<CellInfo>) Arrays.asList(ci));
                         } catch (Exception e) {
                             Rlog.e(TAG, "Exception in networkscan callback onResults", e);
                         }
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index 11770fb..8304d84 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -320,7 +320,8 @@
             return;
         }
         try {
-            mController.getDownloadableSubscriptionMetadata(subscription, callbackIntent);
+            mController.getDownloadableSubscriptionMetadata(
+                    subscription, mContext.getOpPackageName(), callbackIntent);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -349,7 +350,8 @@
             return;
         }
         try {
-            mController.getDefaultDownloadableSubscriptionList(callbackIntent);
+            mController.getDefaultDownloadableSubscriptionList(
+                    mContext.getOpPackageName(), callbackIntent);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -473,6 +475,36 @@
         }
     }
 
+    /**
+     * Ensure that subscriptions will be retained on the next factory reset.
+     *
+     * <p>By default, all subscriptions on the eUICC are erased the first time a device boots (ever
+     * and after factory resets). This ensures that the data is wiped after a factory reset is
+     * performed via fastboot or recovery mode, as these modes do not support the necessary radio
+     * communication needed to wipe the eSIM.
+     *
+     * <p>However, this method may be called right before a factory reset issued via settings when
+     * the user elects to retain subscriptions. Doing so will mark them for retention so that they
+     * are not cleared after the ensuing reset.
+     *
+     * <p>Requires that the calling app has the {@link android.Manifest.permission#MASTER_CLEAR}
+     * permission. This is for internal system use only.
+     *
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     * @hide
+     */
+    public void retainSubscriptionsForFactoryReset(PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.retainSubscriptionsForFactoryReset(callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     private static void sendUnavailableError(PendingIntent callbackIntent) {
         try {
             callbackIntent.send(EMBEDDED_SUBSCRIPTION_RESULT_ERROR);
diff --git a/telephony/java/android/telephony/ims/ImsServiceProxy.java b/telephony/java/android/telephony/ims/ImsServiceProxy.java
index a75cd86..038e295 100644
--- a/telephony/java/android/telephony/ims/ImsServiceProxy.java
+++ b/telephony/java/android/telephony/ims/ImsServiceProxy.java
@@ -90,11 +90,11 @@
                         " status: " + status);
                 if (mSlotId == slotId && feature == mSupportedFeature) {
                     mFeatureStatusCached = status;
+                    if (mStatusCallback != null) {
+                        mStatusCallback.notifyStatusChanged();
+                    }
                 }
             }
-            if (mStatusCallback != null) {
-                mStatusCallback.notifyStatusChanged();
-            }
         }
     };
 
@@ -129,7 +129,9 @@
     @Override
     public void endSession(int sessionId) throws RemoteException {
         synchronized (mLock) {
-            checkServiceIsReady();
+            // Only check to make sure the binder connection still exists. This method should
+            // still be able to be called when the state is STATE_NOT_AVAILABLE.
+            checkBinderConnection();
             getServiceInterface(mBinder).endSession(mSlotId, mSupportedFeature, sessionId);
         }
     }
diff --git a/telephony/java/com/android/internal/telephony/NetworkScanResult.java b/telephony/java/com/android/internal/telephony/NetworkScanResult.java
index 7a7c174..95f39d7 100644
--- a/telephony/java/com/android/internal/telephony/NetworkScanResult.java
+++ b/telephony/java/com/android/internal/telephony/NetworkScanResult.java
@@ -35,10 +35,10 @@
 public final class NetworkScanResult implements Parcelable {
 
     // Contains only part of the scan result and more are coming.
-    public static final int SCAN_STATUS_PARTIAL = 0;
+    public static final int SCAN_STATUS_PARTIAL = 1;
 
     // Contains the last part of the scan result and the scan is now complete.
-    public static final int SCAN_STATUS_COMPLETE = 1;
+    public static final int SCAN_STATUS_COMPLETE = 2;
 
     // The status of the scan, only valid when scanError = SUCCESS.
     public int scanStatus;
diff --git a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
index 725b89b..b3fc90d 100644
--- a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
+++ b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
@@ -26,8 +26,9 @@
 interface IEuiccController {
     oneway void continueOperation(in Intent resolutionIntent, in Bundle resolutionExtras);
     oneway void getDownloadableSubscriptionMetadata(in DownloadableSubscription subscription,
-        in PendingIntent callbackIntent);
-    oneway void getDefaultDownloadableSubscriptionList(in PendingIntent callbackIntent);
+        String callingPackage, in PendingIntent callbackIntent);
+    oneway void getDefaultDownloadableSubscriptionList(
+        String callingPackage, in PendingIntent callbackIntent);
     String getEid();
     oneway void downloadSubscription(in DownloadableSubscription subscription,
         boolean switchAfterDownload, String callingPackage, in PendingIntent callbackIntent);
@@ -39,4 +40,5 @@
     oneway void updateSubscriptionNickname(int subscriptionId, String nickname,
         in PendingIntent callbackIntent);
     oneway void eraseSubscriptions(in PendingIntent callbackIntent);
+    oneway void retainSubscriptionsForFactoryReset(in PendingIntent callbackIntent);
 }
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
index f28d126..0fabc2f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
@@ -30,10 +30,6 @@
     /** Private constructor for utility class. */
     private SmsCbConstants() { }
 
-    /** Channel 50 required by Brazil. ID 0~999 is allocated by GSMA */
-    public static final int MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_50
-            = 0x0032;
-
     /** Start of PWS Message Identifier range (includes ETWS and CMAS). */
     public static final int MESSAGE_ID_PWS_FIRST_IDENTIFIER
             = 0x1100; // 4352
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 582506a..d4098d9 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -278,6 +278,10 @@
                 scAddress, destinationAddress, mtiByte,
                 statusReportRequested, ret);
 
+        // Skip encoding pdu if error occurs when create pdu head and the error will be handled
+        // properly later on encodedMessage sanity check.
+        if (bo == null) return ret;
+
         // User Data (and length)
         byte[] userData;
         try {
@@ -420,6 +424,9 @@
                 scAddress, destinationAddress, (byte) 0x41, // MTI = SMS-SUBMIT,
                                                             // TP-UDHI = true
                 statusReportRequested, ret);
+        // Skip encoding pdu if error occurs when create pdu head and the error will be handled
+        // properly later on encodedMessage sanity check.
+        if (bo == null) return ret;
 
         // TP-Data-Coding-Scheme
         // No class, 8 bit data
@@ -451,7 +458,7 @@
      * @param destinationAddress the address of the destination for the message
      * @param mtiByte
      * @param ret <code>SubmitPdu</code> containing the encoded SC
-     *        address, if applicable, and the encoded message
+     *        address, if applicable, and the encoded message. Returns null on encode error.
      */
     private static ByteArrayOutputStream getSubmitPduHead(
             String scAddress, String destinationAddress, byte mtiByte,
@@ -482,6 +489,9 @@
 
         daBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD(destinationAddress);
 
+        // return empty pduHead for invalid destination address
+        if (daBytes == null) return null;
+
         // destination address length in BCD digits, ignoring TON byte and pad
         // TODO Should be better.
         bo.write((daBytes.length - 1) * 2
diff --git a/tests/StatusBar/AndroidManifest.xml b/tests/StatusBar/AndroidManifest.xml
index 81442bf..6a082e9 100644
--- a/tests/StatusBar/AndroidManifest.xml
+++ b/tests/StatusBar/AndroidManifest.xml
@@ -6,6 +6,7 @@
     <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
     <uses-permission android:name="android.permission.VIBRATE" />
     <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
+    <uses-permission android:name="android.permission.MANAGE_NOTIFICATIONS" />
 
     <application>
         <activity android:name="StatusBarTest" android:label="_StatusBar">
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 5dd42dd..fc68183 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -129,6 +129,42 @@
                     mNM.notify(7001, n);
                 }
             },
+            new Test("with zen") {
+                public void run()
+                {
+                    mNM.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALARMS);
+                    Notification n = new Notification.Builder(NotificationTestList.this,
+                            "default")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setContentTitle("Default priority")
+                            .build();
+                    mNM.notify("default", 7004, n);
+                    try {
+                        Thread.sleep(8000);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    mNM.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL);
+                }
+            },
+            new Test("repeated") {
+                public void run()
+                {
+                    for (int i = 0; i < 50; i++) {
+                        Notification n = new Notification.Builder(NotificationTestList.this,
+                                "default")
+                                .setSmallIcon(R.drawable.icon2)
+                                .setContentTitle("Default priority")
+                                .build();
+                        mNM.notify("default", 7004, n);
+                        try {
+                            Thread.sleep(100);
+                        } catch (InterruptedException e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }
+            },
             new Test("Post a group") {
                 public void run()
                 {
diff --git a/tests/testables/src/android/testing/TestableInstrumentation.java b/tests/testables/src/android/testing/TestableInstrumentation.java
new file mode 100644
index 0000000..93fed85
--- /dev/null
+++ b/tests/testables/src/android/testing/TestableInstrumentation.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package android.testing;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.TestLooperManager;
+import android.support.test.runner.AndroidJUnitRunner;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+/**
+ * Wrapper around instrumentation that spins up a TestLooperManager around
+ * the main looper whenever a test is not using it to attempt to stop crashes
+ * from stopping other tests from running.
+ */
+public class TestableInstrumentation extends AndroidJUnitRunner {
+
+    private static final String TAG = "TestableInstrumentation";
+
+    private static final int MAX_CRASHES = 5;
+    private static MainLooperManager sManager;
+
+    @Override
+    public void onCreate(Bundle arguments) {
+        sManager = new MainLooperManager();
+        Log.setWtfHandler((tag, what, system) -> {
+            if (system) {
+                Log.e(TAG, "WTF!!", what);
+            } else {
+                // These normally kill the app, but we don't want that in a test, instead we want
+                // it to throw.
+                throw new RuntimeException(what);
+            }
+        });
+        super.onCreate(arguments);
+    }
+
+    @Override
+    public void finish(int resultCode, Bundle results) {
+        sManager.destroy();
+        super.finish(resultCode, results);
+    }
+
+    public static void acquireMain() {
+        if (sManager != null) {
+            sManager.acquireMain();
+        }
+    }
+
+    public static void releaseMain() {
+        if (sManager != null) {
+            sManager.releaseMain();
+        }
+    }
+
+    public class MainLooperManager implements Runnable {
+
+        private final ArrayList<Throwable> mExceptions = new ArrayList<>();
+        private Message mStopMessage;
+        private final Handler mMainHandler;
+        private TestLooperManager mManager;
+
+        public MainLooperManager() {
+            mMainHandler = new Handler(Looper.getMainLooper());
+            startManaging();
+        }
+
+        @Override
+        public void run() {
+            try {
+                synchronized (this) {
+                    // Let the thing starting us know we are up and ready to run.
+                    notify();
+                }
+                while (true) {
+                    Message m = mManager.next();
+                    if (m == mStopMessage) {
+                        mManager.recycle(m);
+                        return;
+                    }
+                    try {
+                        mManager.execute(m);
+                    } catch (Throwable t) {
+                        if (!checkStack(t) || (mExceptions.size() == MAX_CRASHES)) {
+                            throw t;
+                        }
+                        mExceptions.add(t);
+                        Log.d(TAG, "Ignoring exception to run more tests", t);
+                    }
+                    mManager.recycle(m);
+                }
+            } finally {
+                mManager.release();
+                synchronized (this) {
+                    // Let the caller know we are done managing the main thread.
+                    notify();
+                }
+            }
+        }
+
+        private boolean checkStack(Throwable t) {
+            StackTraceElement topStack = t.getStackTrace()[0];
+            String className = topStack.getClassName();
+            if (className.equals(TestLooperManager.class.getName())) {
+                topStack = t.getCause().getStackTrace()[0];
+                className = topStack.getClassName();
+            }
+            // Only interested in blocking exceptions from the app itself, not from android
+            // framework.
+            return !className.startsWith("android.")
+                    && !className.startsWith("com.android.internal");
+        }
+
+        public void destroy() {
+            mStopMessage.sendToTarget();
+            if (mExceptions.size() != 0) {
+                throw new RuntimeException("Exception caught during tests", mExceptions.get(0));
+            }
+        }
+
+        public void acquireMain() {
+            synchronized (this) {
+                mStopMessage.sendToTarget();
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+
+        public void releaseMain() {
+            startManaging();
+        }
+
+        private void startManaging() {
+            mStopMessage = mMainHandler.obtainMessage();
+            synchronized (this) {
+                mManager = acquireLooperManager(Looper.getMainLooper());
+                // This bit needs to happen on a background thread or it will hang if called
+                // from the same thread we are looking to block.
+                new Thread(() -> {
+                    // Post a message to the main handler that will manage executing all future
+                    // messages.
+                    mMainHandler.post(this);
+                    while (!mManager.hasMessages(mMainHandler, null, this));
+                    // Lastly run the message that executes this so it can manage the main thread.
+                    Message next = mManager.next();
+                    // Run through messages until we reach ours.
+                    while (next.getCallback() != this) {
+                        mManager.execute(next);
+                        mManager.recycle(next);
+                        next = mManager.next();
+                    }
+                    mManager.execute(next);
+                }).start();
+                if (Looper.myLooper() != Looper.getMainLooper()) {
+                    try {
+                        wait();
+                    } catch (InterruptedException e) {
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/tests/testables/src/android/testing/TestableLooper.java b/tests/testables/src/android/testing/TestableLooper.java
index f6c3cb3..f1a7092 100644
--- a/tests/testables/src/android/testing/TestableLooper.java
+++ b/tests/testables/src/android/testing/TestableLooper.java
@@ -29,7 +29,6 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
-import java.lang.reflect.Field;
 import java.util.Map;
 
 /**
@@ -49,7 +48,7 @@
     private TestLooperManager mQueueWrapper;
 
     public TestableLooper(Looper l) throws Exception {
-        this(InstrumentationRegistry.getInstrumentation().acquireLooperManager(l), l);
+        this(acquireLooperManager(l), l);
     }
 
     private TestableLooper(TestLooperManager wrapper, Looper l) throws Exception {
@@ -78,6 +77,9 @@
      */
     public void destroy() throws NoSuchFieldException, IllegalAccessException {
         mQueueWrapper.release();
+        if (mLooper == Looper.getMainLooper()) {
+            TestableInstrumentation.releaseMain();
+        }
     }
 
     /**
@@ -196,6 +198,13 @@
         }
     }
 
+    private static TestLooperManager acquireLooperManager(Looper l) {
+        if (l == Looper.getMainLooper()) {
+            TestableInstrumentation.acquireMain();
+        }
+        return InstrumentationRegistry.getInstrumentation().acquireLooperManager(l);
+    }
+
     private static final Map<Object, TestableLooper> sLoopers = new ArrayMap<>();
 
     /**
@@ -247,8 +256,7 @@
             }
             boolean set = mTestableLooper.mQueueWrapper == null;
             if (set) {
-                mTestableLooper.mQueueWrapper = InstrumentationRegistry.getInstrumentation()
-                        .acquireLooperManager(mLooper);
+                mTestableLooper.mQueueWrapper = acquireLooperManager(mLooper);
             }
             try {
                 Object[] ret = new Object[1];
@@ -283,6 +291,9 @@
                 if (set) {
                     mTestableLooper.mQueueWrapper.release();
                     mTestableLooper.mQueueWrapper = null;
+                    if (mLooper == Looper.getMainLooper()) {
+                        TestableInstrumentation.releaseMain();
+                    }
                 }
             }
         }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index f596eef..0d4359e 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -291,7 +291,6 @@
             "android.net.wifi.p2p.CALLING_PACKAGE";
 
     IWifiP2pManager mService;
-    private final Map<Channel, Binder> mBinders = new HashMap<>();
 
     private static final int BASE = Protocol.BASE_WIFI_P2P_MANAGER;
 
@@ -670,11 +669,12 @@
      * by doing a call on {@link #initialize}
      */
     public static class Channel {
-        Channel(Context context, Looper looper, ChannelListener l) {
+        Channel(Context context, Looper looper, ChannelListener l, Binder binder) {
             mAsyncChannel = new AsyncChannel();
             mHandler = new P2pHandler(looper);
             mChannelListener = l;
             mContext = context;
+            mBinder = binder;
         }
         private final static int INVALID_LISTENER_KEY = 0;
         private ChannelListener mChannelListener;
@@ -686,6 +686,8 @@
         private final Object mListenerMapLock = new Object();
         private int mListenerKey = 0;
 
+        /* package */ final Binder mBinder;
+
         private AsyncChannel mAsyncChannel;
         private P2pHandler mHandler;
         Context mContext;
@@ -892,8 +894,8 @@
      */
     public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
         Binder binder = new Binder();
-        Channel channel = initalizeChannel(srcContext, srcLooper, listener, getMessenger(binder));
-        mBinders.put(channel, binder);
+        Channel channel = initalizeChannel(srcContext, srcLooper, listener, getMessenger(binder),
+                binder);
         return channel;
     }
 
@@ -903,14 +905,15 @@
      */
     public Channel initializeInternal(Context srcContext, Looper srcLooper,
                                       ChannelListener listener) {
-        return initalizeChannel(srcContext, srcLooper, listener, getP2pStateMachineMessenger());
+        return initalizeChannel(srcContext, srcLooper, listener, getP2pStateMachineMessenger(),
+                null);
     }
 
     private Channel initalizeChannel(Context srcContext, Looper srcLooper, ChannelListener listener,
-                                     Messenger messenger) {
+                                     Messenger messenger, Binder binder) {
         if (messenger == null) return null;
 
-        Channel c = new Channel(srcContext, srcLooper, listener);
+        Channel c = new Channel(srcContext, srcLooper, listener, binder);
         if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger)
                 == AsyncChannel.STATUS_SUCCESSFUL) {
             return c;
@@ -1428,8 +1431,9 @@
      */
     public void close(Channel c) {
         try {
-            mService.close(mBinders.get(c));
-            mBinders.remove(c);
+            if (c != null) {
+                mService.close(c.mBinder);
+            }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }