Merge "Import translations. DO NOT MERGE" into pi-dev
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 9ac54b9..1ef11b1 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -1409,6 +1409,7 @@
 Landroid/os/Debug$MemoryInfo;->otherSwappedOut:I
 Landroid/os/Debug$MemoryInfo;->otherSwappedOutPss:I
 Landroid/os/Environment;->buildExternalStorageAppDataDirs(Ljava/lang/String;)[Ljava/io/File;
+Landroid/os/Environment;->getStorageDirectory()Ljava/io/File;
 Landroid/os/Environment;->getVendorDirectory()Ljava/io/File;
 Landroid/os/Environment;->maybeTranslateEmulatedPathToInternal(Ljava/io/File;)Ljava/io/File;
 Landroid/os/FileObserver$ObserverThread;->onEvent(IILjava/lang/String;)V
@@ -1428,6 +1429,19 @@
 Landroid/os/Handler;-><init>(Z)V
 Landroid/os/Handler;->mCallback:Landroid/os/Handler$Callback;
 Landroid/os/Handler;->mMessenger:Landroid/os/IMessenger;
+Landroid/os/health/HealthKeys$Constants;-><init>(Ljava/lang/Class;)V
+Landroid/os/health/HealthStats;-><init>(Landroid/os/Parcel;)V
+Landroid/os/health/HealthStatsParceler;->getHealthStats()Landroid/os/health/HealthStats;
+Landroid/os/health/HealthStatsParceler;-><init>(Landroid/os/health/HealthStatsWriter;)V
+Landroid/os/health/HealthStatsParceler;-><init>(Landroid/os/Parcel;)V
+Landroid/os/health/HealthStatsWriter;->addMeasurement(IJ)V
+Landroid/os/health/HealthStatsWriter;->addMeasurements(ILjava/lang/String;J)V
+Landroid/os/health/HealthStatsWriter;->addStats(ILjava/lang/String;Landroid/os/health/HealthStatsWriter;)V
+Landroid/os/health/HealthStatsWriter;->addTimer(IIJ)V
+Landroid/os/health/HealthStatsWriter;->addTimers(ILjava/lang/String;Landroid/os/health/TimerStat;)V
+Landroid/os/health/HealthStatsWriter;->flattenToParcel(Landroid/os/Parcel;)V
+Landroid/os/health/HealthStatsWriter;-><init>(Landroid/os/health/HealthKeys$Constants;)V
+Landroid/os/health/SystemHealthManager;->from(Landroid/content/Context;)Landroid/os/health/SystemHealthManager;
 Landroid/os/HwParcel;-><init>(Z)V
 Landroid/os/HwRemoteBinder;-><init>()V
 Landroid/os/IBatteryPropertiesRegistrar$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -1440,6 +1454,7 @@
 Landroid/os/IServiceManager;->checkService(Ljava/lang/String;)Landroid/os/IBinder;
 Landroid/os/IServiceManager;->getService(Ljava/lang/String;)Landroid/os/IBinder;
 Landroid/os/IUserManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/os/LocaleList;->setDefault(Landroid/os/LocaleList;I)V
 Landroid/os/Looper;->mQueue:Landroid/os/MessageQueue;
 Landroid/os/Looper;->setTraceTag(J)V
 Landroid/os/Looper;->sThreadLocal:Ljava/lang/ThreadLocal;
@@ -1455,9 +1470,12 @@
 Landroid/os/MessageQueue;->mQuitAllowed:Z
 Landroid/os/MessageQueue;->nativePollOnce(JI)V
 Landroid/os/MessageQueue;->next()Landroid/os/Message;
+Landroid/os/MessageQueue;->postSyncBarrier()I
+Landroid/os/MessageQueue;->removeSyncBarrier(I)V
 Landroid/os/Message;->recycleUnchecked()V
 Landroid/os/Message;->target:Landroid/os/Handler;
 Landroid/os/Message;->when:J
+Landroid/os/ParcelFileDescriptor;->fromData([BLjava/lang/String;)Landroid/os/ParcelFileDescriptor;
 Landroid/os/ParcelFileDescriptor;-><init>(Ljava/io/FileDescriptor;)V
 Landroid/os/Parcel;->mNativePtr:J
 Landroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;Ljava/lang/ClassLoader;)V
@@ -1470,6 +1488,7 @@
 Landroid/os/PowerManager;->getMinimumScreenBrightnessSetting()I
 Landroid/os/PowerManager;->isLightDeviceIdleMode()Z
 Landroid/os/PowerManager;->mService:Landroid/os/IPowerManager;
+Landroid/os/PowerManager;->nap(J)V
 Landroid/os/PowerManager;->userActivity(JZ)V
 Landroid/os/PowerManager;->validateWakeLockParameters(ILjava/lang/String;)V
 Landroid/os/PowerManager;->wakeUp(JLjava/lang/String;)V
@@ -1500,6 +1519,7 @@
 Landroid/os/storage/StorageManager;->findVolumeByUuid(Ljava/lang/String;)Landroid/os/storage/VolumeInfo;
 Landroid/os/storage/StorageManager;->getBestVolumeDescription(Landroid/os/storage/VolumeInfo;)Ljava/lang/String;
 Landroid/os/storage/StorageManager;->getDisks()Ljava/util/List;
+Landroid/os/storage/StorageManager;->getPrimaryVolume()Landroid/os/storage/StorageVolume;
 Landroid/os/storage/StorageManager;->getStorageBytesUntilLow(Ljava/io/File;)J
 Landroid/os/storage/StorageManager;->getStorageFullBytes(Ljava/io/File;)J
 Landroid/os/storage/StorageManager;->getStorageLowBytes(Ljava/io/File;)J
@@ -1520,6 +1540,7 @@
 Landroid/os/storage/VolumeInfo;->getType()I
 Landroid/os/storage/VolumeInfo;->isPrimary()Z
 Landroid/os/storage/VolumeInfo;->isVisible()Z
+Landroid/os/StrictMode;->conditionallyCheckInstanceCounts()V
 Landroid/os/StrictMode;->disableDeathOnFileUriExposure()V
 Landroid/os/StrictMode;->enterCriticalSpan(Ljava/lang/String;)Landroid/os/StrictMode$Span;
 Landroid/os/StrictMode;->getThreadPolicyMask()I
@@ -2117,6 +2138,7 @@
 Landroid/util/ArrayMap;->append(Ljava/lang/Object;Ljava/lang/Object;)V
 Landroid/util/ArrayMap;->mBaseCacheSize:I
 Landroid/util/ArrayMap;->mTwiceBaseCacheSize:I
+Landroid/util/ArraySet;-><init>(Ljava/util/Collection;)V
 Landroid/util/DisplayMetrics;->noncompatHeightPixels:I
 Landroid/util/DisplayMetrics;->noncompatWidthPixels:I
 Landroid/util/EventLog$Event;-><init>([B)V
@@ -3281,6 +3303,7 @@
 Ldalvik/system/VMRuntime;->getCurrentInstructionSet()Ljava/lang/String;
 Ldalvik/system/VMRuntime;->getInstructionSet(Ljava/lang/String;)Ljava/lang/String;
 Ldalvik/system/VMRuntime;->getRuntime()Ldalvik/system/VMRuntime;
+Ldalvik/system/VMRuntime;->is64BitAbi(Ljava/lang/String;)Z
 Ldalvik/system/VMRuntime;->is64Bit()Z
 Ldalvik/system/VMRuntime;->newNonMovableArray(Ljava/lang/Class;I)Ljava/lang/Object;
 Ldalvik/system/VMRuntime;->registerNativeAllocation(I)V
diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java
index 7d8e394..9e4e97a 100644
--- a/core/java/android/app/slice/SliceProvider.java
+++ b/core/java/android/app/slice/SliceProvider.java
@@ -37,6 +37,7 @@
 import android.os.Process;
 import android.os.StrictMode;
 import android.os.StrictMode.ThreadPolicy;
+import android.util.ArraySet;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -513,7 +514,7 @@
                     .detectAll()
                     .penaltyDeath()
                     .build());
-            return onBindSlice(sliceUri, supportedSpecs);
+            return onBindSlice(sliceUri, new ArraySet<>(supportedSpecs));
         } finally {
             StrictMode.setThreadPolicy(oldPolicy);
         }
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index a9d0911..0c5f228 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -302,6 +302,12 @@
     public abstract boolean isPackageDataProtected(int userId, String packageName);
 
     /**
+     * Returns {@code true} if a given package's state is protected, e.g. it cannot be force
+     * stopped, suspended, disabled or hidden. Otherwise, returns {@code false}.
+     */
+    public abstract boolean isPackageStateProtected(String packageName, int userId);
+
+    /**
      * Returns {@code true} if a given package is installed as ephemeral. Otherwise, returns
      * {@code false}.
      */
diff --git a/core/java/android/hardware/radio/ProgramSelector.java b/core/java/android/hardware/radio/ProgramSelector.java
index 2a878eb..435bcb0 100644
--- a/core/java/android/hardware/radio/ProgramSelector.java
+++ b/core/java/android/hardware/radio/ProgramSelector.java
@@ -411,7 +411,8 @@
     /**
      * Checks, if a given AM/FM frequency is roughly valid and in correct unit.
      *
-     * It does not check the range precisely. In particular, it may be way off for certain regions.
+     * It does not check the range precisely: it may provide false positives, but not false
+     * negatives. In particular, it may be way off for certain regions.
      * The main purpose is to avoid passing inproper units, ie. MHz instead of kHz.
      *
      * @param isAm true, if AM, false if FM.
@@ -420,7 +421,7 @@
      */
     private static boolean isValidAmFmFrequency(boolean isAm, int frequencyKhz) {
         if (isAm) {
-            return frequencyKhz > 150 && frequencyKhz < 30000;
+            return frequencyKhz > 150 && frequencyKhz <= 30000;
         } else {
             return frequencyKhz > 60000 && frequencyKhz < 110000;
         }
@@ -462,7 +463,8 @@
             throw new IllegalArgumentException("Subchannels are not supported for non-HD radio");
         }
         if (!isValidAmFmFrequency(isAm, frequencyKhz)) {
-            throw new IllegalArgumentException("Provided value is not a valid AM/FM frequency");
+            throw new IllegalArgumentException("Provided value is not a valid AM/FM frequency: "
+                    + frequencyKhz);
         }
 
         // We can't use AM_HD or FM_HD, because we don't know HD station ID.
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index a8e8179..65dfb13 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -71,6 +71,7 @@
             mUids = nc.mUids;
             mEstablishingVpnAppUid = nc.mEstablishingVpnAppUid;
             mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities;
+            mSSID = nc.mSSID;
         }
     }
 
@@ -86,6 +87,7 @@
         mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
         mUids = null;
         mEstablishingVpnAppUid = INVALID_UID;
