Merge "Catch unbinding errors" into pi-dev
diff --git a/api/current.txt b/api/current.txt
index 0fcf929..d0eee5c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6468,7 +6468,6 @@
     method public java.lang.CharSequence getOrganizationName(android.content.ComponentName);
     method public java.util.List<android.telephony.data.ApnSetting> getOverrideApns(android.content.ComponentName);
     method public android.app.admin.DevicePolicyManager getParentProfileInstance(android.content.ComponentName);
-    method public java.lang.String getPasswordBlacklistName(android.content.ComponentName);
     method public long getPasswordExpiration(android.content.ComponentName);
     method public long getPasswordExpirationTimeout(android.content.ComponentName);
     method public int getPasswordHistoryLength(android.content.ComponentName);
@@ -6577,7 +6576,6 @@
     method public void setOrganizationName(android.content.ComponentName, java.lang.CharSequence);
     method public void setOverrideApnsEnabled(android.content.ComponentName, boolean);
     method public java.lang.String[] setPackagesSuspended(android.content.ComponentName, java.lang.String[], boolean);
-    method public boolean setPasswordBlacklist(android.content.ComponentName, java.lang.String, java.util.List<java.lang.String>);
     method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
     method public void setPasswordHistoryLength(android.content.ComponentName, int);
     method public void setPasswordMinimumLength(android.content.ComponentName, int);
@@ -27242,6 +27240,8 @@
 
   public class NetworkRequest implements android.os.Parcelable {
     method public int describeContents();
+    method public boolean hasCapability(int);
+    method public boolean hasTransport(int);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.net.NetworkRequest> CREATOR;
   }
diff --git a/api/system-current.txt b/api/system-current.txt
index ed763ba..1284de88 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3105,6 +3105,10 @@
     field public static final int ERROR_INVALID_NETWORK = 1; // 0x1
   }
 
+  public final class NetworkCapabilities implements android.os.Parcelable {
+    field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16
+  }
+
   public class NetworkKey implements android.os.Parcelable {
     ctor public NetworkKey(android.net.WifiKey);
     method public int describeContents();
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index 3b57d34..d964651 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -319,8 +319,10 @@
         index++;  // look at the next file.
     }
     VLOG("GZipSection is using file %s, fd=%d", mFilenames[index], fd.get());
-    if (fd.get() == -1) return -1;
-
+    if (fd.get() == -1) {
+      ALOGW("GZipSection %s can't open all the files", this->name.string());
+      return NO_ERROR; // e.g. LAST_KMSG will reach here in user build.
+    }
     FdBuffer buffer;
     Fpipe p2cPipe;
     Fpipe c2pPipe;
diff --git a/cmds/incidentd/tests/PrivacyBuffer_test.cpp b/cmds/incidentd/tests/PrivacyBuffer_test.cpp
index 5edc0c7..d129269 100644
--- a/cmds/incidentd/tests/PrivacyBuffer_test.cpp
+++ b/cmds/incidentd/tests/PrivacyBuffer_test.cpp
@@ -38,7 +38,7 @@
 const uint8_t MESSAGE_TYPE = 11;
 const string STRING_FIELD_0 = "\x02\viamtestdata";
 const string VARINT_FIELD_1 = "\x08\x96\x01";  // 150
-const string STRING_FIELD_2 = "\x12\vwhatthefuck";
+const string STRING_FIELD_2 = "\x12\vandroidwins";
 const string FIX64_FIELD_3 = "\x19\xff\xff\xff\xff\xff\xff\xff\xff";  // -1
 const string FIX32_FIELD_4 = "\x25\xff\xff\xff\xff";                  // -1
 const string MESSAGE_FIELD_5 = "\x2a\x10" + VARINT_FIELD_1 + STRING_FIELD_2;
@@ -274,4 +274,4 @@
     autoMsg->children = list;
     string expected = "\x2a\xd" + STRING_FIELD_2;
     assertStripByFields(DEST_AUTOMATIC, expected, 1, autoMsg);
-}
\ No newline at end of file
+}
diff --git a/cmds/incidentd/tests/Section_test.cpp b/cmds/incidentd/tests/Section_test.cpp
index f93839b..2f6698b 100644
--- a/cmds/incidentd/tests/Section_test.cpp
+++ b/cmds/incidentd/tests/Section_test.cpp
@@ -19,6 +19,7 @@
 #include <android-base/file.h>
 #include <android-base/test_utils.h>
 #include <android/os/IncidentReportArgs.h>
+#include <android/util/protobuf.h>
 #include <frameworks/base/libs/incident/proto/android/os/header.pb.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
@@ -31,12 +32,13 @@
 const int QUICK_TIMEOUT_MS = 100;
 
 const string VARINT_FIELD_1 = "\x08\x96\x01";  // 150
-const string STRING_FIELD_2 = "\x12\vwhatthefuck";
+const string STRING_FIELD_2 = "\x12\vandroidwins";
 const string FIX64_FIELD_3 = "\x19\xff\xff\xff\xff\xff\xff\xff\xff";  // -1
 
 using namespace android::base;
 using namespace android::binder;
 using namespace android::os;
+using namespace android::util;
 using namespace std;
 using ::testing::StrEq;
 using ::testing::Test;
@@ -154,17 +156,26 @@
     requests.setMainDest(android::os::DEST_LOCAL);
 
     ASSERT_EQ(NO_ERROR, gs.Execute(&requests));
-    std::string expect, gzFile, actual;
+    std::string expected, gzFile, actual;
     ASSERT_TRUE(ReadFileToString(testGzFile, &gzFile));
     ASSERT_TRUE(ReadFileToString(tf.path, &actual));