+        mSSID = null;
     }
 
     /**
@@ -921,7 +923,7 @@
     /**
      * Sets the signal strength. This is a signed integer, with higher values indicating a stronger
      * signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units
-     * reported by WifiManager.
+     * reported by wifi code.
      * <p>
      * Note that when used to register a network callback, this specifies the minimum acceptable
      * signal strength. When received as the state of an existing network it specifies the current
@@ -1053,7 +1055,7 @@
     }
 
     /**
-     * Tests if the set of UIDs that this network applies to is the same of the passed set of UIDs.
+     * Tests if the set of UIDs that this network applies to is the same as the passed network.
      * <p>
      * This test only checks whether equal range objects are in both sets. It will
      * return false if the ranges are not exactly the same, even if the covered UIDs
@@ -1143,6 +1145,62 @@
         mUids.addAll(nc.mUids);
     }
 
+
+    /**
+     * The SSID of the network, or null if not applicable or unknown.
+     * <p>
+     * This is filled in by wifi code.
+     * @hide
+     */
+    private String mSSID;
+
+    /**
+     * Sets the SSID of this network.
+     * @hide
+     */
+    public NetworkCapabilities setSSID(String ssid) {
+        mSSID = ssid;
+        return this;
+    }
+
+    /**
+     * Gets the SSID of this network, or null if none or unknown.
+     * @hide
+     */
+    public String getSSID() {
+        return mSSID;
+    }
+
+    /**
+     * Tests if the SSID of this network is the same as the SSID of the passed network.
+     * @hide
+     */
+    public boolean equalsSSID(NetworkCapabilities nc) {
+        return Objects.equals(mSSID, nc.mSSID);
+    }
+
+    /**
+     * Check if the SSID requirements of this object are matched by the passed object.
+     * @hide
+     */
+    public boolean satisfiedBySSID(NetworkCapabilities nc) {
+        return mSSID == null || mSSID.equals(nc.mSSID);
+    }
+
+    /**
+     * Combine SSIDs of the capabilities.
+     * <p>
+     * This is only legal if either the SSID of this object is null, or both SSIDs are
+     * equal.
+     * @hide
+     */
+    private void combineSSIDs(NetworkCapabilities nc) {
+        if (mSSID != null && !mSSID.equals(nc.mSSID)) {
+            throw new IllegalStateException("Can't combine two SSIDs");
+        }
+        setSSID(nc.mSSID);
+    }
+
     /**
      * Combine a set of Capabilities to this one.  Useful for coming up with the complete set
      * @hide
@@ -1154,6 +1212,7 @@
         combineSpecifiers(nc);
         combineSignalStrength(nc);
         combineUids(nc);
+        combineSSIDs(nc);
     }
 
     /**
@@ -1172,7 +1231,8 @@
                 && (onlyImmutable || satisfiedByLinkBandwidths(nc))
                 && satisfiedBySpecifier(nc)
                 && (onlyImmutable || satisfiedBySignalStrength(nc))
-                && (onlyImmutable || satisfiedByUids(nc)));
+                && (onlyImmutable || satisfiedByUids(nc))
+                && (onlyImmutable || satisfiedBySSID(nc)));
     }
 
     /**
@@ -1259,7 +1319,8 @@
                 && equalsLinkBandwidths(that)
                 && equalsSignalStrength(that)
                 && equalsSpecifier(that)
-                && equalsUids(that));
+                && equalsUids(that)
+                && equalsSSID(that));
     }
 
     @Override
@@ -1274,7 +1335,8 @@
                 + (mLinkDownBandwidthKbps * 19)
                 + Objects.hashCode(mNetworkSpecifier) * 23
                 + (mSignalStrength * 29)
-                + Objects.hashCode(mUids) * 31;
+                + Objects.hashCode(mUids) * 31
+                + Objects.hashCode(mSSID) * 37;
     }
 
     @Override
@@ -1291,6 +1353,7 @@
         dest.writeParcelable((Parcelable) mNetworkSpecifier, flags);
         dest.writeInt(mSignalStrength);
         dest.writeArraySet(mUids);
+        dest.writeString(mSSID);
     }
 
     public static final Creator<NetworkCapabilities> CREATOR =
@@ -1308,6 +1371,7 @@
                 netCap.mSignalStrength = in.readInt();
                 netCap.mUids = (ArraySet<UidRange>) in.readArraySet(
                         null /* ClassLoader, null for default */);
+                netCap.mSSID = in.readString();
                 return netCap;
             }
             @Override
@@ -1358,6 +1422,10 @@
             sb.append(" EstablishingAppUid: ").append(mEstablishingVpnAppUid);
         }
 
+        if (null != mSSID) {
+            sb.append(" SSID: ").append(mSSID);
+        }
+
         sb.append("]");
         return sb.toString();
     }
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 7b01f7a..e3f4ad1 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -1470,6 +1470,17 @@
     }
 
     /**
+     * Determines if DND is currently overriding the ringer
+     */
+    public static boolean isZenOverridingRinger(int zen, ZenModeConfig zenConfig) {
+        // TODO (beverlyt): check if apps can bypass dnd b/77729075
+        return zen == Global.ZEN_MODE_NO_INTERRUPTIONS
+                || zen == Global.ZEN_MODE_ALARMS
+                || (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
+                && ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(zenConfig));
+    }
+
+    /**
      * Determines whether dnd behavior should mute all sounds controlled by ringer
      */
     public static boolean areAllPriorityOnlyNotificationZenSoundsMuted(ZenModeConfig config) {
diff --git a/core/java/com/android/internal/widget/NotificationActionListLayout.java b/core/java/com/android/internal/widget/NotificationActionListLayout.java
index 0482f6c..5729b53 100644
--- a/core/java/com/android/internal/widget/NotificationActionListLayout.java
+++ b/core/java/com/android/internal/widget/NotificationActionListLayout.java
@@ -107,21 +107,23 @@
                 }
             }
         }
-        if (notGoneChildren > 1 && needRebuild) {
+        boolean centerAligned = (mGravity & Gravity.CENTER_HORIZONTAL) != 0;
+        boolean singleChildCentered = notGoneChildren == 1 && centerAligned;
+        boolean needsRegularMeasurement = notGoneChildren > 1 || singleChildCentered;
+
+        if (needsRegularMeasurement && needRebuild) {
             rebuildMeasureOrder(textViews, otherViews);
         }
 
         final boolean constrained =
                 MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED;
-        final boolean centerAligned = (mGravity & Gravity.CENTER_HORIZONTAL) != 0;
 
         final int innerWidth = MeasureSpec.getSize(widthMeasureSpec) - mPaddingLeft - mPaddingRight;
         final int otherSize = mMeasureOrderOther.size();
         int usedWidth = 0;
 
-        // Optimization: Don't do this if there's only one child.
         int measuredChildren = 0;
-        for (int i = 0; i < N && notGoneChildren > 1; i++) {
+        for (int i = 0; i < N && needsRegularMeasurement; i++) {
             // Measure shortest children first. To avoid measuring twice, we approximate by looking
             // at the text length.
             View c;
diff --git a/core/res/res/layout/car_user_switching_dialog.xml b/core/res/res/layout/car_user_switching_dialog.xml
new file mode 100644
index 0000000..7ce35df
--- /dev/null
+++ b/core/res/res/layout/car_user_switching_dialog.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:fitsSystemWindows="true"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    >
+
+  <ImageView
+      android:id="@+id/user_loading_avatar"
+      android:layout_width="@dimen/car_fullscreen_user_pod_image_avatar_width"
+      android:layout_height="@dimen/car_fullscreen_user_pod_image_avatar_height"
+      android:layout_centerHorizontal="true"
+  />
+
+  <TextView android:id="@+id/user_loading"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:layout_marginTop="@dimen/car_padding_4"
+      android:textSize="@dimen/car_body1_size"
+      android:textColor="@color/car_body1_light"
+      android:layout_below="@id/user_loading_avatar"
+      android:gravity="center"
+  />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/user_switching_dialog.xml b/core/res/res/layout/user_switching_dialog.xml
index 496783a..c806210 100644
--- a/core/res/res/layout/user_switching_dialog.xml
+++ b/core/res/res/layout/user_switching_dialog.xml
@@ -24,4 +24,4 @@
         android:paddingStart="?attr/dialogPreferredPadding"
         android:paddingEnd="?attr/dialogPreferredPadding"
         android:paddingTop="24dp"
-        android:paddingBottom="24dp" />
+        android:paddingBottom="24dp" />
\ No newline at end of file
diff --git a/core/res/res/values/colors_car.xml b/core/res/res/values/colors_car.xml
new file mode 100644
index 0000000..6053728
--- /dev/null
+++ b/core/res/res/values/colors_car.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources>
+  <!-- car support colors from
+  https://cs.corp.google.com/android/frameworks/support/car/res/values/colors.xml -->
+  <color name="car_user_switcher_user_image_bgcolor">@color/car_grey_50</color>
+  <color name="car_user_switcher_user_image_fgcolor">@color/car_grey_900</color>
+  <color name="car_card_dark">@color/car_dark_blue_grey_700</color>
+  <color name="car_body1_light">@color/car_grey_100</color>
+
+  <color name="car_grey_50">#fffafafa</color>
+  <color name="car_grey_900">#ff212121</color>
+  <color name="car_dark_blue_grey_700">#ff172026</color>
+  <color name="car_grey_100">#fff5f5f5</color>
+</resources>
diff --git a/core/res/res/values/dimens_car.xml b/core/res/res/values/dimens_car.xml
new file mode 100644
index 0000000..7d14f86
--- /dev/null
+++ b/core/res/res/values/dimens_car.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+-->
+<resources>
+    <!-- TODO replace with car support lib sizes when available -->
+    <dimen name="car_fullscreen_user_pod_icon_text_size">64sp</dimen>
+    <dimen name="car_fullscreen_user_pod_width">243dp</dimen>
+    <dimen name="car_fullscreen_user_pod_height">356dp</dimen>
+    <dimen name="car_fullscreen_user_pod_image_avatar_width">96dp</dimen>
+    <dimen name="car_fullscreen_user_pod_image_avatar_height">96dp</dimen>
+    <dimen name="car_padding_4">20dp</dimen>
+    <dimen name="car_body1_size">32sp</dimen>
+</resources>
\ No newline at end of file
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 04f4d6e..3571967 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4957,4 +4957,8 @@
     <string name="notification_app_name_system">System</string>
     <!-- Application name displayed in notifications [CHAR LIMIT=60] -->
     <string name="notification_app_name_settings">Settings</string>
+
+    <!-- Strings for car -->
+    <!-- String displayed when loading a user in the car [CHAR LIMIT=30] -->
+    <string name="car_loading_profile">Loading</string>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 129a952..0de2cb0 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3344,4 +3344,19 @@
 
   <java-symbol type="integer" name="config_lowBatteryAutoTriggerDefaultLevel" />
 
+  <!-- For car devices -->
+  <java-symbol type="string" name="car_loading_profile" />
+  <java-symbol type="color" name="car_body1_light" />
+  <java-symbol type="color" name="car_user_switcher_user_image_bgcolor" />
+  <java-symbol type="color" name="car_user_switcher_user_image_fgcolor" />
+  <java-symbol type="color" name="car_card_dark" />
+  <java-symbol type="dimen" name="car_body1_size" />
+  <java-symbol type="dimen" name="car_padding_4" />
+  <java-symbol type="dimen" name="car_fullscreen_user_pod_icon_text_size" />
+  <java-symbol type="dimen" name="car_fullscreen_user_pod_image_avatar_height" />
+  <java-symbol type="dimen" name="car_fullscreen_user_pod_image_avatar_width" />
+  <java-symbol type="layout" name="car_user_switching_dialog" />
+  <java-symbol type="id" name="user_loading_avatar" />
+  <java-symbol type="id" name="user_loading" />
+
 </resources>
diff --git a/keystore/java/android/security/keystore/AttestationUtils.java b/keystore/java/android/security/keystore/AttestationUtils.java
index efee8b4..1be8309 100644
--- a/keystore/java/android/security/keystore/AttestationUtils.java
+++ b/keystore/java/android/security/keystore/AttestationUtils.java
@@ -156,7 +156,7 @@
                     break;
                 }
                 case ID_TYPE_MEID: {
-                    final String meid = telephonyService.getDeviceId();
+                    final String meid = telephonyService.getMeid(0);
                     if (meid == null) {
                         throw new DeviceIdAttestationException("Unable to retrieve MEID");
                     }
diff --git a/packages/CaptivePortalLogin/AndroidManifest.xml b/packages/CaptivePortalLogin/AndroidManifest.xml
index 69fbb99..91bc505c 100644
--- a/packages/CaptivePortalLogin/AndroidManifest.xml
+++ b/packages/CaptivePortalLogin/AndroidManifest.xml
@@ -22,6 +22,7 @@
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
+    <uses-permission android:name="android.permission.NETWORK_STACK" />
 
     <application android:label="@string/app_name"
                  android:usesCleartextTraffic="true">
diff --git a/packages/CaptivePortalLogin/res/values-in/strings.xml b/packages/CaptivePortalLogin/res/values-in/strings.xml
index f9f6481..10e3de6 100644
--- a/packages/CaptivePortalLogin/res/values-in/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-in/strings.xml
@@ -4,7 +4,7 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Gunakan jaringan ini sebagaimana adanya"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Jangan gunakan jaringan ini"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Masuk ke jaringan"</string>
+    <string name="action_bar_label" msgid="917235635415966620">"Login ke jaringan"</string>
     <string name="action_bar_title" msgid="5645564790486983117">"Login ke %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Jaringan yang ingin Anda masuki mengalami masalah keamanan."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Misalnya, halaman masuk mungkin bukan milik organisasi yang ditampilkan."</string>
diff --git a/packages/CaptivePortalLogin/res/values-mr/strings.xml b/packages/CaptivePortalLogin/res/values-mr/strings.xml
index fac0a08..6ea9006 100644
--- a/packages/CaptivePortalLogin/res/values-mr/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-mr/strings.xml
@@ -6,7 +6,7 @@
     <string name="action_do_not_use_network" msgid="4577366536956516683">"हे नेटवर्क वापरू नका"</string>
     <string name="action_bar_label" msgid="917235635415966620">"नेटवर्क मध्‍ये साइन इन करा"</string>
     <string name="action_bar_title" msgid="5645564790486983117">"%1$sमध्‍ये साइन इन करा"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ज्या नेटवर्कमध्‍ये आपण सामील होण्याचा प्रयत्न करीत आहात त्यात सुरक्षितता समस्या आहेत."</string>
+    <string name="ssl_error_warning" msgid="6653188881418638872">"ज्या नेटवर्कमध्‍ये तुम्ही सामील होण्याचा प्रयत्न करीत आहात त्यात सुरक्षितता समस्या आहेत."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"उदाहरणार्थ, लॉगिन पृष्‍ठ कदाचित दर्शविलेल्या संस्थेच्या मालकीचे नसावे."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"ब्राउझरद्वारे तरीही सुरु ठेवा"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index cdc3867..0e2a0e0 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -26,12 +26,12 @@
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.Network;
 import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
 import android.net.NetworkRequest;
 import android.net.Proxy;
 import android.net.Uri;
 import android.net.dns.ResolvUtil;
 import android.net.http.SslError;
+import android.net.wifi.WifiInfo;
 import android.os.Build;
 import android.os.Bundle;
 import android.provider.Settings;
@@ -534,15 +534,12 @@
     }
 
     private String getHeaderTitle() {
-        NetworkInfo info = mCm.getNetworkInfo(mNetwork);
-        if (info == null || TextUtils.isEmpty(info.getExtraInfo())) {
-            return getString(R.string.action_bar_label);
-        }
         NetworkCapabilities nc = mCm.getNetworkCapabilities(mNetwork);
-        if (!nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
+        if (nc == null || TextUtils.isEmpty(nc.getSSID())
+            || !nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
             return getString(R.string.action_bar_label);
         }
-        return getString(R.string.action_bar_title, info.getExtraInfo().replaceAll("^\"|\"$", ""));
+        return getString(R.string.action_bar_title, WifiInfo.removeDoubleQuotes(nc.getSSID()));
     }
 
     private String getHeaderSubtitle(URL url) {
diff --git a/packages/CarrierDefaultApp/res/values-mr/strings.xml b/packages/CarrierDefaultApp/res/values-mr/strings.xml
index 7e7792f..e1442c2 100644
--- a/packages/CarrierDefaultApp/res/values-mr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-mr/strings.xml
@@ -11,7 +11,7 @@
     <string name="no_mobile_data_connection" msgid="544980465184147010">"%sने डेटा किंवा रोमिंग प्‍लॅन जोडा"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"मोबाइल डेटा स्थिती"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"मोबाइल नेटवर्कमध्ये साइन इन करा"</string>
-    <string name="ssl_error_warning" msgid="3127935140338254180">"आपण ज्या नेटवर्कमध्‍ये सामील होण्याचा प्रयत्न करत आहात त्यात सुरक्षितता समस्या आहेत."</string>
+    <string name="ssl_error_warning" msgid="3127935140338254180">"तुम्ही ज्या नेटवर्कमध्‍ये सामील होण्याचा प्रयत्न करत आहात त्यात सुरक्षितता समस्या आहेत."</string>
     <string name="ssl_error_example" msgid="6188711843183058764">"उदाहरणार्थ, लॉग इन पृष्‍ठ दर्शवलेल्या संस्थेच्या मालकीचे नसू शकते."</string>
     <string name="ssl_error_continue" msgid="1138548463994095584">"तरीही ब्राउझरद्वारे सुरू ठेवा"</string>
 </resources>
diff --git a/packages/InputDevices/res/values-hu/strings.xml b/packages/InputDevices/res/values-hu/strings.xml
index 39d00d4..4bb1611 100644
--- a/packages/InputDevices/res/values-hu/strings.xml
+++ b/packages/InputDevices/res/values-hu/strings.xml
@@ -3,7 +3,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="8016145283189546017">"Beviteli eszközök"</string>
     <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android-billentyűzet"</string>
-    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"angol (Egyesült Királyság)"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"angol (brit)"</string>
     <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"angol (USA)"</string>
     <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"angol (USA), nemzetközi stílus"</string>
     <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"angol (USA), Colemak-stílus"</string>
diff --git a/packages/InputDevices/res/values-ru/strings.xml b/packages/InputDevices/res/values-ru/strings.xml
index 207f5f9..49bf0b7 100644
--- a/packages/InputDevices/res/values-ru/strings.xml
+++ b/packages/InputDevices/res/values-ru/strings.xml
@@ -35,13 +35,13 @@
     <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"словенский"</string>
     <string name="keyboard_layout_turkish" msgid="7736163250907964898">"турецкий"</string>
     <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"украинский"</string>
-    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"Арабский"</string>
-    <string name="keyboard_layout_greek" msgid="7289253560162386040">"Греческий"</string>
-    <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Иврит"</string>
-    <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Литовский"</string>
-    <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Испанский (Латинская Америка)"</string>
+    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"арабский"</string>
+    <string name="keyboard_layout_greek" msgid="7289253560162386040">"греческий"</string>
+    <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"иврит"</string>
+    <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"литовский"</string>
+    <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"испанский (Латинская Америка)"</string>
     <string name="keyboard_layout_latvian" msgid="4405417142306250595">"латышский"</string>
     <string name="keyboard_layout_persian" msgid="3920643161015888527">"Персидский"</string>
     <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"Азербайджанский"</string>
-    <string name="keyboard_layout_polish" msgid="1121588624094925325">"Польский"</string>
+    <string name="keyboard_layout_polish" msgid="1121588624094925325">"польский"</string>
 </resources>
diff --git a/packages/InputDevices/res/values-uz/strings.xml b/packages/InputDevices/res/values-uz/strings.xml
index 441c2c2..3bd637b 100644
--- a/packages/InputDevices/res/values-uz/strings.xml
+++ b/packages/InputDevices/res/values-uz/strings.xml
@@ -3,20 +3,20 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="8016145283189546017">"Kiritish qurilmalari"</string>
     <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android klaviaturasi"</string>
-    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Inglizcha (BQ)"</string>
-    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Inglizcha (AQSH)"</string>
-    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Inglizcha (AQSH), xalqaro uslubda"</string>
-    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Inglizcha (AQSH), Kolemak uslubida"</string>
-    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Inglizcha (AQSH), Dvorak uslubida"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Ingliz (Birlashgan Qirollik)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Ingliz (AQSH)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Ingliz (AQSH), xalqaro"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Ingliz (AQSH), Kolemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Ingliz (AQSH), Dvorak"</string>
     <string name="keyboard_layout_english_us_workman_label" msgid="2944541595262173111">"Ingliz (AQSH), ishchi uslubda"</string>
-    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Nemischa"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Nemis"</string>
     <string name="keyboard_layout_french_label" msgid="813450119589383723">"Fransuzcha"</string>
     <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Fransuzcha (Kanada)"</string>
     <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Ruscha"</string>
     <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Ruscha, Mac uslubida"</string>
     <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Ispancha"</string>
     <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Shveytsar fransuzcha"</string>
-    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Shveytsar nemischa"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Nemis (Shveytsariya)"</string>
     <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgiyancha"</string>
     <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bolgarcha"</string>
     <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italyancha"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 6413aab..1e0cce9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -34,6 +34,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.ParcelUuid;
+import android.support.annotation.VisibleForTesting;
 import android.util.Log;
 import com.android.internal.R;
 import java.util.ArrayList;
@@ -41,6 +42,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
+
 /**
  * LocalBluetoothProfileManager provides access to the LocalBluetoothProfile
  * objects for the available Bluetooth profiles.
@@ -130,7 +132,7 @@
         addProfile(mHidProfile, HidProfile.NAME,
                 BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED);
 
-        mPanProfile = new PanProfile(context);
+        mPanProfile = new PanProfile(context, mLocalAdapter);
         addPanProfile(mPanProfile, PanProfile.NAME,
                 BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
 
@@ -486,6 +488,16 @@
         return mHearingAidProfile;
     }
 
+    @VisibleForTesting
+    HidProfile getHidProfile() {
+        return mHidProfile;
+    }
+
+    @VisibleForTesting
+    HidDeviceProfile getHidDeviceProfile() {
+        return mHidDeviceProfile;
+    }
+
     /**
      * Fill in a list of LocalBluetoothProfile objects that are supported by
      * the local device and the remote device.
@@ -553,7 +565,7 @@
             removedProfiles.remove(mHidProfile);
         }
 
-        if (mHidProfile != null && mHidDeviceProfile.getConnectionStatus(device)
+        if (mHidDeviceProfile != null && mHidDeviceProfile.getConnectionStatus(device)
                 != BluetoothProfile.STATE_DISCONNECTED) {
             profiles.add(mHidDeviceProfile);
             removedProfiles.remove(mHidDeviceProfile);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
index 3299cb2..e077a67 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
@@ -38,6 +38,7 @@
 
     private BluetoothPan mService;
     private boolean mIsProfileReady;
+    private final LocalBluetoothAdapter mLocalAdapter;
 
     // Tethering direction for each device
     private final HashMap<BluetoothDevice, Integer> mDeviceRoleMap =
@@ -68,10 +69,10 @@
         return mIsProfileReady;
     }
 
-    PanProfile(Context context) {
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        adapter.getProfileProxy(context, new PanServiceListener(),
-                BluetoothProfile.PAN);
+    PanProfile(Context context, LocalBluetoothAdapter adapter) {
+        mLocalAdapter = adapter;
+        mLocalAdapter.getProfileProxy(context, new PanServiceListener(),
+            BluetoothProfile.PAN);
     }
 
     public boolean isConnectable() {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
new file mode 100644
index 0000000..88c7a55
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothUuid;
+import android.content.Context;
+import android.os.ParcelUuid;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(resourceDir = "../../res")
+public class LocalBluetoothProfileManagerTest {
+    @Mock private CachedBluetoothDeviceManager mDeviceManager;
+    @Mock private BluetoothEventManager mEventManager;
+    @Mock private LocalBluetoothAdapter mAdapter;
+    @Mock private BluetoothDevice mDevice;
+    private Context mContext;
+    private LocalBluetoothProfileManager mProfileManager;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        when(mAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
+    }
+
+    /**
+     * Verify HID and HID Device profiles are not null without running updateUuids()
+     */
+    @Test
+    public void constructor_initiateHidAndHidDeviceProfile() {
+        mProfileManager =
+                new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, mEventManager);
+
+        assertThat(mProfileManager.getHidProfile()).isNotNull();
+        assertThat(mProfileManager.getHidDeviceProfile()).isNotNull();
+    }
+
+    /**
+     * Verify updateLocalProfiles() for a local A2DP source adds A2dpProfile
+     */
+    @Test
+    public void updateLocalProfiles_addA2dpToLocalProfiles() {
+        mProfileManager =
+                new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, mEventManager);
+        when(mAdapter.getUuids()).thenReturn(new ParcelUuid[] {BluetoothUuid.AudioSource});
+        assertThat(mProfileManager.getA2dpProfile()).isNull();
+        assertThat(mProfileManager.getHeadsetProfile()).isNull();
+
+        ParcelUuid[] uuids = mAdapter.getUuids();
+        mProfileManager.updateLocalProfiles(uuids);
+
+        assertThat(mProfileManager.getA2dpProfile()).isNotNull();
+        assertThat(mProfileManager.getHeadsetProfile()).isNull();
+    }
+
+    /**
+     * Verify updateProfiles() for a remote HID device updates profiles and removedProfiles
+     */
+    @Test
+    public void updateProfiles_addHidProfileForRemoteDevice() {
+        mProfileManager =
+                new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, mEventManager);
+        ParcelUuid[] uuids = new ParcelUuid[]{BluetoothUuid.Hid};
+        ParcelUuid[] localUuids = new ParcelUuid[]{};
+        List<LocalBluetoothProfile> profiles = new ArrayList<>();
+        List<LocalBluetoothProfile> removedProfiles = new ArrayList<>();
+
+        mProfileManager.updateProfiles(uuids, localUuids, profiles, removedProfiles, false,
+                mDevice);
+
+        assertThat(mProfileManager.getHidProfile()).isNotNull();
+        assertThat(profiles.contains(mProfileManager.getHidProfile())).isTrue();
+        assertThat(removedProfiles.contains(mProfileManager.getHidProfile())).isFalse();
+    }
+}
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
index 67f68d3..c59b067 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
@@ -37,7 +37,7 @@
         android:layout_height="wrap_content"
         android:layout_marginTop="@dimen/car_padding_4"
         android:textSize="@dimen/car_body1_size"