-    expect = "\x2\xC6\x6\n\"" + testFile + "\x12\x9F\x6" + gzFile;
-    EXPECT_THAT(actual, StrEq(expect));
+    // generates the expected protobuf result.
+    size_t fileLen = testFile.size();
+    size_t totalLen = 1 + get_varint_size(fileLen) + fileLen + 3 + gzFile.size();
+    uint8_t header[20];
+    header[0] = '\x2'; // header 0 << 3 + 2
+    uint8_t* ptr = write_raw_varint(header + 1, totalLen);
+    *ptr = '\n'; // header 1 << 3 + 2
+    ptr = write_raw_varint(++ptr, fileLen);
+    expected.assign((const char*)header, ptr - header);
+    expected += testFile + "\x12\x9F\x6" + gzFile;
+    EXPECT_THAT(actual, StrEq(expected));
 }
 
 TEST_F(SectionTest, GZipSectionNoFileFound) {
     GZipSection gs(NOOP_PARSER, "/tmp/nonexist1", "/tmp/nonexist2", NULL);
     requests.setMainFd(STDOUT_FILENO);
-    ASSERT_EQ(-1, gs.Execute(&requests));
+    ASSERT_EQ(NO_ERROR, gs.Execute(&requests));
 }
 
 TEST_F(SectionTest, CommandSectionConstructor) {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 3c6f135..b64aae5 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2747,110 +2747,6 @@
     }
 
     /**
-     * The maximum number of characters allowed in the password blacklist.
-     */
-    private static final int PASSWORD_BLACKLIST_CHARACTER_LIMIT = 128 * 1000;
-
-    /**
-     * Throws an exception if the password blacklist is too large.
-     *
-     * @hide
-     */
-    public static void enforcePasswordBlacklistSize(List<String> blacklist) {
-        if (blacklist == null) {
-            return;
-        }
-        long characterCount = 0;
-        for (final String item : blacklist) {
-            characterCount += item.length();
-        }
-        if (characterCount > PASSWORD_BLACKLIST_CHARACTER_LIMIT) {
-            throw new IllegalArgumentException("128 thousand blacklist character limit exceeded by "
-                      + (characterCount - PASSWORD_BLACKLIST_CHARACTER_LIMIT) + " characters");
-        }
-    }
-
-    /**
-     * Called by an application that is administering the device to blacklist passwords.
-     * <p>
-     * Any blacklisted password or PIN is prevented from being enrolled by the user or the admin.
-     * Note that the match against the blacklist is case insensitive. The blacklist applies for all
-     * password qualities requested by {@link #setPasswordQuality} however it is not taken into
-     * consideration by {@link #isActivePasswordSufficient}.
-     * <p>
-     * The blacklist can be cleared by passing {@code null} or an empty list. The blacklist is
-     * given a name that is used to track which blacklist is currently set by calling {@link
-     * #getPasswordBlacklistName}. If the blacklist is being cleared, the name is ignored and {@link
-     * #getPasswordBlacklistName} will return {@code null}. The name can only be {@code null} when
-     * the blacklist is being cleared.
-     * <p>
-     * The blacklist is limited to a total of 128 thousand characters rather than limiting to a
-     * number of entries.
-     * <p>
-     * This method can be called on the {@link DevicePolicyManager} instance returned by
-     * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
-     * profile.
-     *
-     * @param admin the {@link DeviceAdminReceiver} this request is associated with
-     * @param name name to associate with the blacklist
-     * @param blacklist list of passwords to blacklist or {@code null} to clear the blacklist
-     * @return whether the new blacklist was successfully installed
-     * @throws SecurityException if {@code admin} is not a device or profile owner
-     * @throws IllegalArgumentException if the blacklist surpasses the character limit
-     * @throws NullPointerException if {@code name} is {@code null} when setting a non-empty list
-     *
-     * @see #getPasswordBlacklistName
-     * @see #isActivePasswordSufficient
-     * @see #resetPasswordWithToken
-     */
-    public boolean setPasswordBlacklist(@NonNull ComponentName admin, @Nullable String name,
-            @Nullable List<String> blacklist) {
-        enforcePasswordBlacklistSize(blacklist);
-
-        try {
-            return mService.setPasswordBlacklist(admin, name, blacklist, mParentInstance);
-        } catch (RemoteException re) {
-            throw re.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get the name of the password blacklist set by the given admin.
-     *
-     * @param admin the {@link DeviceAdminReceiver} this request is associated with
-     * @return the name of the blacklist or {@code null} if no blacklist is set
-     *
-     * @see #setPasswordBlacklist
-     */
-    public @Nullable String getPasswordBlacklistName(@NonNull ComponentName admin) {
-        try {
-            return mService.getPasswordBlacklistName(admin, myUserId(), mParentInstance);
-        } catch (RemoteException re) {
-            throw re.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Test if a given password is blacklisted.
-     *
-     * @param userId the user to valiate for
-     * @param password the password to check against the blacklist
-     * @return whether the password is blacklisted
-     *
-     * @see #setPasswordBlacklist
-     *
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.TEST_BLACKLISTED_PASSWORD)
-    public boolean isPasswordBlacklisted(@UserIdInt int userId, @NonNull String password) {
-        try {
-            return mService.isPasswordBlacklisted(userId, password);
-        } catch (RemoteException re) {
-            throw re.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Determine whether the current password the user has set is sufficient to meet the policy
      * requirements (e.g. quality, minimum length) that have been requested by the admins of this
      * user and its participating profiles. Restrictions on profiles that have a separate challenge
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 4b39a9a..37508cd 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -79,10 +79,6 @@
 
     long getPasswordExpiration(in ComponentName who, int userHandle, boolean parent);
 
-    boolean setPasswordBlacklist(in ComponentName who, String name, in List<String> blacklist, boolean parent);
-    String getPasswordBlacklistName(in ComponentName who, int userId, boolean parent);
-    boolean isPasswordBlacklisted(int userId, String password);
-
     boolean isActivePasswordSufficient(int userHandle, boolean parent);
     boolean isProfileActivePasswordSufficientForParent(int userHandle);
     boolean isUsingUnifiedPassword(in ComponentName admin);
diff --git a/core/java/android/app/slice/SliceManager.java b/core/java/android/app/slice/SliceManager.java
index 1afe53d..88b198b 100644
--- a/core/java/android/app/slice/SliceManager.java
+++ b/core/java/android/app/slice/SliceManager.java
@@ -81,6 +81,17 @@
      * An activity can be statically linked to a slice uri by including a meta-data item
      * for this key that contains a valid slice uri for the same application declaring
      * the activity.
+     *
+     * <pre class="prettyprint">
+     * {@literal
+     * <activity android:name="com.example.mypkg.MyActivity">
+     *     <meta-data android:name="android.metadata.SLICE_URI"
+     *                android:value="content://com.example.mypkg/main_slice" />
+     *  </activity>}
+     * </pre>
+     *
+     * @see #mapIntentToUri(Intent)
+     * @see SliceProvider#onMapIntentToUri(Intent)
      */
     public static final String SLICE_METADATA_KEY = "android.metadata.SLICE_URI";
 
@@ -257,16 +268,17 @@
      * <p>
      * This goes through a several stage resolution process to determine if any slice
      * can represent this intent.
-     *  - If the intent contains data that {@link ContentResolver#getType} is
-     *  {@link SliceProvider#SLICE_TYPE} then the data will be returned.
-     *  - If the intent with {@link #CATEGORY_SLICE} added resolves to a provider, then
+     * <ol>
+     *  <li> If the intent contains data that {@link ContentResolver#getType} is
+     *  {@link SliceProvider#SLICE_TYPE} then the data will be returned.</li>
+     *  <li>If the intent with {@link #CATEGORY_SLICE} added resolves to a provider, then
      *  the provider will be asked to {@link SliceProvider#onMapIntentToUri} and that result
-     *  will be returned.
-     *  - Lastly, if the intent explicitly points at an activity, and that activity has
+     *  will be returned.</li>
+     *  <li>Lastly, if the intent explicitly points at an activity, and that activity has
      *  meta-data for key {@link #SLICE_METADATA_KEY}, then the Uri specified there will be
-     *  returned.
-     *  - If no slice is found, then {@code null} is returned.
-     *
+     *  returned.</li>
+     *  <li>If no slice is found, then {@code null} is returned.</li>
+     * </ol>
      * @param intent The intent associated with a slice.
      * @return The Slice Uri provided by the app or null if none exists.
      * @see Slice
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index ff5714b..374b3ab 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -17,6 +17,7 @@
 package android.net;
 
 import android.annotation.IntDef;
+import android.annotation.SystemApi;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -276,6 +277,7 @@
      * this network can be used by system apps to upload telemetry data.
      * @hide
      */
+    @SystemApi
     public static final int NET_CAPABILITY_OEM_PAID = 22;
 
     private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 4f92fa6..caefd89 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -17,6 +17,8 @@
 package android.net;
 
 import android.annotation.NonNull;
+import android.net.NetworkCapabilities.NetCapability;
+import android.net.NetworkCapabilities.Transport;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.Process;
@@ -427,6 +429,20 @@
         return type == Type.BACKGROUND_REQUEST;
     }
 
+    /**
+     * @see Builder#addCapability(int)
+     */
+    public boolean hasCapability(@NetCapability int capability) {
+        return networkCapabilities.hasCapability(capability);
+    }
+
+    /**
+     * @see Builder#addTransportType(int)
+     */
+    public boolean hasTransport(@Transport int transportType) {
+        return networkCapabilities.hasTransport(transportType);
+    }
+
     public String toString() {
         return "NetworkRequest [ " + type + " id=" + requestId +
                 (legacyType != ConnectivityManager.TYPE_NONE ? ", legacyType=" + legacyType : "") +
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b7f6cdef..b0367dc 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11061,7 +11061,14 @@
          */
         public static final String LOW_POWER_MODE_TRIGGER_LEVEL_MAX = "low_power_trigger_level_max";
 
-         /**
+        /**
+         * See com.android.settingslib.fuelgauge.BatterySaverUtils.
+         * @hide
+         */
+        public static final String LOW_POWER_MODE_SUGGESTION_PARAMS =
+                "low_power_mode_suggestion_params";
+
+        /**
          * If not 0, the activity manager will aggressively finish activities and
          * processes as soon as they are no longer needed.  If 0, the normal
          * extended lifetime is used.
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index 1d13335..f4dcce1 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -75,6 +75,7 @@
     public static final int KM_TAG_ALLOW_WHILE_ON_BODY = KM_BOOL | 506;
     public static final int KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED = KM_BOOL | 507;
     public static final int KM_TAG_TRUSTED_CONFIRMATION_REQUIRED = KM_BOOL | 508;
+    public static final int KM_TAG_UNLOCKED_DEVICE_REQUIRED = KM_BOOL | 509;
 
     public static final int KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600;
     public static final int KM_TAG_APPLICATION_ID = KM_BYTES | 601;
@@ -216,6 +217,7 @@
     public static final int KM_ERROR_MISSING_MIN_MAC_LENGTH = -58;
     public static final int KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH = -59;
     public static final int KM_ERROR_CANNOT_ATTEST_IDS = -66;
+    public static final int KM_ERROR_DEVICE_LOCKED = -72;
     public static final int KM_ERROR_UNIMPLEMENTED = -100;
     public static final int KM_ERROR_VERSION_MISMATCH = -101;
     public static final int KM_ERROR_UNKNOWN_ERROR = -1000;
@@ -262,6 +264,7 @@
         sErrorCodeToString.put(KM_ERROR_INVALID_MAC_LENGTH,
                 "Invalid MAC or authentication tag length");
         sErrorCodeToString.put(KM_ERROR_CANNOT_ATTEST_IDS, "Unable to attest device ids");
+        sErrorCodeToString.put(KM_ERROR_DEVICE_LOCKED, "Device locked");
         sErrorCodeToString.put(KM_ERROR_UNIMPLEMENTED, "Not implemented");
         sErrorCodeToString.put(KM_ERROR_UNKNOWN_ERROR, "Unknown error");
     }
diff --git a/core/java/android/service/notification/ScheduleCalendar.java b/core/java/android/service/notification/ScheduleCalendar.java
index 8a7ff4d..0128710 100644
--- a/core/java/android/service/notification/ScheduleCalendar.java
+++ b/core/java/android/service/notification/ScheduleCalendar.java
@@ -144,7 +144,8 @@
         }
         return mSchedule.exitAtAlarm
                 && mSchedule.nextAlarm != 0
-                && time >= mSchedule.nextAlarm;
+                && time >= mSchedule.nextAlarm
+                && isInSchedule(mSchedule.nextAlarm);
     }
 
     private boolean isInSchedule(int daysOffset, long time, long start, long end) {
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 0fea0dc..ea0b825 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -175,9 +175,9 @@
     ];
 
     optional GZippedFileProto last_kmsg = 2007 [
-        (section).type = SECTION_NONE, // disable until selinux permission is gained
+        (section).type = SECTION_GZIP,
         (section).args = "/sys/fs/pstore/console-ramoops /sys/fs/pstore/console-ramoops-0 /proc/last_kmsg",
-        (privacy).dest = DEST_AUTOMATIC
+        (privacy).dest = DEST_EXPLICIT
     ];
 
     // System Services
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 4b9465d..dfc99f6 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -267,6 +267,7 @@
                     Settings.Global.LOW_POWER_MODE,
                     Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL_MAX,
                     Settings.Global.LOW_POWER_MODE_STICKY,
+                    Settings.Global.LOW_POWER_MODE_SUGGESTION_PARAMS,
                     Settings.Global.LTE_SERVICE_FORCED,
                     Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE,
                     Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY,
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 1e2ebf8..81644eb 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -16,6 +16,7 @@
 
 package android.security;
 
+import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.Application;
 import android.app.KeyguardManager;
@@ -279,7 +280,7 @@
     /**
      * Attempt to lock the keystore for {@code user}.
      *
-     * @param user Android user to lock.
+     * @param userId Android user to lock.
      * @return whether {@code user}'s keystore was locked.
      */
     public boolean lock(int userId) {
@@ -300,7 +301,7 @@
      * This is required before keystore entries created with FLAG_ENCRYPTED can be accessed or
      * created.
      *
-     * @param user Android user ID to operate on
+     * @param userId Android user ID to operate on
      * @param password user's keystore password. Should be the most recent value passed to
      * {@link #onUserPasswordChanged} for the user.
      *
@@ -546,6 +547,9 @@
         try {
             args = args != null ? args : new KeymasterArguments();
             entropy = entropy != null ? entropy : new byte[0];
+            if (!args.containsTag(KeymasterDefs.KM_TAG_USER_ID)) {
+                args.addUnsignedInt(KeymasterDefs.KM_TAG_USER_ID, ActivityManager.getCurrentUser());
+            }
             return mBinder.begin(getToken(), alias, purpose, pruneable, args, entropy, uid);
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 4b9f3c80..5d596cb 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -266,6 +266,7 @@
     private final boolean mInvalidatedByBiometricEnrollment;
     private final boolean mIsStrongBoxBacked;
     private final boolean mUserConfirmationRequired;
+    private final boolean mUnlockedDeviceRequired;
 
     /**
      * @hide should be built with Builder
@@ -296,7 +297,8 @@
             boolean userAuthenticationValidWhileOnBody,
             boolean invalidatedByBiometricEnrollment,
             boolean isStrongBoxBacked,
-            boolean userConfirmationRequired) {
+            boolean userConfirmationRequired,
+            boolean unlockedDeviceRequired) {
         if (TextUtils.isEmpty(keyStoreAlias)) {
             throw new IllegalArgumentException("keyStoreAlias must not be empty");
         }
@@ -345,6 +347,7 @@
         mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
         mIsStrongBoxBacked = isStrongBoxBacked;
         mUserConfirmationRequired = userConfirmationRequired;
+        mUnlockedDeviceRequired = unlockedDeviceRequired;
     }
 
     /**
@@ -670,6 +673,15 @@
     }
 
     /**
+     * @hide Returns {@code true} if the key cannot be used unless the device screen is unlocked.
+     *
+     * @see Builder#setUnlockedDeviceRequired(boolean)
+     */
+    public boolean isUnlockedDeviceRequired() {
+        return mUnlockedDeviceRequired;
+    }
+
+    /**
      * @hide
      */
     public long getBoundToSpecificSecureUserId() {
@@ -707,6 +719,7 @@
         private boolean mInvalidatedByBiometricEnrollment = true;
         private boolean mIsStrongBoxBacked = false;
         private boolean mUserConfirmationRequired;
+        private boolean mUnlockedDeviceRequired = false;
 
         /**
          * Creates a new instance of the {@code Builder}.
@@ -1275,6 +1288,18 @@
         }
 
         /**
+         * @hide Sets whether the keystore requires the screen to be unlocked before allowing decryption
+         * using this key. If this is set to {@code true}, any attempt to decrypt using this key
+         * while the screen is locked will fail. A locked device requires a PIN, password,
+         * fingerprint, or other trusted factor to access.
+         */
+        @NonNull
+        public Builder setUnlockedDeviceRequired(boolean unlockedDeviceRequired) {
+            mUnlockedDeviceRequired = unlockedDeviceRequired;
+            return this;
+        }
+
+        /**
          * Builds an instance of {@code KeyGenParameterSpec}.
          */
         @NonNull
@@ -1305,7 +1330,8 @@
                     mUserAuthenticationValidWhileOnBody,
                     mInvalidatedByBiometricEnrollment,
                     mIsStrongBoxBacked,
-                    mUserConfirmationRequired);
+                    mUserConfirmationRequired,
+                    mUnlockedDeviceRequired);
         }
     }
 }
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index 95eeec7..cc7870c 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -224,12 +224,13 @@
     private final boolean mRandomizedEncryptionRequired;
     private final boolean mUserAuthenticationRequired;
     private final int mUserAuthenticationValidityDurationSeconds;
-    private final boolean mTrustedUserPresenceRequred;
+    private final boolean mTrustedUserPresenceRequired;
     private final boolean mUserAuthenticationValidWhileOnBody;
     private final boolean mInvalidatedByBiometricEnrollment;
     private final long mBoundToSecureUserId;
     private final boolean mCriticalToDeviceEncryption;
     private final boolean mUserConfirmationRequired;
+    private final boolean mUnlockedDeviceRequired;
 
     private KeyProtection(
             Date keyValidityStart,
@@ -243,12 +244,13 @@
             boolean randomizedEncryptionRequired,
             boolean userAuthenticationRequired,
             int userAuthenticationValidityDurationSeconds,
-            boolean trustedUserPresenceRequred,
+            boolean trustedUserPresenceRequired,
             boolean userAuthenticationValidWhileOnBody,
             boolean invalidatedByBiometricEnrollment,
             long boundToSecureUserId,
             boolean criticalToDeviceEncryption,
-            boolean userConfirmationRequired) {
+            boolean userConfirmationRequired,
+            boolean unlockedDeviceRequired) {
         mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
         mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
         mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
@@ -262,12 +264,13 @@
         mRandomizedEncryptionRequired = randomizedEncryptionRequired;
         mUserAuthenticationRequired = userAuthenticationRequired;
         mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
-        mTrustedUserPresenceRequred = trustedUserPresenceRequred;
+        mTrustedUserPresenceRequired = trustedUserPresenceRequired;
         mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody;
         mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
         mBoundToSecureUserId = boundToSecureUserId;
         mCriticalToDeviceEncryption = criticalToDeviceEncryption;
         mUserConfirmationRequired = userConfirmationRequired;
+        mUnlockedDeviceRequired = unlockedDeviceRequired;
     }
 
     /**
@@ -444,7 +447,7 @@
      * been performed between the {@code Signature.initSign()} and {@code Signature.sign()} calls.
      */
     public boolean isTrustedUserPresenceRequired() {
-        return mTrustedUserPresenceRequred;
+        return mTrustedUserPresenceRequired;
     }
 
     /**
@@ -505,6 +508,15 @@
     }
 
     /**
+     * @hide Returns {@code true} if the key cannot be used unless the device screen is unlocked.
+     *
+     * @see Builder#setUnlockedDeviceRequired(boolean)
+     */
+    public boolean isUnlockedDeviceRequired() {
+        return mUnlockedDeviceRequired;
+    }
+
+    /**
      * Builder of {@link KeyProtection} instances.
      */
     public final static class Builder {
@@ -524,6 +536,8 @@
         private boolean mUserAuthenticationValidWhileOnBody;
         private boolean mInvalidatedByBiometricEnrollment = true;
         private boolean mUserConfirmationRequired;
+        private boolean mUnlockedDeviceRequired = false;
+
         private long mBoundToSecureUserId = GateKeeper.INVALID_SECURE_USER_ID;
         private boolean mCriticalToDeviceEncryption = false;
 
@@ -914,6 +928,18 @@
         }
 
         /**
+         * @hide Sets whether the keystore requires the screen to be unlocked before allowing decryption
+         * using this key. If this is set to {@code true}, any attempt to decrypt using this key
+         * while the screen is locked will fail. A locked device requires a PIN, password,
+         * fingerprint, or other trusted factor to access.
+         */
+        @NonNull
+        public Builder setUnlockedDeviceRequired(boolean unlockedDeviceRequired) {
+            mUnlockedDeviceRequired = unlockedDeviceRequired;
+            return this;
+        }
+
+        /**
          * Builds an instance of {@link KeyProtection}.
          *
          * @throws IllegalArgumentException if a required field is missing
@@ -937,7 +963,8 @@
                     mInvalidatedByBiometricEnrollment,
                     mBoundToSecureUserId,
                     mCriticalToDeviceEncryption,
-                    mUserConfirmationRequired);
+                    mUserConfirmationRequired,
+                    mUnlockedDeviceRequired);
         }
     }
 }
diff --git a/keystore/java/android/security/keystore/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java
index 0ef08f2..6e50121 100644
--- a/keystore/java/android/security/keystore/KeymasterUtils.java
+++ b/keystore/java/android/security/keystore/KeymasterUtils.java
@@ -16,9 +16,8 @@
 
 package android.security.keystore;
 
-import android.util.Log;
+import android.app.ActivityManager;
 import android.hardware.fingerprint.FingerprintManager;
-import android.os.UserHandle;
 import android.security.GateKeeper;
 import android.security.KeyStore;
 import android.security.keymaster.KeymasterArguments;
@@ -101,8 +100,9 @@
      *         state (e.g., secure lock screen not set up) for generating or importing keys that
      *         require user authentication.
      */
-    public static void addUserAuthArgs(KeymasterArguments args,
-            UserAuthArgs spec) {
+    public static void addUserAuthArgs(KeymasterArguments args, UserAuthArgs spec) {
+        args.addUnsignedInt(KeymasterDefs.KM_TAG_USER_ID, ActivityManager.getCurrentUser());
+
         if (spec.isUserConfirmationRequired()) {
             args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_CONFIRMATION_REQUIRED);
         }
@@ -111,6 +111,10 @@
             args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED);
         }
 
+        if (spec.isUnlockedDeviceRequired()) {
+            args.addBoolean(KeymasterDefs.KM_TAG_UNLOCKED_DEVICE_REQUIRED);
+        }
+
         if (!spec.isUserAuthenticationRequired()) {
             args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
             return;
diff --git a/keystore/java/android/security/keystore/UserAuthArgs.java b/keystore/java/android/security/keystore/UserAuthArgs.java
index 1949592..ad18ff8 100644
--- a/keystore/java/android/security/keystore/UserAuthArgs.java
+++ b/keystore/java/android/security/keystore/UserAuthArgs.java
@@ -33,5 +33,6 @@
     boolean isUserConfirmationRequired();
     long getBoundToSpecificSecureUserId();
     boolean isTrustedUserPresenceRequired();
+    boolean isUnlockedDeviceRequired();
 
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
index 28833a3..835ff07 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
@@ -22,8 +22,9 @@
 import android.os.PowerManager;
 import android.provider.Settings.Global;
 import android.provider.Settings.Secure;
-import android.support.annotation.VisibleForTesting;
+import android.util.KeyValueListParser;
 import android.util.Log;
+import android.util.Slog;
 
 /**
  * Utilities related to battery saver.
@@ -48,13 +49,35 @@
     public static final String ACTION_SHOW_AUTO_SAVER_SUGGESTION
             = "PNW.autoSaverSuggestion";
 
-    /**
-     * We show the auto battery saver suggestion notification when the user manually enables
-     * battery saver for the START_NTH time through the END_NTH time.
-     * (We won't show it for END_NTH + 1 time and after.)
-     */
-    private static final int AUTO_SAVER_SUGGESTION_START_NTH = 4;
-    private static final int AUTO_SAVER_SUGGESTION_END_NTH = 8;
+    private static class Parameters {
+        private final Context mContext;
+
+        /**
+         * We show the auto battery saver suggestion notification when the user manually enables
+         * battery saver for the START_NTH time through the END_NTH time.
+         * (We won't show it for END_NTH + 1 time and after.)
+         */
+        private static final int AUTO_SAVER_SUGGESTION_START_NTH = 4;
+        private static final int AUTO_SAVER_SUGGESTION_END_NTH = 8;
+
+        public final int startNth;
+        public final int endNth;
+
+        public Parameters(Context context) {
+            mContext = context;
+
+            final String newValue = Global.getString(mContext.getContentResolver(),
+                    Global.LOW_POWER_MODE_SUGGESTION_PARAMS);
+            final KeyValueListParser parser = new KeyValueListParser(',');
+            try {
+                parser.setString(newValue);
+            } catch (IllegalArgumentException e) {
+                Slog.wtf(TAG, "Bad constants: " + newValue);
+            }
+            startNth = parser.getInt("start_nth", AUTO_SAVER_SUGGESTION_START_NTH);
+            endNth = parser.getInt("end_nth", AUTO_SAVER_SUGGESTION_END_NTH);
+        }
+    }
 
     /**
      * Enable / disable battery saver by user request.
@@ -85,8 +108,10 @@
                         Secure.getInt(cr, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, 0) + 1;
                 Secure.putInt(cr, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, count);
 
-                if ((count >= AUTO_SAVER_SUGGESTION_START_NTH)
-                        && (count <= AUTO_SAVER_SUGGESTION_END_NTH)
+                final Parameters parameters = new Parameters(context);
+
+                if ((count >= parameters.startNth)
+                        && (count <= parameters.endNth)
                         && Global.getInt(cr, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0) == 0
                         && Secure.getInt(cr,
                         Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, 0) == 0) {
diff --git a/packages/SystemUI/res/values/dimens_car.xml b/packages/SystemUI/res/values/dimens_car.xml
index 5679dd2..6caed61 100644
--- a/packages/SystemUI/res/values/dimens_car.xml
+++ b/packages/SystemUI/res/values/dimens_car.xml
@@ -32,6 +32,8 @@
 
     <dimen name="car_navigation_button_width">64dp</dimen>
     <dimen name="car_navigation_bar_width">760dp</dimen>
+    <dimen name="car_left_navigation_bar_width">96dp</dimen>
+    <dimen name="car_right_navigation_bar_width">96dp</dimen>
 
     <dimen name="car_page_indicator_dot_diameter">12dp</dimen>
     <dimen name="car_page_indicator_margin_bottom">24dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index e9b2be9..4074042 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1748,6 +1748,10 @@
     <!-- Name of the headset in status bar [CHAR LIMIT=30] -->
     <string name="headset">Headset</string>
 
+    <!-- Accessibility description for long click on a quick settings tile - this is used in the
+         context of the sentence "double tap and hold to _Open settings_" [CHAR LIMIT=NONE] -->
+    <string name="accessibility_long_click_tile">Open settings</string>
+
     <!-- Accessibility description of headphones icon [CHAR LIMIT=NONE] -->
     <string name="accessibility_status_bar_headphones">Headphones connected</string>
 
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 2c0e95b..a61ce8c 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -29,30 +29,16 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.util.ArraySet;
-import android.util.TimingsTraceLog;
 import android.util.Log;
+import android.util.TimingsTraceLog;
 
-import com.android.systemui.globalactions.GlobalActionsComponent;
-import com.android.systemui.keyboard.KeyboardUI;
-import com.android.systemui.keyguard.KeyguardViewMediator;
-import com.android.systemui.media.RingtonePlayer;
-import com.android.systemui.pip.PipUI;
 import com.android.systemui.plugins.OverlayPlugin;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.PluginManager;
-import com.android.systemui.power.PowerUI;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.shortcut.ShortcutKeyDispatcher;
-import com.android.systemui.stackdivider.Divider;
-import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarWindowManager;
-import com.android.systemui.usb.StorageNotification;
 import com.android.systemui.util.NotificationChannels;
-import com.android.systemui.util.leak.GarbageMonitor;
-import com.android.systemui.volume.VolumeUI;
 
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -99,6 +85,10 @@
                             mServices[i].onBootCompleted();
                         }
                     }
+
+                    IntentFilter localeChangedFilter = new IntentFilter(
+                            Intent.ACTION_LOCALE_CHANGED);
+                    registerReceiver(mLocaleChangeReceiver, localeChangedFilter);
                 }
             }, filter);
         } else {
@@ -249,4 +239,14 @@
     public SystemUI[] getServices() {
         return mServices;
     }
+
+    private final BroadcastReceiver mLocaleChangeReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
+                // Update names of SystemUi notification channels
+                NotificationChannels.createAll(context);
+            }
+        }
+    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
index a9defc8..09d928f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
@@ -194,6 +194,7 @@
         setClickable(state.state != Tile.STATE_UNAVAILABLE);
         mIcon.setIcon(state);
         setContentDescription(state.contentDescription);
+
         mAccessibilityClass = state.expandedAccessibilityClassName;
         if (state instanceof QSTile.BooleanState) {
             boolean newState = ((BooleanState) state).value;
@@ -269,6 +270,10 @@
                 info.setText(label);
                 info.setChecked(b);
                 info.setCheckable(true);
+                info.addAction(
+                        new AccessibilityNodeInfo.AccessibilityAction(
+                                AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK.getId(),
+                                getResources().getString(R.string.accessibility_long_click_tile)));
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
index 2841136..b7d501e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
@@ -46,6 +46,12 @@
         }
     }
 
+    public void removeAll() {
+        mButtonsByCategory.clear();
+        mButtonsByPackage.clear();
+        mSelectedFacetButton = null;
+    }
+
     /**
      * This will unselect the currently selected CarFacetButton and determine which one should be
      * selected next. It does this by reading the properties on the CarFacetButton and seeing if
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index a95d0a4..3530e0b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -45,6 +45,7 @@
 import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 
 import java.io.FileDescriptor;
@@ -80,12 +81,16 @@
     private boolean mShowRight;
     private boolean mShowBottom;
     private CarFacetButtonController mCarFacetButtonController;
+    private ActivityManagerWrapper mActivityManagerWrapper;
+    private DeviceProvisionedController mDeviceProvisionedController;
+    private boolean mDeviceIsProvisioned = true;
 
     @Override
     public void start() {
         super.start();
         mTaskStackListener = new TaskStackListenerImpl();
-        ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
+        mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
+        mActivityManagerWrapper.registerTaskStackListener(mTaskStackListener);
 
         mStackScroller.setScrollingEnabled(true);
 
@@ -96,12 +101,54 @@
             Log.d(TAG, "Connecting to HVAC service");
             Dependency.get(HvacController.class).connectToCarService();
         }
+        mCarFacetButtonController = Dependency.get(CarFacetButtonController.class);
+        mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
+        mDeviceIsProvisioned = mDeviceProvisionedController.isDeviceProvisioned();
+        if (!mDeviceIsProvisioned) {
+            mDeviceProvisionedController.addCallback(
+                    new DeviceProvisionedController.DeviceProvisionedListener() {
+                        @Override
+                        public void onDeviceProvisionedChanged() {
+                            mDeviceIsProvisioned =
+                                    mDeviceProvisionedController.isDeviceProvisioned();
+                            restartNavBars();
+                        }
+                    });
+        }
     }
 
+    /**
+     * Remove all content from navbars and rebuild them. Used to allow for different nav bars
+     * before and after the device is provisioned
+     */
+    private void restartNavBars() {
+        mCarFacetButtonController.removeAll();
+        if (ENABLE_HVAC_CONNECTION) {
+            Dependency.get(HvacController.class).removeAllComponents();
+        }
+        if (mNavigationBarWindow != null) {
+            mNavigationBarWindow.removeAllViews();
+            mNavigationBarView = null;
+        }
+
+        if (mLeftNavigationBarWindow != null) {
+            mLeftNavigationBarWindow.removeAllViews();
+            mLeftNavigationBarView = null;
+        }
+
+        if (mRightNavigationBarWindow != null) {
+            mRightNavigationBarWindow.removeAllViews();
+            mRightNavigationBarView = null;
+        }
+        buildNavBarContent();
+    }
+
+
     @Override
     public void destroy() {
         mCarBatteryController.stopListening();
         mConnectedDeviceSignalController.stopListening();
+        mActivityManagerWrapper.unregisterTaskStackListener(mTaskStackListener);
 
         if (mNavigationBarWindow != null) {
             mWindowManager.removeViewImmediate(mNavigationBarWindow);
@@ -117,10 +164,10 @@
             mWindowManager.removeViewImmediate(mRightNavigationBarWindow);
             mRightNavigationBarView = null;
         }
-
         super.destroy();
     }
 
+
     @Override
     protected void makeStatusBarView() {
         super.makeStatusBarView();
@@ -167,129 +214,132 @@
 
     @Override
     protected void createNavigationBar() {
-        mCarFacetButtonController = Dependency.get(CarFacetButtonController.class);
-        if (mNavigationBarView != null) {
-            return;
-        }
-
         mShowBottom = mContext.getResources().getBoolean(R.bool.config_enableBottomNavigationBar);
-        if (mShowBottom) {
-            buildBottomBar();
-        }
-
-        int widthForSides = mContext.getResources().getDimensionPixelSize(
-                R.dimen.navigation_bar_height_car_mode);
-
-
         mShowLeft = mContext.getResources().getBoolean(R.bool.config_enableLeftNavigationBar);
-
-        if (mShowLeft) {
-            buildLeft(widthForSides);
-        }
-
         mShowRight = mContext.getResources().getBoolean(R.bool.config_enableRightNavigationBar);
 
+        buildNavBarWindows();
+        buildNavBarContent();
+        attachNavBarWindows();
+    }
+
+    private void buildNavBarContent() {
+        if (mShowBottom) {
+            buildBottomBar((mDeviceIsProvisioned) ? R.layout.car_navigation_bar :
+                    R.layout.car_navigation_bar_unprovisioned);
+        }
+
+        if (mShowLeft) {
+            buildLeft((mDeviceIsProvisioned) ? R.layout.car_left_navigation_bar :
+                    R.layout.car_left_navigation_bar_unprovisioned);
+        }
+
         if (mShowRight) {
-            buildRight(widthForSides);
+            buildRight((mDeviceIsProvisioned) ? R.layout.car_right_navigation_bar :
+                    R.layout.car_right_navigation_bar_unprovisioned);
+        }
+    }
+
+    private void buildNavBarWindows() {
+        if (mShowBottom) {
+
+             mNavigationBarWindow = (ViewGroup) View.inflate(mContext,
+                    R.layout.navigation_bar_window, null);
+        }
+        if (mShowLeft) {
+            mLeftNavigationBarWindow = (ViewGroup) View.inflate(mContext,
+                R.layout.navigation_bar_window, null);
+        }
+        if (mShowRight) {
+            mRightNavigationBarWindow = (ViewGroup) View.inflate(mContext,
+                    R.layout.navigation_bar_window, null);
         }
 
     }
 
+    private void attachNavBarWindows() {
 
-    private void buildBottomBar() {
+        if (mShowBottom) {
+            WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                    LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
+                    WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
+                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                            | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                            | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
+                    PixelFormat.TRANSLUCENT);
+            lp.setTitle("CarNavigationBar");
+            lp.windowAnimations = 0;
+            mWindowManager.addView(mNavigationBarWindow, lp);
+        }
+        if (mShowLeft) {
+            int width = mContext.getResources().getDimensionPixelSize(
+                    R.dimen.car_left_navigation_bar_width);
+            WindowManager.LayoutParams leftlp = new WindowManager.LayoutParams(
+                    width, LayoutParams.MATCH_PARENT,
+                    WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                            | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                            | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
+                    PixelFormat.TRANSLUCENT);
+            leftlp.setTitle("LeftCarNavigationBar");
+            leftlp.windowAnimations = 0;
+            leftlp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
+            leftlp.gravity = Gravity.LEFT;
+            mWindowManager.addView(mLeftNavigationBarWindow, leftlp);
+        }
+        if (mShowRight) {
+            int width = mContext.getResources().getDimensionPixelSize(
+                    R.dimen.car_right_navigation_bar_width);
+            WindowManager.LayoutParams rightlp = new WindowManager.LayoutParams(
+                    width, LayoutParams.MATCH_PARENT,
+                    WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                            | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                            | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
+                    PixelFormat.TRANSLUCENT);
+            rightlp.setTitle("RightCarNavigationBar");
+            rightlp.windowAnimations = 0;
+            rightlp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
+            rightlp.gravity = Gravity.RIGHT;
+            mWindowManager.addView(mRightNavigationBarWindow, rightlp);
+        }
+
+    }
+
+    private void buildBottomBar(int layout) {
         // SystemUI requires that the navigation bar view have a parent. Since the regular
         // StatusBar inflates navigation_bar_window as this parent view, use the same view for the
         // CarNavigationBarView.
-        mNavigationBarWindow = (ViewGroup) View.inflate(mContext,
-                R.layout.navigation_bar_window, null);
-        if (mNavigationBarWindow == null) {
-            Log.e(TAG, "CarStatusBar failed inflate for R.layout.navigation_bar_window");
-        }
-
-
-        View.inflate(mContext, R.layout.car_navigation_bar, mNavigationBarWindow);
+        View.inflate(mContext, layout, mNavigationBarWindow);
         mNavigationBarView = (CarNavigationBarView) mNavigationBarWindow.getChildAt(0);
         if (mNavigationBarView == null) {
             Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_navigation_bar");
             throw new RuntimeException("Unable to build botom nav bar due to missing layout");
         }
         mNavigationBarView.setStatusBar(this);
-
-
-        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
-                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
-                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
-                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
-                PixelFormat.TRANSLUCENT);
-        lp.setTitle("CarNavigationBar");
-        lp.windowAnimations = 0;
-
-
-        mWindowManager.addView(mNavigationBarWindow, lp);
     }
 
-    private void buildLeft(int widthForSides) {
-        mLeftNavigationBarWindow = (ViewGroup) View.inflate(mContext,
-                R.layout.navigation_bar_window, null);
-        if (mLeftNavigationBarWindow == null) {
-            Log.e(TAG, "CarStatusBar failed inflate for R.layout.navigation_bar_window");
-        }
-
-        View.inflate(mContext, R.layout.car_left_navigation_bar, mLeftNavigationBarWindow);
+    private void buildLeft(int layout) {
+        View.inflate(mContext, layout, mLeftNavigationBarWindow);
         mLeftNavigationBarView = (CarNavigationBarView) mLeftNavigationBarWindow.getChildAt(0);
         if (mLeftNavigationBarView == null) {
             Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_navigation_bar");
             throw new RuntimeException("Unable to build left nav bar due to missing layout");
         }
         mLeftNavigationBarView.setStatusBar(this);
-
-        WindowManager.LayoutParams leftlp = new WindowManager.LayoutParams(
-                widthForSides, LayoutParams.MATCH_PARENT,
-                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
-                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
-                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
-                PixelFormat.TRANSLUCENT);
-        leftlp.setTitle("LeftCarNavigationBar");
-        leftlp.windowAnimations = 0;
-        leftlp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
-        leftlp.gravity = Gravity.LEFT;
-        mWindowManager.addView(mLeftNavigationBarWindow, leftlp);
     }
 
 
-    private void buildRight(int widthForSides) {
-        mRightNavigationBarWindow = (ViewGroup) View.inflate(mContext,
-                R.layout.navigation_bar_window, null);
-        if (mRightNavigationBarWindow == null) {
-            Log.e(TAG, "CarStatusBar failed inflate for R.layout.navigation_bar_window");
-        }
-
-        View.inflate(mContext, R.layout.car_right_navigation_bar, mRightNavigationBarWindow);
+    private void buildRight(int layout) {
+        View.inflate(mContext, layout, mRightNavigationBarWindow);
         mRightNavigationBarView = (CarNavigationBarView) mRightNavigationBarWindow.getChildAt(0);
         if (mRightNavigationBarView == null) {
             Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_navigation_bar");
             throw new RuntimeException("Unable to build right nav bar due to missing layout");
         }
-        mRightNavigationBarView.setStatusBar(this);
-
-        WindowManager.LayoutParams rightlp = new WindowManager.LayoutParams(
-                widthForSides, LayoutParams.MATCH_PARENT,
-                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
-                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
-                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
-                PixelFormat.TRANSLUCENT);
-        rightlp.setTitle("RightCarNavigationBar");
-        rightlp.windowAnimations = 0;
-        rightlp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
-        rightlp.gravity = Gravity.RIGHT;
-        mWindowManager.addView(mRightNavigationBarWindow, rightlp);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
index 23bf887..7d283d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
@@ -176,6 +176,14 @@
     };
 
     /**
+     * Removes all registered components. This is useful if you need to rebuild the UI since
+     * components self register.
+     */
+    public void removeAllComponents() {
+        mTempComponents.clear();
+    }
+
+    /**
      * Key for storing {@link TemperatureView}s in a hash map
      */
     private static class HvacKey {
diff --git a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
index 1cbdfe8..7a9cdfd 100644
--- a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
+++ b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
@@ -39,8 +39,7 @@
     public static String BATTERY     = "BAT";
     public static String HINTS       = "HNT";
 
-    @VisibleForTesting
-    static void createAll(Context context) {
+    public static void createAll(Context context) {
         final NotificationManager nm = context.getSystemService(NotificationManager.class);
         final NotificationChannel batteryChannel = new NotificationChannel(BATTERY,
                 context.getString(R.string.notification_channel_battery),
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 31b0461..f31ca0a 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -182,6 +182,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.internal.util.ArrayUtils;
@@ -898,6 +899,8 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
+                // update system notification channels
+                SystemNotificationChannels.createAll(context);
                 mZenModeHelper.updateDefaultZenRules();
                 mRankingHelper.onLocaleChanged(context, ActivityManager.getCurrentUser());
             }
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
index 941cd44..e56caf8 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -19,6 +19,8 @@
 import android.app.ActivityManager;
 import android.content.Context;
 import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.security.IKeystoreService;
 import android.util.Slog;
 
 import com.android.internal.policy.IKeyguardService;
@@ -51,11 +53,16 @@
     private final LockPatternUtils mLockPatternUtils;
     private final StateCallback mCallback;
 
+    IKeystoreService mKeystoreService;
+
     public KeyguardStateMonitor(Context context, IKeyguardService service, StateCallback callback) {
         mLockPatternUtils = new LockPatternUtils(context);
         mCurrentUserId = ActivityManager.getCurrentUser();
         mCallback = callback;
 
+        mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager
+                .getService("android.security.keystore"));
+
         try {
             service.addStateMonitorCallback(this);
         } catch (RemoteException e) {
@@ -86,6 +93,12 @@
     @Override // Binder interface
     public void onShowingStateChanged(boolean showing) {
         mIsShowing = showing;
+
+        try {
+            mKeystoreService.onKeyguardVisibilityChanged(showing, mCurrentUserId);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Error informing keystore of screen lock", e);
+        }
     }
 
     @Override // Binder interface
@@ -130,4 +143,4 @@
         pw.println(prefix + "mTrusted=" + mTrusted);
         pw.println(prefix + "mCurrentUserId=" + mCurrentUserId);
     }
-}
\ No newline at end of file
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
index 71c2ea1..1c9782f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -78,23 +78,6 @@
         return false;
     }
 
-    @Override
-    public boolean setPasswordBlacklist(ComponentName who, String name, List<String> blacklist,
-            boolean parent) {
-        return false;
-    }
-
-    @Override
-    public String getPasswordBlacklistName(ComponentName who, @UserIdInt int userId,
-            boolean parent) {
-        return null;
-    }
-
-    @Override
-    public boolean isPasswordBlacklisted(@UserIdInt int userId, String password) {
-        return false;
-    }
-
     public boolean isUsingUnifiedPassword(ComponentName who) {
         return true;
     }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index ffa7311..90e8a9c 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -820,7 +820,6 @@
         private static final String TAG_PASSWORD_HISTORY_LENGTH = "password-history-length";
         private static final String TAG_MIN_PASSWORD_LENGTH = "min-password-length";
         private static final String ATTR_VALUE = "value";
-        private static final String TAG_PASSWORD_BLACKLIST = "password-blacklist";
         private static final String TAG_PASSWORD_QUALITY = "password-quality";
         private static final String TAG_POLICIES = "policies";
         private static final String TAG_CROSS_PROFILE_WIDGET_PROVIDERS =
@@ -961,9 +960,6 @@
         // Default title of confirm credentials screen
         String organizationName = null;
 
-        // The blacklist data is stored in a file whose name is stored in the XML
-        String passwordBlacklistFile = null;
-
         // The component name of the backup transport which has to be used if backups are mandatory
         // or null if backups are not mandatory.
         ComponentName mandatoryBackupTransport = null;
@@ -1053,11 +1049,6 @@
                     out.endTag(null, TAG_MIN_PASSWORD_NONLETTER);
                 }
             }
-            if (passwordBlacklistFile != null) {
-                out.startTag(null, TAG_PASSWORD_BLACKLIST);
-                out.attribute(null, ATTR_VALUE, passwordBlacklistFile);
-                out.endTag(null, TAG_PASSWORD_BLACKLIST);
-            }
             if (maximumTimeToUnlock != DEF_MAXIMUM_TIME_TO_UNLOCK) {
                 out.startTag(null, TAG_MAX_TIME_TO_UNLOCK);
                 out.attribute(null, ATTR_VALUE, Long.toString(maximumTimeToUnlock));
@@ -1313,8 +1304,6 @@
                 } else if (TAG_MIN_PASSWORD_NONLETTER.equals(tag)) {
                     minimumPasswordMetrics.nonLetter = Integer.parseInt(
                             parser.getAttributeValue(null, ATTR_VALUE));
-                } else if (TAG_PASSWORD_BLACKLIST.equals(tag)) {
-                    passwordBlacklistFile = parser.getAttributeValue(null, ATTR_VALUE);
                 }else if (TAG_MAX_TIME_TO_UNLOCK.equals(tag)) {
                     maximumTimeToUnlock = Long.parseLong(
                             parser.getAttributeValue(null, ATTR_VALUE));
@@ -1589,8 +1578,6 @@
                     pw.println(minimumPasswordMetrics.symbols);
             pw.print(prefix); pw.print("minimumPasswordNonLetter=");
                     pw.println(minimumPasswordMetrics.nonLetter);
-            pw.print(prefix); pw.print("passwordBlacklist=");
-                    pw.println(passwordBlacklistFile != null);
             pw.print(prefix); pw.print("maximumTimeToUnlock=");
                     pw.println(maximumTimeToUnlock);
             pw.print(prefix); pw.print("strongAuthUnlockTimeout=");
@@ -1857,10 +1844,6 @@
             return new LockPatternUtils(mContext);
         }
 
-        PasswordBlacklist newPasswordBlacklist(File file) {
-            return new PasswordBlacklist(file);
-        }
-
         boolean storageManagerIsFileBasedEncryptionEnabled() {
             return StorageManager.isFileEncryptedNativeOnly();
         }
@@ -4413,136 +4396,6 @@
         }
     }
 
-    /* @return the password blacklist set by the admin or {@code null} if none. */
-    PasswordBlacklist getAdminPasswordBlacklistLocked(@NonNull ActiveAdmin admin) {
-        final int userId = UserHandle.getUserId(admin.getUid());
-        return admin.passwordBlacklistFile == null ? null : new PasswordBlacklist(
-                new File(getPolicyFileDirectory(userId), admin.passwordBlacklistFile));
-    }
-
-    private static final String PASSWORD_BLACKLIST_FILE_PREFIX = "password-blacklist-";
-    private static final String PASSWORD_BLACKLIST_FILE_SUFFIX = "";
-
-    @Override
-    public boolean setPasswordBlacklist(ComponentName who, String name, List<String> blacklist,
-            boolean parent) {
-        if (!mHasFeature) {
-            return false;
-        }
-        Preconditions.checkNotNull(who, "who is null");
-
-        synchronized (this) {
-            final ActiveAdmin admin = getActiveAdminForCallerLocked(
-                    who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, parent);
-            final int userId = mInjector.userHandleGetCallingUserId();
-            PasswordBlacklist adminBlacklist = getAdminPasswordBlacklistLocked(admin);
-
-            if (blacklist == null || blacklist.isEmpty()) {
-                // Remove the adminBlacklist
-                admin.passwordBlacklistFile = null;
-                saveSettingsLocked(userId);
-                if (adminBlacklist != null) {
-                    adminBlacklist.delete();
-                }
-                return true;
-            }
-
-            // Validate server side
-            Preconditions.checkNotNull(name, "name is null");
-            DevicePolicyManager.enforcePasswordBlacklistSize(blacklist);
-
-            // Blacklist is case insensitive so normalize to lower case
-            final int blacklistSize = blacklist.size();
-            for (int i = 0; i < blacklistSize; ++i) {
-                blacklist.set(i, blacklist.get(i).toLowerCase());
-            }
-
-            final boolean isNewBlacklist = adminBlacklist == null;
-            if (isNewBlacklist) {
-                // Create a new file for the blacklist. There could be multiple admins, each setting
-                // different blacklists, to restrict a user's credential, for example a managed
-                // profile can impose restrictions on its parent while the parent is already
-                // restricted by its own admin. A deterministic naming scheme would be fragile if
-                // new types of admin are introduced so we generate and save the file name instead.
-                // This isn't a temporary file but it reuses the name generation logic
-                final File file;
-                try {
-                    file = File.createTempFile(PASSWORD_BLACKLIST_FILE_PREFIX,
-                            PASSWORD_BLACKLIST_FILE_SUFFIX, getPolicyFileDirectory(userId));
-                } catch (IOException e) {
-                    Slog.e(LOG_TAG, "Failed to make a file for the blacklist", e);
-                    return false;
-                }
-                adminBlacklist = mInjector.newPasswordBlacklist(file);
-            }
-
-            if (adminBlacklist.savePasswordBlacklist(name, blacklist)) {
-                if (isNewBlacklist) {
-                    // The blacklist was saved so point the admin to the file
-                    admin.passwordBlacklistFile = adminBlacklist.getFile().getName();
-                    saveSettingsLocked(userId);
-                }
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public String getPasswordBlacklistName(ComponentName who, @UserIdInt int userId,
-            boolean parent) {
-        if (!mHasFeature) {
-            return null;
-        }
-        Preconditions.checkNotNull(who, "who is null");
-        enforceFullCrossUsersPermission(userId);
-        synchronized (this) {
-            final ActiveAdmin admin = getActiveAdminForCallerLocked(
-                    who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, parent);
-            final PasswordBlacklist blacklist = getAdminPasswordBlacklistLocked(admin);
-            if (blacklist == null) {
-                return null;
-            }
-            return blacklist.getName();
-        }
-    }
-
-    @Override
-    public boolean isPasswordBlacklisted(@UserIdInt int userId, String password) {
-        if (!mHasFeature) {
-            return false;
-        }
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.TEST_BLACKLISTED_PASSWORD, null);
-        return isPasswordBlacklistedInternal(userId, password);
-    }
-
-    private boolean isPasswordBlacklistedInternal(@UserIdInt int userId, String password) {
-        Preconditions.checkNotNull(password, "Password is null");
-        enforceFullCrossUsersPermission(userId);
-
-        // Normalize to lower case for case insensitive blacklist match
-        final String lowerCasePassword = password.toLowerCase();
-
-        synchronized (this) {
-            final List<ActiveAdmin> admins =
-                    getActiveAdminsForLockscreenPoliciesLocked(userId, /* parent */ false);
-            final int N = admins.size();
-            for (int i = 0; i < N; i++) {
-                final PasswordBlacklist blacklist
-                        = getAdminPasswordBlacklistLocked(admins.get(i));
-                if (blacklist != null) {
-                    if (blacklist.isPasswordBlacklisted(lowerCasePassword)) {
-                        return true;
-                    }
-                }
-            }
-        }
-
-        return false;
-    }
-
     @Override
     public boolean isActivePasswordSufficient(int userHandle, boolean parent) {
         if (!mHasFeature) {
@@ -4938,11 +4791,6 @@
                     return false;
                 }
             }
-
-            if (isPasswordBlacklistedInternal(userHandle, password)) {
-                Slog.w(LOG_TAG, "resetPassword: the password is blacklisted");
-                return false;
-            }
         }
 
         DevicePolicyData policy = getUserData(userHandle);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PasswordBlacklist.java b/services/devicepolicy/java/com/android/server/devicepolicy/PasswordBlacklist.java
deleted file mode 100644
index a17a107..0000000
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PasswordBlacklist.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.devicepolicy;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.util.AtomicFile;
-import android.util.Slog;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.List;
-
-/**
- * Manages the blacklisted passwords.
- *
- * This caller must ensure synchronized access.
- */
-public class PasswordBlacklist {
-    private static final String TAG = "PasswordBlacklist";
-
-    private final AtomicFile mFile;
-
-    /**
-     * Create an object to manage the password blacklist.
-     *
-     * This is a lightweight operation to prepare variables but not perform any IO.
-     */
-    public PasswordBlacklist(File file) {
-        mFile = new AtomicFile(file, "device-policy");
-    }
-
-    /**
-     * Atomically replace the blacklist.
-     *
-     * Pass {@code null} for an empty list.
-     */
-    public boolean savePasswordBlacklist(@NonNull String name, @NonNull List<String> blacklist) {
-        FileOutputStream fos = null;
-        try {
-            fos = mFile.startWrite();
-            final DataOutputStream out = buildStreamForWriting(fos);
-            final Header header = new Header(Header.VERSION_1, name, blacklist.size());
-            header.write(out);
-            final int blacklistSize = blacklist.size();
-            for (int i = 0; i < blacklistSize; ++i) {
-                out.writeUTF(blacklist.get(i));
-            }
-            out.flush();
-            mFile.finishWrite(fos);
-            return true;
-        } catch (IOException e) {
-            mFile.failWrite(fos);
-            return false;
-        }
-    }
-
-    /** @return the name of the blacklist or {@code null} if none set. */
-    public String getName() {
-        try (DataInputStream in = openForReading()) {
-            return Header.read(in).mName;
-        } catch (IOException e) {
-            Slog.wtf(TAG, "Failed to read blacklist file", e);
-        }
-        return null;
-    }
-
-    /** @return the number of blacklisted passwords. */
-    public int getSize() {
-        final int blacklistSize;
-        try (DataInputStream in = openForReading()) {
-            return Header.read(in).mSize;
-        } catch (IOException e) {
-            Slog.wtf(TAG, "Failed to read blacklist file", e);
-        }
-        return 0;
-    }
-
-    /** @return whether the password matches an blacklisted item. */
-    public boolean isPasswordBlacklisted(@NonNull String password) {
-        final int blacklistSize;
-        try (DataInputStream in = openForReading()) {
-            final Header header = Header.read(in);
-            for (int i = 0; i < header.mSize; ++i) {
-                if (in.readUTF().equals(password)) {
-                    return true;
-                }
-            }
-        } catch (IOException e) {
-            Slog.wtf(TAG, "Failed to read blacklist file", e);
-            // Fail safe and block all passwords. Setting a new blacklist should resolve this
-            // problem which can be identified by examining the log.
-            return true;
-        }
-        return false;
-    }
-
-    /** Delete the blacklist completely from disk. */
-    public void delete() {
-        mFile.delete();
-    }
-
-    /** Get the file the blacklist is stored in. */
-    public File getFile() {
-        return mFile.getBaseFile();
-    }
-
-    private DataOutputStream buildStreamForWriting(FileOutputStream fos) {
-        return new DataOutputStream(new BufferedOutputStream(fos));
-    }
-
-    private DataInputStream openForReading() throws IOException {
-        return new DataInputStream(new BufferedInputStream(mFile.openRead()));
-    }
-
-    /**
-     * Helper to read and write the header of the blacklist file.
-     */
-    private static class Header {
-        static final int VERSION_1 = 1;
-
-        final int mVersion; // File format version
-        final String mName;
-        final int mSize;
-
-        Header(int version, String name, int size) {
-            mVersion = version;
-            mName = name;
-            mSize = size;
-        }
-
-        void write(DataOutputStream out) throws IOException {
-            out.writeInt(mVersion);
-            out.writeUTF(mName);
-            out.writeInt(mSize);
-        }
-
-        static Header read(DataInputStream in) throws IOException {
-            final int version = in.readInt();
-            final String name = in.readUTF();
-            final int size = in.readInt();
-            return new Header(version, name, size);
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
index 520f318..cd39285 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -98,12 +98,6 @@
         this.context = injector.context;
     }
 
-    @Override
-    public boolean isPasswordBlacklisted(int userId, String password) {
-        return false;
-    }
-
-
     public void notifyChangeToContentObserver(Uri uri, int userHandle) {
         ContentObserver co = mMockInjector.mContentObservers.get(new Pair<>(uri, userHandle));
         if (co != null) {
@@ -220,11 +214,6 @@
         }
 
         @Override
-        PasswordBlacklist newPasswordBlacklist(File file) {
-            return services.passwordBlacklist;
-        }
-
-        @Override
         boolean storageManagerIsFileBasedEncryptionEnabled() {
             return services.storageManager.isFileBasedEncryptionEnabled();
         }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index ccf4a82..b76064b 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -4192,36 +4192,6 @@
         assertTrue(dpm.clearResetPasswordToken(admin1));
     }
 
-    public void testSetPasswordBlacklistCannotBeCalledByNonAdmin() throws Exception {
-        assertExpectException(SecurityException.class, /* messageRegex= */ null,
-                () -> dpm.setPasswordBlacklist(admin1, null, null));
-        verifyZeroInteractions(getServices().passwordBlacklist);
-    }
-
-    public void testClearingPasswordBlacklistDoesNotCreateNewBlacklist() throws Exception {
-        setupProfileOwner();
-        dpm.setPasswordBlacklist(admin1, null, null);
-        verifyZeroInteractions(getServices().passwordBlacklist);
-    }
-
-    public void testSetPasswordBlacklistCreatesNewBlacklist() throws Exception {
-        final String name = "myblacklist";
-        final List<String> explicit = Arrays.asList("password", "letmein");
-        setupProfileOwner();
-        dpm.setPasswordBlacklist(admin1, name, explicit);
-        verify(getServices().passwordBlacklist).savePasswordBlacklist(name, explicit);
-    }
-
-    public void testSetPasswordBlacklistOnlyConvertsExplicitToLowerCase() throws Exception {
-        final List<String> mixedCase = Arrays.asList("password", "LETMEIN", "FooTBAll");
-        final List<String> lowerCase = Arrays.asList("password", "letmein", "football");
-        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
-        setupDeviceOwner();
-        final String name = "Name of the Blacklist";
-        dpm.setPasswordBlacklist(admin1, name, mixedCase);
-        verify(getServices().passwordBlacklist).savePasswordBlacklist(name, lowerCase);
-    }
-
     public void testIsActivePasswordSufficient() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         mContext.packageName = admin1.getPackageName();
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
index 81ed6e2..e753df1 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -96,7 +96,6 @@
     public final IBackupManager ibackupManager;
     public final IAudioService iaudioService;
     public final LockPatternUtils lockPatternUtils;
-    public final PasswordBlacklist passwordBlacklist;
     public final StorageManagerForMock storageManager;
     public final WifiManager wifiManager;
     public final SettingsForMock settings;
@@ -135,7 +134,6 @@
         ibackupManager = mock(IBackupManager.class);
         iaudioService = mock(IAudioService.class);
         lockPatternUtils = mock(LockPatternUtils.class);
-        passwordBlacklist = mock(PasswordBlacklist.class);
         storageManager = mock(StorageManagerForMock.class);
         wifiManager = mock(WifiManager.class);
         settings = mock(SettingsForMock.class);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/PasswordBlacklistTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/PasswordBlacklistTest.java
deleted file mode 100644
index 1b3fc2c..0000000
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/PasswordBlacklistTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.devicepolicy;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Unit tests for {@link PasswordBlacklist}.
- *
- * bit FrameworksServicesTests:com.android.server.devicepolicy.PasswordBlacklistTest
- * runtest -x frameworks/base/services/tests/servicestests/src/com/android/server/devicepolicy/PasswordBlacklistTest.java
- */
-@RunWith(AndroidJUnit4.class)
-public final class PasswordBlacklistTest {
-    private File mBlacklistFile;
-    private PasswordBlacklist mBlacklist;
-
-    @Before
-    public void setUp() throws IOException {
-        mBlacklistFile = File.createTempFile("pwdbl", null);
-        mBlacklist = new PasswordBlacklist(mBlacklistFile);
-    }
-
-    @After
-    public void tearDown() {
-        mBlacklist.delete();
-    }
-
-    @Test
-    public void matchIsExact() {
-        // Note: Case sensitivity is handled by the user of PasswordBlacklist by normalizing the
-        // values stored in and tested against it.
-        mBlacklist.savePasswordBlacklist("matchIsExact", Arrays.asList("password", "qWERty"));
-        assertTrue(mBlacklist.isPasswordBlacklisted("password"));
-        assertTrue(mBlacklist.isPasswordBlacklisted("qWERty"));
-        assertFalse(mBlacklist.isPasswordBlacklisted("Password"));
-        assertFalse(mBlacklist.isPasswordBlacklisted("qwert"));
-        assertFalse(mBlacklist.isPasswordBlacklisted("letmein"));
-    }
-
-    @Test
-    public void matchIsNotRegex() {
-        mBlacklist.savePasswordBlacklist("matchIsNotRegex", Arrays.asList("a+b*"));
-        assertTrue(mBlacklist.isPasswordBlacklisted("a+b*"));
-        assertFalse(mBlacklist.isPasswordBlacklisted("aaaa"));
-        assertFalse(mBlacklist.isPasswordBlacklisted("abbbb"));
-        assertFalse(mBlacklist.isPasswordBlacklisted("aaaa"));
-    }
-
-    @Test
-    public void matchFailsSafe() throws IOException {
-        try (FileOutputStream fos = new FileOutputStream(mBlacklistFile)) {
-            // Write a malformed blacklist file
-            fos.write(17);
-        }
-        assertTrue(mBlacklist.isPasswordBlacklisted("anything"));
-        assertTrue(mBlacklist.isPasswordBlacklisted("at"));
-        assertTrue(mBlacklist.isPasswordBlacklisted("ALL"));
-    }
-
-    @Test
-    public void blacklistCanBeNamed() {
-        final String name = "identifier";
-        mBlacklist.savePasswordBlacklist(name, Arrays.asList("one", "two", "three"));
-        assertEquals(mBlacklist.getName(), name);
-    }
-
-    @Test
-    public void reportsTheCorrectNumberOfEntries() {
-        mBlacklist.savePasswordBlacklist("Count Entries", Arrays.asList("1", "2", "3", "4"));
-        assertEquals(mBlacklist.getSize(), 4);
-    }
-
-    @Test
-    public void reportsBlacklistFile() {
-        assertEquals(mBlacklistFile, mBlacklist.getFile());
-    }
-}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java
index 36136a8..ce74457 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java
@@ -206,6 +206,31 @@
     }
 
     @Test
+    public void testShouldExitForAlarm_oldAlarm() {
+        // Cal: today 2:15pm
+        Calendar cal = new GregorianCalendar();
+        cal.set(Calendar.HOUR_OF_DAY, 14);
+        cal.set(Calendar.MINUTE, 15);
+        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+
+        // ScheduleInfo: today 12:16pm  - today 3:15pm
+        mScheduleInfo.days = new int[] {getTodayDay()};
+        mScheduleInfo.startHour = 12;
+        mScheduleInfo.endHour = 3;
+        mScheduleInfo.startMinute = 16;
+        mScheduleInfo.endMinute = 15;
+        mScheduleInfo.exitAtAlarm = true;
+        mScheduleInfo.nextAlarm = 1000; // very old alarm
+
+        mScheduleCalendar.setSchedule(mScheduleInfo);
+        assertTrue(mScheduleCalendar.isInSchedule(cal.getTimeInMillis()));
+
+        // don't exit for an alarm if it's an old alarm
+        assertFalse(mScheduleCalendar.shouldExitForAlarm(1000));
+    }
+
+    @Test
     public void testMaybeSetNextAlarm_settingOff() {
         mScheduleInfo.exitAtAlarm = false;
         mScheduleInfo.nextAlarm = 0;