-        android:textColor="@color/qs_user_detail_name"
+        android:textColor="@color/car_body1_light"
         android:ellipsize="end"
         android:singleLine="true"
         android:gravity="center"
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
index 22452b7..27d0e46 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
@@ -18,20 +18,12 @@
         android:fitsSystemWindows="true"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:background="@android:color/black"
+        android:background="@color/car_card_dark"
         android:visibility="gone">
 
-    <!-- This progressbar is activated while we're switching users. -->
-    <ProgressBar
-        android:id="@+id/switching_users"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:indeterminate="true"
-        android:visibility="gone"
-        android:layout_gravity="center" />
-
     <RelativeLayout
         android:id="@+id/container"
+        android:background="@color/car_card_dark"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
diff --git a/packages/SystemUI/res/values/dimens_car.xml b/packages/SystemUI/res/values/dimens_car.xml
index 2b91891..0cd3825 100644
--- a/packages/SystemUI/res/values/dimens_car.xml
+++ b/packages/SystemUI/res/values/dimens_car.xml
@@ -20,7 +20,7 @@
     <dimen name="car_margin_standard">112dp</dimen>
 
     <!-- TODO replace with car support lib sizes when available -->
-    <dimen name="car_fullscreen_user_pod_icon_text_size">32sp</dimen>
+    <dimen name="car_fullscreen_user_pod_icon_text_size">64sp</dimen>
     <dimen name="car_fullscreen_user_pod_width">243dp</dimen>
     <dimen name="car_fullscreen_user_pod_height">356dp</dimen>
     <dimen name="car_fullscreen_user_pod_image_avatar_width">96dp</dimen>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java
index 0f52209..2bdbf0b 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java
@@ -16,8 +16,7 @@
 
 package com.android.systemui.shared.system;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
-
+import android.app.WindowConfiguration;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.view.RemoteAnimationTarget;
@@ -29,9 +28,16 @@
 
     public static final int MODE_OPENING = RemoteAnimationTarget.MODE_OPENING;
     public static final int MODE_CLOSING = RemoteAnimationTarget.MODE_CLOSING;
+    public final int mode;
+
+    public static final int ACTIVITY_TYPE_UNDEFINED = WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+    public static final int ACTIVITY_TYPE_STANDARD = WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+    public static final int ACTIVITY_TYPE_HOME = WindowConfiguration.ACTIVITY_TYPE_HOME;
+    public static final int ACTIVITY_TYPE_RECENTS = WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+    public static final int ACTIVITY_TYPE_ASSISTANT = WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
+    public final int activityType;
 
     public final int taskId;
-    public final int mode;
     public final SurfaceControlCompat leash;
     public final boolean isTranslucent;
     public final Rect clipRect;
@@ -39,11 +45,9 @@
     public final Point position;
     public final Rect sourceContainerBounds;
     public final boolean isNotInRecents;
-
-    private final RemoteAnimationTarget mTarget;
+    public final Rect contentInsets;
 
     public RemoteAnimationTargetCompat(RemoteAnimationTarget app) {
-        mTarget = app;
         taskId = app.taskId;
         mode = app.mode;
         leash = new SurfaceControlCompat(app.leash);
@@ -53,6 +57,8 @@
         sourceContainerBounds = app.sourceContainerBounds;
         prefixOrderIndex = app.prefixOrderIndex;
         isNotInRecents = app.isNotInRecents;
+        contentInsets = app.contentInsets;
+        activityType = app.windowConfiguration.getActivityType();
     }
 
     public static RemoteAnimationTargetCompat[] wrap(RemoteAnimationTarget[] apps) {
@@ -63,18 +69,4 @@
         }
         return appsCompat;
     }
-
-    /**
-     * TODO: Get as a method for compatibility (will move into ctor once Launcher updates)
-     */
-    public Rect getContentInsets() {
-        return mTarget.contentInsets;
-    }
-
-    /**
-     * TODO: Get as a method for compatibility (will move into ctor once Launcher updates)
-     */
-    public boolean isAssistantActivityType() {
-        return mTarget.windowConfiguration.getActivityType() == ACTIVITY_TYPE_ASSISTANT;
-    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java
new file mode 100644
index 0000000..c16cf92
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.shared.system;
+
+import android.provider.Settings;
+
+public class SettingsCompat {
+
+    public static final String SWIPE_UP_SETTING_NAME
+            = Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED;
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
index 302face..56cb888 100644
--- a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
@@ -25,6 +25,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.os.Bundle;
+import android.text.BidiFormatter;
 import android.util.Log;
 import android.widget.CheckBox;
 import android.widget.TextView;
@@ -50,8 +51,10 @@
 
         try {
             PackageManager pm = getPackageManager();
-            CharSequence app1 = pm.getApplicationInfo(mCallingPkg, 0).loadLabel(pm);
-            CharSequence app2 = pm.getApplicationInfo(mProviderPkg, 0).loadLabel(pm);
+            CharSequence app1 = BidiFormatter.getInstance().unicodeWrap(
+                    pm.getApplicationInfo(mCallingPkg, 0).loadSafeLabel(pm).toString());
+            CharSequence app2 = BidiFormatter.getInstance().unicodeWrap(
+                    pm.getApplicationInfo(mProviderPkg, 0).loadSafeLabel(pm).toString());
             AlertDialog dialog = new AlertDialog.Builder(this)
                     .setTitle(getString(R.string.slice_permission_title, app1, app2))
                     .setView(R.layout.slice_permission_request)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 70880d3..d1913df 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -32,6 +32,7 @@
 import android.media.AudioManager;
 import android.os.Handler;
 import android.provider.AlarmClock;
+import android.service.notification.ZenModeConfig;
 import android.support.annotation.VisibleForTesting;
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
@@ -48,10 +49,8 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
-import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.qs.QSDetail.Callback;
-import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.PhoneStatusBarView;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
@@ -61,8 +60,10 @@
 import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
 import com.android.systemui.statusbar.policy.DateView;
 import com.android.systemui.statusbar.policy.NextAlarmController;
+import com.android.systemui.statusbar.policy.ZenModeController;
 
 import java.util.Locale;
+import java.util.Objects;
 
 /**
  * View that contains the top-most bits of the screen (primarily the status bar with date, time, and
@@ -70,7 +71,8 @@
  * contents.
  */
 public class QuickStatusBarHeader extends RelativeLayout implements
-        View.OnClickListener, NextAlarmController.NextAlarmChangeCallback {
+        View.OnClickListener, NextAlarmController.NextAlarmChangeCallback,
+        ZenModeController.Callback {
     private static final String TAG = "QuickStatusBarHeader";
     private static final boolean DEBUG = false;
 
@@ -117,6 +119,7 @@
     private DateView mDateView;
 
     private NextAlarmController mAlarmController;
+    private ZenModeController mZenController;
     /** Counts how many times the long press tooltip has been shown to the user. */
     private int mShownCount;
 
@@ -136,6 +139,7 @@
     public QuickStatusBarHeader(Context context, AttributeSet attrs) {
         super(context, attrs);
         mAlarmController = Dependency.get(NextAlarmController.class);
+        mZenController = Dependency.get(ZenModeController.class);
         mShownCount = getStoredShownCount();
     }
 
@@ -182,19 +186,45 @@
     }
 
     private void updateStatusText() {
+        boolean changed = updateRingerStatus() || updateAlarmStatus();
+
+        if (changed) {
+            boolean alarmVisible = mNextAlarmTextView.getVisibility() == View.VISIBLE;
+            boolean ringerVisible = mRingerModeTextView.getVisibility() == View.VISIBLE;
+            mStatusSeparator.setVisibility(alarmVisible && ringerVisible ? View.VISIBLE
+                    : View.GONE);
+            updateTooltipShow();
+        }
+    }
+
+    private boolean updateRingerStatus() {
+        boolean isOriginalVisible = mRingerModeTextView.getVisibility() == View.VISIBLE;
+        CharSequence originalRingerText = mRingerModeTextView.getText();
+
         boolean ringerVisible = false;
-        if (mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
-            mRingerModeIcon.setImageResource(R.drawable.stat_sys_ringer_vibrate);
-            mRingerModeTextView.setText(R.string.qs_status_phone_vibrate);
-            ringerVisible = true;
-        } else if (mRingerMode == AudioManager.RINGER_MODE_SILENT) {
-            mRingerModeIcon.setImageResource(R.drawable.stat_sys_ringer_silent);
-            mRingerModeTextView.setText(R.string.qs_status_phone_muted);
-            ringerVisible = true;
+        if (!ZenModeConfig.isZenOverridingRinger(mZenController.getZen(),
+                mZenController.getConfig())) {
+            if (mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
+                mRingerModeIcon.setImageResource(R.drawable.stat_sys_ringer_vibrate);
+                mRingerModeTextView.setText(R.string.qs_status_phone_vibrate);
+                ringerVisible = true;
+            } else if (mRingerMode == AudioManager.RINGER_MODE_SILENT) {
+                mRingerModeIcon.setImageResource(R.drawable.stat_sys_ringer_silent);
+                mRingerModeTextView.setText(R.string.qs_status_phone_muted);
+                ringerVisible = true;
+            }
         }
         mRingerModeIcon.setVisibility(ringerVisible ? View.VISIBLE : View.GONE);
         mRingerModeTextView.setVisibility(ringerVisible ? View.VISIBLE : View.GONE);
 
+        return isOriginalVisible != ringerVisible ||
+                !Objects.equals(originalRingerText, mRingerModeTextView.getText());
+    }
+
+    private boolean updateAlarmStatus() {
+        boolean isOriginalVisible = mNextAlarmTextView.getVisibility() == View.VISIBLE;
+        CharSequence originalAlarmText = mNextAlarmTextView.getText();
+
         boolean alarmVisible = false;
         if (mNextAlarm != null) {
             alarmVisible = true;
@@ -202,10 +232,10 @@
         }
         mNextAlarmIcon.setVisibility(alarmVisible ? View.VISIBLE : View.GONE);
         mNextAlarmTextView.setVisibility(alarmVisible ? View.VISIBLE : View.GONE);
-        mStatusSeparator.setVisibility(alarmVisible && ringerVisible ? View.VISIBLE : View.GONE);
-        updateTooltipShow();
-    }
 
+        return isOriginalVisible != alarmVisible ||
+                !Objects.equals(originalAlarmText, mNextAlarmTextView.getText());
+    }
 
     private void applyDarkness(int id, Rect tintArea, float intensity, int color) {
         View v = findViewById(id);
@@ -368,10 +398,12 @@
         mListening = listening;
 
         if (listening) {
+            mZenController.addCallback(this);
             mAlarmController.addCallback(this);
             mContext.registerReceiver(mRingerReceiver,
                     new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
         } else {
+            mZenController.removeCallback(this);
             mAlarmController.removeCallback(this);
             mContext.unregisterReceiver(mRingerReceiver);
         }
@@ -391,6 +423,17 @@
         updateStatusText();
     }
 
+    @Override
+    public void onZenChanged(int zen) {
+        updateStatusText();
+
+    }
+
+    @Override
+    public void onConfigChanged(ZenModeConfig config) {
+        updateStatusText();
+    }
+
     private void updateTooltipShow() {
         if (hasStatusText()) {
             hideLongPressTooltip(true /* shouldShowStatusText */);
@@ -547,5 +590,4 @@
     public static float getColorIntensity(@ColorInt int color) {
         return color == Color.WHITE ? 0 : 1;
     }
-
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 4aa83d0..394c322 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -217,7 +217,7 @@
     }
 
     public boolean isCustomizing() {
-        return mCustomizing;
+        return mCustomizing || mOpening;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
index 6104599..c1af1fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.view.View;
 import android.view.ViewStub;
-import android.widget.ProgressBar;
 
 import android.support.v7.widget.GridLayoutManager;
 import android.support.v7.widget.RecyclerView;
@@ -37,7 +36,6 @@
     private final View mContainer;
     private final View mParent;
     private final UserGridRecyclerView mUserGridView;
-    private final ProgressBar mSwitchingUsers;
     private final int mShortAnimDuration;
     private final StatusBar mStatusBar;
     private final UserManagerHelper mUserManagerHelper;
@@ -60,8 +58,6 @@
 
         mShortAnimDuration = mContainer.getResources()
             .getInteger(android.R.integer.config_shortAnimTime);
-
-        mSwitchingUsers = mParent.findViewById(R.id.switching_users);
     }
 
     public void show() {
@@ -112,10 +108,11 @@
 
     private void toggleSwitchInProgress(boolean inProgress) {
         if (inProgress) {
-            crossFade(mSwitchingUsers, mContainer);
+            crossFade(mParent, mContainer);
         } else {
-            crossFade(mContainer, mSwitchingUsers);
+            crossFade(mContainer, mParent);
         }
+
     }
 
     private void crossFade(View incoming, View outgoing) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/PageIndicator.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/PageIndicator.java
deleted file mode 100644
index c830ff8..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/PageIndicator.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar.car;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.database.DataSetObserver;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.support.v4.view.PagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-
-import com.android.systemui.R;
-
-import java.lang.ref.WeakReference;
-
-/**
- * Displays the dots underneath the ViewPager on the lock screen. This is really just a simplified
- * version of PagerTitleStrip. We don't inherit from there because it's impossible to bypass some
- * of the overriden logic in that class.
- */
-public class PageIndicator extends View {
-    private static final String TAG = "PageIndicator";
-    // These can be made a styleable attribute in the future if necessary.
-    private static final int SELECTED_COLOR = 0xFFF5F5F5;  // grey 100
-    private static final int UNSELECTED_COLOR = 0xFFBDBDBD;  // grey 400
-    private final PageListener mPageListener = new PageListener();
-
-    private ViewPager mPager;
-    private WeakReference<PagerAdapter> mWatchingAdapter;
-
-    private int mPageCount;
-    private int mCurrentPosition;
-    private Paint mPaint;
-    private int mRadius;
-    private int mStep;
-
-    public PageIndicator(Context context) {
-        super(context);
-        init();
-    }
-
-    public PageIndicator(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init();
-    }
-
-    private void init() {
-        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-        mPaint.setStyle(Paint.Style.FILL);
-        mRadius = getResources().getDimensionPixelSize(R.dimen.car_page_indicator_dot_diameter) / 2;
-        mStep = mRadius * 3;
-    }
-
-    public void setupWithViewPager(ViewPager pager) {
-        mPager = pager;
-
-        final PagerAdapter adapter = (PagerAdapter) pager.getAdapter();
-        pager.addOnPageChangeListener(mPageListener);
-        pager.addOnAdapterChangeListener(mPageListener);
-        updateAdapter(mWatchingAdapter != null ? mWatchingAdapter.get() : null, adapter);
-        invalidate();
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        if (mPager != null) {
-            updateAdapter(mPager.getAdapter(), null);
-            mPager.removeOnPageChangeListener(mPageListener);
-            mPager.removeOnAdapterChangeListener(mPageListener);
-            mPager = null;
-        }
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-
-        // Don't draw anything unless there's multiple pages to scroll through.  No need to clear
-        // any previous dots, since onDraw provides a canvas that's already cleared.
-        if (mPageCount <= 1)
-            return;
-
-        int x = canvas.getWidth() / 2 - (mPageCount / 2) * mStep;
-        int y = canvas.getHeight() / 2;
-
-        for (int i = 0; i < mPageCount; i++) {
-            if (i == mCurrentPosition) {
-                mPaint.setColor(SELECTED_COLOR);
-            } else {
-                mPaint.setColor(UNSELECTED_COLOR);
-            }
-
-            canvas.drawCircle(x, y, mRadius, mPaint);
-            x += mStep;
-        }
-    }
-
-    void updateAdapter(PagerAdapter oldAdapter, PagerAdapter newAdapter) {
-        if (oldAdapter != null) {
-            oldAdapter.unregisterDataSetObserver(mPageListener);
-            mWatchingAdapter = null;
-        }
-
-        if (newAdapter != null) {
-            newAdapter.registerDataSetObserver(mPageListener);
-            mWatchingAdapter = new WeakReference<>(newAdapter);
-        }
-
-        updateDots();
-
-        if (mPager != null) {
-            requestLayout();
-        }
-    }
-
-    private <T> T getRef(WeakReference<T> weakRef) {
-        if (weakRef == null) {
-            return null;
-        }
-        return weakRef.get();
-    }
-
-    private void updateDots() {
-        PagerAdapter adapter = getRef(mWatchingAdapter);
-        if (adapter == null) {
-            return;
-        }
-
-        int count = adapter.getCount();
-        if (mPageCount == count) {
-            // Nothing to be done.
-            return;
-        }
-
-        mPageCount = count;
-        mCurrentPosition = 0;
-        invalidate();
-    }
-
-    private class PageListener extends DataSetObserver implements ViewPager.OnPageChangeListener,
-            ViewPager.OnAdapterChangeListener {
-
-        @Override
-        public void onPageScrolled(int unused1, float unused2, int unused3) { }
-
-        @Override
-        public void onPageSelected(int position) {
-            if (mCurrentPosition == position) {
-                return;
-            }
-
-            if (mPageCount <= position) {
-                Log.e(TAG, "Position out of bounds, position=" + position + " size=" + mPageCount);
-                return;
-            }
-
-            mCurrentPosition = position;
-            invalidate();
-        }
-
-        @Override
-        public void onPageScrollStateChanged(int state) { }
-
-        @Override
-        public void onAdapterChanged(ViewPager viewPager, PagerAdapter oldAdapter,
-                PagerAdapter newAdapter) {
-            updateAdapter(oldAdapter, newAdapter);
-        }
-
-        @Override
-        public void onChanged() {
-            updateDots();
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
index 5ad08ac..a171468 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
@@ -263,13 +263,13 @@
             GradientDrawable shape = new GradientDrawable();
             shape.setShape(GradientDrawable.RADIAL_GRADIENT);
             shape.setGradientRadius(1.0f);
-            shape.setColor(mContext.getColor(R.color.car_user_switcher_no_user_image_bgcolor));
+            shape.setColor(mContext.getColor(R.color.car_grey_50));
             shape.setBounds(0, 0, mPodImageAvatarWidth, mPodImageAvatarHeight);
             shape.draw(canvas);
 
             // Draw the letter in the center.
             Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
-            paint.setColor(mContext.getColor(R.color.car_user_switcher_no_user_image_fgcolor));
+            paint.setColor(mContext.getColor(R.color.car_grey_900));
             paint.setTextAlign(Align.CENTER);
             if (isAddUserText) {
                 paint.setTextSize(mRes.getDimensionPixelSize(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 3e7b0d9..420c517 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -50,6 +50,7 @@
 import android.provider.Settings;
 import android.provider.Settings.Global;
 import android.service.notification.StatusBarNotification;
+import android.service.notification.ZenModeConfig;
 import android.telecom.TelecomManager;
 import android.util.ArraySet;
 import android.util.Log;
@@ -287,6 +288,11 @@
     }
 
     @Override
+    public void onConfigChanged(ZenModeConfig config) {
+        updateVolumeZen();
+    }
+
+    @Override
     public void onLocationActiveChanged(boolean active) {
         updateLocation();
     }
@@ -363,16 +369,16 @@
             zenDescription = mContext.getString(R.string.interruption_level_priority);
         }
 
-        if (zen != Global.ZEN_MODE_NO_INTERRUPTIONS && zen != Global.ZEN_MODE_ALARMS &&
-                audioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE) {
-            volumeVisible = true;
-            volumeIconId = R.drawable.stat_sys_ringer_vibrate;
-            volumeDescription = mContext.getString(R.string.accessibility_ringer_vibrate);
-        } else if (zen != Global.ZEN_MODE_NO_INTERRUPTIONS && zen != Global.ZEN_MODE_ALARMS &&
-                audioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
-            volumeVisible = true;
-            volumeIconId = R.drawable.stat_sys_ringer_silent;
-            volumeDescription = mContext.getString(R.string.accessibility_ringer_silent);
+        if (!ZenModeConfig.isZenOverridingRinger(zen, mZenController.getConfig())) {
+            if (audioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE) {
+                volumeVisible = true;
+                volumeIconId = R.drawable.stat_sys_ringer_vibrate;
+                volumeDescription = mContext.getString(R.string.accessibility_ringer_vibrate);
+            } else if (audioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
+                volumeVisible = true;
+                volumeIconId = R.drawable.stat_sys_ringer_silent;
+                volumeDescription = mContext.getString(R.string.accessibility_ringer_silent);
+            }
         }
 
         if (zenVisible) {
diff --git a/packages/VpnDialogs/res/values-cs/strings.xml b/packages/VpnDialogs/res/values-cs/strings.xml
index 47d950f..5cc809c 100644
--- a/packages/VpnDialogs/res/values-cs/strings.xml
+++ b/packages/VpnDialogs/res/values-cs/strings.xml
@@ -25,8 +25,8 @@
     <string name="data_received" msgid="4062776929376067820">"Přijato:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bajtů / <xliff:g id="NUMBER_1">%2$s</xliff:g> paketů"</string>
     <string name="always_on_disconnected_title" msgid="1906740176262776166">"Nelze se připojit k trvalé VPN"</string>
-    <string name="always_on_disconnected_message" msgid="555634519845992917">"Aplikace <xliff:g id="VPN_APP_0">%1$s</xliff:g> je nastavena k trvalému připojení, ale nyní se nemůže připojit. Než se telefon bude moci připojit pomocí aplikace <xliff:g id="VPN_APP_1">%1$s</xliff:g>, použije veřejnou síť."</string>
-    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Aplikace <xliff:g id="VPN_APP">%1$s</xliff:g> je nastavena k trvalému připojení, ale nyní se nemůže připojit. Než se budete moci připojit pomocí VPN, zůstanete offline."</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"Aplikace <xliff:g id="VPN_APP_0">%1$s</xliff:g> je nastavena k trvalému připojení, ale teď se nemůže připojit. Než se telefon bude moci připojit pomocí aplikace <xliff:g id="VPN_APP_1">%1$s</xliff:g>, použije veřejnou síť."</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Aplikace <xliff:g id="VPN_APP">%1$s</xliff:g> je nastavena k trvalému připojení, ale teď se nemůže připojit. Než se budete moci připojit pomocí VPN, zůstanete offline."</string>
     <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
     <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Změnit nastavení VPN"</string>
     <string name="configure" msgid="4905518375574791375">"Konfigurovat"</string>
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 6463bed..079d815 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1383,7 +1383,8 @@
         if (nai != null) {
             synchronized (nai) {
                 if (nai.networkCapabilities != null) {
-                    return networkCapabilitiesWithoutUidsUnlessAllowed(nai.networkCapabilities,
+                    return networkCapabilitiesRestrictedForCallerPermissions(
+                            nai.networkCapabilities,
                             Binder.getCallingPid(), Binder.getCallingUid());
                 }
             }
@@ -1397,10 +1398,12 @@
         return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network));
     }
 
-    private NetworkCapabilities networkCapabilitiesWithoutUidsUnlessAllowed(
+    private NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions(
             NetworkCapabilities nc, int callerPid, int callerUid) {
-        if (checkSettingsPermission(callerPid, callerUid)) return new NetworkCapabilities(nc);
-        return new NetworkCapabilities(nc).setUids(null);
+        final NetworkCapabilities newNc = new NetworkCapabilities(nc);
+        if (!checkSettingsPermission(callerPid, callerUid)) newNc.setUids(null);
+        if (!checkNetworkStackPermission(callerPid, callerUid)) newNc.setSSID(null);
+        return newNc;
     }
 
     private void restrictRequestUidsForCaller(NetworkCapabilities nc) {
@@ -1659,6 +1662,11 @@
                 android.Manifest.permission.NETWORK_SETTINGS, pid, uid);
     }
 
+    private boolean checkNetworkStackPermission(int pid, int uid) {
+        return PERMISSION_GRANTED == mContext.checkPermission(
+                android.Manifest.permission.NETWORK_STACK, pid, uid);
+    }
+
     private void enforceTetherAccessPermission() {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE,
@@ -4235,6 +4243,15 @@
         }
     }
 
+    // This checks that the passed capabilities either do not request a specific SSID, or the
+    // calling app has permission to do so.
+    private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc,
+            int callerPid, int callerUid) {
+        if (null != nc.getSSID() && !checkNetworkStackPermission(callerPid, callerUid)) {
+            throw new SecurityException("Insufficient permissions to request a specific SSID");
+        }
+    }
+
     private ArrayList<Integer> getSignalStrengthThresholds(NetworkAgentInfo nai) {
         final SortedSet<Integer> thresholds = new TreeSet();
         synchronized (nai) {
@@ -4304,6 +4321,8 @@
             enforceMeteredApnPolicy(networkCapabilities);
         }
         ensureRequestableCapabilities(networkCapabilities);
+        ensureSufficientPermissionsForRequest(networkCapabilities,
+                Binder.getCallingPid(), Binder.getCallingUid());
         // Set the UID range for this request to the single UID of the requester, or to an empty
         // set of UIDs if the caller has the appropriate permission and UIDs have not been set.
         // This will overwrite any allowed UIDs in the requested capabilities. Though there
@@ -4382,6 +4401,8 @@
         enforceNetworkRequestPermissions(networkCapabilities);
         enforceMeteredApnPolicy(networkCapabilities);
         ensureRequestableCapabilities(networkCapabilities);
+        ensureSufficientPermissionsForRequest(networkCapabilities,
+                Binder.getCallingPid(), Binder.getCallingUid());
         ensureValidNetworkSpecifier(networkCapabilities);
         restrictRequestUidsForCaller(networkCapabilities);
 
@@ -4437,6 +4458,8 @@
         }
 
         NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
+        ensureSufficientPermissionsForRequest(networkCapabilities,
+                Binder.getCallingPid(), Binder.getCallingUid());
         restrictRequestUidsForCaller(nc);
         // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so
         // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get
@@ -4463,6 +4486,8 @@
             enforceAccessPermission();
         }
         ensureValidNetworkSpecifier(networkCapabilities);
+        ensureSufficientPermissionsForRequest(networkCapabilities,
+                Binder.getCallingPid(), Binder.getCallingUid());
 
         final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
         restrictRequestUidsForCaller(nc);
@@ -5034,7 +5059,7 @@
             }
             case ConnectivityManager.CALLBACK_CAP_CHANGED: {
                 // networkAgent can't be null as it has been accessed a few lines above.
-                final NetworkCapabilities nc = networkCapabilitiesWithoutUidsUnlessAllowed(
+                final NetworkCapabilities nc = networkCapabilitiesRestrictedForCallerPermissions(
                         networkAgent.networkCapabilities, nri.mPid, nri.mUid);
                 putParcelable(bundle, nc);
                 break;
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index fb5fba0..d4290ee 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -960,7 +960,8 @@
                         // synchronize to ensure incrementPendingBroadcastsLocked()
                         // is called before decrementPendingBroadcasts()
                         mPendingIntent.send(mContext, 0, statusChanged, this, mLocationHandler,
-                                getResolutionPermission(mAllowedResolutionLevel));
+                                getResolutionPermission(mAllowedResolutionLevel),
+                                PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
                         // call this after broadcasting so we do not increment
                         // if we throw an exeption.
                         incrementPendingBroadcastsLocked();
@@ -995,7 +996,8 @@
                         // synchronize to ensure incrementPendingBroadcastsLocked()
                         // is called before decrementPendingBroadcasts()
                         mPendingIntent.send(mContext, 0, locationChanged, this, mLocationHandler,
-                                getResolutionPermission(mAllowedResolutionLevel));
+                                getResolutionPermission(mAllowedResolutionLevel),
+                                PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
                         // call this after broadcasting so we do not increment
                         // if we throw an exeption.
                         incrementPendingBroadcastsLocked();
@@ -1037,7 +1039,8 @@
                         // synchronize to ensure incrementPendingBroadcastsLocked()
                         // is called before decrementPendingBroadcasts()
                         mPendingIntent.send(mContext, 0, providerIntent, this, mLocationHandler,
-                                getResolutionPermission(mAllowedResolutionLevel));
+                                getResolutionPermission(mAllowedResolutionLevel),
+                                PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
                         // call this after broadcasting so we do not increment
                         // if we throw an exeption.
                         incrementPendingBroadcastsLocked();
diff --git a/services/core/java/com/android/server/PendingIntentUtils.java b/services/core/java/com/android/server/PendingIntentUtils.java
new file mode 100644
index 0000000..1600101
--- /dev/null
+++ b/services/core/java/com/android/server/PendingIntentUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.annotation.Nullable;
+import android.app.BroadcastOptions;
+import android.os.Bundle;
+
+/**
+ * Some utility methods for system server.
+ * @hide
+ */
+public class PendingIntentUtils {
+    /**
+     * Creates a Bundle that can be used to restrict the background PendingIntents.
+     * @param bundle when provided, will merge the extra options to restrict background
+     *              PendingIntent into the existing bundle.
+     * @return the created Bundle.
+     */
+    public static Bundle createDontSendToRestrictedAppsBundle(@Nullable Bundle bundle) {
+        final BroadcastOptions options = BroadcastOptions.makeBasic();
+        options.setDontSendToRestrictedApps(true);
+        if (bundle == null) {
+            return options.toBundle();
+        }
+        bundle.putAll(options.toBundle());
+        return bundle;
+    }
+
+    // Disable the constructor.
+    private PendingIntentUtils() {}
+}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 47284cb..f620c77 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -6771,6 +6771,13 @@
                 int[] users = userId == UserHandle.USER_ALL
                         ? mUserController.getUsers() : new int[] { userId };
                 for (int user : users) {
+                    if (getPackageManagerInternalLocked().isPackageStateProtected(
+                            packageName, user)) {
+                        Slog.w(TAG, "Ignoring request to force stop protected package "
+                                + packageName + " u" + user);
+                        return;
+                    }
+
                     int pkgUid = -1;
                     try {
                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
diff --git a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
new file mode 100644
index 0000000..e34ee63
--- /dev/null
+++ b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.am;
+
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Paint.Align;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.GradientDrawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+import com.android.internal.R;
+
+/**
+ * Dialog to show when a user switch it about to happen for the car. The intent is to snapshot the
+ * screen immediately after the dialog shows so that the user is informed that something is
+ * happening in the background rather than just freeze the screen and not know if the user-switch
+ * affordance was being handled.
+ *
+ */
+final class CarUserSwitchingDialog extends UserSwitchingDialog {
+    private static final String TAG = "ActivityManagerCarUserSwitchingDialog";
+
+    public CarUserSwitchingDialog(ActivityManagerService service, Context context, UserInfo oldUser,
+        UserInfo newUser, boolean aboveSystem, String switchingFromSystemUserMessage,
+        String switchingToSystemUserMessage) {
+        super(service, context, oldUser, newUser, aboveSystem, switchingFromSystemUserMessage,
+            switchingToSystemUserMessage);
+
+        getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+    }
+
+    @Override
+    void inflateContent() {
+        // Set up the dialog contents
+        setCancelable(false);
+        Resources res = getContext().getResources();
+        // Custom view due to alignment and font size requirements
+        View view = LayoutInflater.from(getContext()).inflate(R.layout.car_user_switching_dialog,
+            null);
+
+        ((ImageView) view.findViewById(R.id.user_loading_avatar))
+            .setImageBitmap(getDefaultUserIcon(mNewUser));
+        ((TextView) view.findViewById(R.id.user_loading))
+            .setText(res.getString(R.string.car_loading_profile));
+        setView(view);
+    }
+
+    /**
+     * Returns the default user icon.  This icon is a circle with a letter in it.  The letter is
+     * the first character in the username.
+     *
+     * @param userInfo the profile of the user for which the icon should be created
+     */
+    private Bitmap getDefaultUserIcon(UserInfo userInfo) {
+        Resources res = mContext.getResources();
+        int mPodImageAvatarWidth = res.getDimensionPixelSize(
+            R.dimen.car_fullscreen_user_pod_image_avatar_width);
+        int mPodImageAvatarHeight = res.getDimensionPixelSize(
+            R.dimen.car_fullscreen_user_pod_image_avatar_height);
+        CharSequence displayText = userInfo.name.subSequence(0, 1);
+        Bitmap out = Bitmap.createBitmap(mPodImageAvatarWidth, mPodImageAvatarHeight,
+            Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(out);
+
+        // Draw the circle background.
+        GradientDrawable shape = new GradientDrawable();
+        shape.setShape(GradientDrawable.RADIAL_GRADIENT);
+        shape.setGradientRadius(1.0f);
+        shape.setColor(mContext.getColor(R.color.car_user_switcher_user_image_bgcolor));
+        shape.setBounds(0, 0, mPodImageAvatarWidth, mPodImageAvatarHeight);
+        shape.draw(canvas);
+
+        // Draw the letter in the center.
+        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        paint.setColor(mContext.getColor(R.color.car_user_switcher_user_image_fgcolor));
+        paint.setTextAlign(Align.CENTER);
+        paint.setTextSize(res.getDimensionPixelSize(
+            R.dimen.car_fullscreen_user_pod_icon_text_size));
+
+        Paint.FontMetricsInt metrics = paint.getFontMetricsInt();
+        // The Y coordinate is measured by taking half the height of the pod, but that would
+        // draw the character putting the bottom of the font in the middle of the pod.  To
+        // correct this, half the difference between the top and bottom distance metrics of the
+        // font gives the offset of the font.  Bottom is a positive value, top is negative, so
+        // the different is actually a sum.  The "half" operation is then factored out.
+        canvas.drawText(displayText.toString(), mPodImageAvatarWidth / 2,
+            (mPodImageAvatarHeight - (metrics.bottom + metrics.top)) / 2, paint);
+
+        return out;
+    }
+}
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index fecb934..060d4c8 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -79,6 +79,7 @@
 import android.text.format.DateUtils;
 import android.util.ArraySet;
 import android.util.IntArray;
+import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -86,6 +87,7 @@
 import android.util.TimingsTraceLog;
 import android.util.proto.ProtoOutputStream;
 
+import android.view.Window;
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -2177,9 +2179,18 @@
 
         void showUserSwitchingDialog(UserInfo fromUser, UserInfo toUser,
                 String switchingFromSystemUserMessage, String switchingToSystemUserMessage) {
-            Dialog d = new UserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
+            Dialog d;
+            if (!mService.mContext.getPackageManager()
+                    .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+                d = new UserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
                     true /* above system */, switchingFromSystemUserMessage,
                     switchingToSystemUserMessage);
+            } else {
+                d = new CarUserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
+                    true /* above system */, switchingFromSystemUserMessage,
+                    switchingToSystemUserMessage);
+            }
+
             d.show();
         }
 
diff --git a/services/core/java/com/android/server/am/UserSwitchingDialog.java b/services/core/java/com/android/server/am/UserSwitchingDialog.java
index afcba3b..98f5557 100644
--- a/services/core/java/com/android/server/am/UserSwitchingDialog.java
+++ b/services/core/java/com/android/server/am/UserSwitchingDialog.java
@@ -39,7 +39,7 @@
  * in the background rather than just freeze the screen and not know if the user-switch affordance
  * was being handled.
  */
-final class UserSwitchingDialog extends AlertDialog
+class UserSwitchingDialog extends AlertDialog
         implements ViewTreeObserver.OnWindowShownListener {
     private static final String TAG = "ActivityManagerUserSwitchingDialog";
 
@@ -51,53 +51,69 @@
     private static final int MSG_START_USER = 1;
     @GuardedBy("this")
     private boolean mStartedUser;
+    final protected UserInfo mOldUser;
+    final protected UserInfo mNewUser;
+    final private String mSwitchingFromSystemUserMessage;
+    final private String mSwitchingToSystemUserMessage;
+    final protected Context mContext;
 
     public UserSwitchingDialog(ActivityManagerService service, Context context, UserInfo oldUser,
             UserInfo newUser, boolean aboveSystem, String switchingFromSystemUserMessage,
             String switchingToSystemUserMessage) {
         super(context);
 
+        mContext = context;
         mService = service;
         mUserId = newUser.id;
+        mOldUser = oldUser;
+        mNewUser = newUser;
+        mSwitchingFromSystemUserMessage = switchingFromSystemUserMessage;
+        mSwitchingToSystemUserMessage = switchingToSystemUserMessage;
 
+        inflateContent();
+
+        if (aboveSystem) {
+            getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+        }
+
+        WindowManager.LayoutParams attrs = getWindow().getAttributes();
+        attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR |
+            WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        getWindow().setAttributes(attrs);
+    }
+
+    void inflateContent() {
         // Set up the dialog contents
         setCancelable(false);
         Resources res = getContext().getResources();
         // Custom view due to alignment and font size requirements
-        View view = LayoutInflater.from(getContext()).inflate(R.layout.user_switching_dialog, null);
+        View view = LayoutInflater.from(getContext()).inflate(R.layout.user_switching_dialog,
+            null);
 
         String viewMessage = null;
-        if (UserManager.isSplitSystemUser() && newUser.id == UserHandle.USER_SYSTEM) {
-            viewMessage = res.getString(R.string.user_logging_out_message, oldUser.name);
-        } else if (UserManager.isDeviceInDemoMode(context)) {
-            if (oldUser.isDemo()) {
+        if (UserManager.isSplitSystemUser() && mNewUser.id == UserHandle.USER_SYSTEM) {
+            viewMessage = res.getString(R.string.user_logging_out_message, mOldUser.name);
+        } else if (UserManager.isDeviceInDemoMode(mContext)) {
+            if (mOldUser.isDemo()) {
                 viewMessage = res.getString(R.string.demo_restarting_message);
             } else {
                 viewMessage = res.getString(R.string.demo_starting_message);
             }
         } else {
-            if (oldUser.id == UserHandle.USER_SYSTEM) {
-                viewMessage = switchingFromSystemUserMessage;
-            } else if (newUser.id == UserHandle.USER_SYSTEM) {
-                viewMessage = switchingToSystemUserMessage;
+            if (mOldUser.id == UserHandle.USER_SYSTEM) {
+                viewMessage = mSwitchingFromSystemUserMessage;
+            } else if (mNewUser.id == UserHandle.USER_SYSTEM) {
+                viewMessage = mSwitchingToSystemUserMessage;
             }
 
             // If switchingFromSystemUserMessage or switchingToSystemUserMessage is null, fallback
             // to system message.
             if (viewMessage == null) {
-                viewMessage = res.getString(R.string.user_switching_message, newUser.name);
+                viewMessage = res.getString(R.string.user_switching_message, mNewUser.name);
             }
         }
         ((TextView) view.findViewById(R.id.message)).setText(viewMessage);
         setView(view);
-
-        if (aboveSystem) {
-            getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
-        }
-        WindowManager.LayoutParams attrs = getWindow().getAttributes();
-        attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR |
-                WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-        getWindow().setAttributes(attrs);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index ca8823f..0ee55ed 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -165,12 +165,22 @@
     private final ICameraServiceProxy.Stub mCameraServiceProxy = new ICameraServiceProxy.Stub() {
         @Override
         public void pingForUserUpdate() {
+            if (Binder.getCallingUid() != Process.CAMERASERVER_UID) {
+                Slog.e(TAG, "Calling UID: " + Binder.getCallingUid() + " doesn't match expected " +
+                        " camera service UID!");
+                return;
+            }
             notifySwitchWithRetries(30);
         }
 
         @Override
         public void notifyCameraState(String cameraId, int newCameraState, int facing,
                 String clientName, int apiLevel) {
+            if (Binder.getCallingUid() != Process.CAMERASERVER_UID) {
+                Slog.e(TAG, "Calling UID: " + Binder.getCallingUid() + " doesn't match expected " +
+                        " camera service UID!");
+                return;
+            }
             String state = cameraStateToString(newCameraState);
             String facingStr = cameraFacingToString(facing);
             if (DEBUG) Slog.v(TAG, "Camera " + cameraId + " facing " + facingStr + " state now " +
@@ -301,7 +311,12 @@
             }
             mCameraUsageHistory.clear();
         }
-        CameraStatsJobService.schedule(mContext);
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            CameraStatsJobService.schedule(mContext);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
     }
 
     private void switchUserLocked(int userHandle) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 0d935db..02459bd 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -23,6 +23,7 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.net.NetworkCapabilities;
+import android.net.wifi.WifiInfo;
 import android.os.UserHandle;
 import android.telephony.TelephonyManager;
 import android.util.Slog;
@@ -176,7 +177,8 @@
             switch (transportType) {
                 case TRANSPORT_WIFI:
                     title = r.getString(R.string.wifi_available_sign_in, 0);
-                    details = r.getString(R.string.network_available_sign_in_detailed, extraInfo);
+                    details = r.getString(R.string.network_available_sign_in_detailed,
+                            WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID()));
                     break;
                 case TRANSPORT_CELLULAR:
                     title = r.getString(R.string.network_available_sign_in, 0);
diff --git a/services/core/java/com/android/server/location/GeofenceManager.java b/services/core/java/com/android/server/location/GeofenceManager.java
index d50ffe9..fafe99c 100644
--- a/services/core/java/com/android/server/location/GeofenceManager.java
+++ b/services/core/java/com/android/server/location/GeofenceManager.java
@@ -42,6 +42,7 @@
 import android.util.Slog;
 
 import com.android.server.LocationManagerService;
+import com.android.server.PendingIntentUtils;
 
 public class GeofenceManager implements LocationListener, PendingIntent.OnFinished {
     private static final String TAG = "GeofenceManager";
@@ -401,7 +402,8 @@
         mWakeLock.acquire();
         try {
             pendingIntent.send(mContext, 0, intent, this, null,
-                    android.Manifest.permission.ACCESS_FINE_LOCATION);
+                    android.Manifest.permission.ACCESS_FINE_LOCATION,
+                    PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
         } catch (PendingIntent.CanceledException e) {
             removeFence(null, pendingIntent);
             mWakeLock.release();
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
index 1faa9f7..5d71cc7 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
@@ -70,8 +70,6 @@
     private static final String LOCK_SCREEN_HASH_ALGORITHM = "SHA-256";
     private static final int TRUSTED_HARDWARE_MAX_ATTEMPTS = 10;
 
-    // TODO: Reduce the minimal length once all other components are updated
-    private static final int MIN_CREDENTIAL_LEN_TO_USE_SCRYPT = 24;
     @VisibleForTesting
     static final int SCRYPT_PARAM_N = 4096;
     @VisibleForTesting
@@ -246,7 +244,7 @@
             }
         }
 
-        boolean useScryptToHashCredential = shouldUseScryptToHashCredential(rootCertAlias);
+        boolean useScryptToHashCredential = shouldUseScryptToHashCredential();
         byte[] salt = generateSalt();
         byte[] localLskfHash;
         if (useScryptToHashCredential) {
@@ -514,10 +512,7 @@
         return keyEntries;
     }
 
-    private boolean shouldUseScryptToHashCredential(String rootCertAlias) {
-        return mCredentialType == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD
-                && mCredential.length() >= MIN_CREDENTIAL_LEN_TO_USE_SCRYPT
-                // TODO: Remove the test cert check once all other components are updated
-                && mTestOnlyInsecureCertificateHelper.isTestOnlyCertificateAlias(rootCertAlias);
+    private boolean shouldUseScryptToHashCredential() {
+        return mCredentialType == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
     }
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a047604..57c2b75 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -23856,6 +23856,11 @@
         }
 
         @Override
+        public boolean isPackageStateProtected(String packageName, int userId) {
+            return mProtectedPackages.isPackageStateProtected(userId, packageName);
+        }
+
+        @Override
         public boolean isPackageEphemeral(int userId, String packageName) {
             synchronized (mPackages) {
                 final PackageSetting ps = mSettings.mPackages.get(packageName);
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 46a636c..fce4b20 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2550,6 +2550,7 @@
                     | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                     | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                     | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+            lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
             if (ActivityManager.isHighEndGfx()) {
                 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
                 lp.privateFlags |=
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index b7b9612..a9cdafd 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -44,7 +44,6 @@
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.os.Binder;
-import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -52,7 +51,6 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.ArrayMap;
-import android.util.AtomicFile;
 import android.util.Slog;
 import android.util.Xml.Encoding;
 
@@ -71,9 +69,7 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.File;
 import java.io.IOException;
-import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -136,11 +132,16 @@
     @Override
     public Uri[] getPinnedSlices(String pkg) {
         verifyCaller(pkg);
+        int callingUser = Binder.getCallingUserHandle().getIdentifier();
         ArrayList<Uri> ret = new ArrayList<>();
         synchronized (mLock) {
             for (PinnedSliceState state : mPinnedSlicesByUri.values()) {
                 if (Objects.equals(pkg, state.getPkg())) {
-                    ret.add(state.getUri());
+                    Uri uri = state.getUri();
+                    int userId = ContentProvider.getUserIdFromUri(uri, callingUser);
+                    if (userId == callingUser) {
+                        ret.add(ContentProvider.getUriWithoutUserId(uri));
+                    }
                 }
             }
         }
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 1ee642a..6478632 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -549,7 +549,12 @@
         @Override
         public void startAnimation(SurfaceControl animationLeash, Transaction t,
                 OnAnimationFinishedCallback finishCallback) {
+            // Restore z-layering, position and stack crop until client has a chance to modify it.
+            t.setLayer(animationLeash, mTask.getPrefixOrderIndex());
             t.setPosition(animationLeash, mPosition.x, mPosition.y);
+            mTmpRect.set(mBounds);
+            mTmpRect.offsetTo(0, 0);
+            t.setWindowCrop(animationLeash, mTmpRect);
             mCapturedLeash = animationLeash;
             mCapturedFinishCallback = finishCallback;
         }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java
index 0e5b7b3..a9d6c29 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java
@@ -92,8 +92,8 @@
             new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
     private static final String TEST_APP_KEY_ALIAS = "rcleaver";
     private static final int TEST_GENERATION_ID = 2;
-    private static final int TEST_CREDENTIAL_TYPE = CREDENTIAL_TYPE_PASSWORD;
-    private static final String TEST_CREDENTIAL = "password1234";
+    private static final int TEST_CREDENTIAL_TYPE = CREDENTIAL_TYPE_PATTERN;
+    private static final String TEST_CREDENTIAL = "pas123";
     private static final byte[] THM_ENCRYPTED_RECOVERY_KEY_HEADER =
             "V1 THM_encrypted_recovery_key".getBytes(StandardCharsets.UTF_8);
 
@@ -278,8 +278,8 @@
     }
 
     @Test
-    public void run_useScryptToHashLongPasswordInTestMode() throws Exception {
-        String longPassword = TrustedRootCertificates.INSECURE_PASSWORD_PREFIX + "0123456789";
+    public void run_useScryptToHashPasswordInTestMode() throws Exception {
+        String password = TrustedRootCertificates.INSECURE_PASSWORD_PREFIX + "";  // The shortest
         String appKeyAlias = TrustedRootCertificates.INSECURE_KEY_ALIAS_PREFIX + "alias";
         mKeySyncTask = new KeySyncTask(
                 mRecoverableKeyStoreDb,
@@ -287,7 +287,7 @@
                 mSnapshotListenersStorage,
                 TEST_USER_ID,
                 CREDENTIAL_TYPE_PASSWORD,
-                /*credential=*/ longPassword,
+                /*credential=*/ password,
                 /*credentialUpdated=*/ false,
                 mPlatformKeyManager,
                 mTestOnlyInsecureCertificateHelper,
@@ -309,7 +309,7 @@
         assertThat(keyChainSnapshot.getKeyChainProtectionParams()).hasSize(1);
         assertThat(keyChainSnapshot.getKeyChainProtectionParams().get(0).getLockScreenUiFormat()).
                 isEqualTo(UI_FORMAT_PASSWORD);
-        verify(mMockScrypt).scrypt(eq(longPassword.getBytes()), any(),
+        verify(mMockScrypt).scrypt(eq(password.getBytes()), any(),
                 eq(KeySyncTask.SCRYPT_PARAM_N), eq(KeySyncTask.SCRYPT_PARAM_R),
                 eq(KeySyncTask.SCRYPT_PARAM_P), eq(KeySyncTask.SCRYPT_PARAM_OUTLEN_BYTES));
         KeyDerivationParams keyDerivationParams =
@@ -320,16 +320,15 @@
     }
 
     @Test
-    public void run_useSha256ToHashShortPasswordInTestMode() throws Exception {
-        String shortPassword = TrustedRootCertificates.INSECURE_PASSWORD_PREFIX + "012345678";
-        String appKeyAlias = TrustedRootCertificates.INSECURE_KEY_ALIAS_PREFIX + "alias";
+    public void run_useSha256ToHashPatternInProdMode() throws Exception {
+        String pattern = "123456";
         mKeySyncTask = new KeySyncTask(
                 mRecoverableKeyStoreDb,
                 mRecoverySnapshotStorage,
                 mSnapshotListenersStorage,
                 TEST_USER_ID,
-                CREDENTIAL_TYPE_PASSWORD,
-                /*credential=*/ shortPassword,
+                CREDENTIAL_TYPE_PATTERN,
+                /*credential=*/ pattern,
                 /*credentialUpdated=*/ false,
                 mPlatformKeyManager,
                 mTestOnlyInsecureCertificateHelper,
@@ -337,20 +336,16 @@
         mRecoverableKeyStoreDb.setServerParams(
                 TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_VAULT_HANDLE);
         mRecoverableKeyStoreDb.setPlatformKeyGenerationId(TEST_USER_ID, TEST_GENERATION_ID);
-        mRecoverableKeyStoreDb.setActiveRootOfTrust(TEST_USER_ID, TEST_RECOVERY_AGENT_UID,
-                TrustedRootCertificates.TEST_ONLY_INSECURE_CERTIFICATE_ALIAS);
+        addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS);
         mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
-                TEST_USER_ID, TEST_RECOVERY_AGENT_UID,
-                TrustedRootCertificates.TEST_ONLY_INSECURE_CERTIFICATE_ALIAS,
-                TestData.getInsecureCertPathForEndpoint1());
-        addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, appKeyAlias);
+                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_ROOT_CERT_ALIAS, TestData.CERT_PATH_1);
 
         mKeySyncTask.run();
 
         KeyChainSnapshot keyChainSnapshot = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID);
         assertThat(keyChainSnapshot.getKeyChainProtectionParams()).hasSize(1);
         assertThat(keyChainSnapshot.getKeyChainProtectionParams().get(0).getLockScreenUiFormat()).
-                isEqualTo(UI_FORMAT_PASSWORD);
+                isEqualTo(UI_FORMAT_PATTERN);
         verify(mMockScrypt, never()).scrypt(any(), any(), anyInt(), anyInt(), anyInt(), anyInt());
         KeyDerivationParams keyDerivationParams =
                 keyChainSnapshot.getKeyChainProtectionParams().get(0).getKeyDerivationParams();
@@ -359,8 +354,8 @@
     }
 
     @Test
-    public void run_useSha256ToHashShortPasswordInProdMode() throws Exception {
-        String shortPassword = "01234567890123456789abc";  // 23 chars
+    public void run_useScryptToHashPasswordInProdMode() throws Exception {
+        String shortPassword = "abc";
         mKeySyncTask = new KeySyncTask(
                 mRecoverableKeyStoreDb,
                 mRecoverySnapshotStorage,
@@ -385,45 +380,13 @@
         assertThat(keyChainSnapshot.getKeyChainProtectionParams()).hasSize(1);
         assertThat(keyChainSnapshot.getKeyChainProtectionParams().get(0).getLockScreenUiFormat()).
                 isEqualTo(UI_FORMAT_PASSWORD);
-        verify(mMockScrypt, never()).scrypt(any(), any(), anyInt(), anyInt(), anyInt(), anyInt());
+        verify(mMockScrypt).scrypt(eq(shortPassword.getBytes()), any(),
+                eq(KeySyncTask.SCRYPT_PARAM_N), eq(KeySyncTask.SCRYPT_PARAM_R),
+                eq(KeySyncTask.SCRYPT_PARAM_P), eq(KeySyncTask.SCRYPT_PARAM_OUTLEN_BYTES));
         KeyDerivationParams keyDerivationParams =
                 keyChainSnapshot.getKeyChainProtectionParams().get(0).getKeyDerivationParams();
         assertThat(keyDerivationParams.getAlgorithm()).isEqualTo(
-                KeyDerivationParams.ALGORITHM_SHA256);
-    }
-
-    @Test
-    public void run_useSha256ToHashLongPasswordInProdMode() throws Exception {
-        String longPassword = "01234567890123456789abcd";  // 24 chars
-        mKeySyncTask = new KeySyncTask(
-                mRecoverableKeyStoreDb,
-                mRecoverySnapshotStorage,
-                mSnapshotListenersStorage,
-                TEST_USER_ID,
-                CREDENTIAL_TYPE_PASSWORD,
-                /*credential=*/ longPassword,
-                /*credentialUpdated=*/ false,
-                mPlatformKeyManager,
-                mTestOnlyInsecureCertificateHelper,
-                mMockScrypt);
-        mRecoverableKeyStoreDb.setServerParams(
-                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_VAULT_HANDLE);
-        mRecoverableKeyStoreDb.setPlatformKeyGenerationId(TEST_USER_ID, TEST_GENERATION_ID);
-        addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS);
-        mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
-                TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_ROOT_CERT_ALIAS, TestData.CERT_PATH_1);
-
-        mKeySyncTask.run();
-
-        KeyChainSnapshot keyChainSnapshot = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID);
-        assertThat(keyChainSnapshot.getKeyChainProtectionParams()).hasSize(1);
-        assertThat(keyChainSnapshot.getKeyChainProtectionParams().get(0).getLockScreenUiFormat()).
-                isEqualTo(UI_FORMAT_PASSWORD);
-        verify(mMockScrypt, never()).scrypt(any(), any(), anyInt(), anyInt(), anyInt(), anyInt());
-        KeyDerivationParams keyDerivationParams =
-                keyChainSnapshot.getKeyChainProtectionParams().get(0).getKeyDerivationParams();
-        assertThat(keyDerivationParams.getAlgorithm()).isEqualTo(
-                KeyDerivationParams.ALGORITHM_SHA256);
+                KeyDerivationParams.ALGORITHM_SCRYPT);
     }
 
     @Test
@@ -644,13 +607,14 @@
 
     @Test
     public void run_setsCorrectTypeForPassword() throws Exception {
+        String password = "password";
         mKeySyncTask = new KeySyncTask(
                 mRecoverableKeyStoreDb,
                 mRecoverySnapshotStorage,
                 mSnapshotListenersStorage,
                 TEST_USER_ID,
                 CREDENTIAL_TYPE_PASSWORD,
-                "password",
+                password,
                 /*credentialUpdated=*/ false,
                 mPlatformKeyManager,
                 mTestOnlyInsecureCertificateHelper,
@@ -659,8 +623,7 @@
         mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
                 TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_ROOT_CERT_ALIAS, TestData.CERT_PATH_1);
         when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID)).thenReturn(true);
-        SecretKey applicationKey =
-                addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS);
+        addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS);
 
         mKeySyncTask.run();
 
@@ -668,18 +631,21 @@
         assertThat(keyChainSnapshot.getKeyChainProtectionParams()).hasSize(1);
         assertThat(keyChainSnapshot.getKeyChainProtectionParams().get(0).getLockScreenUiFormat()).
                 isEqualTo(UI_FORMAT_PASSWORD);
-        verify(mMockScrypt, never()).scrypt(any(), any(), anyInt(), anyInt(), anyInt(), anyInt());
+        verify(mMockScrypt).scrypt(eq(password.getBytes()), any(),
+                eq(KeySyncTask.SCRYPT_PARAM_N), eq(KeySyncTask.SCRYPT_PARAM_R),
+                eq(KeySyncTask.SCRYPT_PARAM_P), eq(KeySyncTask.SCRYPT_PARAM_OUTLEN_BYTES));
     }
 
     @Test
     public void run_setsCorrectTypeForPin() throws Exception {
+        String pin = "1234";
         mKeySyncTask = new KeySyncTask(
                 mRecoverableKeyStoreDb,
                 mRecoverySnapshotStorage,
                 mSnapshotListenersStorage,
                 TEST_USER_ID,
                 CREDENTIAL_TYPE_PASSWORD,
-                /*credential=*/ "1234",
+                /*credential=*/ pin,
                 /*credentialUpdated=*/ false,
                 mPlatformKeyManager,
                 mTestOnlyInsecureCertificateHelper,
@@ -698,7 +664,9 @@
         // Password with only digits is changed to pin.
         assertThat(keyChainSnapshot.getKeyChainProtectionParams().get(0).getLockScreenUiFormat()).
                 isEqualTo(UI_FORMAT_PIN);
-        verify(mMockScrypt, never()).scrypt(any(), any(), anyInt(), anyInt(), anyInt(), anyInt());
+        verify(mMockScrypt).scrypt(eq(pin.getBytes()), any(),
+                eq(KeySyncTask.SCRYPT_PARAM_N), eq(KeySyncTask.SCRYPT_PARAM_R),
+                eq(KeySyncTask.SCRYPT_PARAM_P), eq(KeySyncTask.SCRYPT_PARAM_OUTLEN_BYTES));
     }
 
     @Test
diff --git a/tests/net/java/android/net/NetworkCapabilitiesTest.java b/tests/net/java/android/net/NetworkCapabilitiesTest.java
index cdb4307..da897ae 100644
--- a/tests/net/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/java/android/net/NetworkCapabilitiesTest.java
@@ -39,12 +39,14 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import android.os.Parcel;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.ArraySet;
 
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -53,6 +55,8 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class NetworkCapabilitiesTest {
+    private static final String TEST_SSID = "TEST_SSID";
+
     @Test
     public void testMaybeMarkCapabilitiesRestricted() {
         // verify EIMS is restricted
@@ -259,6 +263,8 @@
             .addCapability(NET_CAPABILITY_EIMS)
             .addCapability(NET_CAPABILITY_NOT_METERED);
         assertEqualsThroughMarshalling(netCap);
+        netCap.setSSID(TEST_SSID);
+        assertEqualsThroughMarshalling(netCap);
     }
 
     @Test
@@ -354,6 +360,21 @@
     }
 
     @Test
+    public void testSSID() {
+        NetworkCapabilities nc1 = new NetworkCapabilities();
+        NetworkCapabilities nc2 = new NetworkCapabilities();
+        assertTrue(nc2.satisfiedBySSID(nc1));
+
+        nc1.setSSID(TEST_SSID);
+        assertTrue(nc2.satisfiedBySSID(nc1));
+        nc2.setSSID("different " + TEST_SSID);
+        assertFalse(nc2.satisfiedBySSID(nc1));
+
+        assertTrue(nc1.satisfiedByImmutableNetworkCapabilities(nc2));
+        assertFalse(nc1.satisfiedByNetworkCapabilities(nc2));
+    }
+
+    @Test
     public void testCombineCapabilities() {
         NetworkCapabilities nc1 = new NetworkCapabilities();
         NetworkCapabilities nc2 = new NetworkCapabilities();
@@ -374,6 +395,19 @@
         // will never be satisfied.
         assertTrue(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING));
         assertTrue(nc2.hasUnwantedCapability(NET_CAPABILITY_NOT_ROAMING));
+
+        nc1.setSSID(TEST_SSID);
+        nc2.combineCapabilities(nc1);
+        assertTrue(TEST_SSID.equals(nc2.getSSID()));
+
+        // Because they now have the same SSID, the folllowing call should not throw
+        nc2.combineCapabilities(nc1);
+
+        nc1.setSSID("different " + TEST_SSID);
+        try {
+            nc2.combineCapabilities(nc1);
+            fail("Expected IllegalStateException: can't combine different SSIDs");
+        } catch (IllegalStateException expected) {}
     }
 
     @Test