Merge "Revert "Revert "Give transitioning fragment a context prior to retrieving transition"""
diff --git a/api/current.txt b/api/current.txt
index 851cf4d..e0dfb6c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5530,6 +5530,8 @@
     method public void enableCarMode(int);
     method public int getCurrentModeType();
     method public int getNightMode();
+    method public boolean isNightModeLocked();
+    method public boolean isUiModeLocked();
     method public void setNightMode(int);
     field public static java.lang.String ACTION_ENTER_CAR_MODE;
     field public static java.lang.String ACTION_ENTER_DESK_MODE;
@@ -8286,6 +8288,7 @@
     field public static final java.lang.String ACTION_INSERT_OR_EDIT = "android.intent.action.INSERT_OR_EDIT";
     field public static final java.lang.String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE";
     field public static final java.lang.String ACTION_LOCALE_CHANGED = "android.intent.action.LOCALE_CHANGED";
+    field public static final java.lang.String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED";
     field public static final java.lang.String ACTION_MAIN = "android.intent.action.MAIN";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_ADDED = "android.intent.action.MANAGED_PROFILE_ADDED";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_REMOVED = "android.intent.action.MANAGED_PROFILE_REMOVED";
@@ -28065,8 +28068,9 @@
     method public boolean isSystemUser();
     method public boolean isUserAGoat();
     method public boolean isUserRunning(android.os.UserHandle);
+    method public boolean isUserRunningAndLocked(android.os.UserHandle);
+    method public boolean isUserRunningAndUnlocked(android.os.UserHandle);
     method public boolean isUserRunningOrStopping(android.os.UserHandle);
-    method public boolean isUserRunningUnlocked(android.os.UserHandle);
     method public deprecated boolean setRestrictionsChallenge(java.lang.String);
     method public deprecated void setUserRestriction(java.lang.String, boolean);
     method public deprecated void setUserRestrictions(android.os.Bundle);
@@ -29632,6 +29636,7 @@
     ctor public ContactsContract.CommonDataKinds.Callable();
     field public static final android.net.Uri CONTENT_FILTER_URI;
     field public static final android.net.Uri CONTENT_URI;
+    field public static final android.net.Uri ENTERPRISE_CONTENT_FILTER_URI;
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
@@ -29778,6 +29783,7 @@
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/phone_v2";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/phone_v2";
     field public static final android.net.Uri CONTENT_URI;
+    field public static final android.net.Uri ENTERPRISE_CONTENT_FILTER_URI;
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
@@ -29957,7 +29963,7 @@
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String CONTENT_VCARD_TYPE = "text/x-vcard";
     field public static final android.net.Uri CONTENT_VCARD_URI;
-    field public static final android.net.Uri CORP_CONTENT_FILTER_URI;
+    field public static final android.net.Uri ENTERPRISE_CONTENT_FILTER_URI;
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
@@ -30086,10 +30092,12 @@
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact_directory";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/contact_directories";
     field public static final android.net.Uri CONTENT_URI;
-    field public static final android.net.Uri CORP_CONTENT_URI;
     field public static final long DEFAULT = 0L; // 0x0L
     field public static final java.lang.String DIRECTORY_AUTHORITY = "authority";
     field public static final java.lang.String DISPLAY_NAME = "displayName";
+    field public static final android.net.Uri ENTERPRISE_CONTENT_URI;
+    field public static final long ENTERPRISE_DEFAULT = 1000000000L; // 0x3b9aca00L
+    field public static final long ENTERPRISE_LOCAL_INVISIBLE = 1000000001L; // 0x3b9aca01L
     field public static final java.lang.String EXPORT_SUPPORT = "exportSupport";
     field public static final int EXPORT_SUPPORT_ANY_ACCOUNT = 2; // 0x2
     field public static final int EXPORT_SUPPORT_NONE = 0; // 0x0
@@ -30436,6 +30444,7 @@
     field public static final java.lang.String COLUMN_MIME_TYPE = "mime_type";
     field public static final java.lang.String COLUMN_SIZE = "_size";
     field public static final java.lang.String COLUMN_SUMMARY = "summary";
+    field public static final int FLAG_ARCHIVE = 2048; // 0x800
     field public static final int FLAG_DIR_PREFERS_GRID = 16; // 0x10
     field public static final int FLAG_DIR_PREFERS_LAST_MODIFIED = 32; // 0x20
     field public static final int FLAG_DIR_SUPPORTS_CREATE = 8; // 0x8
@@ -38648,10 +38657,11 @@
     field public static final int RTL = 1; // 0x1
   }
 
-  public final class LocaleList {
+  public final class LocaleList implements android.os.Parcelable {
     ctor public LocaleList();
     ctor public LocaleList(java.util.Locale);
     ctor public LocaleList(java.util.Locale[]);
+    method public int describeContents();
     method public static android.util.LocaleList forLanguageTags(java.lang.String);
     method public java.util.Locale get(int);
     method public java.util.Locale getBestMatch(java.lang.String[]);
@@ -38661,6 +38671,8 @@
     method public boolean isEmpty();
     method public int size();
     method public java.lang.String toLanguageTags();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.util.LocaleList> CREATOR;
   }
 
   public final class Log {
@@ -42944,6 +42956,7 @@
     field public int initialSelStart;
     field public int inputType;
     field public java.lang.CharSequence label;
+    field public android.util.LocaleList locales;
     field public java.lang.String packageName;
     field public java.lang.String privateImeOptions;
   }
@@ -64082,4 +64095,3 @@
   }
 
 }
-
diff --git a/api/system-current.txt b/api/system-current.txt
index 77a5c92..3baeeca 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -134,6 +134,7 @@
     field public static final java.lang.String MODIFY_AUDIO_ROUTING = "android.permission.MODIFY_AUDIO_ROUTING";
     field public static final java.lang.String MODIFY_AUDIO_SETTINGS = "android.permission.MODIFY_AUDIO_SETTINGS";
     field public static final java.lang.String MODIFY_CELL_BROADCASTS = "android.permission.MODIFY_CELL_BROADCASTS";
+    field public static final java.lang.String MODIFY_DAY_NIGHT_MODE = "android.permission.MODIFY_DAY_NIGHT_MODE";
     field public static final java.lang.String MODIFY_NETWORK_ACCOUNTING = "android.permission.MODIFY_NETWORK_ACCOUNTING";
     field public static final java.lang.String MODIFY_PARENTAL_CONTROLS = "android.permission.MODIFY_PARENTAL_CONTROLS";
     field public static final java.lang.String MODIFY_PHONE_STATE = "android.permission.MODIFY_PHONE_STATE";
@@ -5649,6 +5650,8 @@
     method public void enableCarMode(int);
     method public int getCurrentModeType();
     method public int getNightMode();
+    method public boolean isNightModeLocked();
+    method public boolean isUiModeLocked();
     method public void setNightMode(int);
     field public static java.lang.String ACTION_ENTER_CAR_MODE;
     field public static java.lang.String ACTION_ENTER_DESK_MODE;
@@ -8543,6 +8546,7 @@
     field public static final java.lang.String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE";
     field public static final java.lang.String ACTION_INTENT_FILTER_NEEDS_VERIFICATION = "android.intent.action.INTENT_FILTER_NEEDS_VERIFICATION";
     field public static final java.lang.String ACTION_LOCALE_CHANGED = "android.intent.action.LOCALE_CHANGED";
+    field public static final java.lang.String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED";
     field public static final java.lang.String ACTION_MAIN = "android.intent.action.MAIN";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_ADDED = "android.intent.action.MANAGED_PROFILE_ADDED";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_REMOVED = "android.intent.action.MANAGED_PROFILE_REMOVED";
@@ -30049,8 +30053,9 @@
     method public boolean isSystemUser();
     method public boolean isUserAGoat();
     method public boolean isUserRunning(android.os.UserHandle);
+    method public boolean isUserRunningAndLocked(android.os.UserHandle);
+    method public boolean isUserRunningAndUnlocked(android.os.UserHandle);
     method public boolean isUserRunningOrStopping(android.os.UserHandle);
-    method public boolean isUserRunningUnlocked(android.os.UserHandle);
     method public deprecated boolean setRestrictionsChallenge(java.lang.String);
     method public deprecated void setUserRestriction(java.lang.String, boolean);
     method public deprecated void setUserRestrictions(android.os.Bundle);
@@ -31616,6 +31621,7 @@
     ctor public ContactsContract.CommonDataKinds.Callable();
     field public static final android.net.Uri CONTENT_FILTER_URI;
     field public static final android.net.Uri CONTENT_URI;
+    field public static final android.net.Uri ENTERPRISE_CONTENT_FILTER_URI;
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
@@ -31762,6 +31768,7 @@
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/phone_v2";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/phone_v2";
     field public static final android.net.Uri CONTENT_URI;
+    field public static final android.net.Uri ENTERPRISE_CONTENT_FILTER_URI;
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
@@ -31941,7 +31948,7 @@
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String CONTENT_VCARD_TYPE = "text/x-vcard";
     field public static final android.net.Uri CONTENT_VCARD_URI;
-    field public static final android.net.Uri CORP_CONTENT_FILTER_URI;
+    field public static final android.net.Uri ENTERPRISE_CONTENT_FILTER_URI;
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
@@ -32070,10 +32077,12 @@
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact_directory";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/contact_directories";
     field public static final android.net.Uri CONTENT_URI;
-    field public static final android.net.Uri CORP_CONTENT_URI;
     field public static final long DEFAULT = 0L; // 0x0L
     field public static final java.lang.String DIRECTORY_AUTHORITY = "authority";
     field public static final java.lang.String DISPLAY_NAME = "displayName";
+    field public static final android.net.Uri ENTERPRISE_CONTENT_URI;
+    field public static final long ENTERPRISE_DEFAULT = 1000000000L; // 0x3b9aca00L
+    field public static final long ENTERPRISE_LOCAL_INVISIBLE = 1000000001L; // 0x3b9aca01L
     field public static final java.lang.String EXPORT_SUPPORT = "exportSupport";
     field public static final int EXPORT_SUPPORT_ANY_ACCOUNT = 2; // 0x2
     field public static final int EXPORT_SUPPORT_NONE = 0; // 0x0
@@ -32450,6 +32459,7 @@
     field public static final java.lang.String COLUMN_MIME_TYPE = "mime_type";
     field public static final java.lang.String COLUMN_SIZE = "_size";
     field public static final java.lang.String COLUMN_SUMMARY = "summary";
+    field public static final int FLAG_ARCHIVE = 2048; // 0x800
     field public static final int FLAG_DIR_PREFERS_GRID = 16; // 0x10
     field public static final int FLAG_DIR_PREFERS_LAST_MODIFIED = 32; // 0x20
     field public static final int FLAG_DIR_SUPPORTS_CREATE = 8; // 0x8
@@ -40973,10 +40983,11 @@
     field public static final int RTL = 1; // 0x1
   }
 
-  public final class LocaleList {
+  public final class LocaleList implements android.os.Parcelable {
     ctor public LocaleList();
     ctor public LocaleList(java.util.Locale);
     ctor public LocaleList(java.util.Locale[]);
+    method public int describeContents();
     method public static android.util.LocaleList forLanguageTags(java.lang.String);
     method public java.util.Locale get(int);
     method public java.util.Locale getBestMatch(java.lang.String[]);
@@ -40986,6 +40997,8 @@
     method public boolean isEmpty();
     method public int size();
     method public java.lang.String toLanguageTags();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.util.LocaleList> CREATOR;
   }
 
   public final class Log {
@@ -45272,6 +45285,7 @@
     field public int initialSelStart;
     field public int inputType;
     field public java.lang.CharSequence label;
+    field public android.util.LocaleList locales;
     field public java.lang.String packageName;
     field public java.lang.String privateImeOptions;
   }
diff --git a/api/test-current.txt b/api/test-current.txt
index af92704..1338d90 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5530,6 +5530,8 @@
     method public void enableCarMode(int);
     method public int getCurrentModeType();
     method public int getNightMode();
+    method public boolean isNightModeLocked();
+    method public boolean isUiModeLocked();
     method public void setNightMode(int);
     field public static java.lang.String ACTION_ENTER_CAR_MODE;
     field public static java.lang.String ACTION_ENTER_DESK_MODE;
@@ -8286,6 +8288,7 @@
     field public static final java.lang.String ACTION_INSERT_OR_EDIT = "android.intent.action.INSERT_OR_EDIT";
     field public static final java.lang.String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE";
     field public static final java.lang.String ACTION_LOCALE_CHANGED = "android.intent.action.LOCALE_CHANGED";
+    field public static final java.lang.String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED";
     field public static final java.lang.String ACTION_MAIN = "android.intent.action.MAIN";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_ADDED = "android.intent.action.MANAGED_PROFILE_ADDED";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_REMOVED = "android.intent.action.MANAGED_PROFILE_REMOVED";
@@ -28065,8 +28068,9 @@
     method public boolean isSystemUser();
     method public boolean isUserAGoat();
     method public boolean isUserRunning(android.os.UserHandle);
+    method public boolean isUserRunningAndLocked(android.os.UserHandle);
+    method public boolean isUserRunningAndUnlocked(android.os.UserHandle);
     method public boolean isUserRunningOrStopping(android.os.UserHandle);
-    method public boolean isUserRunningUnlocked(android.os.UserHandle);
     method public deprecated boolean setRestrictionsChallenge(java.lang.String);
     method public deprecated void setUserRestriction(java.lang.String, boolean);
     method public deprecated void setUserRestrictions(android.os.Bundle);
@@ -29634,6 +29638,7 @@
     ctor public ContactsContract.CommonDataKinds.Callable();
     field public static final android.net.Uri CONTENT_FILTER_URI;
     field public static final android.net.Uri CONTENT_URI;
+    field public static final android.net.Uri ENTERPRISE_CONTENT_FILTER_URI;
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
@@ -29780,6 +29785,7 @@
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/phone_v2";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/phone_v2";
     field public static final android.net.Uri CONTENT_URI;
+    field public static final android.net.Uri ENTERPRISE_CONTENT_FILTER_URI;
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
@@ -29959,7 +29965,7 @@
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String CONTENT_VCARD_TYPE = "text/x-vcard";
     field public static final android.net.Uri CONTENT_VCARD_URI;
-    field public static final android.net.Uri CORP_CONTENT_FILTER_URI;
+    field public static final android.net.Uri ENTERPRISE_CONTENT_FILTER_URI;
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
@@ -30088,10 +30094,12 @@
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact_directory";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/contact_directories";
     field public static final android.net.Uri CONTENT_URI;
-    field public static final android.net.Uri CORP_CONTENT_URI;
     field public static final long DEFAULT = 0L; // 0x0L
     field public static final java.lang.String DIRECTORY_AUTHORITY = "authority";
     field public static final java.lang.String DISPLAY_NAME = "displayName";
+    field public static final android.net.Uri ENTERPRISE_CONTENT_URI;
+    field public static final long ENTERPRISE_DEFAULT = 1000000000L; // 0x3b9aca00L
+    field public static final long ENTERPRISE_LOCAL_INVISIBLE = 1000000001L; // 0x3b9aca01L
     field public static final java.lang.String EXPORT_SUPPORT = "exportSupport";
     field public static final int EXPORT_SUPPORT_ANY_ACCOUNT = 2; // 0x2
     field public static final int EXPORT_SUPPORT_NONE = 0; // 0x0
@@ -30438,6 +30446,7 @@
     field public static final java.lang.String COLUMN_MIME_TYPE = "mime_type";
     field public static final java.lang.String COLUMN_SIZE = "_size";
     field public static final java.lang.String COLUMN_SUMMARY = "summary";
+    field public static final int FLAG_ARCHIVE = 2048; // 0x800
     field public static final int FLAG_DIR_PREFERS_GRID = 16; // 0x10
     field public static final int FLAG_DIR_PREFERS_LAST_MODIFIED = 32; // 0x20
     field public static final int FLAG_DIR_SUPPORTS_CREATE = 8; // 0x8
@@ -38650,10 +38659,11 @@
     field public static final int RTL = 1; // 0x1
   }
 
-  public final class LocaleList {
+  public final class LocaleList implements android.os.Parcelable {
     ctor public LocaleList();
     ctor public LocaleList(java.util.Locale);
     ctor public LocaleList(java.util.Locale[]);
+    method public int describeContents();
     method public static android.util.LocaleList forLanguageTags(java.lang.String);
     method public java.util.Locale get(int);
     method public java.util.Locale getBestMatch(java.lang.String[]);
@@ -38663,6 +38673,8 @@
     method public boolean isEmpty();
     method public int size();
     method public java.lang.String toLanguageTags();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.util.LocaleList> CREATOR;
   }
 
   public final class Log {
@@ -42946,6 +42958,7 @@
     field public int initialSelStart;
     field public int inputType;
     field public java.lang.CharSequence label;
+    field public android.util.LocaleList locales;
     field public java.lang.String packageName;
     field public java.lang.String privateImeOptions;
   }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 798deb1..52fcbf7 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2113,7 +2113,9 @@
         public int[] taskIds;
         public String[] taskNames;
         public Rect[] taskBounds;
+        public int[] taskUserIds;
         public int displayId;
+        public int userId;
 
         @Override
         public int describeContents() {
@@ -2137,7 +2139,9 @@
                 dest.writeInt(taskBounds[i].right);
                 dest.writeInt(taskBounds[i].bottom);
             }
+            dest.writeIntArray(taskUserIds);
             dest.writeInt(displayId);
+            dest.writeInt(userId);
         }
 
         public void readFromParcel(Parcel source) {
@@ -2157,7 +2161,9 @@
             } else {
                 taskBounds = null;
             }
+            taskUserIds = source.createIntArray();
             displayId = source.readInt();
+            userId = source.readInt();
         }
 
         public static final Creator<StackInfo> CREATOR = new Creator<StackInfo>() {
@@ -2183,6 +2189,7 @@
             sb.append(prefix); sb.append("Stack id="); sb.append(stackId);
                     sb.append(" bounds="); sb.append(bounds.toShortString());
                     sb.append(" displayId="); sb.append(displayId);
+                    sb.append(" userId="); sb.append(userId);
                     sb.append("\n");
             prefix = prefix + "  ";
             for (int i = 0; i < taskIds.length; ++i) {
@@ -2191,6 +2198,7 @@
                         if (taskBounds != null) {
                             sb.append(" bounds="); sb.append(taskBounds[i].toShortString());
                         }
+                        sb.append(" userId=").append(taskUserIds[i]);
                         sb.append("\n");
             }
             return sb.toString();
@@ -3108,9 +3116,29 @@
      * @param userid the user's id. Zero indicates the default user.
      * @hide
      */
-    public boolean isUserRunning(int userid) {
+    public boolean isUserRunning(int userId) {
         try {
-            return ActivityManagerNative.getDefault().isUserRunning(userid, 0);
+            return ActivityManagerNative.getDefault().isUserRunning(userId, 0);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /** {@hide} */
+    public boolean isUserRunningAndLocked(int userId) {
+        try {
+            return ActivityManagerNative.getDefault().isUserRunning(userId,
+                    ActivityManager.FLAG_AND_LOCKED);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /** {@hide} */
+    public boolean isUserRunningAndUnlocked(int userId) {
+        try {
+            return ActivityManagerNative.getDefault().isUserRunning(userId,
+                    ActivityManager.FLAG_AND_UNLOCKED);
         } catch (RemoteException e) {
             return false;
         }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 74f0c0e..c264368 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4841,7 +4841,7 @@
         if (ii != null) {
             final ApplicationInfo instrApp = new ApplicationInfo();
             ii.copyTo(instrApp);
-
+            instrApp.initForUser(UserHandle.myUserId());
             final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                     appContext.getClassLoader(), false, true, false);
             final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
diff --git a/core/java/android/app/IUiModeManager.aidl b/core/java/android/app/IUiModeManager.aidl
index 7e9873e..cae54b6 100644
--- a/core/java/android/app/IUiModeManager.aidl
+++ b/core/java/android/app/IUiModeManager.aidl
@@ -51,4 +51,14 @@
      * 2 for night, and 3 for automatic mode switching.
      */
     int getNightMode();
+
+    /**
+     * Tells if UI mode is locked or not.
+     */
+    boolean isUiModeLocked();
+
+    /**
+     * Tells if Night mode is locked or not.
+     */
+    boolean isNightModeLocked();
 }
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
index 0f6ce12..4416415 100644
--- a/core/java/android/app/UiModeManager.java
+++ b/core/java/android/app/UiModeManager.java
@@ -233,4 +233,35 @@
         }
         return -1;
     }
+
+    /**
+     * @return If UI mode is locked or not. When UI mode is locked, calls to change UI mode
+     *         like {@link #enableCarMode(int)} will silently fail.
+     */
+    public boolean isUiModeLocked() {
+        if (mService != null) {
+            try {
+                return mService.isUiModeLocked();
+            } catch (RemoteException e) {
+                Log.e(TAG, "isUiModeLocked: RemoteException", e);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * @return If Night mode is locked or not. When Night mode is locked, changing Night mode
+     *         is only allowed to privileged system components and normal application's call
+     *         to change Night mode using {@link #setNightMode(int)} will silently fail.
+     */
+    public boolean isNightModeLocked() {
+        if (mService != null) {
+            try {
+                return mService.isNightModeLocked();
+            } catch (RemoteException e) {
+                Log.e(TAG, "isNightModeLocked: RemoteException", e);
+            }
+        }
+        return true;
+    }
 }
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 2d825fa..3e8a51e 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -74,6 +74,8 @@
  * {@link #listenUsingRfcommWithServiceRecord(String,UUID)}; or start a scan for
  * Bluetooth LE devices with {@link #startLeScan(LeScanCallback callback)}.
  *
+ * <p>This class is thread safe.
+ *
  * <p class="note"><strong>Note:</strong>
  * Most methods require the {@link android.Manifest.permission#BLUETOOTH}
  * permission and some also require the
@@ -82,7 +84,7 @@
  * <div class="special reference">
  * <h3>Developer Guides</h3>
  * <p>For more information about using Bluetooth, read the
- * <a href="{@docRoot}guide/topics/wireless/bluetooth.html">Bluetooth</a> developer guide.</p>
+ * <a href="{@docRoot}guide/topics/wireless/bluetooth.html">Bluetooth</a> developer guide.
  * </div>
  *
  * {@see BluetoothDevice}
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index d27dfa0..cd5c205 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -25,6 +25,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.ParcelUuid;
+import android.os.Process;
 import android.os.RemoteException;
 import android.util.Log;
 
@@ -823,6 +824,9 @@
             return false;
         }
         try {
+            Log.i(TAG, "createBond() for device " + getAddress() +
+                    " called by pid: " + Process.myPid() +
+                    " tid: " + Process.myTid());
             return sService.createBond(this, TRANSPORT_AUTO);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
@@ -854,6 +858,9 @@
             throw new IllegalArgumentException(transport + " is not a valid Bluetooth transport");
         }
         try {
+            Log.i(TAG, "createBond() for device " + getAddress() +
+                    " called by pid: " + Process.myPid() +
+                    " tid: " + Process.myTid());
             return sService.createBond(this, transport);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
@@ -922,6 +929,9 @@
             return false;
         }
         try {
+            Log.i(TAG, "cancelBondProcess() for device " + getAddress() +
+                    " called by pid: " + Process.myPid() +
+                    " tid: " + Process.myTid());
             return sService.cancelBondProcess(this);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
@@ -943,6 +953,9 @@
             return false;
         }
         try {
+            Log.i(TAG, "removeBond() for device " + getAddress() +
+                    " called by pid: " + Process.myPid() +
+                    " tid: " + Process.myTid());
             return sService.removeBond(this);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 2178c38..b65d825 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1926,6 +1926,24 @@
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_ALARM_CHANGED = "android.intent.action.ALARM_CHANGED";
+
+    /**
+     * Broadcast Action: This is broadcast once, after the system has finished
+     * booting and the user is in a "locked" state. A user is locked when their
+     * credential-encrypted private app data storage is unavailable. Once the
+     * user has entered their credentials (such as a lock pattern or PIN) for
+     * the first time, the {@link #ACTION_BOOT_COMPLETED} broadcast will be
+     * sent.
+     * <p>
+     * You must hold the
+     * {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED} permission in
+     * order to receive this broadcast.
+     * <p class="note">
+     * This is a protected intent that can only be sent by the system.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED";
+
     /**
      * Broadcast Action: This is broadcast once, after the system has finished
      * booting.  It can be used to perform application-specific initialization,
@@ -1938,6 +1956,7 @@
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
+
     /**
      * Broadcast Action: This is broadcast when a user action should request a
      * temporary system dialog to dismiss.  Some examples of temporary system
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index aa960a4..abd4c28 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -259,6 +259,14 @@
      */
     public static final int SKIP_CURRENT_PROFILE = 0x00000002;
 
+    /**
+     * Flag for {@link addCrossProfileIntentFilter}: if this flag is set:
+     * activities in the other profiles can respond to the intent only if no activity with
+     * non-negative priority in current profile can respond to the intent.
+     * @hide
+     */
+    public static final int ONLY_IF_NO_MATCH_FOUND = 0x00000004;
+
     /** @hide */
     @IntDef({PERMISSION_GRANTED, PERMISSION_DENIED})
     @Retention(RetentionPolicy.SOURCE)
@@ -4636,7 +4644,8 @@
      * @param filter The {@link IntentFilter} the intent has to match
      * @param sourceUserId The source user id.
      * @param targetUserId The target user id.
-     * @param flags The only possible value is {@link SKIP_CURRENT_PROFILE}
+     * @param flags The possible values are {@link SKIP_CURRENT_PROFILE} and
+     *        {@link ONLY_IF_NO_MATCH_FOUND}.
      * @hide
      */
     public abstract void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId,
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index b3f03c3..a413f36 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -294,14 +294,16 @@
      */
     public static class ServiceInfo<V> {
         public final V type;
+        public final ComponentInfo componentInfo;
         public final ComponentName componentName;
         public final int uid;
 
         /** @hide */
-        public ServiceInfo(V type, ComponentName componentName, int uid) {
+        public ServiceInfo(V type, ComponentInfo componentInfo, ComponentName componentName) {
             this.type = type;
+            this.componentInfo = componentInfo;
             this.componentName = componentName;
-            this.uid = uid;
+            this.uid = (componentInfo != null) ? componentInfo.applicationInfo.uid : -1;
         }
 
         @Override
@@ -362,8 +364,9 @@
     @VisibleForTesting
     protected List<ResolveInfo> queryIntentServices(int userId) {
         final PackageManager pm = mContext.getPackageManager();
-        return pm.queryIntentServicesAsUser(
-                new Intent(mInterfaceName), PackageManager.GET_META_DATA, userId);
+        return pm.queryIntentServicesAsUser(new Intent(mInterfaceName),
+                PackageManager.GET_META_DATA | PackageManager.GET_ENCRYPTION_UNAWARE_COMPONENTS,
+                userId);
     }
 
     /**
@@ -563,9 +566,7 @@
                 return null;
             }
             final android.content.pm.ServiceInfo serviceInfo = service.serviceInfo;
-            final ApplicationInfo applicationInfo = serviceInfo.applicationInfo;
-            final int uid = applicationInfo.uid;
-            return new ServiceInfo<V>(v, componentName, uid);
+            return new ServiceInfo<V>(v, serviceInfo, componentName);
         } catch (NameNotFoundException e) {
             throw new XmlPullParserException(
                     "Unable to load resources for pacakge " + si.packageName);
diff --git a/core/java/android/net/LocalSocket.java b/core/java/android/net/LocalSocket.java
index a374a86..e14facb1 100644
--- a/core/java/android/net/LocalSocket.java
+++ b/core/java/android/net/LocalSocket.java
@@ -25,7 +25,8 @@
 
 /**
  * Creates a (non-server) socket in the UNIX-domain namespace. The interface
- * here is not entirely unlike that of java.net.Socket
+ * here is not entirely unlike that of java.net.Socket. This class and the streams
+ * returned from it may be used from multiple threads.
  */
 public class LocalSocket implements Closeable {
 
diff --git a/core/java/android/net/http/HttpResponseCache.java b/core/java/android/net/http/HttpResponseCache.java
index 188287f..729aff0 100644
--- a/core/java/android/net/http/HttpResponseCache.java
+++ b/core/java/android/net/http/HttpResponseCache.java
@@ -36,7 +36,8 @@
  * saving time and bandwidth. This class supports {@link
  * java.net.HttpURLConnection} and {@link javax.net.ssl.HttpsURLConnection};
  * there is no platform-provided cache for {@code DefaultHttpClient} or
- * {@code AndroidHttpClient}.
+ * {@code AndroidHttpClient}. Installation and instances are thread
+ * safe.
  *
  * <h3>Installing an HTTP response cache</h3>
  * Enable caching of all of your application's HTTP requests by installing the
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 79390d4..c2fc5e4 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -755,6 +755,23 @@
     }
 
     /**
+     * Return whether the given user is running in a "locked" state. A user
+     * is unlocked only after they've entered their credentials (such as a lock
+     * pattern or PIN), and credential-encrypted private app data storage is
+     * available.
+     *
+     * @param user to retrieve the unlocked state for.
+     */
+    public boolean isUserRunningAndLocked(UserHandle user) {
+        try {
+            return ActivityManagerNative.getDefault().isUserRunning(
+                    user.getIdentifier(), ActivityManager.FLAG_AND_LOCKED);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
      * Return whether the given user is running in an "unlocked" state. A user
      * is unlocked only after they've entered their credentials (such as a lock
      * pattern or PIN), and credential-encrypted private app data storage is
@@ -762,7 +779,7 @@
      *
      * @param user to retrieve the unlocked state for.
      */
-    public boolean isUserRunningUnlocked(UserHandle user) {
+    public boolean isUserRunningAndUnlocked(UserHandle user) {
         try {
             return ActivityManagerNative.getDefault().isUserRunning(
                     user.getIdentifier(), ActivityManager.FLAG_AND_UNLOCKED);
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 94a2bea..c0d95a1 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -394,12 +394,19 @@
                 Uri.withAppendedPath(AUTHORITY_URI, "directories");
 
         /**
-         * The content:// style URI for enterprise Directory table. Requests to this URI can be
-         * performed on the UI thread because they are always unblocking.
+         * URI used for getting all directories from primary and managed profile.
+         * It supports the same semantics as {@link #CONTENT_URI} and returns the same columns.
+         * If the device has no managed profile that is linked to the current profile, it behaves
+         * in the exact same way as {@link #CONTENT_URI}.
+         * If there is a managed profile linked to the current profile, it will merge
+         * managed profile and current profile's results and return.
+         *
+         * Note: this query returns primary profile results before managed profile results,
+         * and this order is not affected by sorting parameter.
          *
          */
-        public static final Uri CORP_CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI,
-                "directories_corp");
+        public static final Uri ENTERPRISE_CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI,
+                "directories_enterprise");
 
         /**
          * The MIME-type of {@link #CONTENT_URI} providing a directory of
@@ -426,16 +433,12 @@
 
         /**
          * _ID of the work profile default directory, which represents locally stored contacts.
-         *
-         * @hide
          */
         public static final long ENTERPRISE_DEFAULT = Directory.ENTERPRISE_DIRECTORY_ID_BASE
                 + DEFAULT;
 
         /**
          * _ID of the work profile directory that represents locally stored invisible contacts.
-         *
-         * @hide
          */
         public static final long ENTERPRISE_LOCAL_INVISIBLE = Directory.ENTERPRISE_DIRECTORY_ID_BASE
                 + LOCAL_INVISIBLE;
@@ -1640,12 +1643,12 @@
                 CONTENT_URI, "filter");
 
         /**
-         * It supports the same semantics as {@link #CONTENT_FILTER_URI} and returns the same
-         * columns. If there is a corp profile linked to the current profile, it will query corp
-         * profile, otherwise it will return null.
+         * It supports the similar semantics as {@link #CONTENT_FILTER_URI} and returns the same
+         * columns. This URI requires {@link ContactsContract#DIRECTORY_PARAM_KEY} in parameters,
+         * otherwise it will throw UnsupportedOperationException.
          */
-        public static final Uri CORP_CONTENT_FILTER_URI = Uri.withAppendedPath(
-                CORP_CONTENT_URI, "filter");
+        public static final Uri ENTERPRISE_CONTENT_FILTER_URI = Uri.withAppendedPath(
+                CONTENT_URI, "filter_enterprise");
 
         /**
          * The content:// style URI for this table joined with useful data from
@@ -5915,6 +5918,14 @@
                     "filter");
 
             /**
+             * It supports the similar semantics as {@link #CONTENT_FILTER_URI} and returns the same
+             * columns. This URI requires {@link ContactsContract#DIRECTORY_PARAM_KEY} in
+             * parameters, otherwise it will throw UnsupportedOperationException.
+             */
+            public static final Uri ENTERPRISE_CONTENT_FILTER_URI = Uri.withAppendedPath(
+                    CONTENT_URI, "filter_enterprise");
+
+            /**
              * A boolean query parameter that can be used with {@link #CONTENT_FILTER_URI}.
              * If "1" or "true", display names are searched.  If "0" or "false", display names
              * are not searched.  Default is "1".
@@ -7395,6 +7406,14 @@
              */
             public static final Uri CONTENT_FILTER_URI = Uri.withAppendedPath(CONTENT_URI,
                     "filter");
+
+            /**
+             * Similar to {@link Phone#ENTERPRISE_CONTENT_FILTER_URI}, but allows users to filter
+             * callable data. This URI requires {@link ContactsContract#DIRECTORY_PARAM_KEY} in
+             * parameters, otherwise it will throw UnsupportedOperationException.
+             */
+            public static final Uri ENTERPRISE_CONTENT_FILTER_URI = Uri.withAppendedPath(
+                    CONTENT_URI, "filter_enterprise");
         }
 
         /**
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index d53bb0d..77a4485 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -234,6 +234,7 @@
          * @see #FLAG_DIR_PREFERS_GRID
          * @see #FLAG_DIR_PREFERS_LAST_MODIFIED
          * @see #FLAG_VIRTUAL_DOCUMENT
+         * @see #FLAG_ARCHIVE
          */
         public static final String COLUMN_FLAGS = "flags";
 
@@ -368,6 +369,18 @@
         public static final int FLAG_VIRTUAL_DOCUMENT = 1 << 10;
 
         /**
+         * Flag indicating that a document is an archive, and it's contents can be
+         * obtained via {@link DocumentsProvider#queryChildDocuments}.
+         * <p>
+         * The <em>provider</em> support library offers utility classes to add common
+         * archive support.
+         *
+         * @see #COLUMN_FLAGS
+         * @see DocumentsProvider#queryChildDocuments(String, String[], String)
+         */
+        public static final int FLAG_ARCHIVE = 1 << 11;
+
+        /**
          * Flag indicating that document titles should be hidden when viewing
          * this directory in a larger format grid. For example, a directory
          * containing only images may want the image thumbnails to speak for
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c92382a..fa1bf76 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4931,6 +4931,15 @@
                 "accessibility_autoclick_delay";
 
         /**
+         * Whether or not larger size icons are used for the pointer of mouse/trackpad for
+         * accessibility.
+         * (0 = false, 1 = true)
+         * @hide
+         */
+        public static final String ACCESSIBILITY_LARGE_POINTER_ICON =
+                "accessibility_large_pointer_icon";
+
+        /**
          * The timeout for considering a press to be a long press in milliseconds.
          * @hide
          */
diff --git a/core/java/android/util/EventLog.java b/core/java/android/util/EventLog.java
index 558b8f5..6bda83d2 100644
--- a/core/java/android/util/EventLog.java
+++ b/core/java/android/util/EventLog.java
@@ -52,7 +52,7 @@
     private static HashMap<String, Integer> sTagCodes = null;
     private static HashMap<Integer, String> sTagNames = null;
 
-    /** A previously logged event read from the logs. */
+    /** A previously logged event read from the logs. Instances are thread safe. */
     public static final class Event {
         private final ByteBuffer mBuffer;
 
diff --git a/core/java/android/util/LocaleList.aidl b/core/java/android/util/LocaleList.aidl
new file mode 100644
index 0000000..f5de354
--- /dev/null
+++ b/core/java/android/util/LocaleList.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+parcelable LocaleList;
diff --git a/core/java/android/util/LocaleList.java b/core/java/android/util/LocaleList.java
index c1d23bb..b2ee045 100644
--- a/core/java/android/util/LocaleList.java
+++ b/core/java/android/util/LocaleList.java
@@ -19,6 +19,8 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.Size;
+import android.os.Parcel;
+import android.os.Parcelable;
 
 import com.android.internal.annotations.GuardedBy;
 
@@ -35,11 +37,12 @@
  * LocaleList is an immutable list of Locales, typically used to keep an
  * ordered user preferences for locales.
  */
-public final class LocaleList {
+public final class LocaleList implements Parcelable {
     private final Locale[] mList;
     // This is a comma-separated list of the locales in the LocaleList created at construction time,
     // basically the result of running each locale's toLanguageTag() method and concatenating them
     // with commas in between.
+    @NonNull
     private final String mStringRepresentation;
 
     private static final Locale[] sEmptyList = new Locale[0];
@@ -101,6 +104,16 @@
         return sb.toString();
     }
 
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int parcelableFlags) {
+        dest.writeString(mStringRepresentation);
+    }
+
     @NonNull
     public String toLanguageTags() {
         return mStringRepresentation;
@@ -163,10 +176,25 @@
         }
     }
 
+    public static final Parcelable.Creator<LocaleList> CREATOR
+            = new Parcelable.Creator<LocaleList>() {
+        @Override
+        public LocaleList createFromParcel(Parcel source) {
+            return LocaleList.forLanguageTags(source.readString());
+        }
+
+        @Override
+        public LocaleList[] newArray(int size) {
+            return new LocaleList[size];
+        }
+    };
+
+    @NonNull
     public static LocaleList getEmptyLocaleList() {
         return sEmptyLocaleList;
     }
 
+    @NonNull
     public static LocaleList forLanguageTags(@Nullable String list) {
         if (list == null || list.equals("")) {
             return getEmptyLocaleList();
diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java
index b61706e..d2a7d4a 100644
--- a/core/java/android/view/PointerIcon.java
+++ b/core/java/android/view/PointerIcon.java
@@ -16,6 +16,8 @@
 
 package android.view;
 
+import android.os.UserHandle;
+import android.provider.Settings;
 import com.android.internal.util.XmlUtils;
 
 import android.annotation.XmlRes;
@@ -199,9 +201,14 @@
             styleIndex = getSystemIconStyleIndex(STYLE_DEFAULT);
         }
 
+        int accessibilityConfig = Settings.Secure.getIntForUser(
+                    context.getContentResolver(), Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON,
+                    0, UserHandle.USER_CURRENT);
+        int defStyle = (accessibilityConfig == 1) ?
+                com.android.internal.R.style.LargePointer : com.android.internal.R.style.Pointer;
         TypedArray a = context.obtainStyledAttributes(null,
                 com.android.internal.R.styleable.Pointer,
-                com.android.internal.R.attr.pointerStyle, 0);
+                0, defStyle);
         int resourceId = a.getResourceId(styleIndex, -1);
         a.recycle();
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3669d97..fc347ea 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3057,14 +3057,29 @@
     /**
      * @hide
      *
-     * Makes system ui transparent.
+     * Makes navigation bar transparent (but not the status bar).
      */
-    public static final int SYSTEM_UI_TRANSPARENT = 0x00008000;
+    public static final int NAVIGATION_BAR_TRANSPARENT = 0x00008000;
+
+    /**
+     * @hide
+     *
+     * Makes status bar transparent (but not the navigation bar).
+     */
+    public static final int STATUS_BAR_TRANSPARENT = 0x0000008;
+
+    /**
+     * @hide
+     *
+     * Makes both status bar and navigation bar transparent.
+     */
+    public static final int SYSTEM_UI_TRANSPARENT = NAVIGATION_BAR_TRANSPARENT
+            | STATUS_BAR_TRANSPARENT;
 
     /**
      * @hide
      */
-    public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x00003FFF;
+    public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x00003FF7;
 
     /**
      * These are the system UI flags that can be cleared by events outside
@@ -5505,20 +5520,26 @@
     }
 
     /**
-     * Bring up the context menu for this view.
+     * Shows the context menu for this view.
      *
-     * @return Whether a context menu was displayed.
+     * @return {@code true} if the context menu was shown, {@code false}
+     *         otherwise
+     * @see #showContextMenu(float, float)
      */
     public boolean showContextMenu() {
         return getParent().showContextMenuForChild(this);
     }
 
     /**
-     * Bring up the context menu for this view, referring to the item under the specified point.
+     * Shows the context menu for this view anchored to the specified
+     * view-relative coordinate.
      *
-     * @param x The referenced x coordinate.
-     * @param y The referenced y coordinate.
-     * @return Whether a context menu was displayed.
+     * @param x the X coordinate in pixels relative to the view to which the
+     *          menu should be anchored
+     * @param y the Y coordinate in pixels relative to the view to which the
+     *          menu should be anchored
+     * @return {@code true} if the context menu was shown, {@code false}
+     *         otherwise
      */
     public boolean showContextMenu(float x, float y) {
         return getParent().showContextMenuForChild(this, x, y);
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index 6ae448a..f2ab35e 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -174,26 +174,38 @@
     public void focusableViewAvailable(View v);
 
     /**
-     * Bring up a context menu for the specified view or its ancestors.
-     *
-     * <p>In most cases, a subclass does not need to override this.  However, if
+     * Shows the context menu for the specified view or its ancestors.
+     * <p>
+     * In most cases, a subclass does not need to override this. However, if
      * the subclass is added directly to the window manager (for example,
      * {@link ViewManager#addView(View, android.view.ViewGroup.LayoutParams)})
-     * then it should override this and show the context menu.</p>
-     * 
-     * @param originalView The source view where the context menu was first invoked
-     * @return true if a context menu was displayed
+     * then it should override this and show the context menu.
+     *
+     * @param originalView the source view where the context menu was first
+     *                     invoked
+     * @return {@code true} if the context menu was shown, {@code false}
+     *         otherwise
+     * @see #showContextMenuForChild(View, float, float)
      */
     public boolean showContextMenuForChild(View originalView);
 
     /**
-     * Bring up a context menu for the specified view at the given x/y offset from
-     * the top left corner.
+     * Shows the context menu for the specified view or its ancestors anchored
+     * to the specified view-relative coordinate.
+     * <p>
+     * In most cases, a subclass does not need to override this. However, if
+     * the subclass is added directly to the window manager (for example,
+     * {@link ViewManager#addView(View, android.view.ViewGroup.LayoutParams)})
+     * then it should override this and show the context menu.
      *
-     * @param originalView
-     * @param x The x offset at which to open the menu
-     * @param y The y offset at which to open the menu
-     * @return true if a context menu was displayed
+     * @param originalView the source view where the context menu was first
+     *                     invoked
+     * @param x the X coordinate in pixels relative to the original view to
+     *          which the menu should be anchored
+     * @param y the Y coordinate in pixels relative to the original view to
+     *          which the menu should be anchored
+     * @return {@code true} if the context menu was shown, {@code false}
+     *         otherwise
      */
     public boolean showContextMenuForChild(View originalView, float x, float y);
 
diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java
index 6130fd5..3ff9522 100644
--- a/core/java/android/view/inputmethod/EditorInfo.java
+++ b/core/java/android/view/inputmethod/EditorInfo.java
@@ -21,6 +21,7 @@
 import android.os.Parcelable;
 import android.text.InputType;
 import android.text.TextUtils;
+import android.util.LocaleList;
 import android.util.Printer;
 
 /**
@@ -340,6 +341,22 @@
     public Bundle extras;
 
     /**
+     * Additional context information that tells what languages are expected by the user.
+     *
+     * <p><strong>IME authors:</strong> Possible use cases for IME developers would be:</p>
+     * <ul>
+     *     <li>Automatically switching keyboard layout.</li>
+     *     <li>Changing language model for better typing experience.</li>
+     * </ul>
+     *
+     * <p><strong>Editor authors:</strong> Providing this context information can help IMEs to
+     * improve text input experience.  For example, chat applications can remember what language is
+     * used in the last conversation for each chat session, and put the last used language at the
+     * top of {@link #locales}.</p>
+     */
+    public LocaleList locales = LocaleList.getEmptyLocaleList();
+
+    /**
      * Ensure that the data in this EditorInfo is compatible with an application
      * that was developed against the given target API version.  This can
      * impact the following input types:
@@ -393,6 +410,7 @@
                 + " fieldId=" + fieldId
                 + " fieldName=" + fieldName);
         pw.println(prefix + "extras=" + extras);
+        pw.println(prefix + "locales=" + locales);
     }
 
     /**
@@ -416,6 +434,7 @@
         dest.writeInt(fieldId);
         dest.writeString(fieldName);
         dest.writeBundle(extras);
+        locales.writeToParcel(dest, flags);
     }
 
     /**
@@ -439,6 +458,7 @@
                     res.fieldId = source.readInt();
                     res.fieldName = source.readString();
                     res.extras = source.readBundle();
+                    res.locales = LocaleList.CREATOR.createFromParcel(source);
                     return res;
                 }
 
diff --git a/core/java/android/widget/ActionMenuPresenter.java b/core/java/android/widget/ActionMenuPresenter.java
index 41f1ce7..0032f17 100644
--- a/core/java/android/widget/ActionMenuPresenter.java
+++ b/core/java/android/widget/ActionMenuPresenter.java
@@ -933,7 +933,7 @@
             super(context, menu, anchorView, overflowOnly,
                     com.android.internal.R.attr.actionOverflowMenuStyle);
             setGravity(Gravity.END);
-            setCallback(mPopupPresenterCallback);
+            setPresenterCallback(mPopupPresenterCallback);
         }
 
         @Override
@@ -956,7 +956,7 @@
                 setAnchorView(mOverflowButton == null ? (View) mMenuView : mOverflowButton);
             }
 
-            setCallback(mPopupPresenterCallback);
+            setPresenterCallback(mPopupPresenterCallback);
         }
 
         @Override
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index d666939..cca84ee 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6439,6 +6439,9 @@
                 outAttrs.initialCapsMode = ic.getCursorCapsMode(getInputType());
                 return ic;
             }
+            // LocaleList is designed to be immutable.  This is theoretically equivalent to copy
+            // the snapshot of the current text locales.
+            outAttrs.locales = getTextLocales();
         }
         return null;
     }
diff --git a/core/java/com/android/internal/policy/BackdropFrameRenderer.java b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
index b101733..75ca639 100644
--- a/core/java/com/android/internal/policy/BackdropFrameRenderer.java
+++ b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
@@ -17,6 +17,7 @@
 package com.android.internal.policy;
 
 import android.graphics.Rect;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Looper;
 import android.view.Choreographer;
@@ -44,6 +45,7 @@
     // The render nodes for the multi threaded renderer.
     private ThreadedRenderer mRenderer;
     private RenderNode mFrameAndBackdropNode;
+    private RenderNode mSystemBarBackgroundNode;
 
     private final Rect mOldTargetRect = new Rect();
     private final Rect mNewTargetRect = new Rect();
@@ -62,13 +64,16 @@
 
     private Drawable mCaptionBackgroundDrawable;
     private Drawable mResizingBackgroundDrawable;
+    private ColorDrawable mStatusBarColor;
 
     public BackdropFrameRenderer(DecorView decorView, ThreadedRenderer renderer, Rect initialBounds,
-            Drawable resizingBackgroundDrawable, Drawable captionBackgroundDrawable) {
+            Drawable resizingBackgroundDrawable, Drawable captionBackgroundDrawable,
+            int statusBarColor) {
         setName("ResizeFrame");
 
         mRenderer = renderer;
-        onResourcesLoaded(decorView, resizingBackgroundDrawable, captionBackgroundDrawable);
+        onResourcesLoaded(decorView, resizingBackgroundDrawable, captionBackgroundDrawable,
+                statusBarColor);
 
         // Create a render node for the content and frame backdrop
         // which can be resized independently from the content.
@@ -87,10 +92,24 @@
     }
 
     void onResourcesLoaded(DecorView decorView, Drawable resizingBackgroundDrawable,
-            Drawable captionBackgroundDrawableDrawable) {
+            Drawable captionBackgroundDrawableDrawable, int statusBarColor) {
         mDecorView = decorView;
         mResizingBackgroundDrawable = resizingBackgroundDrawable;
         mCaptionBackgroundDrawable = captionBackgroundDrawableDrawable;
+        if (statusBarColor != 0) {
+            mStatusBarColor = new ColorDrawable(statusBarColor);
+            addSystemBarNodeIfNeeded();
+        } else {
+            mStatusBarColor = null;
+        }
+    }
+
+    private void addSystemBarNodeIfNeeded() {
+        if (mSystemBarBackgroundNode != null) {
+            return;
+        }
+        mSystemBarBackgroundNode = RenderNode.create("SystemBarBackgroundNode", null);
+        mRenderer.addRenderNode(mSystemBarBackgroundNode, false);
     }
 
     /**
@@ -132,6 +151,9 @@
                 // Remove the render node again
                 // (see comment above - better to do that only once).
                 mRenderer.removeRenderNode(mFrameAndBackdropNode);
+                if (mSystemBarBackgroundNode != null) {
+                    mRenderer.removeRenderNode(mSystemBarBackgroundNode);
+                }
 
                 mRenderer = null;
 
@@ -232,6 +254,8 @@
         // inaccessible. For that case we remember the previous metrics to avoid flashes.
         // Note that even when there is no visible caption, the caption child will exist.
         final int captionHeight = mDecorView.getCaptionHeight();
+        final int statusBarHeight = mDecorView.getStatusBarHeight();
+
         // The caption height will probably never dynamically change while we are resizing.
         // Once set to something other then 0 it should be kept that way.
         if (captionHeight != 0) {
@@ -256,7 +280,7 @@
         mFrameAndBackdropNode.setLeftTopRightBottom(left, top, left + width, top + height);
 
         // Draw the caption and content backdrops in to our render node.
-        final DisplayListCanvas canvas = mFrameAndBackdropNode.start(width, height);
+        DisplayListCanvas canvas = mFrameAndBackdropNode.start(width, height);
         mCaptionBackgroundDrawable.setBounds(0, 0, left + width, top + mLastCaptionHeight);
         mCaptionBackgroundDrawable.draw(canvas);
 
@@ -265,6 +289,15 @@
         mResizingBackgroundDrawable.draw(canvas);
         mFrameAndBackdropNode.end(canvas);
 
+        if (mSystemBarBackgroundNode != null && mStatusBarColor != null) {
+            canvas = mSystemBarBackgroundNode.start(width, height);
+            mSystemBarBackgroundNode.setLeftTopRightBottom(left, top, left + width, top + height);
+            mStatusBarColor.setBounds(0, 0, left + width, statusBarHeight);
+            mStatusBarColor.draw(canvas);
+            mSystemBarBackgroundNode.end(canvas);
+            mRenderer.drawRenderNode(mSystemBarBackgroundNode);
+        }
+
         // We need to render the node explicitly
         mRenderer.drawRenderNode(mFrameAndBackdropNode);
 
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 27fe03c..9107b1f 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -21,8 +21,7 @@
 import com.android.internal.view.RootViewSurfaceTaker;
 import com.android.internal.view.StandaloneActionMode;
 import com.android.internal.view.menu.ContextMenuBuilder;
-import com.android.internal.view.menu.MenuDialogHelper;
-import com.android.internal.view.menu.MenuPopupHelper;
+import com.android.internal.view.menu.MenuHelper;
 import com.android.internal.widget.ActionBarContextView;
 import com.android.internal.widget.BackgroundFallback;
 import com.android.internal.widget.DecorCaptionView;
@@ -152,6 +151,8 @@
     private final Interpolator mShowInterpolator;
     private final Interpolator mHideInterpolator;
     private final int mBarEnterExitDuration;
+    private final boolean mForceWindowDrawsStatusBarBackground;
+    private final int mSemiTransparentStatusBarColor;
 
     private final BackgroundFallback mBackgroundFallback = new BackgroundFallback();
 
@@ -198,6 +199,10 @@
 
         mBarEnterExitDuration = context.getResources().getInteger(
                 R.integer.dock_enter_exit_duration);
+        mForceWindowDrawsStatusBarBackground = context.getResources().getBoolean(
+                R.bool.config_forceWindowDrawsStatusBarBackground);
+        mSemiTransparentStatusBarColor = context.getResources().getColor(
+                R.color.system_bar_background_semi_transparent, null /* theme */);
 
         setWindow(window);
     }
@@ -659,30 +664,23 @@
 
     @Override
     public boolean showContextMenuForChild(View originalView) {
-        // Reuse the context menu builder
-        if (mWindow.mContextMenu == null) {
-            mWindow.mContextMenu = new ContextMenuBuilder(getContext());
-            mWindow.mContextMenu.setCallback(mWindow.mContextMenuCallback);
-        } else {
-            mWindow.mContextMenu.clearAll();
-        }
-
-        final MenuDialogHelper helper = mWindow.mContextMenu.show(originalView,
-                originalView.getWindowToken());
-        if (helper != null) {
-            helper.setPresenterCallback(mWindow.mContextMenuCallback);
-        } else if (mWindow.mContextMenuHelper != null) {
-            // No menu to show, but if we have a menu currently showing it just became blank.
-            // Close it.
-            mWindow.mContextMenuHelper.dismiss();
-        }
-        mWindow.mContextMenuHelper = helper;
-        return helper != null;
+        return showContextMenuForChildInternal(originalView, 0, 0, false);
     }
 
     @Override
     public boolean showContextMenuForChild(View originalView, float x, float y) {
-        // Reuse the context menu builder
+        return showContextMenuForChildInternal(originalView, x, y, true);
+    }
+
+    private boolean showContextMenuForChildInternal(View originalView,
+            float x, float y, boolean isPopup) {
+        // Only allow one context menu at a time.
+        if (mWindow.mContextMenuHelper != null) {
+            mWindow.mContextMenuHelper.dismiss();
+            mWindow.mContextMenuHelper = null;
+        }
+
+        // Reuse the context menu builder.
         if (mWindow.mContextMenu == null) {
             mWindow.mContextMenu = new ContextMenuBuilder(getContext());
             mWindow.mContextMenu.setCallback(mWindow.mContextMenuCallback);
@@ -690,16 +688,18 @@
             mWindow.mContextMenu.clearAll();
         }
 
-        final MenuPopupHelper helper = mWindow.mContextMenu.showPopup(
-                getContext(), originalView, x, y);
-        if (helper != null) {
-            helper.setCallback(mWindow.mContextMenuCallback);
-        } else if (mWindow.mContextMenuPopupHelper != null) {
-            // No menu to show, but if we have a menu currently showing it just became blank.
-            // Close it.
-            mWindow.mContextMenuPopupHelper.dismiss();
+        final MenuHelper helper;
+        if (isPopup) {
+            helper = mWindow.mContextMenu.showPopup(getContext(), originalView, x, y);
+        } else {
+            helper = mWindow.mContextMenu.showDialog(originalView, originalView.getWindowToken());
         }
-        mWindow.mContextMenuPopupHelper = helper;
+
+        if (helper != null) {
+            helper.setPresenterCallback(mWindow.mContextMenuCallback);
+        }
+
+        mWindow.mContextMenuHelper = helper;
         return helper != null;
     }
 
@@ -890,14 +890,15 @@
             int navBarSize = navBarToRightEdge ? mLastRightInset : mLastBottomInset;
             updateColorViewInt(mNavigationColorViewState, sysUiVisibility,
                     mWindow.mNavigationBarColor, navBarSize, navBarToRightEdge,
-                    0 /* rightInset */, animate && !disallowAnimate);
+                    0 /* rightInset */, animate && !disallowAnimate, false /* force */);
 
             boolean statusBarNeedsRightInset = navBarToRightEdge
                     && mNavigationColorViewState.present;
             int statusBarRightInset = statusBarNeedsRightInset ? mLastRightInset : 0;
-            updateColorViewInt(mStatusColorViewState, sysUiVisibility, mWindow.mStatusBarColor,
-                    mLastTopInset, false /* matchVertical */, statusBarRightInset,
-                    animate && !disallowAnimate);
+            updateColorViewInt(mStatusColorViewState, sysUiVisibility,
+                    calculateStatusBarColor(), mLastTopInset,
+                    false /* matchVertical */, statusBarRightInset, animate && !disallowAnimate,
+                    mForceWindowDrawsStatusBarBackground);
         }
 
         // When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, we still need
@@ -941,6 +942,21 @@
         return insets;
     }
 
+    private int calculateStatusBarColor() {
+        int flags = mWindow.getAttributes().flags;
+        return (flags & FLAG_TRANSLUCENT_STATUS) != 0 ? mSemiTransparentStatusBarColor
+                : (flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0 ? mWindow.mStatusBarColor
+                : Color.BLACK;
+    }
+
+    private int getCurrentColor(ColorViewState state) {
+        if (state.visible) {
+            return state.color;
+        } else {
+            return 0;
+        }
+    }
+
     /**
      * Update a color view
      *
@@ -954,13 +970,15 @@
      * @param animate if true, the change will be animated.
      */
     private void updateColorViewInt(final ColorViewState state, int sysUiVis, int color,
-            int size, boolean verticalBar, int rightMargin, boolean animate) {
+            int size, boolean verticalBar, int rightMargin, boolean animate, boolean force) {
         state.present = size > 0 && (sysUiVis & state.systemUiHideFlag) == 0
                 && (mWindow.getAttributes().flags & state.hideWindowFlag) == 0
-                && (mWindow.getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
+                && ((mWindow.getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
+                        || force);
         boolean show = state.present
                 && (color & Color.BLACK) != 0
-                && (mWindow.getAttributes().flags & state.translucentFlag) == 0;
+                && ((mWindow.getAttributes().flags & state.translucentFlag) == 0  || force);
+        boolean showView = show && !isResizing();
 
         boolean visibilityChanged = false;
         View view = state.view;
@@ -970,7 +988,7 @@
         int resolvedGravity = verticalBar ? state.horizontalGravity : state.verticalGravity;
 
         if (view == null) {
-            if (show) {
+            if (showView) {
                 state.view = view = new View(mContext);
                 view.setBackgroundColor(color);
                 view.setTransitionName(state.transitionName);
@@ -986,7 +1004,7 @@
                 updateColorViewTranslations();
             }
         } else {
-            int vis = show ? VISIBLE : INVISIBLE;
+            int vis = showView ? VISIBLE : INVISIBLE;
             visibilityChanged = state.targetVisibility != vis;
             state.targetVisibility = vis;
             LayoutParams lp = (LayoutParams) view.getLayoutParams();
@@ -998,14 +1016,14 @@
                 lp.rightMargin = rightMargin;
                 view.setLayoutParams(lp);
             }
-            if (show) {
+            if (showView) {
                 view.setBackgroundColor(color);
             }
         }
         if (visibilityChanged) {
             view.animate().cancel();
-            if (animate) {
-                if (show) {
+            if (animate && !isResizing()) {
+                if (showView) {
                     if (view.getVisibility() != VISIBLE) {
                         view.setVisibility(VISIBLE);
                         view.setAlpha(0.0f);
@@ -1025,9 +1043,11 @@
                 }
             } else {
                 view.setAlpha(1.0f);
-                view.setVisibility(show ? VISIBLE : INVISIBLE);
+                view.setVisibility(showView ? VISIBLE : INVISIBLE);
             }
         }
+        state.visible = show;
+        state.color = color;
     }
 
     private void updateColorViewTranslations() {
@@ -1559,7 +1579,8 @@
 
         if (mBackdropFrameRenderer != null) {
             mBackdropFrameRenderer.onResourcesLoaded(
-                    this, mResizingBackgroundDrawable, mCaptionBackgroundDrawable);
+                    this, mResizingBackgroundDrawable, mCaptionBackgroundDrawable,
+                    getCurrentColor(mStatusColorViewState));
         }
 
         mDecorCaptionView = createDecorCaptionView(inflater);
@@ -1674,9 +1695,15 @@
         if (mDecorCaptionView != null) {
             mDecorCaptionView.removeContentView();
         } else {
-            // This window doesn't have caption, so we need to just remove the
-            // children of the decor view.
-            removeAllViews();
+            // This window doesn't have caption, so we need to remove everything except our views
+            // we might have added.
+            for (int i = getChildCount() - 1; i >= 0; i--) {
+                View v = getChildAt(i);
+                if (v != mStatusColorViewState.view && v != mNavigationColorViewState.view
+                        && v != mStatusGuard && v != mNavigationGuard) {
+                    removeViewAt(i);
+                }
+            }
         }
     }
 
@@ -1700,18 +1727,22 @@
         final ThreadedRenderer renderer = (ThreadedRenderer) getHardwareRenderer();
         if (renderer != null) {
             mBackdropFrameRenderer = new BackdropFrameRenderer(this, renderer,
-                    initialBounds, mResizingBackgroundDrawable, mCaptionBackgroundDrawable);
+                    initialBounds, mResizingBackgroundDrawable, mCaptionBackgroundDrawable,
+                    getCurrentColor(mStatusColorViewState));
 
             // Get rid of the shadow while we are resizing. Shadow drawing takes considerable time.
             // If we want to get the shadow shown while resizing, we would need to elevate a new
             // element which owns the caption and has the elevation.
             updateElevation();
+
+            updateColorViews(null /* insets */, false);
         }
     }
 
     @Override
     public void onWindowDragResizeEnd() {
         releaseThreadedRenderer();
+        updateColorViews(null /* insets */, false);
     }
 
     @Override
@@ -1744,6 +1775,10 @@
         }
     }
 
+    private boolean isResizing() {
+        return mBackdropFrameRenderer != null;
+    }
+
     /**
      * The elevation gets set for the first time and the framework needs to be informed that
      * the surface layer gets created with the shadow size in mind.
@@ -1759,8 +1794,7 @@
         final boolean wasAdjustedForStack = mElevationAdjustedForStack;
         // Do not use a shadow when we are in resizing mode (mBackdropFrameRenderer not null)
         // since the shadow is bound to the content size and not the target size.
-        if (ActivityManager.StackId.hasWindowShadow(mStackId)
-                && mBackdropFrameRenderer == null) {
+        if (ActivityManager.StackId.hasWindowShadow(mStackId) && !isResizing()) {
             elevation = hasWindowFocus() ?
                     DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP : DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP;
             // TODO(skuhne): Remove this if clause once b/22668382 got fixed.
@@ -1790,6 +1824,10 @@
         return isShowingCaption() ? mDecorCaptionView.getCaptionHeight() : 0;
     }
 
+    int getStatusBarHeight() {
+        return mStatusColorViewState.view != null ? mStatusColorViewState.view.getHeight() : 0;
+    }
+
     /**
      * Converts a DIP measure into physical pixels.
      * @param dip The dip value.
@@ -1804,6 +1842,8 @@
         View view = null;
         int targetVisibility = View.INVISIBLE;
         boolean present = false;
+        boolean visible;
+        int color;
 
         final int id;
         final int systemUiHideFlag;
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 6e7e5cf..57d2244 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -53,7 +53,7 @@
 import com.android.internal.view.menu.ListMenuPresenter;
 import com.android.internal.view.menu.MenuBuilder;
 import com.android.internal.view.menu.MenuDialogHelper;
-import com.android.internal.view.menu.MenuPopupHelper;
+import com.android.internal.view.menu.MenuHelper;
 import com.android.internal.view.menu.MenuPresenter;
 import com.android.internal.view.menu.MenuView;
 import com.android.internal.widget.DecorContentParent;
@@ -232,8 +232,7 @@
     private boolean mAlwaysReadCloseOnTouchAttr = false;
 
     ContextMenuBuilder mContextMenu;
-    MenuDialogHelper mContextMenuHelper;
-    MenuPopupHelper mContextMenuPopupHelper;
+    MenuHelper mContextMenuHelper;
     private boolean mClosingActionMenu;
 
     private int mVolumeControlStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE;
@@ -1103,10 +1102,6 @@
             mContextMenuHelper.dismiss();
             mContextMenuHelper = null;
         }
-        if (mContextMenuPopupHelper != null) {
-            mContextMenuPopupHelper.dismiss();
-            mContextMenuPopupHelper = null;
-        }
     }
 
     @Override
@@ -2411,6 +2406,13 @@
             setNeedsMenuKey(WindowManager.LayoutParams.NEEDS_MENU_SET_FALSE);
         }
 
+        if (!mForcedStatusBarColor) {
+            mStatusBarColor = a.getColor(R.styleable.Window_statusBarColor, 0xFF000000);
+        }
+        if (!mForcedNavigationBarColor) {
+            mNavigationBarColor = a.getColor(R.styleable.Window_navigationBarColor, 0xFF000000);
+        }
+
         // Non-floating windows on high end devices must put up decor beneath the system bars and
         // therefore must know about visibility changes of those.
         if (!mIsFloating && ActivityManager.isHighEndGfx()) {
@@ -2421,12 +2423,6 @@
                         FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS & ~getForcedWindowFlags());
             }
         }
-        if (!mForcedStatusBarColor) {
-            mStatusBarColor = a.getColor(R.styleable.Window_statusBarColor, 0xFF000000);
-        }
-        if (!mForcedNavigationBarColor) {
-            mNavigationBarColor = a.getColor(R.styleable.Window_navigationBarColor, 0xFF000000);
-        }
         if (a.getBoolean(R.styleable.Window_windowLightStatusBar, false)) {
             decor.setSystemUiVisibility(
                     decor.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
diff --git a/core/java/com/android/internal/view/menu/ContextMenuBuilder.java b/core/java/com/android/internal/view/menu/ContextMenuBuilder.java
index aaa1bf1..82f061c 100644
--- a/core/java/com/android/internal/view/menu/ContextMenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/ContextMenuBuilder.java
@@ -17,7 +17,6 @@
 package com.android.internal.view.menu;
 
 import android.content.Context;
-import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.IBinder;
 import android.util.EventLog;
@@ -35,7 +34,7 @@
  * <p>
  * To use this class, instantiate it via {@link #ContextMenuBuilder(Context)},
  * and optionally populate it with any of your custom items.  Finally,
- * call {@link #show(View, IBinder)} which will populate the menu
+ * call {@link #showDialog(View, IBinder)} which will populate the menu
  * with a view's context menu items and show the context menu.
  */
 public class ContextMenuBuilder extends MenuBuilder implements ContextMenu {
@@ -75,7 +74,7 @@
      * @return If the context menu was shown, the {@link MenuDialogHelper} for
      *         dismissing it. Otherwise, null.
      */
-    public MenuDialogHelper show(View originalView, IBinder token) {
+    public MenuDialogHelper showDialog(View originalView, IBinder token) {
         if (originalView != null) {
             // Let relevant views and their populate context listeners populate
             // the context menu
diff --git a/core/java/com/android/internal/view/menu/MenuDialogHelper.java b/core/java/com/android/internal/view/menu/MenuDialogHelper.java
index b9e0e40..ecab29f 100644
--- a/core/java/com/android/internal/view/menu/MenuDialogHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuDialogHelper.java
@@ -26,13 +26,10 @@
 import android.view.WindowManager;
 
 /**
- * Helper for menus that appear as Dialogs (context and submenus).
- * 
- * @hide
+ * Presents a menu as a modal dialog.
  */
-public class MenuDialogHelper implements DialogInterface.OnKeyListener,
-        DialogInterface.OnClickListener,
-        DialogInterface.OnDismissListener,
+public class MenuDialogHelper implements MenuHelper, DialogInterface.OnKeyListener,
+        DialogInterface.OnClickListener, DialogInterface.OnDismissListener,
         MenuPresenter.Callback {
     private MenuBuilder mMenu;
     private AlertDialog mDialog;
@@ -125,6 +122,7 @@
 
     }
 
+    @Override
     public void setPresenterCallback(MenuPresenter.Callback cb) {
         mPresenterCallback = cb;
     }
@@ -134,6 +132,7 @@
      * 
      * @see Dialog#dismiss()
      */
+    @Override
     public void dismiss() {
         if (mDialog != null) {
             mDialog.dismiss();
diff --git a/core/java/com/android/internal/view/menu/MenuHelper.java b/core/java/com/android/internal/view/menu/MenuHelper.java
new file mode 100644
index 0000000..9534722
--- /dev/null
+++ b/core/java/com/android/internal/view/menu/MenuHelper.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.view.menu;
+
+/**
+ * Interface for a helper capable of presenting a menu.
+ */
+public interface MenuHelper {
+    void setPresenterCallback(MenuPresenter.Callback cb);
+    void dismiss();
+}
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 59d5f94..044ee6e 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -30,7 +30,7 @@
 /**
  * Presents a menu as a small, simple popup anchored to another view.
  */
-public class MenuPopupHelper {
+public class MenuPopupHelper implements MenuHelper {
     private final Context mContext;
 
     // Immutable cached popup menu properties.
@@ -244,6 +244,7 @@
     /**
      * Dismisses the popup, if showing.
      */
+    @Override
     public void dismiss() {
         if (isShowing()) {
             mPopup.dismiss();
@@ -270,7 +271,8 @@
         return mPopup != null && mPopup.isShowing();
     }
 
-    public void setCallback(@Nullable MenuPresenter.Callback cb) {
+    @Override
+    public void setPresenterCallback(@Nullable MenuPresenter.Callback cb) {
         mPresenterCallback = cb;
         if (mPopup != null) {
             mPopup.setCallback(cb);
diff --git a/core/java/com/android/internal/view/menu/StandardMenuPopup.java b/core/java/com/android/internal/view/menu/StandardMenuPopup.java
index caee0d2..6a5f6d8 100644
--- a/core/java/com/android/internal/view/menu/StandardMenuPopup.java
+++ b/core/java/com/android/internal/view/menu/StandardMenuPopup.java
@@ -245,7 +245,7 @@
             MenuPopupHelper subPopup = new MenuPopupHelper(
                     mContext, subMenu, mShownAnchorView, mOverflowOnly, mPopupStyleAttr,
                     mPopupStyleRes);
-            subPopup.setCallback(mPresenterCallback);
+            subPopup.setPresenterCallback(mPresenterCallback);
             subPopup.setForceShowIcon(mAdapter.getForceShowIcon());
 
             if (subPopup.tryShow()) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 77072aa..ee493019 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2720,6 +2720,13 @@
     <permission android:name="android.permission.DISPATCH_NFC_MESSAGE"
                 android:protectionLevel="signature|privileged" />
 
+    <!-- @SystemApi Allows changing day / night mode when system is configured with
+         config_lockDayNightMode set to true. If requesting app does not have permission,
+         it will be ignored.
+        @hide -->
+    <permission android:name="android.permission.MODIFY_DAY_NIGHT_MODE"
+                android:protectionLevel="signature|privileged" />
+
     <!-- The system process is explicitly the only one allowed to launch the
          confirmation UI for full backup/restore -->
     <uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
diff --git a/core/res/res/drawable-mdpi/pointer_alias_large.png b/core/res/res/drawable-mdpi/pointer_alias_large.png
new file mode 100644
index 0000000..283bf7f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_alias_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_all_scroll_large.png b/core/res/res/drawable-mdpi/pointer_all_scroll_large.png
new file mode 100644
index 0000000..c29db87
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_all_scroll_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_arrow_large.png b/core/res/res/drawable-mdpi/pointer_arrow_large.png
new file mode 100644
index 0000000..9f59c4c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_cell_large.png b/core/res/res/drawable-mdpi/pointer_cell_large.png
new file mode 100644
index 0000000..3dec5e5
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_cell_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_context_menu_large.png b/core/res/res/drawable-mdpi/pointer_context_menu_large.png
new file mode 100644
index 0000000..7c9e250
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_context_menu_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_copy_large.png b/core/res/res/drawable-mdpi/pointer_copy_large.png
new file mode 100644
index 0000000..18f4696
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_copy_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_crosshair_large.png b/core/res/res/drawable-mdpi/pointer_crosshair_large.png
new file mode 100644
index 0000000..ea1f5fc
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_crosshair_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_grab_large.png b/core/res/res/drawable-mdpi/pointer_grab_large.png
new file mode 100644
index 0000000..2e32766
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_grab_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_grabbing_large.png b/core/res/res/drawable-mdpi/pointer_grabbing_large.png
new file mode 100644
index 0000000..3c54751
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_grabbing_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_hand_large.png b/core/res/res/drawable-mdpi/pointer_hand_large.png
new file mode 100644
index 0000000..785047f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_hand_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_help_large.png b/core/res/res/drawable-mdpi/pointer_help_large.png
new file mode 100644
index 0000000..6552f9b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_help_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_horizontal_double_arrow_large.png b/core/res/res/drawable-mdpi/pointer_horizontal_double_arrow_large.png
new file mode 100644
index 0000000..7086106
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_horizontal_double_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_nodrop_large.png b/core/res/res/drawable-mdpi/pointer_nodrop_large.png
new file mode 100644
index 0000000..da981df
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_nodrop_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_text_large.png b/core/res/res/drawable-mdpi/pointer_text_large.png
new file mode 100644
index 0000000..2fba190
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_text_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_top_left_diagonal_double_arrow_large.png b/core/res/res/drawable-mdpi/pointer_top_left_diagonal_double_arrow_large.png
new file mode 100644
index 0000000..eecaa89
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_top_left_diagonal_double_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_top_right_diagonal_double_arrow_large.png b/core/res/res/drawable-mdpi/pointer_top_right_diagonal_double_arrow_large.png
new file mode 100644
index 0000000..9d47ecf
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_top_right_diagonal_double_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_vertical_double_arrow_large.png b/core/res/res/drawable-mdpi/pointer_vertical_double_arrow_large.png
new file mode 100644
index 0000000..fd777b1
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_vertical_double_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_vertical_text_large.png b/core/res/res/drawable-mdpi/pointer_vertical_text_large.png
new file mode 100644
index 0000000..1cbe49a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_vertical_text_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_zoom_in_large.png b/core/res/res/drawable-mdpi/pointer_zoom_in_large.png
new file mode 100644
index 0000000..923ad79
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_zoom_in_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_zoom_out_large.png b/core/res/res/drawable-mdpi/pointer_zoom_out_large.png
new file mode 100644
index 0000000..aa47eb9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_zoom_out_large.png
Binary files differ
diff --git a/core/res/res/drawable/pointer_alias_large_icon.xml b/core/res/res/drawable/pointer_alias_large_icon.xml
new file mode 100644
index 0000000..149f58c
--- /dev/null
+++ b/core/res/res/drawable/pointer_alias_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_alias_large"
+    android:hotSpotX="19dp"
+    android:hotSpotY="11dp" />
diff --git a/core/res/res/drawable/pointer_all_scroll_large_icon.xml b/core/res/res/drawable/pointer_all_scroll_large_icon.xml
new file mode 100644
index 0000000..c580f76
--- /dev/null
+++ b/core/res/res/drawable/pointer_all_scroll_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_all_scroll_large"
+    android:hotSpotX="32dp"
+    android:hotSpotY="31dp" />
diff --git a/core/res/res/drawable/pointer_arrow_large_icon.xml b/core/res/res/drawable/pointer_arrow_large_icon.xml
new file mode 100644
index 0000000..22c7bfe
--- /dev/null
+++ b/core/res/res/drawable/pointer_arrow_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_arrow_large"
+    android:hotSpotX="10dp"
+    android:hotSpotY="10dp" />
diff --git a/core/res/res/drawable/pointer_cell_large_icon.xml b/core/res/res/drawable/pointer_cell_large_icon.xml
new file mode 100644
index 0000000..f2530b7
--- /dev/null
+++ b/core/res/res/drawable/pointer_cell_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_cell_large"
+    android:hotSpotX="30dp"
+    android:hotSpotY="30dp" />
diff --git a/core/res/res/drawable/pointer_context_menu_large_icon.xml b/core/res/res/drawable/pointer_context_menu_large_icon.xml
new file mode 100644
index 0000000..c57e615
--- /dev/null
+++ b/core/res/res/drawable/pointer_context_menu_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_context_menu_large"
+    android:hotSpotX="11dp"
+    android:hotSpotY="11dp" />
diff --git a/core/res/res/drawable/pointer_copy_large_icon.xml b/core/res/res/drawable/pointer_copy_large_icon.xml
new file mode 100644
index 0000000..4ee3f18
--- /dev/null
+++ b/core/res/res/drawable/pointer_copy_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_copy_large"
+    android:hotSpotX="10dp"
+    android:hotSpotY="10dp" />
diff --git a/core/res/res/drawable/pointer_crosshair_large_icon.xml b/core/res/res/drawable/pointer_crosshair_large_icon.xml
new file mode 100644
index 0000000..6a71b7b
--- /dev/null
+++ b/core/res/res/drawable/pointer_crosshair_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_crosshair_large"
+    android:hotSpotX="31dp"
+    android:hotSpotY="30dp" />
diff --git a/core/res/res/drawable/pointer_grab_large_icon.xml b/core/res/res/drawable/pointer_grab_large_icon.xml
new file mode 100644
index 0000000..f2df1cb
--- /dev/null
+++ b/core/res/res/drawable/pointer_grab_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_grab_large"
+    android:hotSpotX="21dp"
+    android:hotSpotY="11dp" />
diff --git a/core/res/res/drawable/pointer_grabbing_large_icon.xml b/core/res/res/drawable/pointer_grabbing_large_icon.xml
new file mode 100644
index 0000000..e4042bf
--- /dev/null
+++ b/core/res/res/drawable/pointer_grabbing_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_grabbing_large"
+    android:hotSpotX="20dp"
+    android:hotSpotY="12dp" />
diff --git a/core/res/res/drawable/pointer_hand_large_icon.xml b/core/res/res/drawable/pointer_hand_large_icon.xml
new file mode 100644
index 0000000..e34422a
--- /dev/null
+++ b/core/res/res/drawable/pointer_hand_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_hand_large"
+    android:hotSpotX="25dp"
+    android:hotSpotY="7dp" />
diff --git a/core/res/res/drawable/pointer_help_large_icon.xml b/core/res/res/drawable/pointer_help_large_icon.xml
new file mode 100644
index 0000000..4c60a55
--- /dev/null
+++ b/core/res/res/drawable/pointer_help_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_help_large"
+    android:hotSpotX="10dp"
+    android:hotSpotY="11dp" />
diff --git a/core/res/res/drawable/pointer_horizontal_double_arrow_large_icon.xml b/core/res/res/drawable/pointer_horizontal_double_arrow_large_icon.xml
new file mode 100644
index 0000000..a2039e6
--- /dev/null
+++ b/core/res/res/drawable/pointer_horizontal_double_arrow_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_horizontal_double_arrow_large"
+    android:hotSpotX="35dp"
+    android:hotSpotY="29dp" />
diff --git a/core/res/res/drawable/pointer_nodrop_large_icon.xml b/core/res/res/drawable/pointer_nodrop_large_icon.xml
new file mode 100644
index 0000000..cde2e41
--- /dev/null
+++ b/core/res/res/drawable/pointer_nodrop_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_nodrop_large"
+    android:hotSpotX="10dp"
+    android:hotSpotY="10dp" />
diff --git a/core/res/res/drawable/pointer_text_large_icon.xml b/core/res/res/drawable/pointer_text_large_icon.xml
new file mode 100644
index 0000000..24d35b0
--- /dev/null
+++ b/core/res/res/drawable/pointer_text_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_text_large"
+    android:hotSpotX="30dp"
+    android:hotSpotY="32dp" />
diff --git a/core/res/res/drawable/pointer_top_left_diagonal_double_arrow_large_icon.xml b/core/res/res/drawable/pointer_top_left_diagonal_double_arrow_large_icon.xml
new file mode 100644
index 0000000..270ccc9
--- /dev/null
+++ b/core/res/res/drawable/pointer_top_left_diagonal_double_arrow_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_top_left_diagonal_double_arrow_large"
+    android:hotSpotX="32dp"
+    android:hotSpotY="30dp" />
diff --git a/core/res/res/drawable/pointer_top_right_diagonal_double_arrow_large_icon.xml b/core/res/res/drawable/pointer_top_right_diagonal_double_arrow_large_icon.xml
new file mode 100644
index 0000000..e350a43
--- /dev/null
+++ b/core/res/res/drawable/pointer_top_right_diagonal_double_arrow_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_top_right_diagonal_double_arrow_large"
+    android:hotSpotX="32dp"
+    android:hotSpotY="31dp" />
diff --git a/core/res/res/drawable/pointer_vertical_double_arrow_large_icon.xml b/core/res/res/drawable/pointer_vertical_double_arrow_large_icon.xml
new file mode 100644
index 0000000..65728ad
--- /dev/null
+++ b/core/res/res/drawable/pointer_vertical_double_arrow_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_vertical_double_arrow_large"
+    android:hotSpotX="29dp"
+    android:hotSpotY="32dp" />
diff --git a/core/res/res/drawable/pointer_vertical_text_large_icon.xml b/core/res/res/drawable/pointer_vertical_text_large_icon.xml
new file mode 100644
index 0000000..48211cb
--- /dev/null
+++ b/core/res/res/drawable/pointer_vertical_text_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_vertical_text_large"
+    android:hotSpotX="32dp"
+    android:hotSpotY="30dp" />
diff --git a/core/res/res/drawable/pointer_zoom_in_large_icon.xml b/core/res/res/drawable/pointer_zoom_in_large_icon.xml
new file mode 100644
index 0000000..3eb89f56
--- /dev/null
+++ b/core/res/res/drawable/pointer_zoom_in_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_zoom_in_large"
+    android:hotSpotX="25dp"
+    android:hotSpotY="26dp" />
diff --git a/core/res/res/drawable/pointer_zoom_out_large_icon.xml b/core/res/res/drawable/pointer_zoom_out_large_icon.xml
new file mode 100644
index 0000000..df6412e
--- /dev/null
+++ b/core/res/res/drawable/pointer_zoom_out_large_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_zoom_out_large"
+    android:hotSpotX="26dp"
+    android:hotSpotY="26dp" />
diff --git a/core/res/res/values-mcc302-mnc220/config.xml b/core/res/res/values-mcc302-mnc220/config.xml
index 09a63aa..454e4b6 100644
--- a/core/res/res/values-mcc302-mnc220/config.xml
+++ b/core/res/res/values-mcc302-mnc220/config.xml
@@ -37,7 +37,7 @@
          Or string format of ApnSettingV3.
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
     <string-array translatable="false" name="config_tether_apndata">
-        <item>[ApnSettingV3]TELUS ISP,isp.telus.com,,,,,,,,,302,220,,DUN,,,true,0,,,,,,,gid,54</item>
+        <item>[ApnSettingV3]TELUS ISP,isp.telus.com,,,,,,,,,302,220,,DUN,IP,IP,true,0,,,,,,,gid,54</item>
         <item>[ApnSettingV3]Tethered Mobile Internet,isp.mb.com,,,,,,,,,302,220,,DUN,,,true,0,,,,,,,gid,50</item>
         <item>[ApnSettingV3]Tethered Public Mobile,isp.mb.com,,,,,,,,,302,220,,DUN,,,true,0,,,,,,,gid,4D4F</item>
     </string-array>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index f9f8162..34a66d0 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1026,9 +1026,6 @@
         <!-- ============== -->
         <eat-comment />
 
-        <!-- Reference to the Pointer style -->
-        <attr name="pointerStyle" format="reference" />
-
         <!-- The drawable for accessibility focused views. -->
         <attr name="accessibilityFocusedDrawable" format="reference" />
 
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index dad68ba..af8ff2e 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -173,4 +173,7 @@
     <color name="Red_800">#ffb93221</color>
 
     <color name="chooser_service_row_background_color">#fff5f5f5</color>
+
+    <!-- Status bar color for semi transparent mode. -->
+    <color name="system_bar_background_semi_transparent">#66000000</color> <!-- 40% black -->
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d9e0472..ea6cf11 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -716,6 +716,13 @@
 
     <bool name="config_carDockEnablesAccelerometer">true</bool>
 
+    <!--  Control whether to launch Car dock home app when user presses home button or when
+          car dock intent is fired.
+          In mobile device, usually separate home app is expected in car mode, and this should be
+          enabled. But in environments like real car, default home app may be enough, and in that
+          case, this can be disabled (set to false). -->
+    <bool name="config_enableCarDockHomeLaunch">true</bool>
+
     <!-- HDMI behavior -->
 
     <!-- The number of degrees to rotate the display when the device has HDMI connected
@@ -733,6 +740,15 @@
          Any other values will have surprising consequences. -->
     <integer name="config_defaultUiModeType">1</integer>
 
+    <!--  Control whether to lock UI mode to what is selected from config_defaultUiModeType.
+          Once UI mode is locked, applications cannot change it anymore. -->
+    <bool name="config_lockUiMode">false</bool>
+
+    <!--  Control whether to lock day/night mode change from normal application. When it is
+          true, day / night mode change is only allowed to apps with MODIFY_DAY_NIGHT_MODE
+          permission. -->
+    <bool name="config_lockDayNightMode">false</bool>
+
     <!-- Control the default night mode to use when there is no other mode override set.
          One of the following values (see UiModeManager.java):
              0 - MODE_NIGHT_AUTO
@@ -2384,4 +2400,9 @@
          The duplication is necessary, because this information is used before the features are
          available to the system.-->
     <bool name="config_freeformWindowManagement">false</bool>
+
+    <!-- If set, this will force all windows to draw the status bar background, including the apps
+         that have not requested doing so (via the WindowManager.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
+         flag). -->
+    <bool name="config_forceWindowDrawsStatusBarBackground">true</bool>
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index e6f279d..9a4016b 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1368,6 +1368,42 @@
         <item name="pointerIconGrabbing">@drawable/pointer_grabbing_icon</item>
     </style>
 
+    <style name="LargePointer">
+        <item name="pointerIconArrow">@drawable/pointer_arrow_large_icon</item>
+        <item name="pointerIconSpotHover">@drawable/pointer_spot_hover_icon</item>
+        <item name="pointerIconSpotTouch">@drawable/pointer_spot_touch_icon</item>
+        <item name="pointerIconSpotAnchor">@drawable/pointer_spot_anchor_icon</item>
+        <item name="pointerIconHand">@drawable/pointer_hand_large_icon</item>
+        <item name="pointerIconContextMenu">@drawable/pointer_context_menu_large_icon</item>
+        <item name="pointerIconHelp">@drawable/pointer_help_large_icon</item>
+        <!-- TODO: create large wait icon. -->
+        <item name="pointerIconWait">@drawable/pointer_wait_icon</item>
+        <item name="pointerIconCell">@drawable/pointer_cell_large_icon</item>
+        <item name="pointerIconCrosshair">@drawable/pointer_crosshair_large_icon</item>
+        <item name="pointerIconText">@drawable/pointer_text_large_icon</item>
+        <item name="pointerIconVerticalText">@drawable/pointer_vertical_text_large_icon</item>
+        <item name="pointerIconAlias">@drawable/pointer_alias_large_icon</item>
+        <item name="pointerIconCopy">@drawable/pointer_copy_large_icon</item>
+        <item name="pointerIconAllScroll">@drawable/pointer_all_scroll_large_icon</item>
+        <item name="pointerIconNodrop">@drawable/pointer_nodrop_large_icon</item>
+        <item name="pointerIconHorizontalDoubleArrow">
+            @drawable/pointer_horizontal_double_arrow_large_icon
+        </item>
+        <item name="pointerIconVerticalDoubleArrow">
+            @drawable/pointer_vertical_double_arrow_large_icon
+        </item>
+        <item name="pointerIconTopRightDiagonalDoubleArrow">
+            @drawable/pointer_top_right_diagonal_double_arrow_large_icon
+        </item>
+        <item name="pointerIconTopLeftDiagonalDoubleArrow">
+            @drawable/pointer_top_left_diagonal_double_arrow_large_icon
+        </item>
+        <item name="pointerIconZoomIn">@drawable/pointer_zoom_in_large_icon</item>
+        <item name="pointerIconZoomOut">@drawable/pointer_zoom_out_large_icon</item>
+        <item name="pointerIconGrab">@drawable/pointer_grab_large_icon</item>
+        <item name="pointerIconGrabbing">@drawable/pointer_grabbing_large_icon</item>
+    </style>
+
     <!-- Wifi dialog styles -->
     <!-- @hide -->
     <style name="wifi_item">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3860f68..b5fc08b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -227,7 +227,6 @@
   <java-symbol type="attr" name="gestureOverlayViewStyle" />
   <java-symbol type="attr" name="keyboardViewStyle" />
   <java-symbol type="attr" name="numberPickerStyle" />
-  <java-symbol type="attr" name="pointerStyle" />
   <java-symbol type="attr" name="preferenceFrameLayoutStyle" />
   <java-symbol type="attr" name="searchDialogTheme" />
   <java-symbol type="attr" name="textAppearanceAutoCorrectionSuggestion" />
@@ -1424,6 +1423,8 @@
   <java-symbol type="style" name="Theme.DeviceDefault.Dialog.NoFrame" />
   <java-symbol type="style" name="Theme.IconMenu" />
   <java-symbol type="style" name="Theme.DeviceDefault.VoiceInteractionSession" />
+  <java-symbol type="style" name="Pointer" />
+  <java-symbol type="style" name="LargePointer" />
 
   <java-symbol type="attr" name="mediaRouteButtonStyle" />
   <java-symbol type="attr" name="externalRouteEnabledDrawable" />
@@ -1476,11 +1477,14 @@
   <java-symbol type="bool" name="config_carDockEnablesAccelerometer" />
   <java-symbol type="bool" name="config_deskDockEnablesAccelerometer" />
   <java-symbol type="bool" name="config_disableMenuKeyInLockScreen" />
+  <java-symbol type="bool" name="config_enableCarDockHomeLaunch" />
   <java-symbol type="bool" name="config_enableLockBeforeUnlockScreen" />
   <java-symbol type="bool" name="config_enableLockScreenRotation" />
   <java-symbol type="bool" name="config_enableLockScreenTranslucentDecor" />
   <java-symbol type="bool" name="config_enableTranslucentDecor" />
   <java-symbol type="bool" name="config_lidControlsSleep" />
+  <java-symbol type="bool" name="config_lockDayNightMode" />
+  <java-symbol type="bool" name="config_lockUiMode" />
   <java-symbol type="bool" name="config_reverseDefaultRotation" />
   <java-symbol type="bool" name="config_showNavigationBar" />
   <java-symbol type="bool" name="config_supportAutoRotation" />
@@ -2344,6 +2348,8 @@
 
   <java-symbol type="string" name="config_packagedKeyboardName" />
   <java-symbol type="string" name="default_notification_topic_label" />
+  <java-symbol type="bool" name="config_forceWindowDrawsStatusBarBackground" />
+  <java-symbol type="color" name="system_bar_background_semi_transparent" />
 
   <!-- EditText suggestion popup. -->
   <java-symbol type="id" name="suggestionContainer" />
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index d56674a..bf7718e 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -428,9 +428,6 @@
         <item name="fastScrollOverlayPosition">floating</item>
         <item name="fastScrollTextColor">@color/primary_text_dark</item>
 
-        <!-- Pointer style -->
-        <item name="pointerStyle">@style/Pointer</item>
-
         <!-- Accessibility focused drawable -->
         <item name="accessibilityFocusedDrawable">@drawable/view_accessibility_focused</item>
 
diff --git a/core/tests/coretests/apks/keyset/permUse/AndroidManifest.xml b/core/tests/coretests/apks/keyset/permUse/AndroidManifest.xml
index b7645b0..c56079f8 100644
--- a/core/tests/coretests/apks/keyset/permUse/AndroidManifest.xml
+++ b/core/tests/coretests/apks/keyset/permUse/AndroidManifest.xml
@@ -21,11 +21,11 @@
     <key-sets>
         <key-set android:name="A">
           <public-key android:name="keyA"
-                      android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ=="/>
+                      android:value="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsMpNthdOxud7roPDZMMomOqXgJJdRfIWpkKEqmC61Mv+Nf6QY3TorEwJeghjSmqj7IbBKrtvfQq4E2XJO1HuspmQO4Ng2gvn+r+6EwNfKc9k55d6s+27SR867jKurBbHNtZMG+tjL1yH4r+tNzcuJCsgyAFqLmxFdcxEwzNvREyRpoYc5RDR0mmTwkMCUhJ6CId1EYEKiCEdNzxv+fWPEb21u+/MWpleGCILs8kglRVb2q/WOzAAvGr4FY5plfaE6N+lr7+UschQ+aMi1+uqewo2o0qPFVmZP5hnwj55K4UMzu/NhhDqQQsX4cSGES1KgHo5MTqRqZjN/I7emw5pFQIDAQAB"/>
         </key-set>
         <key-set android:name="B">
           <public-key android:name="keyB"
-                      android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTfQsY8UuXiXmvw/y7Tpr7HoyfAC0nE/8Qdk3ZtEr9asa5qqP0F6xzCI1PGVFV+WLVRwm6FdB9StENL5EKyQFcCAwEAAQ==" />
+                      android:value="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEtGr5cL2N7ztHiHmphB1/1eq+43lEAmP36iiEJAfX+cVReGSPFXqNnnM8Vptd2boAe332lrFw9rKPmbkZA+jOTA==" />
         </key-set>
         <upgrade-key-set android:name="A"/>
         <upgrade-key-set android:name="B"/>
diff --git a/core/tests/coretests/apks/keyset/uA/AndroidManifest.xml b/core/tests/coretests/apks/keyset/uA/AndroidManifest.xml
index f31b75f..8c440f5 100644
--- a/core/tests/coretests/apks/keyset/uA/AndroidManifest.xml
+++ b/core/tests/coretests/apks/keyset/uA/AndroidManifest.xml
@@ -20,7 +20,7 @@
     <key-sets>
         <key-set android:name="A" >
           <public-key android:name="keyA"
-                      android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ=="/>
+                      android:value="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsMpNthdOxud7roPDZMMomOqXgJJdRfIWpkKEqmC61Mv+Nf6QY3TorEwJeghjSmqj7IbBKrtvfQq4E2XJO1HuspmQO4Ng2gvn+r+6EwNfKc9k55d6s+27SR867jKurBbHNtZMG+tjL1yH4r+tNzcuJCsgyAFqLmxFdcxEwzNvREyRpoYc5RDR0mmTwkMCUhJ6CId1EYEKiCEdNzxv+fWPEb21u+/MWpleGCILs8kglRVb2q/WOzAAvGr4FY5plfaE6N+lr7+UschQ+aMi1+uqewo2o0qPFVmZP5hnwj55K4UMzu/NhhDqQQsX4cSGES1KgHo5MTqRqZjN/I7emw5pFQIDAQAB"/>
         </key-set>
         <upgrade-key-set android:name="A"/>
     </key-sets>
diff --git a/core/tests/coretests/apks/keyset/uAB/AndroidManifest.xml b/core/tests/coretests/apks/keyset/uAB/AndroidManifest.xml
index 8ad3471..015c3ad 100644
--- a/core/tests/coretests/apks/keyset/uAB/AndroidManifest.xml
+++ b/core/tests/coretests/apks/keyset/uAB/AndroidManifest.xml
@@ -20,9 +20,9 @@
     <key-sets>
         <key-set android:name="AB" >
           <public-key android:name="keyA"
-                      android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ==" />
+                      android:value="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsMpNthdOxud7roPDZMMomOqXgJJdRfIWpkKEqmC61Mv+Nf6QY3TorEwJeghjSmqj7IbBKrtvfQq4E2XJO1HuspmQO4Ng2gvn+r+6EwNfKc9k55d6s+27SR867jKurBbHNtZMG+tjL1yH4r+tNzcuJCsgyAFqLmxFdcxEwzNvREyRpoYc5RDR0mmTwkMCUhJ6CId1EYEKiCEdNzxv+fWPEb21u+/MWpleGCILs8kglRVb2q/WOzAAvGr4FY5plfaE6N+lr7+UschQ+aMi1+uqewo2o0qPFVmZP5hnwj55K4UMzu/NhhDqQQsX4cSGES1KgHo5MTqRqZjN/I7emw5pFQIDAQAB" />
           <public-key android:name="keyB"
-                      android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTfQsY8UuXiXmvw/y7Tpr7HoyfAC0nE/8Qdk3ZtEr9asa5qqP0F6xzCI1PGVFV+WLVRwm6FdB9StENL5EKyQFcCAwEAAQ==" />
+                      android:value="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEtGr5cL2N7ztHiHmphB1/1eq+43lEAmP36iiEJAfX+cVReGSPFXqNnnM8Vptd2boAe332lrFw9rKPmbkZA+jOTA==" />
         </key-set>
         <upgrade-key-set android:name="AB"/>
     </key-sets>
diff --git a/core/tests/coretests/apks/keyset/uAuB/AndroidManifest.xml b/core/tests/coretests/apks/keyset/uAuB/AndroidManifest.xml
index cdbd639..9491dbea 100644
--- a/core/tests/coretests/apks/keyset/uAuB/AndroidManifest.xml
+++ b/core/tests/coretests/apks/keyset/uAuB/AndroidManifest.xml
@@ -20,11 +20,11 @@
     <key-sets>
         <key-set android:name="A" >
           <public-key android:name="keyA"
-                      android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ==" />
+                      android:value="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsMpNthdOxud7roPDZMMomOqXgJJdRfIWpkKEqmC61Mv+Nf6QY3TorEwJeghjSmqj7IbBKrtvfQq4E2XJO1HuspmQO4Ng2gvn+r+6EwNfKc9k55d6s+27SR867jKurBbHNtZMG+tjL1yH4r+tNzcuJCsgyAFqLmxFdcxEwzNvREyRpoYc5RDR0mmTwkMCUhJ6CId1EYEKiCEdNzxv+fWPEb21u+/MWpleGCILs8kglRVb2q/WOzAAvGr4FY5plfaE6N+lr7+UschQ+aMi1+uqewo2o0qPFVmZP5hnwj55K4UMzu/NhhDqQQsX4cSGES1KgHo5MTqRqZjN/I7emw5pFQIDAQAB" />
         </key-set>
         <key-set android:name="B" >
           <public-key android:name="keyB"
-                      android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTfQsY8UuXiXmvw/y7Tpr7HoyfAC0nE/8Qdk3ZtEr9asa5qqP0F6xzCI1PGVFV+WLVRwm6FdB9StENL5EKyQFcCAwEAAQ==" />
+                      android:value="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEtGr5cL2N7ztHiHmphB1/1eq+43lEAmP36iiEJAfX+cVReGSPFXqNnnM8Vptd2boAe332lrFw9rKPmbkZA+jOTA==" />
         </key-set>
         <upgrade-key-set android:name="A"/>
         <upgrade-key-set android:name="B"/>
diff --git a/core/tests/coretests/apks/keyset/uB/AndroidManifest.xml b/core/tests/coretests/apks/keyset/uB/AndroidManifest.xml
index 61063c3..f491840 100644
--- a/core/tests/coretests/apks/keyset/uB/AndroidManifest.xml
+++ b/core/tests/coretests/apks/keyset/uB/AndroidManifest.xml
@@ -20,7 +20,7 @@
     <key-sets>
         <key-set android:name="B" >
           <public-key android:name="keyB"
-                      android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTfQsY8UuXiXmvw/y7Tpr7HoyfAC0nE/8Qdk3ZtEr9asa5qqP0F6xzCI1PGVFV+WLVRwm6FdB9StENL5EKyQFcCAwEAAQ==" />
+                      android:value="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEtGr5cL2N7ztHiHmphB1/1eq+43lEAmP36iiEJAfX+cVReGSPFXqNnnM8Vptd2boAe332lrFw9rKPmbkZA+jOTA==" />
         </key-set>
         <upgrade-key-set android:name="B"/>
     </key-sets>
diff --git a/core/tests/coretests/certs/keyset_A.pk8 b/core/tests/coretests/certs/keyset_A.pk8
index 3976b94..4076313 100644
--- a/core/tests/coretests/certs/keyset_A.pk8
+++ b/core/tests/coretests/certs/keyset_A.pk8
Binary files differ
diff --git a/core/tests/coretests/certs/keyset_A.x509.pem b/core/tests/coretests/certs/keyset_A.x509.pem
index 0fe334e..548bf13 100644
--- a/core/tests/coretests/certs/keyset_A.x509.pem
+++ b/core/tests/coretests/certs/keyset_A.x509.pem
@@ -1,14 +1,18 @@
 -----BEGIN CERTIFICATE-----
-MIICKjCCAdQCCQCpDXPnNpO5UjANBgkqhkiG9w0BAQUFADCBmzELMAkGA1UEBhMC
-VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcx
-DzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHQW5kcm9pZDEYMBYGA1UEAxMPd3d3
-LmV4YW1wbGUuY29tMSIwIAYJKoZIhvcNAQkBFhNkY2FzaG1hbkBnb29nbGUuY29t
-MB4XDTE0MDQyMTE4MTkwM1oXDTE3MDQyMDE4MTkwM1owgZsxCzAJBgNVBAYTAlVT
-MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MQ8w
-DQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB0FuZHJvaWQxGDAWBgNVBAMTD3d3dy5l
-eGFtcGxlLmNvbTEiMCAGCSqGSIb3DQEJARYTZGNhc2htYW5AZ29vZ2xlLmNvbTBc
-MA0GCSqGSIb3DQEBAQUAA0sAMEgCQQCaDdTbIKn9FeAv22zfMKPDtl/0uQ++vuTG
-/ZpSLB5FE1E2xwjZPi8RyFGC5vPWGz/cyJq1dG1By1AGVMqDFAojAgMBAAEwDQYJ
-KoZIhvcNAQEFBQADQQCPTVDKxVZpxFH6Nm7sxpRplLzxbs/xyGELLIjEBVrgB0CM
-HAxFpPRHDSFpTxGG2mBCSrf+lD2Bf+WiIojx+RLY
+MIIC+TCCAeGgAwIBAgIJALuyfpZeCDiwMA0GCSqGSIb3DQEBBQUAMBMxETAPBgNV
+BAMMCGtleXNldF9BMB4XDTE1MTIwMjIxMTEzNFoXDTQzMDQxOTIxMTEzNFowEzER
+MA8GA1UEAwwIa2V5c2V0X0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCwyk22F07G53uug8NkwyiY6peAkl1F8hamQoSqYLrUy/41/pBjdOisTAl6CGNK
+aqPshsEqu299CrgTZck7Ue6ymZA7g2DaC+f6v7oTA18pz2Tnl3qz7btJHzruMq6s
+Fsc21kwb62MvXIfiv603Ny4kKyDIAWoubEV1zETDM29ETJGmhhzlENHSaZPCQwJS
+EnoIh3URgQqIIR03PG/59Y8RvbW778xamV4YIguzySCVFVvar9Y7MAC8avgVjmmV
+9oTo36Wvv5SxyFD5oyLX66p7CjajSo8VWZk/mGfCPnkrhQzO782GEOpBCxfhxIYR
+LUqAejkxOpGpmM38jt6bDmkVAgMBAAGjUDBOMB0GA1UdDgQWBBTVcIVD9u9538W/
+NE2Y36YiPtYmPzAfBgNVHSMEGDAWgBTVcIVD9u9538W/NE2Y36YiPtYmPzAMBgNV
+HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCjTN3mgaKep55wR1ULf4ULIc/m
+mjfZK7ZnJcynBEIGyjAqt4mMIfKRV/DllLsf997r7bz12qUSLbhWGFSq4a2ceOIp
+RG0+CGXV8Ez5Hz4o99MAP37Zdd5Lfq8fdlg2Mro2MMr21Tf3i2Y2LOfkXEZrW7rQ
+A5ZRVksoRcPQWaaNA85LGRSCiC2XSjg8TLn1qKwQUXVGQ6fwLKqAeeV2+hynADih
+FUaf7HxE5H3bHLByLmLKtab3Ta/g8VXxxRYuyd/rYsWMAHsjZge6xoVajm6Wvj5Q
+AvIxV99+PK7dkjVpg3O2oN1O4DQlqqvxdhjNP733DI4cihfJYV9Vn+wKj3TA
 -----END CERTIFICATE-----
diff --git a/core/tests/coretests/certs/keyset_B.pk8 b/core/tests/coretests/certs/keyset_B.pk8
index a44ebb3..839d96c 100644
--- a/core/tests/coretests/certs/keyset_B.pk8
+++ b/core/tests/coretests/certs/keyset_B.pk8
Binary files differ
diff --git a/core/tests/coretests/certs/keyset_B.x509.pem b/core/tests/coretests/certs/keyset_B.x509.pem
index 2806de5..537e047 100644
--- a/core/tests/coretests/certs/keyset_B.x509.pem
+++ b/core/tests/coretests/certs/keyset_B.x509.pem
@@ -1,14 +1,10 @@
 -----BEGIN CERTIFICATE-----
-MIICKjCCAdQCCQC+5GnAgmYS6DANBgkqhkiG9w0BAQUFADCBmzELMAkGA1UEBhMC
-VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcx
-DzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHQW5kcm9pZDEYMBYGA1UEAxMPd3d3
-LmV4YW1wbGUuY29tMSIwIAYJKoZIhvcNAQkBFhNkY2FzaG1hbkBnb29nbGUuY29t
-MB4XDTE0MDQyMTE4MjczM1oXDTE3MDQyMDE4MjczM1owgZsxCzAJBgNVBAYTAlVT
-MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MQ8w
-DQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB0FuZHJvaWQxGDAWBgNVBAMTD3d3dy5l
-eGFtcGxlLmNvbTEiMCAGCSqGSIb3DQEJARYTZGNhc2htYW5AZ29vZ2xlLmNvbTBc
-MA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDE30LGPFLl4l5r8P8u06a+x6MnwAtJxP/E
-HZN2bRK/WrGuaqj9BescwiNTxlRVfli1UcJuhXQfUrRDS+RCskBXAgMBAAEwDQYJ
-KoZIhvcNAQEFBQADQQCYYyur2/sMB88MOhQE8RHNmdO0zEQYAz66z3ctTNqiNsbK
-T9iKj0CT3cjqgfN5ex4onhnoIIPtON7DIHFWke5x
+MIIBbDCCAROgAwIBAgIJALP/7jQfVyFBMAoGCCqGSM49BAMCMBMxETAPBgNVBAMM
+CGtleXNldF9CMB4XDTE1MTIwMzIwNDgwNFoXDTQzMDQyMDIwNDgwNFowEzERMA8G
+A1UEAwwIa2V5c2V0X0IwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS0avlwvY3v
+O0eIeamEHX/V6r7jeUQCY/fqKIQkB9f5xVF4ZI8Veo2eczxWm13ZugB7ffaWsXD2
+so+ZuRkD6M5Mo1AwTjAdBgNVHQ4EFgQUHrv1BwZU/MchAsa3VL0n458IwVswHwYD
+VR0jBBgwFoAUHrv1BwZU/MchAsa3VL0n458IwVswDAYDVR0TBAUwAwEB/zAKBggq
+hkjOPQQDAgNHADBEAiBp2nTHHhywNIyLpe8mYUsbwozVWM5/2xFidQe9Edua0AIg
+Wt9BCfzrcsBh2Rlje9Im9sq6hIyLSS1pe6ZcI3+lDis=
 -----END CERTIFICATE-----
diff --git a/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java b/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java
index 32b4557..271c639 100644
--- a/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java
+++ b/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java
@@ -188,7 +188,10 @@
 
     private static RegisteredServicesCache.ServiceInfo<TestServiceType> newServiceInfo(
             TestServiceType type, int uid) {
-        return new RegisteredServicesCache.ServiceInfo<>(type, null, uid);
+        final ComponentInfo info = new ComponentInfo();
+        info.applicationInfo = new ApplicationInfo();
+        info.applicationInfo.uid = uid;
+        return new RegisteredServicesCache.ServiceInfo<>(type, info, null);
     }
 
     private void assertNotEmptyFileCreated(TestServicesCache cache, int userId) {
diff --git a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
index c279c8f..d133a12 100644
--- a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
+++ b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
@@ -1191,4 +1191,25 @@
                     InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
         }
     }
+
+    @SmallTest
+    public void testConstructLocaleFromString() throws Exception {
+        assertEquals(new Locale("en"), InputMethodUtils.constructLocaleFromString("en"));
+        assertEquals(new Locale("en", "US"), InputMethodUtils.constructLocaleFromString("en_US"));
+        assertEquals(new Locale("en", "US", "POSIX"),
+                InputMethodUtils.constructLocaleFromString("en_US_POSIX"));
+
+        // Special rewrite rule for "tl" for versions of Android earlier than Lollipop that did not
+        // support three letter language codes, and used "tl" (Tagalog) as the language string for
+        // "fil" (Filipino).
+        assertEquals(new Locale("fil"), InputMethodUtils.constructLocaleFromString("tl"));
+        assertEquals(new Locale("fil", "PH"), InputMethodUtils.constructLocaleFromString("tl_PH"));
+        assertEquals(new Locale("fil", "PH", "POSIX"),
+                InputMethodUtils.constructLocaleFromString("tl_PH_POSIX"));
+
+        // So far rejecting an invalid/unexpected locale string is out of the scope of this method.
+        assertEquals(new Locale("a"), InputMethodUtils.constructLocaleFromString("a"));
+        assertEquals(new Locale("a b c"), InputMethodUtils.constructLocaleFromString("a b c"));
+        assertEquals(new Locale("en-US"), InputMethodUtils.constructLocaleFromString("en-US"));
+    }
 }
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index fc4916c..d98497b 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -30,7 +30,6 @@
     utils/StringUtils.cpp \
     utils/TestWindowContext.cpp \
     utils/VectorDrawableUtils.cpp \
-    utils/TestUtils.cpp \
     AmbientShadow.cpp \
     AnimationContext.cpp \
     Animator.cpp \
@@ -90,6 +89,9 @@
     VectorDrawablePath.cpp \
     protos/hwui.proto
 
+hwui_test_common_src_files := \
+    tests/common/TestUtils.cpp
+
 hwui_cflags := \
     -DEGL_EGLEXT_PROTOTYPES -DGL_GLEXT_PROTOTYPES \
     -DATRACE_TAG=ATRACE_TAG_VIEW -DLOG_TAG=\"OpenGLRenderer\" \
@@ -180,8 +182,8 @@
         -DHWUI_NULL_GPU
 LOCAL_SRC_FILES := \
         $(hwui_src_files) \
-        tests/nullegl.cpp \
-        tests/nullgles.cpp
+        tests/common/nullegl.cpp \
+        tests/common/nullgles.cpp
 LOCAL_C_INCLUDES := $(hwui_c_includes) $(call hwui_proto_include)
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(hwui_c_includes) $(call hwui_proto_include)
 
@@ -215,28 +217,29 @@
         -DHWUI_NULL_GPU
 
 LOCAL_SRC_FILES += \
-    unit_tests/CanvasStateTests.cpp \
-    unit_tests/ClipAreaTests.cpp \
-    unit_tests/DamageAccumulatorTests.cpp \
-    unit_tests/DeviceInfoTests.cpp \
-    unit_tests/FatVectorTests.cpp \
-    unit_tests/LayerUpdateQueueTests.cpp \
-    unit_tests/LinearAllocatorTests.cpp \
-    unit_tests/VectorDrawableTests.cpp \
-    unit_tests/OffscreenBufferPoolTests.cpp \
-    unit_tests/StringUtilsTests.cpp
+    $(hwui_test_common_src_files) \
+    tests/unit/CanvasStateTests.cpp \
+    tests/unit/ClipAreaTests.cpp \
+    tests/unit/DamageAccumulatorTests.cpp \
+    tests/unit/DeviceInfoTests.cpp \
+    tests/unit/FatVectorTests.cpp \
+    tests/unit/LayerUpdateQueueTests.cpp \
+    tests/unit/LinearAllocatorTests.cpp \
+    tests/unit/VectorDrawableTests.cpp \
+    tests/unit/OffscreenBufferPoolTests.cpp \
+    tests/unit/StringUtilsTests.cpp
 
 ifeq (true, $(HWUI_NEW_OPS))
     LOCAL_SRC_FILES += \
-        unit_tests/BakedOpStateTests.cpp \
-        unit_tests/RecordingCanvasTests.cpp \
-        unit_tests/OpReordererTests.cpp
+        tests/unit/BakedOpStateTests.cpp \
+        tests/unit/RecordingCanvasTests.cpp \
+        tests/unit/OpReordererTests.cpp
 endif
 
 include $(BUILD_NATIVE_TEST)
 
 # ------------------------
-# test app
+# Macro-bench app
 # ------------------------
 
 include $(CLEAR_VARS)
@@ -255,11 +258,12 @@
 LOCAL_WHOLE_STATIC_LIBRARIES := libhwui_static
 
 LOCAL_SRC_FILES += \
-    tests/TestContext.cpp \
-    tests/TestSceneRunner.cpp \
-    tests/main.cpp
+    $(hwui_test_common_src_files) \
+    tests/macrobench/TestContext.cpp \
+    tests/macrobench/TestSceneRunner.cpp \
+    tests/macrobench/main.cpp
 
-LOCAL_SRC_FILES += $(call all-cpp-files-under, tests/scenes)
+LOCAL_SRC_FILES += $(call all-cpp-files-under, tests/common/scenes)
 
 include $(BUILD_EXECUTABLE)
 
@@ -285,14 +289,15 @@
 LOCAL_STATIC_LIBRARIES := libbenchmark libbase
 
 LOCAL_SRC_FILES += \
-    microbench/DisplayListCanvasBench.cpp \
-    microbench/LinearAllocatorBench.cpp \
-    microbench/PathParserBench.cpp \
-    microbench/ShadowBench.cpp
+    $(hwui_test_common_src_files) \
+    tests/microbench/DisplayListCanvasBench.cpp \
+    tests/microbench/LinearAllocatorBench.cpp \
+    tests/microbench/PathParserBench.cpp \
+    tests/microbench/ShadowBench.cpp
 
 ifeq (true, $(HWUI_NEW_OPS))
     LOCAL_SRC_FILES += \
-        microbench/OpReordererBench.cpp
+        tests/microbench/OpReordererBench.cpp
 endif
 
 include $(BUILD_EXECUTABLE)
diff --git a/libs/hwui/tests/TestScene.h b/libs/hwui/tests/common/TestScene.h
similarity index 100%
rename from libs/hwui/tests/TestScene.h
rename to libs/hwui/tests/common/TestScene.h
diff --git a/libs/hwui/utils/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
similarity index 100%
rename from libs/hwui/utils/TestUtils.cpp
rename to libs/hwui/tests/common/TestUtils.cpp
diff --git a/libs/hwui/utils/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
similarity index 100%
rename from libs/hwui/utils/TestUtils.h
rename to libs/hwui/tests/common/TestUtils.h
diff --git a/libs/hwui/tests/nullegl.cpp b/libs/hwui/tests/common/nullegl.cpp
similarity index 100%
rename from libs/hwui/tests/nullegl.cpp
rename to libs/hwui/tests/common/nullegl.cpp
diff --git a/libs/hwui/tests/nullgles.cpp b/libs/hwui/tests/common/nullgles.cpp
similarity index 100%
rename from libs/hwui/tests/nullgles.cpp
rename to libs/hwui/tests/common/nullgles.cpp
diff --git a/libs/hwui/tests/scenes/HwLayerAnimation.cpp b/libs/hwui/tests/common/scenes/HwLayerAnimation.cpp
similarity index 100%
rename from libs/hwui/tests/scenes/HwLayerAnimation.cpp
rename to libs/hwui/tests/common/scenes/HwLayerAnimation.cpp
diff --git a/libs/hwui/tests/scenes/ListViewAnimation.cpp b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
similarity index 100%
rename from libs/hwui/tests/scenes/ListViewAnimation.cpp
rename to libs/hwui/tests/common/scenes/ListViewAnimation.cpp
diff --git a/libs/hwui/tests/scenes/OvalAnimation.cpp b/libs/hwui/tests/common/scenes/OvalAnimation.cpp
similarity index 100%
rename from libs/hwui/tests/scenes/OvalAnimation.cpp
rename to libs/hwui/tests/common/scenes/OvalAnimation.cpp
diff --git a/libs/hwui/tests/scenes/PartialDamageAnimation.cpp b/libs/hwui/tests/common/scenes/PartialDamageAnimation.cpp
similarity index 100%
rename from libs/hwui/tests/scenes/PartialDamageAnimation.cpp
rename to libs/hwui/tests/common/scenes/PartialDamageAnimation.cpp
diff --git a/libs/hwui/tests/scenes/RecentsAnimation.cpp b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
similarity index 100%
rename from libs/hwui/tests/scenes/RecentsAnimation.cpp
rename to libs/hwui/tests/common/scenes/RecentsAnimation.cpp
diff --git a/libs/hwui/tests/scenes/RectGridAnimation.cpp b/libs/hwui/tests/common/scenes/RectGridAnimation.cpp
similarity index 100%
rename from libs/hwui/tests/scenes/RectGridAnimation.cpp
rename to libs/hwui/tests/common/scenes/RectGridAnimation.cpp
diff --git a/libs/hwui/tests/scenes/SaveLayerAnimation.cpp b/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp
similarity index 100%
rename from libs/hwui/tests/scenes/SaveLayerAnimation.cpp
rename to libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp
diff --git a/libs/hwui/tests/scenes/ShadowGrid2Animation.cpp b/libs/hwui/tests/common/scenes/ShadowGrid2Animation.cpp
similarity index 100%
rename from libs/hwui/tests/scenes/ShadowGrid2Animation.cpp
rename to libs/hwui/tests/common/scenes/ShadowGrid2Animation.cpp
diff --git a/libs/hwui/tests/scenes/ShadowGridAnimation.cpp b/libs/hwui/tests/common/scenes/ShadowGridAnimation.cpp
similarity index 100%
rename from libs/hwui/tests/scenes/ShadowGridAnimation.cpp
rename to libs/hwui/tests/common/scenes/ShadowGridAnimation.cpp
diff --git a/libs/hwui/tests/scenes/TestSceneBase.h b/libs/hwui/tests/common/scenes/TestSceneBase.h
similarity index 86%
rename from libs/hwui/tests/scenes/TestSceneBase.h
rename to libs/hwui/tests/common/scenes/TestSceneBase.h
index a208509..8a24149 100644
--- a/libs/hwui/tests/scenes/TestSceneBase.h
+++ b/libs/hwui/tests/common/scenes/TestSceneBase.h
@@ -19,10 +19,10 @@
 #include "DisplayListCanvas.h"
 #include "RecordingCanvas.h"
 #include "RenderNode.h"
-#include "tests/Benchmark.h"
-#include "tests/TestContext.h"
-#include "tests/TestScene.h"
-#include "utils/TestUtils.h"
+#include "tests/macrobench/Benchmark.h"
+#include "tests/macrobench/TestContext.h"
+#include "tests/common/TestScene.h"
+#include "tests/common/TestUtils.h"
 
 #include <functional>
 
diff --git a/libs/hwui/tests/Benchmark.h b/libs/hwui/tests/macrobench/Benchmark.h
similarity index 97%
rename from libs/hwui/tests/Benchmark.h
rename to libs/hwui/tests/macrobench/Benchmark.h
index 3f87d7f..aad8eb3 100644
--- a/libs/hwui/tests/Benchmark.h
+++ b/libs/hwui/tests/macrobench/Benchmark.h
@@ -16,7 +16,7 @@
 #ifndef TESTS_BENCHMARK_H
 #define TESTS_BENCHMARK_H
 
-#include "TestScene.h"
+#include "tests/common/TestScene.h"
 
 #include <string>
 #include <vector>
diff --git a/libs/hwui/tests/TestContext.cpp b/libs/hwui/tests/macrobench/TestContext.cpp
similarity index 100%
rename from libs/hwui/tests/TestContext.cpp
rename to libs/hwui/tests/macrobench/TestContext.cpp
diff --git a/libs/hwui/tests/TestContext.h b/libs/hwui/tests/macrobench/TestContext.h
similarity index 100%
rename from libs/hwui/tests/TestContext.h
rename to libs/hwui/tests/macrobench/TestContext.h
diff --git a/libs/hwui/tests/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
similarity index 98%
rename from libs/hwui/tests/TestSceneRunner.cpp
rename to libs/hwui/tests/macrobench/TestSceneRunner.cpp
index 0376e10..1e1c6a1 100644
--- a/libs/hwui/tests/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -18,7 +18,7 @@
 #include "Benchmark.h"
 #include "RenderNode.h"
 #include "TestContext.h"
-#include "scenes/TestSceneBase.h"
+#include "tests/common/scenes/TestSceneBase.h"
 #include "renderthread/RenderProxy.h"
 #include "renderthread/RenderTask.h"
 
diff --git a/libs/hwui/tests/how_to_run.txt b/libs/hwui/tests/macrobench/how_to_run.txt
similarity index 100%
rename from libs/hwui/tests/how_to_run.txt
rename to libs/hwui/tests/macrobench/how_to_run.txt
diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/macrobench/main.cpp
similarity index 100%
rename from libs/hwui/tests/main.cpp
rename to libs/hwui/tests/macrobench/main.cpp
diff --git a/libs/hwui/microbench/DisplayListCanvasBench.cpp b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
similarity index 98%
rename from libs/hwui/microbench/DisplayListCanvasBench.cpp
rename to libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
index 4be1f99..2e59eb4 100644
--- a/libs/hwui/microbench/DisplayListCanvasBench.cpp
+++ b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
@@ -22,8 +22,8 @@
 #else
 #include "DisplayListCanvas.h"
 #endif
-#include "microbench/MicroBench.h"
-#include "utils/TestUtils.h"
+#include "tests/common/TestUtils.h"
+#include "tests/microbench/MicroBench.h"
 
 using namespace android;
 using namespace android::uirenderer;
diff --git a/libs/hwui/microbench/LinearAllocatorBench.cpp b/libs/hwui/tests/microbench/LinearAllocatorBench.cpp
similarity index 97%
rename from libs/hwui/microbench/LinearAllocatorBench.cpp
rename to libs/hwui/tests/microbench/LinearAllocatorBench.cpp
index 75f57cb..28513e4 100644
--- a/libs/hwui/microbench/LinearAllocatorBench.cpp
+++ b/libs/hwui/tests/microbench/LinearAllocatorBench.cpp
@@ -16,8 +16,8 @@
 
 #include <benchmark/Benchmark.h>
 
+#include "tests/microbench/MicroBench.h"
 #include "utils/LinearAllocator.h"
-#include "microbench/MicroBench.h"
 
 #include <vector>
 
diff --git a/libs/hwui/microbench/MicroBench.h b/libs/hwui/tests/microbench/MicroBench.h
similarity index 100%
rename from libs/hwui/microbench/MicroBench.h
rename to libs/hwui/tests/microbench/MicroBench.h
diff --git a/libs/hwui/microbench/OpReordererBench.cpp b/libs/hwui/tests/microbench/OpReordererBench.cpp
similarity index 98%
rename from libs/hwui/microbench/OpReordererBench.cpp
rename to libs/hwui/tests/microbench/OpReordererBench.cpp
index 53b64c3..406bfcc 100644
--- a/libs/hwui/microbench/OpReordererBench.cpp
+++ b/libs/hwui/tests/microbench/OpReordererBench.cpp
@@ -23,7 +23,7 @@
 #include "OpReorderer.h"
 #include "RecordedOp.h"
 #include "RecordingCanvas.h"
-#include "utils/TestUtils.h"
+#include "tests/common/TestUtils.h"
 #include "Vector.h"
 #include "microbench/MicroBench.h"
 
diff --git a/libs/hwui/microbench/PathParserBench.cpp b/libs/hwui/tests/microbench/PathParserBench.cpp
similarity index 100%
rename from libs/hwui/microbench/PathParserBench.cpp
rename to libs/hwui/tests/microbench/PathParserBench.cpp
diff --git a/libs/hwui/microbench/ShadowBench.cpp b/libs/hwui/tests/microbench/ShadowBench.cpp
similarity index 98%
rename from libs/hwui/microbench/ShadowBench.cpp
rename to libs/hwui/tests/microbench/ShadowBench.cpp
index 1b0f5ea..98ec4d9 100644
--- a/libs/hwui/microbench/ShadowBench.cpp
+++ b/libs/hwui/tests/microbench/ShadowBench.cpp
@@ -21,7 +21,7 @@
 #include "Vector.h"
 #include "VertexBuffer.h"
 #include "TessellationCache.h"
-#include "microbench/MicroBench.h"
+#include "tests/microbench/MicroBench.h"
 
 #include <SkPath.h>
 
diff --git a/libs/hwui/microbench/how_to_run.txt b/libs/hwui/tests/microbench/how_to_run.txt
similarity index 100%
rename from libs/hwui/microbench/how_to_run.txt
rename to libs/hwui/tests/microbench/how_to_run.txt
diff --git a/libs/hwui/unit_tests/BakedOpStateTests.cpp b/libs/hwui/tests/unit/BakedOpStateTests.cpp
similarity index 98%
rename from libs/hwui/unit_tests/BakedOpStateTests.cpp
rename to libs/hwui/tests/unit/BakedOpStateTests.cpp
index 7ad2f9b..de14abf 100644
--- a/libs/hwui/unit_tests/BakedOpStateTests.cpp
+++ b/libs/hwui/tests/unit/BakedOpStateTests.cpp
@@ -18,7 +18,7 @@
 
 #include <BakedOpState.h>
 #include <RecordedOp.h>
-#include <utils/TestUtils.h>
+#include <tests/common/TestUtils.h>
 
 namespace android {
 namespace uirenderer {
diff --git a/libs/hwui/unit_tests/CanvasStateTests.cpp b/libs/hwui/tests/unit/CanvasStateTests.cpp
similarity index 100%
rename from libs/hwui/unit_tests/CanvasStateTests.cpp
rename to libs/hwui/tests/unit/CanvasStateTests.cpp
diff --git a/libs/hwui/unit_tests/ClipAreaTests.cpp b/libs/hwui/tests/unit/ClipAreaTests.cpp
similarity index 100%
rename from libs/hwui/unit_tests/ClipAreaTests.cpp
rename to libs/hwui/tests/unit/ClipAreaTests.cpp
diff --git a/libs/hwui/unit_tests/DamageAccumulatorTests.cpp b/libs/hwui/tests/unit/DamageAccumulatorTests.cpp
similarity index 100%
rename from libs/hwui/unit_tests/DamageAccumulatorTests.cpp
rename to libs/hwui/tests/unit/DamageAccumulatorTests.cpp
diff --git a/libs/hwui/unit_tests/DeviceInfoTests.cpp b/libs/hwui/tests/unit/DeviceInfoTests.cpp
similarity index 100%
rename from libs/hwui/unit_tests/DeviceInfoTests.cpp
rename to libs/hwui/tests/unit/DeviceInfoTests.cpp
diff --git a/libs/hwui/unit_tests/FatVectorTests.cpp b/libs/hwui/tests/unit/FatVectorTests.cpp
similarity index 98%
rename from libs/hwui/unit_tests/FatVectorTests.cpp
rename to libs/hwui/tests/unit/FatVectorTests.cpp
index c6ccf4d..64b0ba1 100644
--- a/libs/hwui/unit_tests/FatVectorTests.cpp
+++ b/libs/hwui/tests/unit/FatVectorTests.cpp
@@ -17,7 +17,7 @@
 #include <gtest/gtest.h>
 #include <utils/FatVector.h>
 
-#include <utils/TestUtils.h>
+#include <tests/common/TestUtils.h>
 
 using namespace android;
 using namespace android::uirenderer;
diff --git a/libs/hwui/unit_tests/LayerUpdateQueueTests.cpp b/libs/hwui/tests/unit/LayerUpdateQueueTests.cpp
similarity index 98%
rename from libs/hwui/unit_tests/LayerUpdateQueueTests.cpp
rename to libs/hwui/tests/unit/LayerUpdateQueueTests.cpp
index cc15cc6..8b0e91c 100644
--- a/libs/hwui/unit_tests/LayerUpdateQueueTests.cpp
+++ b/libs/hwui/tests/unit/LayerUpdateQueueTests.cpp
@@ -19,7 +19,7 @@
 #include <LayerUpdateQueue.h>
 #include <RenderNode.h>
 
-#include <utils/TestUtils.h>
+#include <tests/common/TestUtils.h>
 
 namespace android {
 namespace uirenderer {
diff --git a/libs/hwui/unit_tests/LinearAllocatorTests.cpp b/libs/hwui/tests/unit/LinearAllocatorTests.cpp
similarity index 98%
rename from libs/hwui/unit_tests/LinearAllocatorTests.cpp
rename to libs/hwui/tests/unit/LinearAllocatorTests.cpp
index 0591db6..78d65dd 100644
--- a/libs/hwui/unit_tests/LinearAllocatorTests.cpp
+++ b/libs/hwui/tests/unit/LinearAllocatorTests.cpp
@@ -17,7 +17,7 @@
 #include <gtest/gtest.h>
 #include <utils/LinearAllocator.h>
 
-#include <utils/TestUtils.h>
+#include <tests/common/TestUtils.h>
 
 using namespace android;
 using namespace android::uirenderer;
diff --git a/libs/hwui/unit_tests/OffscreenBufferPoolTests.cpp b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
similarity index 98%
rename from libs/hwui/unit_tests/OffscreenBufferPoolTests.cpp
rename to libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
index de86aed..2187654 100644
--- a/libs/hwui/unit_tests/OffscreenBufferPoolTests.cpp
+++ b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
@@ -17,7 +17,7 @@
 #include <gtest/gtest.h>
 #include <renderstate/OffscreenBufferPool.h>
 
-#include <utils/TestUtils.h>
+#include <tests/common/TestUtils.h>
 
 using namespace android;
 using namespace android::uirenderer;
diff --git a/libs/hwui/unit_tests/OpReordererTests.cpp b/libs/hwui/tests/unit/OpReordererTests.cpp
similarity index 99%
rename from libs/hwui/unit_tests/OpReordererTests.cpp
rename to libs/hwui/tests/unit/OpReordererTests.cpp
index 2ce1d0a..98a430a 100644
--- a/libs/hwui/unit_tests/OpReordererTests.cpp
+++ b/libs/hwui/tests/unit/OpReordererTests.cpp
@@ -21,7 +21,7 @@
 #include <OpReorderer.h>
 #include <RecordedOp.h>
 #include <RecordingCanvas.h>
-#include <utils/TestUtils.h>
+#include <tests/common/TestUtils.h>
 
 #include <unordered_map>
 
diff --git a/libs/hwui/unit_tests/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
similarity index 99%
rename from libs/hwui/unit_tests/RecordingCanvasTests.cpp
rename to libs/hwui/tests/unit/RecordingCanvasTests.cpp
index 81f0851..2449ce8 100644
--- a/libs/hwui/unit_tests/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -18,7 +18,7 @@
 
 #include <RecordedOp.h>
 #include <RecordingCanvas.h>
-#include <utils/TestUtils.h>
+#include <tests/common/TestUtils.h>
 
 namespace android {
 namespace uirenderer {
diff --git a/libs/hwui/unit_tests/StringUtilsTests.cpp b/libs/hwui/tests/unit/StringUtilsTests.cpp
similarity index 100%
rename from libs/hwui/unit_tests/StringUtilsTests.cpp
rename to libs/hwui/tests/unit/StringUtilsTests.cpp
diff --git a/libs/hwui/unit_tests/VectorDrawableTests.cpp b/libs/hwui/tests/unit/VectorDrawableTests.cpp
similarity index 100%
rename from libs/hwui/unit_tests/VectorDrawableTests.cpp
rename to libs/hwui/tests/unit/VectorDrawableTests.cpp
diff --git a/libs/hwui/unit_tests/how_to_run.txt b/libs/hwui/tests/unit/how_to_run.txt
similarity index 100%
rename from libs/hwui/unit_tests/how_to_run.txt
rename to libs/hwui/tests/unit/how_to_run.txt
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index bd6af78..6a1167a 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -91,7 +91,14 @@
 
     mLocked.buttonState = 0;
 
+    mPolicy->loadPointerIcon(&mLocked.pointerIcon);
+
     loadResources();
+
+    if (mLocked.pointerIcon.isValid()) {
+        mLocked.pointerIconChanged = true;
+        updatePointerLocked();
+    }
 }
 
 PointerController::~PointerController() {
@@ -325,6 +332,23 @@
     }
 }
 
+void PointerController::reloadPointerResources() {
+    AutoMutex _l(mLock);
+
+    loadResources();
+
+    if (mLocked.presentation == PRESENTATION_POINTER) {
+        mLocked.additionalMouseResources.clear();
+        mLocked.animationResources.clear();
+        mPolicy->loadPointerIcon(&mLocked.pointerIcon);
+        mPolicy->loadAdditionalMouseResources(&mLocked.additionalMouseResources,
+                                              &mLocked.animationResources);
+    }
+
+    mLocked.presentationChanged = true;
+    updatePointerLocked();
+}
+
 void PointerController::setDisplayViewport(int32_t width, int32_t height, int32_t orientation) {
     AutoMutex _l(mLock);
 
@@ -415,15 +439,6 @@
     }
 }
 
-void PointerController::setPointerIcon(const SpriteIcon& icon) {
-    AutoMutex _l(mLock);
-
-    mLocked.pointerIcon = icon.copy();
-    mLocked.pointerIconChanged = true;
-
-    updatePointerLocked();
-}
-
 void PointerController::handleMessage(const Message& message) {
     switch (message.what) {
     case MSG_INACTIVITY_TIMEOUT:
diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h
index b6c01d2..4fd2d85 100644
--- a/libs/input/PointerController.h
+++ b/libs/input/PointerController.h
@@ -62,6 +62,7 @@
     virtual ~PointerControllerPolicyInterface() { }
 
 public:
+    virtual void loadPointerIcon(SpriteIcon* icon) = 0;
     virtual void loadPointerResources(PointerResources* outResources) = 0;
     virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
             std::map<int32_t, PointerAnimation>* outAnimationResources) = 0;
@@ -105,8 +106,8 @@
 
     void updatePointerShape(int32_t iconId);
     void setDisplayViewport(int32_t width, int32_t height, int32_t orientation);
-    void setPointerIcon(const SpriteIcon& icon);
     void setInactivityTimeout(InactivityTimeout inactivityTimeout);
+    void reloadPointerResources();
 
 private:
     static const size_t MAX_RECYCLED_SPRITES = 12;
diff --git a/media/java/android/media/MediaMetadataEditor.java b/media/java/android/media/MediaMetadataEditor.java
index 566b93f..877c872 100644
--- a/media/java/android/media/MediaMetadataEditor.java
+++ b/media/java/android/media/MediaMetadataEditor.java
@@ -73,7 +73,8 @@
 
     /**
      * Applies all of the metadata changes that have been set since the MediaMetadataEditor instance
-     * was created or since {@link #clear()} was called.
+     * was created or since {@link #clear()} was called. Subclasses should synchronize on
+     * {@code this} for thread safety.
      */
     public abstract void apply();
 
diff --git a/packages/DocumentsUI/res/values/config.xml b/packages/DocumentsUI/res/values/config.xml
index ad419aa..ff28e15 100644
--- a/packages/DocumentsUI/res/values/config.xml
+++ b/packages/DocumentsUI/res/values/config.xml
@@ -15,6 +15,9 @@
 -->
 
 <resources>
+    <!-- Allow Advanced Devices default value to be customised -->
+    <bool name="config_defaultAdvancedDevices">false</bool>
+
     <bool name="productivity_device">true</bool>
     <!-- Intentionally unset. Vendors should set this in an overlay. -->
     <string name="trusted_quick_viewer_package"></string>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/LocalPreferences.java b/packages/DocumentsUI/src/com/android/documentsui/LocalPreferences.java
index e6c5ae2..113e9d7 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/LocalPreferences.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/LocalPreferences.java
@@ -24,8 +24,10 @@
     private static final String KEY_FILE_SIZE = "fileSize";
 
     public static boolean getDisplayAdvancedDevices(Context context) {
+        boolean defaultAdvanced = context.getResources()
+                .getBoolean(R.bool.config_defaultAdvancedDevices);
         return PreferenceManager.getDefaultSharedPreferences(context)
-                .getBoolean(KEY_ADVANCED_DEVICES, false);
+                .getBoolean(KEY_ADVANCED_DEVICES, defaultAdvanced);
     }
 
     public static boolean getDisplayFileSize(Context context) {
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerTest.java
index a045d06..ed617e7 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerTest.java
@@ -24,6 +24,9 @@
 import android.test.InstrumentationTestCase;
 
 import java.io.IOException;
+import java.util.concurrent.Callable;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
 
 @RealDeviceTest
 public class MtpManagerTest extends InstrumentationTestCase {
@@ -53,20 +56,23 @@
 
     public void testCancelEvent() throws Exception {
         final CancellationSignal signal = new CancellationSignal();
-        final Thread thread = new Thread() {
-            @Override
-            public void run() {
-                try {
-                    mManager.readEvent(mUsbDevice.getDeviceId(), signal);
-                } catch (OperationCanceledException | IOException e) {
-                    getInstrumentation().show(e.getMessage());
-                }
-            }
-        };
+        final FutureTask<Boolean> future = new FutureTask<Boolean>(
+                new Callable<Boolean>() {
+                    @Override
+                    public Boolean call() throws IOException {
+                        try {
+                            mManager.readEvent(mUsbDevice.getDeviceId(), signal);
+                            return false;
+                        } catch (OperationCanceledException exception) {
+                            return true;
+                        }
+                    }
+                });
+        final Thread thread = new Thread(future);
         thread.start();
         Thread.sleep(TIMEOUT_MS);
         signal.cancel();
-        thread.join(TIMEOUT_MS);
+        assertTrue(future.get(TIMEOUT_MS, TimeUnit.MILLISECONDS));
     }
 
     private Context getContext() {
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResultInstrumentation.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResultInstrumentation.java
index 3e64f9a2..4e4cf78 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResultInstrumentation.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResultInstrumentation.java
@@ -23,6 +23,10 @@
 import junit.framework.Test;
 import junit.framework.TestListener;
 
+/**
+ * Instrumentation that can show the test result in the TestResultActivity.
+ * It's useful when it runs testcases with a real USB device and could not use USB port for ADB.
+ */
 public class TestResultInstrumentation extends InstrumentationTestRunner implements TestListener {
     private boolean mHasError = false;
 
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java
index e6c12cb..f910321 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java
@@ -33,7 +33,7 @@
 /**
  * Static utility methods for testing.
  */
-class TestUtil {
+final class TestUtil {
     private static final String ACTION_USB_PERMISSION =
             "com.android.mtp.USB_PERMISSION";
 
@@ -42,12 +42,11 @@
     /**
      * Requests permission for a MTP device and returns the first MTP device that has at least one
      * storage.
-     * @throws Exception
      */
     static UsbDevice setupMtpDevice(
             TestResultInstrumentation instrumentation,
             UsbManager usbManager,
-            MtpManager manager) throws Exception {
+            MtpManager manager) throws InterruptedException, IOException {
         for (int i = 0; i < 2; i++) {
             final UsbDevice device = findMtpDevice(instrumentation, usbManager);
             manager.openDevice(device.getDeviceId());
@@ -121,7 +120,7 @@
     private static void waitForStorages(
             TestResultInstrumentation instrumentation,
             MtpManager manager,
-            int deviceId) throws Exception {
+            int deviceId) throws IOException, InterruptedException {
         while (true) {
             if (manager.getRoots(deviceId).length == 0) {
                 instrumentation.show("Wait for storages.");
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index bfd8af9..5618e9b 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -21,7 +21,6 @@
     <drawable name="ticker_background_color">#ff1d1d1d</drawable>
     <drawable name="system_bar_background">@color/system_bar_background_opaque</drawable>
     <color name="system_bar_background_opaque">#ff000000</color>
-    <color name="system_bar_background_semi_transparent">#66000000</color> <!-- 40% black -->
     <color name="system_bar_background_transparent">#00000000</color>
     <color name="notification_panel_solid_background">#ff000000</color>
     <drawable name="status_bar_notification_row_background_color">#ff090909</drawable>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 902db26..a0052ce 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -175,7 +175,7 @@
     <integer name="recents_animate_task_view_remove_duration">250</integer>
 
     <!-- The animation duration for scrolling the stack to a particular item. -->
-    <integer name="recents_animate_task_stack_scroll_duration">225</integer>
+    <integer name="recents_animate_task_stack_scroll_duration">200</integer>
 
     <!-- The animation duration for entering and exiting the history. -->
     <integer name="recents_history_transition_duration">250</integer>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d6a361c..002b9f5 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1171,13 +1171,23 @@
     <!-- Toggles fullscreen screenshots. DO NOT TRANSLATE -->
     <string name="overview_fullscreen_thumbnails">Enable fullscreen screenshots</string>
     <!-- Description for the toggle for fullscreen screenshots. DO NOT TRANSLATE -->
-    <string name="overview_fullscreen_thumbnails_desc">Enable fullscreen screenshots in Overview</string>
+    <string name="overview_fullscreen_thumbnails_desc">Enable fullscreen screenshots in Overview. Restart required.</string>
+
+    <!-- Toggle to enable the Overview nav bar gesture. DO NOT TRANSLATE -->
+    <string name="overview_nav_bar_gesture">Enable navigation bar gesture</string>
+    <!-- Description for the toggle to enable the Overview nav bar gesture. DO NOT TRANSLATE -->
+    <string name="overview_nav_bar_gesture_desc">Enables the gesture to enter Overview by swiping up on the Nav bar</string>
 
     <!-- Toggle to show the history view in Overview. DO NOT TRANSLATE -->
     <string name="overview_show_history">Show History</string>
     <!-- Description for the toggle to show the history view in Overview. DO NOT TRANSLATE -->
     <string name="overview_show_history_desc">Enables the history view to see more recent tasks</string>
 
+    <!-- Toggle to set the initial scroll state to be paging or stack. DO NOT TRANSLATE -->
+    <string name="overview_initial_state_paging">Initialize to paging</string>
+    <!-- Description for the toggle to set the initial scroll state to be paging or stack. DO NOT TRANSLATE -->
+    <string name="overview_initial_state_paging_desc">Determines whether Overview will initially be in a stacked or paged state</string>
+
     <!-- Category in the System UI Tuner settings, where new/experimental
          settings are -->
     <string name="experimental">Experimental</string>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index f398af3..8dcf8a7 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -93,11 +93,21 @@
             android:summary="@string/overview_page_on_toggle_desc" />
 
         <com.android.systemui.tuner.TunerSwitch
+            android:key="overview_initial_state_paging"
+            android:title="@string/overview_initial_state_paging"
+            android:summary="@string/overview_initial_state_paging_desc" />
+
+        <com.android.systemui.tuner.TunerSwitch
             android:key="overview_fast_toggle"
             android:title="@string/overview_fast_toggle_via_button"
             android:summary="@string/overview_fast_toggle_via_button_desc" />
 
         <com.android.systemui.tuner.TunerSwitch
+            android:key="overview_nav_bar_gesture"
+            android:title="@string/overview_nav_bar_gesture"
+            android:summary="@string/overview_nav_bar_gesture_desc" />
+
+        <com.android.systemui.tuner.TunerSwitch
             android:key="overview_fullscreen_thumbnails"
             android:title="@string/overview_fullscreen_thumbnails"
             android:summary="@string/overview_fullscreen_thumbnails_desc" />
diff --git a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
index 4cb8a3c..7f6cda0 100644
--- a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
@@ -32,7 +32,7 @@
     /**
      * Docks the top-most task and opens recents.
      */
-    void dockTopTask(boolean draggingInRecents, Rect initialBounds);
+    void dockTopTask(boolean draggingInRecents, int stackCreateMode, Rect initialBounds);
 
     /**
      * Called during a drag-from-navbar-in gesture.
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index c98ecb5..b81c23a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -365,8 +365,8 @@
     }
 
     @Override
-    public void dockTopTask(boolean draggingInRecents, Rect initialBounds) {
-        mImpl.dockTopTask(draggingInRecents, initialBounds);
+    public void dockTopTask(boolean draggingInRecents, int stackCreateMode, Rect initialBounds) {
+        mImpl.dockTopTask(draggingInRecents, stackCreateMode,initialBounds);
         if (draggingInRecents) {
             mDraggingInRecentsCurrentUser = sSystemServicesProxy.getCurrentUser();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 063bb3e..384b86f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -425,10 +425,6 @@
             EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
         }
 
-        if (!launchState.launchedHasConfigurationChanged) {
-            mRecentsView.disableLayersForOneFrame();
-        }
-
         // Notify that recents is now visible
         SystemServicesProxy ssp = Recents.getSystemServices();
         EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, ssp, true));
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
index 43db666..e0bd59b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
@@ -82,7 +82,7 @@
             if (launchedFromHome) {
                 return numTasks - 1;
             } else {
-                if (flags.isFastToggleRecentsEnabled()) {
+                if (flags.isFastToggleRecentsEnabled() || !flags.isInitialStatePaging()) {
                     return numTasks - 1;
                 } else {
                     return numTasks - 2;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index cdfad18..53c10b7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -115,8 +115,8 @@
         // Recompute some values based on the given state, since we can not rely on the resource
         // system to get certain values.
         boolean isLandscape = windowRect.width() > windowRect.height();
-        hasTransposedNavBar = isLandscape && isLargeScreen && !isXLargeScreen;
-        hasTransposedSearchBar = isLandscape && isLargeScreen && !isXLargeScreen;
+        hasTransposedNavBar = isLandscape && !isXLargeScreen;
+        hasTransposedSearchBar = isLandscape && !isXLargeScreen;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
index e8b8816..d778886 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
@@ -30,6 +30,7 @@
     private static final String KEY_PAGE_ON_TOGGLE = "overview_page_on_toggle";
     private static final String KEY_FULLSCREEN_THUMBNAILS = "overview_fullscreen_thumbnails";
     private static final String KEY_SHOW_HISTORY = "overview_show_history";
+    private static final String KEY_INITIAL_STATE_PAGING = "overview_initial_state_paging";
 
     public static class Static {
         // Enables debug drawing for the transition thumbnail
@@ -54,6 +55,7 @@
     private boolean mPageOnToggle;
     private boolean mUseFullscreenThumbnails;
     private boolean mShowHistory;
+    private boolean mInitialStatePaging;
 
     /**
      * We read the prefs once when we start the activity, then update them as the tuner changes
@@ -63,7 +65,7 @@
         // Register all our flags, this will also call onTuningChanged() for each key, which will
         // initialize the current state of each flag
         TunerService.get(context).addTunable(this, KEY_FAST_TOGGLE, KEY_PAGE_ON_TOGGLE,
-                KEY_FULLSCREEN_THUMBNAILS, KEY_SHOW_HISTORY);
+                KEY_FULLSCREEN_THUMBNAILS, KEY_SHOW_HISTORY, KEY_INITIAL_STATE_PAGING);
     }
 
     /**
@@ -94,6 +96,13 @@
         return mShowHistory;
     }
 
+    /**
+     * @return whether the initial stack state is paging.
+     */
+    public boolean isInitialStatePaging() {
+        return mInitialStatePaging;
+    }
+
     @Override
     public void onTuningChanged(String key, String newValue) {
         switch (key) {
@@ -113,6 +122,10 @@
                 mShowHistory = (newValue != null) &&
                         (Integer.parseInt(newValue) != 0);
                 break;
+            case KEY_INITIAL_STATE_PAGING:
+                mInitialStatePaging = (newValue != null) &&
+                        (Integer.parseInt(newValue) != 0);
+                break;
         }
         EventBus.getDefault().send(new DebugFlagsChangedEvent());
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 3efb0cc..2a4017a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -539,12 +539,11 @@
         showRelativeAffiliatedTask(false);
     }
 
-    public void dockTopTask(boolean draggingInRecents, Rect initialBounds) {
+    public void dockTopTask(boolean draggingInRecents, int stackCreateMode, Rect initialBounds) {
         SystemServicesProxy ssp = Recents.getSystemServices();
         ActivityManager.RunningTaskInfo topTask = ssp.getTopMostTask();
         if (topTask != null && !SystemServicesProxy.isHomeStack(topTask.stackId)) {
-            ssp.moveTaskToDockedStack(topTask.id,
-                    ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, initialBounds);
+            ssp.moveTaskToDockedStack(topTask.id, stackCreateMode, initialBounds);
             showRecents(false /* triggeredFromAltTab */, draggingInRecents, false /* animate */,
                     true /* reloadTasks*/);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 2b20c07..5d17e2c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -115,7 +115,6 @@
 
     /** Private constructor */
     public SystemServicesProxy(Context context) {
-        RecentsDebugFlags flags = Recents.getDebugFlags();
         mAccm = AccessibilityManager.getInstance(context);
         mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
         mIam = ActivityManagerNative.getDefault();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index 530cd2d..7a98393 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -137,7 +137,7 @@
 
     /** Returns the index of this task in the list of filtered tasks */
     int indexOf(Task t) {
-        if (mTaskIndices.containsKey(t.key)) {
+        if (t != null && mTaskIndices.containsKey(t.key)) {
             return mTaskIndices.get(t.key);
         }
         return -1;
@@ -199,8 +199,8 @@
     /** Task stack callbacks */
     public interface TaskStackCallbacks {
         /* Notifies when a task has been removed from the stack */
-        void onStackTaskRemoved(TaskStack stack, Task removedTask, int removedTaskIndex,
-                boolean wasFrontMostTask, Task newFrontMostTask);
+        void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask,
+            Task newFrontMostTask);
 
         /* Notifies when a task has been removed from the history */
         void onHistoryTaskRemoved(TaskStack stack, Task removedTask);
@@ -393,8 +393,7 @@
             }
             if (mCb != null) {
                 // Notify that a task has been removed
-                mCb.onStackTaskRemoved(this, t, removedTaskIndex, wasFrontMostTask,
-                        newFrontMostTask);
+                mCb.onStackTaskRemoved(this, t, wasFrontMostTask, newFrontMostTask);
             }
         } else if (mHistoryTaskList.contains(t)) {
             removeTaskImpl(mHistoryTaskList, t);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index dac705d..a0a1bac 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.recents.views;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Canvas;
@@ -27,6 +29,8 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewPropertyAnimator;
 import android.view.WindowInsets;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
@@ -55,6 +59,8 @@
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
+import com.android.systemui.stackdivider.WindowManagerProxy;
+import com.android.systemui.statusbar.FlingAnimationUtils;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -94,8 +100,10 @@
 
     Rect mSystemInsets = new Rect();
 
+    final FlingAnimationUtils mFlingAnimationUtils;
+
     public RecentsView(Context context) {
-        super(context);
+        this(context, null);
     }
 
     public RecentsView(Context context, AttributeSet attrs) {
@@ -118,6 +126,7 @@
                 com.android.internal.R.interpolator.fast_out_linear_in);
         mHistoryTransitionDuration = res.getInteger(R.integer.recents_history_transition_duration);
         mTouchHandler = new RecentsViewTouchHandler(this);
+        mFlingAnimationUtils = new FlingAnimationUtils(context, 0.3f);
 
         LayoutInflater inflater = LayoutInflater.from(context);
         mHistoryButton = inflater.inflate(R.layout.recents_history_button, this, false);
@@ -445,12 +454,6 @@
         return super.verifyDrawable(who);
     }
 
-    public void disableLayersForOneFrame() {
-        if (mTaskStackView != null) {
-            mTaskStackView.disableLayersForOneFrame();
-        }
-    }
-
     /**** TaskStackView.TaskStackCallbacks Implementation ****/
 
     @Override
@@ -517,7 +520,22 @@
     }
 
     public final void onBusEvent(DraggingInRecentsEndedEvent event) {
-        animate().translationY(0f);
+        ViewPropertyAnimator animator = animate();
+        if (event.velocity > mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
+            animator.translationY(getHeight());
+            animator.withEndAction(new Runnable() {
+                @Override
+                public void run() {
+                    WindowManagerProxy.getInstance().maximizeDockedStack();
+                }
+            });
+            mFlingAnimationUtils.apply(animator, getTranslationY(), getHeight(), event.velocity);
+        } else {
+            animator.translationY(0f);
+            animator.setListener(null);
+            mFlingAnimationUtils.apply(animator, getTranslationY(), 0, event.velocity);
+        }
+        animator.start();
     }
 
     public final void onBusEvent(ShowHistoryEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index 5c906a6..7d5daae 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -118,18 +118,21 @@
      */
     public static class StackState {
 
-        public static final StackState FREEFORM_ONLY = new StackState(1f);
-        public static final StackState STACK_ONLY = new StackState(0f);
-        public static final StackState SPLIT = new StackState(0.5f);
+        public static final StackState FREEFORM_ONLY = new StackState(1f, 0);
+        public static final StackState STACK_ONLY = new StackState(0f, 0);
+        public static final StackState SPLIT = new StackState(0.5f, 255);
 
         public final float freeformHeightPct;
+        public final int freeformBackgroundAlpha;
 
         /**
          * @param freeformHeightPct the percentage of the stack height (not including paddings) to
          *                          allocate to the freeform workspace
+         * @param freeformBackgroundAlpha the background alpha for the freeform workspace
          */
-        StackState(float freeformHeightPct) {
+        StackState(float freeformHeightPct, int freeformBackgroundAlpha) {
             this.freeformHeightPct = freeformHeightPct;
+            this.freeformBackgroundAlpha = freeformBackgroundAlpha;
         }
 
         /**
@@ -210,7 +213,7 @@
 
     Context mContext;
     private TaskStackView mStackView;
-    private Interpolator mFastOutSlowInInterpolator;
+    private Interpolator mLinearOutSlowInInterpolator;
     private StackState mState = StackState.SPLIT;
 
     // The task bounds (untransformed) for layout.  This rect is anchored at mTaskRoot.
@@ -278,7 +281,6 @@
     FreeformWorkspaceLayoutAlgorithm mFreeformLayoutAlgorithm;
 
     public TaskStackLayoutAlgorithm(Context context, TaskStackView stackView) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
         Resources res = context.getResources();
         mStackView = stackView;
 
@@ -293,8 +295,8 @@
         mMaxTranslationZ = res.getDimensionPixelSize(R.dimen.recents_task_view_z_max);
         mContext = context;
         mFreeformLayoutAlgorithm = new FreeformWorkspaceLayoutAlgorithm();
-        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
-                com.android.internal.R.interpolator.fast_out_slow_in);
+        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
+                com.android.internal.R.interpolator.linear_out_slow_in);
     }
 
     /**
@@ -309,9 +311,6 @@
      */
     public void setSystemInsets(Rect systemInsets) {
         mSystemInsets.set(systemInsets);
-        if (DEBUG) {
-            Log.d(TAG, "setSystemInsets: " + systemInsets);
-        }
     }
 
     /**
@@ -343,6 +342,7 @@
 
         // The freeform height is the visible height (not including system insets) - padding above
         // freeform and below stack - gap between the freeform and stack
+        mState = state;
         mStackTopOffset = mFocusedPeekHeight + heightPadding;
         mStackBottomOffset = mSystemInsets.bottom + heightPadding;
         state.computeRects(mFreeformRect, mStackRect, taskStackBounds, widthPadding, heightPadding,
@@ -486,8 +486,9 @@
         if (Float.compare(newState, getFocusState()) != 0) {
             mFocusStateAnimator = ObjectAnimator.ofFloat(this, FOCUS_STATE, getFocusState(),
                     newState);
-            mFocusStateAnimator.setDuration(200);
-            mFocusStateAnimator.setInterpolator(mFastOutSlowInInterpolator);
+            mFocusStateAnimator.setDuration(mContext.getResources().getInteger(
+                    R.integer.recents_animate_task_stack_scroll_duration));
+            mFocusStateAnimator.setInterpolator(mLinearOutSlowInInterpolator);
             mFocusStateAnimator.start();
         }
     }
@@ -498,7 +499,8 @@
     public float getDefaultFocusState() {
         RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
         RecentsDebugFlags debugFlags = Recents.getDebugFlags();
-        if (debugFlags.isPageOnToggleEnabled() || launchState.launchedWithAltTab) {
+        if (launchState.launchedWithAltTab ||
+                (debugFlags.isPageOnToggleEnabled() && debugFlags.isInitialStatePaging())) {
             return 1f;
         }
         return 0f;
@@ -514,6 +516,14 @@
     }
 
     /**
+     *
+     * Returns the current stack state.
+     */
+    public StackState getStackState() {
+        return mState;
+    }
+
+    /**
      * Computes the maximum number of visible tasks and thumbnails when the scroll is at the initial
      * stack scroll.  Requires that update() is called first.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index f0d5eab..cc5aaae 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.recents.views;
 
+import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.content.ComponentName;
 import android.content.Context;
@@ -23,8 +24,11 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.util.IntProperty;
 import android.util.Log;
+import android.util.Property;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -90,6 +94,19 @@
     private static final float SHOW_HISTORY_BUTTON_SCROLL_THRESHOLD = 0.3f;
     private static final float HIDE_HISTORY_BUTTON_SCROLL_THRESHOLD = 0.3f;
 
+    public static final Property<ColorDrawable, Integer> COLOR_DRAWABLE_ALPHA =
+            new IntProperty<ColorDrawable>("colorDrawableAlpha") {
+                @Override
+                public void setValue(ColorDrawable object, int alpha) {
+                    object.setAlpha(alpha);
+                }
+
+                @Override
+                public Integer get(ColorDrawable object) {
+                    return object.getAlpha();
+                }
+            };
+
     /** The TaskView callbacks */
     interface TaskStackViewCallbacks {
         public void onTaskViewClicked(TaskStackView stackView, TaskView tv, TaskStack stack, Task t,
@@ -102,10 +119,11 @@
     TaskStackViewTouchHandler mTouchHandler;
     TaskStackViewCallbacks mCb;
     ColorDrawable mFreeformWorkspaceBackground;
+    ObjectAnimator mFreeformWorkspaceBackgroundAnimator;
     ViewPool<TaskView, Task> mViewPool;
     ArrayList<TaskViewTransform> mCurrentTaskTransforms = new ArrayList<>();
     DozeTrigger mUIDozeTrigger;
-    int mFocusedTaskIndex = -1;
+    Task mFocusedTask;
     // Optimizations
     int mStackViewsAnimationDuration;
     boolean mStackViewsDirty = true;
@@ -119,7 +137,6 @@
     int[] mTmpVisibleRange = new int[2];
     Rect mTmpRect = new Rect();
     RectF mTmpTaskRect = new RectF();
-    TaskViewTransform mTmpTransform = new TaskViewTransform();
     TaskViewTransform mTmpStackBackTransform = new TaskViewTransform();
     TaskViewTransform mTmpStackFrontTransform = new TaskViewTransform();
     HashMap<Task, TaskView> mTmpTaskViewMap = new HashMap<>();
@@ -127,7 +144,6 @@
     List<TaskView> mImmutableTaskViews = new ArrayList<>();
     List<TaskView> mTmpTaskViews = new ArrayList<>();
     LayoutInflater mInflater;
-    boolean mLayersDisabled;
     boolean mTouchExplorationEnabled;
 
     Interpolator mFastOutSlowInInterpolator;
@@ -186,6 +202,7 @@
         setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
 
         mFreeformWorkspaceBackground = new ColorDrawable(0x33000000);
+        mFreeformWorkspaceBackground.setCallback(this);
     }
 
     /** Sets the callbacks */
@@ -462,24 +479,14 @@
                         Log.d(TAG, "picking up from pool: " + task.key);
                     }
                     tv = mViewPool.pickUpViewFromPool(task, task);
-                    if (mLayersDisabled) {
-                        tv.disableLayersForOneFrame();
-                    }
                 } else {
                     // Reattach it in the right z order
-                    detachViewFromParent(tv);
-                    int insertIndex = -1;
                     int taskIndex = mStack.indexOfStackTask(task);
-                    taskViews = getTaskViews();
-                    taskViewCount = taskViews.size();
-                    for (int j = 0; j < taskViewCount; j++) {
-                        Task tvTask = taskViews.get(j).getTask();
-                        if (taskIndex <= mStack.indexOfStackTask(tvTask)) {
-                            insertIndex = j;
-                            break;
-                        }
+                    int insertIndex = findTaskViewInsertIndex(task, taskIndex);
+                    if (insertIndex != getTaskViews().indexOf(tv)){
+                        detachViewFromParent(tv);
+                        attachViewToParent(tv, insertIndex, tv.getLayoutParams());
                     }
-                    attachViewToParent(tv, insertIndex, tv.getLayoutParams());
                 }
 
                 // Animate the task into place
@@ -500,9 +507,6 @@
 
                 if (tv == null) {
                     tv = mViewPool.pickUpViewFromPool(task, task);
-                    if (mLayersDisabled) {
-                        tv.disableLayersForOneFrame();
-                    }
                     if (mStackViewsAnimationDuration > 0) {
                         // For items in the list, put them in start animating them from the
                         // approriate ends of the list where they are expected to appear
@@ -613,7 +617,6 @@
         SystemServicesProxy ssp = Recents.getSystemServices();
         if (ssp.hasFreeformWorkspaceSupport()) {
             mTmpRect.set(mLayoutAlgorithm.mFreeformRect);
-            mFreeformWorkspaceBackground.setAlpha(255);
             mFreeformWorkspaceBackground.setBounds(mTmpRect);
         }
 
@@ -643,7 +646,7 @@
      * @return whether or not the stack will scroll as a part of this focus change
      */
     private boolean setFocusedTask(int taskIndex, boolean scrollToTask, final boolean animated,
-                                final boolean requestViewFocus) {
+            final boolean requestViewFocus) {
         // Find the next task to focus
         int newFocusedTaskIndex = mStack.getStackTaskCount() > 0 ?
                 Math.max(0, Math.min(mStack.getStackTaskCount() - 1, taskIndex)) : -1;
@@ -651,16 +654,13 @@
                 mStack.getStackTasks().get(newFocusedTaskIndex) : null;
 
         // Reset the last focused task state if changed
-        if (mFocusedTaskIndex != -1) {
-            Task focusedTask = mStack.getStackTasks().get(mFocusedTaskIndex);
-            if (focusedTask != newFocusedTask) {
-                resetFocusedTask(focusedTask);
-            }
+        if (mFocusedTask != null) {
+            resetFocusedTask(mFocusedTask);
         }
 
         boolean willScroll = false;
-        mFocusedTaskIndex = newFocusedTaskIndex;
-        if (mFocusedTaskIndex != -1) {
+        mFocusedTask = newFocusedTask;
+        if (newFocusedTask != null) {
             Runnable focusTaskRunnable = new Runnable() {
                 @Override
                 public void run() {
@@ -730,13 +730,11 @@
      */
     public void setRelativeFocusedTask(boolean forward, boolean stackTasksOnly, boolean animated,
                                        boolean cancelWindowAnimations) {
-        int newIndex = -1;
-        if (mFocusedTaskIndex != -1) {
+        int newIndex = mStack.indexOfStackTask(mFocusedTask);
+        if (mFocusedTask != null) {
             if (stackTasksOnly) {
                 List<Task> tasks =  mStack.getStackTasks();
-                newIndex = mFocusedTaskIndex;
-                Task task = tasks.get(mFocusedTaskIndex);
-                if (task.isFreeformTask()) {
+                if (mFocusedTask.isFreeformTask()) {
                     // Try and focus the front most stack task
                     TaskView tv = getFrontMostTaskView(stackTasksOnly);
                     if (tv != null) {
@@ -744,7 +742,7 @@
                     }
                 } else {
                     // Try the next task if it is a stack task
-                    int tmpNewIndex = mFocusedTaskIndex + (forward ? -1 : 1);
+                    int tmpNewIndex = newIndex + (forward ? -1 : 1);
                     if (0 <= tmpNewIndex && tmpNewIndex < tasks.size()) {
                         Task t = tasks.get(tmpNewIndex);
                         if (!t.isFreeformTask()) {
@@ -756,7 +754,7 @@
                 // No restrictions, lets just move to the new task (looping forward/backwards if
                 // necessary)
                 int taskCount = mStack.getStackTaskCount();
-                newIndex = (mFocusedTaskIndex + (forward ? -1 : 1) + taskCount) % taskCount;
+                newIndex = (newIndex + (forward ? -1 : 1) + taskCount) % taskCount;
             }
         } else {
             // We don't have a focused task, so focus the first visible task view
@@ -785,17 +783,14 @@
                 tv.setFocusedState(false, false /* animated */, false /* requestViewFocus */);
             }
         }
-        mFocusedTaskIndex = -1;
+        mFocusedTask = null;
     }
 
     /**
      * Returns the focused task.
      */
     Task getFocusedTask() {
-        if (mFocusedTaskIndex != -1) {
-            return mStack.getStackTasks().get(mFocusedTaskIndex);
-        }
-        return null;
+        return mFocusedTask;
     }
 
     @Override
@@ -820,12 +815,13 @@
         super.onInitializeAccessibilityNodeInfo(info);
         List<TaskView> taskViews = getTaskViews();
         int taskViewCount = taskViews.size();
-        if (taskViewCount > 1 && mFocusedTaskIndex != -1) {
+        if (taskViewCount > 1 && mFocusedTask != null) {
             info.setScrollable(true);
-            if (mFocusedTaskIndex > 0) {
+            int focusedTaskIndex = mStack.indexOfStackTask(mFocusedTask);
+            if (focusedTaskIndex > 0) {
                 info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
             }
-            if (mFocusedTaskIndex < mStack.getStackTaskCount() - 1) {
+            if (focusedTaskIndex < mStack.getStackTaskCount() - 1) {
                 info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
             }
         }
@@ -1028,6 +1024,11 @@
             mStartEnterAnimationContext = null;
         }
 
+        // Animate in the freeform workspace
+        animateFreeformWorkspaceBackgroundAlpha(
+                mLayoutAlgorithm.getStackState().freeformBackgroundAlpha, 150,
+                mFastOutSlowInInterpolator);
+
         // Set the task focused state without requesting view focus, and leave the focus animations
         // until after the enter-animation
         RecentsConfiguration config = Recents.getConfiguration();
@@ -1089,11 +1090,11 @@
                     // requesting view focus in onFirstLayout(), actually request view focus and
                     // animate the focused state if we are alt-tabbing now, after the window enter
                     // animation is completed
-                    if (mFocusedTaskIndex != -1) {
+                    if (mFocusedTask != null) {
                         RecentsConfiguration config = Recents.getConfiguration();
                         RecentsActivityLaunchState launchState = config.getLaunchState();
-                        setFocusedTask(mFocusedTaskIndex, false /* scrollToTask */,
-                                launchState.launchedWithAltTab);
+                        setFocusedTask(mStack.indexOfStackTask(mFocusedTask),
+                                false /* scrollToTask */, launchState.launchedWithAltTab);
                     }
                 }
             });
@@ -1107,6 +1108,11 @@
         mStackScroller.stopBoundScrollAnimation();
         // Animate all the task views out of view
         ctx.offscreenTranslationY = mLayoutAlgorithm.mStackRect.bottom;
+        // Dismiss the freeform workspace background
+        int taskViewExitToHomeDuration = getResources().getInteger(
+                R.integer.recents_task_exit_to_home_duration);
+        animateFreeformWorkspaceBackgroundAlpha(0, taskViewExitToHomeDuration,
+                mFastOutSlowInInterpolator);
 
         List<TaskView> taskViews = getTaskViews();
         int taskViewCount = taskViews.size();
@@ -1147,8 +1153,6 @@
 
     @Override
     protected void dispatchDraw(Canvas canvas) {
-        mLayersDisabled = false;
-
         // Draw the freeform workspace background
         SystemServicesProxy ssp = Recents.getSystemServices();
         if (ssp.hasFreeformWorkspaceSupport()) {
@@ -1160,12 +1164,12 @@
         super.dispatchDraw(canvas);
     }
 
-    public void disableLayersForOneFrame() {
-        mLayersDisabled = true;
-        List<TaskView> taskViews = getTaskViews();
-        for (int i = 0; i < taskViews.size(); i++) {
-            taskViews.get(i).disableLayersForOneFrame();
+    @Override
+    protected boolean verifyDrawable(Drawable who) {
+        if (who == mFreeformWorkspaceBackground) {
+            return true;
         }
+        return super.verifyDrawable(who);
     }
 
     /**
@@ -1183,9 +1187,9 @@
     /**** TaskStackCallbacks Implementation ****/
 
     @Override
-    public void onStackTaskRemoved(TaskStack stack, Task removedTask, int removedTaskIndex,
-            boolean wasFrontMostTask, Task newFrontMostTask) {
-        if (mFocusedTaskIndex == removedTaskIndex) {
+    public void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask,
+            Task newFrontMostTask) {
+        if (mFocusedTask == removedTask) {
             resetFocusedTask(removedTask);
         }
 
@@ -1314,19 +1318,8 @@
         tv.setNoUserInteractionState();
 
         // Find the index where this task should be placed in the stack
-        int insertIndex = -1;
         int taskIndex = mStack.indexOfStackTask(task);
-        if (taskIndex != -1) {
-            List<TaskView> taskViews = getTaskViews();
-            int taskViewCount = taskViews.size();
-            for (int i = 0; i < taskViewCount; i++) {
-                Task tvTask = taskViews.get(i).getTask();
-                if (taskIndex < mStack.indexOfStackTask(tvTask)) {
-                    insertIndex = i;
-                    break;
-                }
-            }
-        }
+        int insertIndex = findTaskViewInsertIndex(task, taskIndex);
 
         // Add/attach the view to the hierarchy
         if (isNewView) {
@@ -1344,7 +1337,7 @@
         tv.setCallbacks(this);
         tv.setTouchEnabled(true);
         tv.setClipViewInStack(true);
-        if (mFocusedTaskIndex == taskIndex) {
+        if (mFocusedTask == task) {
             tv.setFocusedState(true, false /* animated */, false /* requestViewFocus */);
         }
     }
@@ -1430,10 +1423,12 @@
     }
 
     public final void onBusEvent(DismissFocusedTaskViewEvent event) {
-        if (mFocusedTaskIndex != -1) {
-            Task t = mStack.getStackTasks().get(mFocusedTaskIndex);
-            TaskView tv = getChildViewForTask(t);
-            tv.dismissTask();
+        if (mFocusedTask != null) {
+            TaskView tv = getChildViewForTask(mFocusedTask);
+            if (tv != null) {
+                tv.dismissTask();
+            }
+            resetFocusedTask(mFocusedTask);
         }
     }
 
@@ -1575,4 +1570,50 @@
         // Remove the task from the stack
         mStack.removeTask(task);
     }
+
+    /**
+     * Starts an alpha animation on the freeform workspace background.
+     */
+    private void animateFreeformWorkspaceBackgroundAlpha(int targetAlpha, int duration,
+            Interpolator interpolator) {
+        if (mFreeformWorkspaceBackground.getAlpha() == targetAlpha) {
+            return;
+        }
+
+        Utilities.cancelAnimationWithoutCallbacks(mFreeformWorkspaceBackgroundAnimator);
+        mFreeformWorkspaceBackgroundAnimator = ObjectAnimator.ofInt(mFreeformWorkspaceBackground,
+                COLOR_DRAWABLE_ALPHA, mFreeformWorkspaceBackground.getAlpha(), targetAlpha);
+        mFreeformWorkspaceBackgroundAnimator.setDuration(duration);
+        mFreeformWorkspaceBackgroundAnimator.setInterpolator(interpolator);
+        mFreeformWorkspaceBackgroundAnimator.start();
+    }
+
+    /**
+     * Returns the insert index for the task in the current set of task views.  If the given task
+     * is already in the task view list, then this method returns the insert index assuming it
+     * is first removed at the previous index.
+     *
+     * @param task the task we are finding the index for
+     * @param taskIndex the index of the task in the stack
+     */
+    private int findTaskViewInsertIndex(Task task, int taskIndex) {
+        if (taskIndex != -1) {
+            List<TaskView> taskViews = getTaskViews();
+            boolean foundTaskView = false;
+            int taskViewCount = taskViews.size();
+            for (int i = 0; i < taskViewCount; i++) {
+                Task tvTask = taskViews.get(i).getTask();
+                if (tvTask == task) {
+                    foundTaskView = true;
+                } else if (taskIndex < mStack.indexOfStackTask(tvTask)) {
+                    if (foundTaskView) {
+                        return i - 1;
+                    } else {
+                        return i;
+                    }
+                }
+            }
+        }
+        return -1;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
index 4095d2e..56942a8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
@@ -49,7 +49,7 @@
     ObjectAnimator mScrollAnimator;
     float mFinalAnimatedScroll;
 
-    Interpolator mLinearOutSlowInInterpolator;
+    private Interpolator mLinearOutSlowInInterpolator;
 
     public TaskStackViewScroller(Context context, TaskStackLayoutAlgorithm layoutAlgorithm) {
         mContext = context;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 907ed2f..1a6f129 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -176,11 +176,11 @@
             }
             case MotionEvent.ACTION_POINTER_DOWN: {
                 final int index = ev.getActionIndex();
-                mDownX = (int) ev.getX();
-                mDownY = (int) ev.getY();
+                mActivePointerId = ev.getPointerId(index);
+                mDownX = (int) ev.getX(index);
+                mDownY = (int) ev.getY(index);
                 mLastY = mDownY;
                 mDownScrollP = mScroller.getStackScroll();
-                mActivePointerId = ev.getPointerId(index);
                 mVelocityTracker.addMovement(ev);
                 break;
             }
@@ -221,6 +221,10 @@
                     // Select a new active pointer id and reset the motion state
                     final int newPointerIndex = (pointerIndex == 0) ? 1 : 0;
                     mActivePointerId = ev.getPointerId(newPointerIndex);
+                    mDownX = (int) ev.getX(pointerIndex);
+                    mDownY = (int) ev.getY(pointerIndex);
+                    mLastY = mDownY;
+                    mDownScrollP = mScroller.getStackScroll();
                 }
                 mVelocityTracker.addMovement(ev);
                 break;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 1baa1a3..813a1fc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -659,10 +659,6 @@
         }
     }
 
-    public void disableLayersForOneFrame() {
-        mHeaderView.disableLayersForOneFrame();
-    }
-
     /**** TaskCallbacks Implementation ****/
 
     /** Binds this task view to the task */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index ec59f31..78a2c7f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -80,13 +80,10 @@
 
     // Header dim, which is only used when task view hardware layers are not used
     Paint mDimLayerPaint = new Paint();
-    PorterDuffColorFilter mDimColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_ATOP);
 
     Interpolator mFastOutSlowInInterpolator;
     Interpolator mFastOutLinearInInterpolator;
 
-    boolean mLayersDisabled;
-
     public TaskViewHeader(Context context) {
         this(context, null);
     }
@@ -111,6 +108,7 @@
         });
 
         // Load the dismiss resources
+        mDimLayerPaint.setColor(Color.argb(0, 0, 0, 0));
         mLightDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_light);
         mDarkDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_dark);
         mDismissContentDescription =
@@ -173,21 +171,13 @@
         canvas.restoreToCount(count);
     }
 
-    @Override
-    public boolean hasOverlappingRendering() {
-        return false;
-    }
-
     /**
      * Sets the dim alpha, only used when we are not using hardware layers.
      * (see RecentsConfiguration.useHardwareLayers)
      */
     void setDimAlpha(int alpha) {
-        mDimColorFilter.setColor(Color.argb(alpha, 0, 0, 0));
-        mDimLayerPaint.setColorFilter(mDimColorFilter);
-        if (!mLayersDisabled) {
-            setLayerType(LAYER_TYPE_HARDWARE, mDimLayerPaint);
-        }
+        mDimLayerPaint.setColor(Color.argb(alpha, 0, 0, 0));
+        invalidate();
     }
 
     /** Returns the secondary color for a primary color. */
@@ -341,23 +331,11 @@
     @Override
     protected void dispatchDraw(Canvas canvas) {
         super.dispatchDraw(canvas);
-        if (mLayersDisabled) {
-            mLayersDisabled = false;
-            postOnAnimation(new Runnable() {
-                @Override
-                public void run() {
-                    mLayersDisabled = false;
-                    setLayerType(LAYER_TYPE_HARDWARE, mDimLayerPaint);
-                }
-            });
-        }
-    }
 
-    public void disableLayersForOneFrame() {
-        mLayersDisabled = true;
-
-        // Disable layer for a frame so we can draw our first frame faster.
-        setLayerType(LAYER_TYPE_NONE, null);
+        // Draw the thumbnail with the rounded corners
+        canvas.drawRoundRect(0, 0, getWidth(), getHeight(),
+                mCornerRadius,
+                mCornerRadius, mDimLayerPaint);
     }
 
     /** Notifies the associated TaskView has been focused. */
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 98f3f0c..93264ff 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -74,7 +74,7 @@
 
     private final Rect mTmpRect = new Rect();
     private final Rect mLastResizeRect = new Rect();
-    private final WindowManagerProxy mWindowManagerProxy = new WindowManagerProxy();
+    private final WindowManagerProxy mWindowManagerProxy = WindowManagerProxy.getInstance();
     private Interpolator mFastOutSlowInInterpolator;
     private final Interpolator mTouchResponseInterpolator =
             new PathInterpolator(0.3f, 0f, 0.1f, 1f);
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
index 0d3f803..58de5d5 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
@@ -37,6 +37,8 @@
 
     private static final String TAG = "WindowManagerProxy";
 
+    private static final WindowManagerProxy sInstance = new WindowManagerProxy();
+
     @GuardedBy("mResizeRect")
     private final Rect mResizeRect = new Rect();
     private final Rect mTmpRect = new Rect();
@@ -78,6 +80,13 @@
         }
     };
 
+    private WindowManagerProxy() {
+    }
+
+    public static WindowManagerProxy getInstance() {
+        return sInstance;
+    }
+
     public void resizeDockedStack(Rect rect) {
         synchronized (mResizeRect) {
             mResizeRect.set(rect);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
index 1601b83..a3f404a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
@@ -146,7 +146,8 @@
                 mWarning = 0xffff0000;
             } else {
                 mOpaque = context.getColor(R.color.system_bar_background_opaque);
-                mSemiTransparent = context.getColor(R.color.system_bar_background_semi_transparent);
+                mSemiTransparent = context.getColor(
+                        com.android.internal.R.color.system_bar_background_semi_transparent);
                 mTransparent = context.getColor(R.color.system_bar_background_transparent);
                 mWarning = context.getColor(com.android.internal.R.color.battery_saver_mode_color);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
index d91bfb9..a2616fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
@@ -16,30 +16,29 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.app.ActivityManager;
 import android.content.Context;
-import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Rect;
-import android.os.SystemProperties;
 import android.view.GestureDetector;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.ViewConfiguration;
-import android.view.WindowManager;
 
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.stackdivider.Divider;
-import com.android.systemui.statusbar.BaseStatusBar;
+import com.android.systemui.tuner.TunerService;
 
 import static android.view.WindowManager.*;
 
 /**
  * Class to detect gestures on the navigation bar.
  */
-public class NavigationBarGestureHelper extends GestureDetector.SimpleOnGestureListener {
+public class NavigationBarGestureHelper extends GestureDetector.SimpleOnGestureListener
+        implements TunerService.Tunable {
 
-    private static final String DOCK_WINDOW_GESTURE_ENABLED_PROP = "persist.dock_gesture_enabled";
+    private static final String KEY_DOCK_WINDOW_GESTURE = "overview_nav_bar_gesture";
 
     /**
      * When dragging from the navigation bar, we drag in recents.
@@ -53,6 +52,7 @@
 
     private RecentsComponent mRecentsComponent;
     private Divider mDivider;
+    private Context mContext;
     private boolean mIsVertical;
     private boolean mIsRTL;
 
@@ -69,13 +69,14 @@
     private int mDragMode;
 
     public NavigationBarGestureHelper(Context context) {
+        mContext = context;
         ViewConfiguration configuration = ViewConfiguration.get(context);
         Resources r = context.getResources();
         mScrollTouchSlop = r.getDimensionPixelSize(R.dimen.navigation_bar_min_swipe_distance);
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
         mMinFlingVelocity = configuration.getScaledMinimumFlingVelocity();
         mTaskSwitcherDetector = new GestureDetector(context, this);
-        mDockWindowEnabled = SystemProperties.getBoolean(DOCK_WINDOW_GESTURE_ENABLED_PROP, false);
+        TunerService.get(context).addTunable(this, KEY_DOCK_WINDOW_GESTURE);
     }
 
     public void setComponents(RecentsComponent recentsComponent, Divider divider) {
@@ -172,6 +173,7 @@
                     == DOCKED_INVALID) {
                 mDragMode = calculateDragMode();
                 Rect initialBounds = null;
+                int createMode = ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
                 if (mDragMode == DRAG_MODE_DIVIDER) {
                     initialBounds = new Rect();
                     mDivider.getView().calculateBoundsForPosition(mIsVertical
@@ -181,8 +183,12 @@
                                     ? DOCKED_TOP
                                     : DOCKED_LEFT,
                             initialBounds);
+                } else if (mDragMode == DRAG_MODE_RECENTS && mTouchDownX
+                        < mContext.getResources().getDisplayMetrics().widthPixels / 2) {
+                    createMode = ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
                 }
-                mRecentsComponent.dockTopTask(mDragMode == DRAG_MODE_RECENTS, initialBounds);
+                mRecentsComponent.dockTopTask(mDragMode == DRAG_MODE_RECENTS, createMode,
+                        initialBounds);
                 if (mDragMode == DRAG_MODE_DIVIDER) {
                     mDivider.getView().startDragging();
                 }
@@ -259,4 +265,14 @@
         }
         return true;
     }
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        switch (key) {
+            case KEY_DOCK_WINDOW_GESTURE:
+                mDockWindowEnabled = (newValue != null) &&
+                        (Integer.parseInt(newValue) != 0);
+                break;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 685c4e5..e51cf7ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1133,7 +1133,9 @@
         @Override
         public boolean onLongClick(View v) {
             if (mRecents != null) {
-                mRecents.dockTopTask(false /* draggingInRecents */, null /* initialBounds */);
+                mRecents.dockTopTask(false /* draggingInRecents */,
+                        ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
+                        null /* initialBounds */);
                 return true;
             }
             return false;
@@ -2486,12 +2488,14 @@
 
             // update status bar mode
             final int sbMode = computeBarMode(oldVal, newVal, mStatusBarView.getBarTransitions(),
-                    View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_TRANSLUCENT);
+                    View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_TRANSLUCENT,
+                    View.STATUS_BAR_TRANSPARENT);
 
             // update navigation bar mode
             final int nbMode = mNavigationBarView == null ? -1 : computeBarMode(
                     oldVal, newVal, mNavigationBarView.getBarTransitions(),
-                    View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT);
+                    View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT,
+                    View.NAVIGATION_BAR_TRANSPARENT);
             final boolean sbModeChanged = sbMode != -1;
             final boolean nbModeChanged = nbMode != -1;
             boolean checkBarModes = false;
@@ -2542,21 +2546,21 @@
     }
 
     private int computeBarMode(int oldVis, int newVis, BarTransitions transitions,
-            int transientFlag, int translucentFlag) {
-        final int oldMode = barMode(oldVis, transientFlag, translucentFlag);
-        final int newMode = barMode(newVis, transientFlag, translucentFlag);
+            int transientFlag, int translucentFlag, int transparentFlag) {
+        final int oldMode = barMode(oldVis, transientFlag, translucentFlag, transparentFlag);
+        final int newMode = barMode(newVis, transientFlag, translucentFlag, transparentFlag);
         if (oldMode == newMode) {
             return -1; // no mode change
         }
         return newMode;
     }
 
-    private int barMode(int vis, int transientFlag, int translucentFlag) {
-        int lightsOutTransparent = View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_TRANSPARENT;
+    private int barMode(int vis, int transientFlag, int translucentFlag, int transparentFlag) {
+        int lightsOutTransparent = View.SYSTEM_UI_FLAG_LOW_PROFILE | transparentFlag;
         return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
                 : (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT
                 : (vis & lightsOutTransparent) == lightsOutTransparent ? MODE_LIGHTS_OUT_TRANSPARENT
-                : (vis & View.SYSTEM_UI_TRANSPARENT) != 0 ? MODE_TRANSPARENT
+                : (vis & transparentFlag) != 0 ? MODE_TRANSPARENT
                 : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
                 : MODE_OPAQUE;
     }
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 6aa5263..033a4b8 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -624,7 +624,13 @@
             byte[] hash = credentialUtil.toHash(credential, userId);
             if (Arrays.equals(hash, storedHash.hash)) {
                 unlockKeystore(credentialUtil.adjustForKeystore(credential), userId);
-                unlockUser(userId, null);
+
+                // TODO: pass through a meaningful token from gatekeeper to
+                // unlock credential keys; for now pass through a stub value to
+                // indicate that we came from a user challenge.
+                final byte[] token = String.valueOf(userId).getBytes();
+                unlockUser(userId, token);
+
                 // migrate credential to GateKeeper
                 credentialUtil.setCredential(credential, null, userId);
                 if (!hasChallenge) {
@@ -677,7 +683,13 @@
         if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
             // credential has matched
             unlockKeystore(credential, userId);
-            unlockUser(userId, null);
+
+            // TODO: pass through a meaningful token from gatekeeper to
+            // unlock credential keys; for now pass through a stub value to
+            // indicate that we came from a user challenge.
+            final byte[] token = String.valueOf(userId).getBytes();
+            unlockUser(userId, token);
+
             UserInfo info = UserManager.get(mContext).getUserInfo(userId);
             if (LockPatternUtils.isSeparateWorkChallengeEnabled() && info.isManagedProfile()) {
                 TrustManager trustManager =
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index bd43a71..807c0d6 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -100,6 +100,7 @@
 import com.android.internal.util.HexDump;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
+import com.android.internal.widget.LockPatternUtils;
 import com.android.server.NativeDaemonConnector.Command;
 import com.android.server.NativeDaemonConnector.SensitiveArg;
 import com.android.server.pm.PackageManagerService;
@@ -435,6 +436,7 @@
     private PackageManagerService mPms;
 
     private final Callbacks mCallbacks;
+    private final LockPatternUtils mLockPatternUtils;
 
     // Two connectors - mConnector & mCryptConnector
     private final CountDownLatch mConnectedSignal = new CountDownLatch(2);
@@ -1429,6 +1431,7 @@
 
         mContext = context;
         mCallbacks = new Callbacks(FgThread.get().getLooper());
+        mLockPatternUtils = new LockPatternUtils(mContext);
 
         // XXX: This will go away soon in favor of IMountServiceObserver
         mPms = (PackageManagerService) ServiceManager.getService("package");
@@ -2721,6 +2724,12 @@
         enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
         waitForReady();
 
+        // When a user has secure lock screen, require a challenge token to
+        // actually unlock. This check is mostly in place for emulation mode.
+        if (mLockPatternUtils.isSecure(userId) && ArrayUtils.isEmpty(token)) {
+            throw new IllegalStateException("Token required to unlock secure user " + userId);
+        }
+
         final String encodedToken;
         if (ArrayUtils.isEmpty(token)) {
             encodedToken = "!";
diff --git a/services/core/java/com/android/server/NativeDaemonConnector.java b/services/core/java/com/android/server/NativeDaemonConnector.java
index e6b6074..d6dbad8 100644
--- a/services/core/java/com/android/server/NativeDaemonConnector.java
+++ b/services/core/java/com/android/server/NativeDaemonConnector.java
@@ -177,6 +177,7 @@
 
             mCallbacks.onDaemonConnected();
 
+            FileDescriptor[] fdList = null;
             byte[] buffer = new byte[BUFFER_SIZE];
             int start = 0;
 
@@ -186,6 +187,7 @@
                     loge("got " + count + " reading with start = " + start);
                     break;
                 }
+                fdList = socket.getAncillaryFileDescriptors();
 
                 // Add our starting point to the count and reset the start.
                 count += start;
@@ -200,8 +202,8 @@
 
                         boolean releaseWl = false;
                         try {
-                            final NativeDaemonEvent event = NativeDaemonEvent.parseRawEvent(
-                                    rawEvent);
+                            final NativeDaemonEvent event =
+                                    NativeDaemonEvent.parseRawEvent(rawEvent, fdList);
 
                             log("RCV <- {" + event + "}");
 
diff --git a/services/core/java/com/android/server/NativeDaemonEvent.java b/services/core/java/com/android/server/NativeDaemonEvent.java
index 4e61c0b..e6feda3 100644
--- a/services/core/java/com/android/server/NativeDaemonEvent.java
+++ b/services/core/java/com/android/server/NativeDaemonEvent.java
@@ -19,6 +19,7 @@
 import android.util.Slog;
 import com.google.android.collect.Lists;
 
+import java.io.FileDescriptor;
 import java.util.ArrayList;
 
 /**
@@ -35,15 +36,17 @@
     private final String mRawEvent;
     private final String mLogMessage;
     private String[] mParsed;
+    private FileDescriptor[] mFdList;
 
     private NativeDaemonEvent(int cmdNumber, int code, String message,
-                              String rawEvent, String logMessage) {
+                              String rawEvent, String logMessage, FileDescriptor[] fdList) {
         mCmdNumber = cmdNumber;
         mCode = code;
         mMessage = message;
         mRawEvent = rawEvent;
         mLogMessage = logMessage;
         mParsed = null;
+        mFdList = fdList;
     }
 
     static public final String SENSITIVE_MARKER = "{{sensitive}}";
@@ -60,6 +63,10 @@
         return mMessage;
     }
 
+    public FileDescriptor[] getFileDescriptors() {
+        return mFdList;
+    }
+
     @Deprecated
     public String getRawEvent() {
         return mRawEvent;
@@ -127,7 +134,7 @@
      * @throws IllegalArgumentException when line doesn't match format expected
      *             from native side.
      */
-    public static NativeDaemonEvent parseRawEvent(String rawEvent) {
+    public static NativeDaemonEvent parseRawEvent(String rawEvent, FileDescriptor[] fdList) {
         final String[] parsed = rawEvent.split(" ");
         if (parsed.length < 2) {
             throw new IllegalArgumentException("Insufficient arguments");
@@ -164,7 +171,7 @@
 
         final String message = rawEvent.substring(skiplength);
 
-        return new NativeDaemonEvent(cmdNumber, code, message, rawEvent, logMessage);
+        return new NativeDaemonEvent(cmdNumber, code, message, rawEvent, logMessage, fdList);
     }
 
     /**
diff --git a/services/core/java/com/android/server/SystemService.java b/services/core/java/com/android/server/SystemService.java
index e0a9ab4..ce3166d 100644
--- a/services/core/java/com/android/server/SystemService.java
+++ b/services/core/java/com/android/server/SystemService.java
@@ -133,6 +133,15 @@
     public void onStartUser(int userHandle) {}
 
     /**
+     * Called when an existing user is unlocked. This means the
+     * credential-encrypted storage for that user is now available, and
+     * encryption-aware component filtering is no longer in effect.
+     *
+     * @param userHandle The identifier of the user.
+     */
+    public void onUnlockUser(int userHandle) {}
+
+    /**
      * Called when switching to a different foreground user, for system services that have
      * special behavior for whichever user is currently in the foreground.  This is called
      * before any application processes are aware of the new user.
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index 92e6814..ecc69e9 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -165,6 +165,19 @@
         }
     }
 
+    public void unlockUser(final int userHandle) {
+        final int serviceLen = mServices.size();
+        for (int i = 0; i < serviceLen; i++) {
+            final SystemService service = mServices.get(i);
+            try {
+                service.onUnlockUser(userHandle);
+            } catch (Exception ex) {
+                Slog.wtf(TAG, "Failure reporting unlock of user " + userHandle
+                        + " to service " + service.getClass().getName(), ex);
+            }
+        }
+    }
+
     public void switchUser(final int userHandle) {
         final int serviceLen = mServices.size();
         for (int i = 0; i < serviceLen; i++) {
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 0b67ad8..6f713cd 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -57,7 +57,6 @@
     private static final boolean LOG = false;
 
     // Enable launching of applications when entering the dock.
-    private static final boolean ENABLE_LAUNCH_CAR_DOCK_APP = true;
     private static final boolean ENABLE_LAUNCH_DESK_DOCK_APP = true;
 
     final Object mLock = new Object();
@@ -76,6 +75,13 @@
     private boolean mComputedNightMode;
     private int mCarModeEnableFlags;
 
+    // flag set by resource, whether to enable Car dock launch when starting car mode.
+    private boolean mEnableCarDockLaunch = true;
+    // flag set by resource, whether to lock UI mode to the default one or not.
+    private boolean mUiModeLocked = false;
+    // flag set by resource, whether to night mode change for normal all or not.
+    private boolean mNightModeLocked = false;
+
     int mCurUiMode = 0;
     private int mSetUiMode = 0;
     private boolean mHoldingConfiguration = false;
@@ -176,6 +182,10 @@
                 com.android.internal.R.integer.config_carDockKeepsScreenOn) == 1);
         mDeskModeKeepsScreenOn = (res.getInteger(
                 com.android.internal.R.integer.config_deskDockKeepsScreenOn) == 1);
+        mEnableCarDockLaunch = res.getBoolean(
+                com.android.internal.R.bool.config_enableCarDockHomeLaunch);
+        mUiModeLocked = res.getBoolean(com.android.internal.R.bool.config_lockUiMode);
+        mNightModeLocked = res.getBoolean(com.android.internal.R.bool.config_lockDayNightMode);
 
         final PackageManager pm = context.getPackageManager();
         mTelevision = pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
@@ -199,6 +209,10 @@
     private final IBinder mService = new IUiModeManager.Stub() {
         @Override
         public void enableCarMode(int flags) {
+            if (isUiModeLocked()) {
+                Slog.e(TAG, "enableCarMode while UI mode is locked");
+                return;
+            }
             final long ident = Binder.clearCallingIdentity();
             try {
                 synchronized (mLock) {
@@ -214,6 +228,10 @@
 
         @Override
         public void disableCarMode(int flags) {
+            if (isUiModeLocked()) {
+                Slog.e(TAG, "disableCarMode while UI mode is locked");
+                return;
+            }
             final long ident = Binder.clearCallingIdentity();
             try {
                 synchronized (mLock) {
@@ -241,6 +259,13 @@
 
         @Override
         public void setNightMode(int mode) {
+            if (isNightModeLocked() &&  (getContext().checkCallingOrSelfPermission(
+                    android.Manifest.permission.MODIFY_DAY_NIGHT_MODE)
+                    != PackageManager.PERMISSION_GRANTED)) {
+                Slog.e(TAG,
+                        "Night mode locked, requires MODIFY_DAY_NIGHT_MODE permission");
+                return;
+            }
             switch (mode) {
                 case UiModeManager.MODE_NIGHT_NO:
                 case UiModeManager.MODE_NIGHT_YES:
@@ -273,6 +298,20 @@
         }
 
         @Override
+        public boolean isUiModeLocked() {
+            synchronized (mLock) {
+                return mUiModeLocked;
+            }
+        }
+
+        @Override
+        public boolean isNightModeLocked() {
+            synchronized (mLock) {
+                return mNightModeLocked;
+            }
+        }
+
+        @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
                     != PackageManager.PERMISSION_GRANTED) {
@@ -293,10 +332,13 @@
             pw.print("  mDockState="); pw.print(mDockState);
                     pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState);
             pw.print("  mNightMode="); pw.print(mNightMode);
+                    pw.print(" mNightModeLocked="); pw.print(mNightModeLocked);
                     pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled);
                     pw.print(" mComputedNightMode="); pw.print(mComputedNightMode);
-                    pw.print(" mCarModeEnableFlags="); pw.println(mCarModeEnableFlags);
+                    pw.print(" mCarModeEnableFlags="); pw.print(mCarModeEnableFlags);
+                    pw.print(" mEnableCarDockLaunch="); pw.println(mEnableCarDockLaunch);
             pw.print("  mCurUiMode=0x"); pw.print(Integer.toHexString(mCurUiMode));
+                    pw.print(" mUiModeLocked="); pw.print(mUiModeLocked);
                     pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode));
             pw.print("  mHoldingConfiguration="); pw.print(mHoldingConfiguration);
                     pw.print(" mSystemReady="); pw.println(mSystemReady);
@@ -356,7 +398,9 @@
 
     private void updateConfigurationLocked() {
         int uiMode = mDefaultUiModeType;
-        if (mTelevision) {
+        if (mUiModeLocked) {
+            // no-op, keeps default one
+        } else if (mTelevision) {
             uiMode = Configuration.UI_MODE_TYPE_TELEVISION;
         } else if (mWatch) {
             uiMode = Configuration.UI_MODE_TYPE_WATCH;
@@ -460,7 +504,7 @@
         } else {
             String category = null;
             if (mCarModeEnabled) {
-                if (ENABLE_LAUNCH_CAR_DOCK_APP
+                if (mEnableCarDockLaunch
                         && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
                     category = Intent.CATEGORY_CAR_DOCK;
                 }
@@ -503,7 +547,7 @@
         if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(action)) {
             // Only launch car home when car mode is enabled and the caller
             // has asked us to switch to it.
-            if (ENABLE_LAUNCH_CAR_DOCK_APP
+            if (mEnableCarDockLaunch
                     && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
                 category = Intent.CATEGORY_CAR_DOCK;
             }
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 93eaf0e..91702cf 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -3484,6 +3484,14 @@
                 return false;
             }
 
+            final ActivityManager am = mContext.getSystemService(ActivityManager.class);
+            if (am.isUserRunningAndLocked(mAccounts.userId)
+                    && !authenticatorInfo.componentInfo.encryptionAware) {
+                Slog.w(TAG, "Blocking binding to authenticator " + authenticatorInfo.componentName
+                        + " which isn't encryption aware");
+                return false;
+            }
+
             Intent intent = new Intent();
             intent.setAction(AccountManager.ACTION_AUTHENTICATOR_INTENT);
             intent.setComponent(authenticatorInfo.componentName);
@@ -3498,7 +3506,6 @@
                 return false;
             }
 
-
             return true;
         }
     }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ef623eb..b769d39 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1487,6 +1487,7 @@
     static final int APP_BOOST_DEACTIVATE_MSG = 58;
     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
     static final int IDLE_UIDS_MSG = 60;
+    static final int SYSTEM_USER_UNLOCK_MSG = 61;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1989,6 +1990,10 @@
                 mSystemServiceManager.startUser(msg.arg1);
                 break;
             }
+            case SYSTEM_USER_UNLOCK_MSG: {
+                mSystemServiceManager.unlockUser(msg.arg1);
+                break;
+            }
             case SYSTEM_USER_CURRENT_MSG: {
                 mBatteryStatsService.noteEvent(
                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 36a7cee..7413e5a 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1424,16 +1424,15 @@
     final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
             boolean preserveWindows) {
         ActivityRecord top = topRunningActivityLocked();
-        if (top == null) {
-            return;
-        }
         if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top
                 + " configChanges=0x" + Integer.toHexString(configChanges));
-        checkTranslucentActivityWaiting(top);
+        if (top != null) {
+            checkTranslucentActivityWaiting(top);
+        }
 
         // If the top activity is not fullscreen, then we need to
         // make sure any activities under it are now visible.
-        boolean aboveTop = true;
+        boolean aboveTop = top != null;
         final boolean stackInvisible = !isStackVisibleLocked();
         boolean behindFullscreenActivity = stackInvisible;
         boolean noStackActivityResumed = (isInStackLocked(starting) == null);
@@ -1447,13 +1446,15 @@
                 if (r.finishing) {
                     continue;
                 }
-                if (aboveTop && r != top) {
+                final boolean isTop = r == top;
+                if (aboveTop && !isTop) {
                     continue;
                 }
                 aboveTop = false;
                 // mLaunchingBehind: Activities launching behind are at the back of the task stack
                 // but must be drawn initially for the animation as though they were visible.
-                if (!behindFullscreenActivity || r.mLaunchTaskBehind) {
+                if ((!behindFullscreenActivity || r.mLaunchTaskBehind)
+                        && okToShowLocked(r)) {
                     if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                             "Make visible? " + r + " finishing=" + r.finishing
                             + " state=" + r.state);
@@ -1464,7 +1465,7 @@
                     }
 
                     if (r.app == null || r.app.thread == null) {
-                        if (makeVisibleAndRestartIfNeeded(starting, configChanges, top,
+                        if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
                                 noStackActivityResumed, r)) {
                             if (activityNdx >= activities.size()) {
                                 // Record may be removed if its process needs to restart.
@@ -1474,18 +1475,19 @@
                             }
                         }
                     } else if (r.visible) {
-                        if (alreadyVisible(r)) {
+                        // If this activity is already visible, then there is nothing to do here.
+                        if (handleAlreadyVisible(r)) {
                             noStackActivityResumed = false;
                         }
                     } else {
-                        becomeVisible(starting, r);
+                        makeVisible(starting, r);
                     }
                     // Aggregate current change flags.
                     configChanges |= r.configChangeFlags;
                     behindFullscreenActivity = updateBehindFullscreen(stackInvisible,
                             behindFullscreenActivity, task, r);
                 } else {
-                    becomeInvisible(stackInvisible, behindFullscreenActivity, r);
+                    makeInvisible(stackInvisible, behindFullscreenActivity, r);
                 }
             }
             if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
@@ -1516,12 +1518,12 @@
     }
 
     private boolean makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
-            ActivityRecord top, boolean noStackActivityResumed, ActivityRecord r) {
+            boolean isTop, boolean noStackActivityResumed, ActivityRecord r) {
         // We need to make sure the app is running if it's the top, or it is just made visible from
         // invisible. If the app is already visible, it must have died while it was visible. In this
         // case, we'll show the dead window but will not restart the app. Otherwise we could end up
         // thrashing.
-        if (r == top || !r.visible) {
+        if (isTop || !r.visible) {
             // This activity needs to be visible, but isn't even running...
             // get it started and resume if no other stack in this stack is resumed.
             if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r);
@@ -1540,7 +1542,7 @@
         return false;
     }
 
-    private void becomeInvisible(boolean stackInvisible, boolean behindFullscreenActivity,
+    private void makeInvisible(boolean stackInvisible, boolean behindFullscreenActivity,
             ActivityRecord r) {
         if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r + " finishing="
                 + r.finishing + " state=" + r.state + " stackInvisible=" + stackInvisible
@@ -1606,7 +1608,7 @@
         return behindFullscreenActivity;
     }
 
-    private void becomeVisible(ActivityRecord starting, ActivityRecord r) {
+    private void makeVisible(ActivityRecord starting, ActivityRecord r) {
         // This activity is not currently visible, but is running. Tell it to become visible.
         r.visible = true;
         if (r.state != ActivityState.RESUMED && r != starting) {
@@ -1631,8 +1633,7 @@
         }
     }
 
-    private boolean alreadyVisible(ActivityRecord r) {
-        // If this activity is already visible, then there is nothing else to do here.
+    private boolean handleAlreadyVisible(ActivityRecord r) {
         if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Skipping: already visible at " + r);
         r.stopFreezingScreenLocked(false);
         try {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index a6af0d10..18b3e62 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2702,7 +2702,6 @@
             Configuration config) {
         if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);
 
-        ArrayList<ActivityRecord> stops = null;
         ArrayList<ActivityRecord> finishes = null;
         ArrayList<UserState> startingUsers = null;
         int NS = 0;
@@ -2756,7 +2755,7 @@
         }
 
         // Atomically retrieve all of the other things to do.
-        stops = processStoppingActivitiesLocked(true);
+        final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(true);
         NS = stops != null ? stops.size() : 0;
         if ((NF = mFinishingActivities.size()) > 0) {
             finishes = new ArrayList<>(mFinishingActivities);
@@ -4304,12 +4303,14 @@
         mWindowManager.getStackBounds(stack.mStackId, info.bounds);
         info.displayId = Display.DEFAULT_DISPLAY;
         info.stackId = stack.mStackId;
+        info.userId = stack.mCurrentUser;
 
         ArrayList<TaskRecord> tasks = stack.getAllTasks();
         final int numTasks = tasks.size();
         int[] taskIds = new int[numTasks];
         String[] taskNames = new String[numTasks];
         Rect[] taskBounds = new Rect[numTasks];
+        int[] taskUserIds = new int[numTasks];
         for (int i = 0; i < numTasks; ++i) {
             final TaskRecord task = tasks.get(i);
             taskIds[i] = task.taskId;
@@ -4319,10 +4320,12 @@
                     : "unknown";
             taskBounds[i] = new Rect();
             mWindowManager.getTaskBounds(task.taskId, taskBounds[i]);
+            taskUserIds[i] = task.userId;
         }
         info.taskIds = taskIds;
         info.taskNames = taskNames;
         info.taskBounds = taskBounds;
+        info.taskUserIds = taskUserIds;
         return info;
     }
 
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 3e0ae17..f6f82da 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -34,6 +34,7 @@
 import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_MSG;
 import static com.android.server.am.ActivityManagerService.SYSTEM_USER_CURRENT_MSG;
 import static com.android.server.am.ActivityManagerService.SYSTEM_USER_START_MSG;
+import static com.android.server.am.ActivityManagerService.SYSTEM_USER_UNLOCK_MSG;
 import static com.android.server.am.ActivityManagerService.USER_SWITCH_TIMEOUT_MSG;
 
 import android.annotation.NonNull;
@@ -81,8 +82,6 @@
 import java.util.List;
 import java.util.Set;
 
-import libcore.util.EmptyArray;
-
 /**
  * Helper class for {@link ActivityManagerService} responsible for multi-user functionality.
  */
@@ -147,7 +146,6 @@
         // User 0 is the first and only user that runs at boot.
         final UserState uss = new UserState(UserHandle.SYSTEM);
         mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
-        updateUserUnlockedState(uss);
         mUserLru.add(UserHandle.USER_SYSTEM);
         updateStartedUserArrayLocked();
     }
@@ -173,8 +171,8 @@
                 num--;
                 continue;
             }
-            if (oldUss.mState == UserState.STATE_STOPPING
-                    || oldUss.mState == UserState.STATE_SHUTDOWN) {
+            if (oldUss.state == UserState.STATE_STOPPING
+                    || oldUss.state == UserState.STATE_SHUTDOWN) {
                 // This user is already stopping, doesn't count.
                 num--;
                 i++;
@@ -199,17 +197,65 @@
     }
 
     void finishUserBoot(UserState uss) {
+        finishUserBoot(uss, null);
+    }
+
+    void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
+        final int userId = uss.mHandle.getIdentifier();
         synchronized (mService) {
-            if (uss.mState == UserState.STATE_BOOTING
-                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
-                uss.mState = UserState.STATE_RUNNING;
-                final int userId = uss.mHandle.getIdentifier();
-                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
+            // Bail if we ended up with a stale user
+            if (mStartedUsers.get(userId) != uss) return;
+
+            // We always walk through all the user lifecycle states to send
+            // consistent developer events. We step into RUNNING_LOCKED here,
+            // but we might immediately step into RUNNING below if the user
+            // storage is already unlocked.
+            if (uss.state == UserState.STATE_BOOTING) {
+                uss.setState(UserState.STATE_RUNNING_LOCKED);
+
+                Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
                 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
-                mService.broadcastIntentLocked(null, null, intent,
-                        null, null, 0, null, null,
-                        new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
+                mService.broadcastIntentLocked(null, null, intent, null, resultTo, 0, null, null,
+                        new String[] { android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
+                        AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
+            }
+
+            maybeUnlockUser(userId);
+        }
+    }
+
+    /**
+     * Consider stepping from {@link UserState#STATE_RUNNING_LOCKED} into
+     * {@link UserState#STATE_RUNNING}, which only occurs if the user storage is
+     * actually unlocked.
+     */
+    void finishUserUnlock(UserState uss) {
+        final int userId = uss.mHandle.getIdentifier();
+        synchronized (mService) {
+            // Bail if we ended up with a stale user
+            if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
+
+            // Only keep marching forward if user is actually unlocked
+            if (!isUserKeyUnlocked(userId)) return;
+
+            if (uss.state == UserState.STATE_RUNNING_LOCKED) {
+                uss.setState(UserState.STATE_RUNNING);
+
+                mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0));
+
+                final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
+                unlockedIntent.addFlags(
+                        Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
+                mService.broadcastIntentLocked(null, null, unlockedIntent, null, null, 0, null,
+                        null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
+                        userId);
+
+                final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
+                bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+                bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
+                mService.broadcastIntentLocked(null, null, bootIntent, null, null, 0, null, null,
+                        new String[] { android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
                         AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
             }
         }
@@ -291,9 +337,9 @@
             uss.mStopCallbacks.add(callback);
         }
 
-        if (uss.mState != UserState.STATE_STOPPING
-                && uss.mState != UserState.STATE_SHUTDOWN) {
-            uss.mState = UserState.STATE_STOPPING;
+        if (uss.state != UserState.STATE_STOPPING
+                && uss.state != UserState.STATE_SHUTDOWN) {
+            uss.setState(UserState.STATE_STOPPING);
             updateStartedUserArrayLocked();
 
             long ident = Binder.clearCallingIdentity();
@@ -321,11 +367,11 @@
                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
                         // On to the next.
                         synchronized (mService) {
-                            if (uss.mState != UserState.STATE_STOPPING) {
+                            if (uss.state != UserState.STATE_STOPPING) {
                                 // Whoops, we are being started back up.  Abort, abort!
                                 return;
                             }
-                            uss.mState = UserState.STATE_SHUTDOWN;
+                            uss.setState(UserState.STATE_SHUTDOWN);
                         }
                         mService.mBatteryStatsService.noteEvent(
                                 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
@@ -355,7 +401,7 @@
             callbacks = new ArrayList<>(uss.mStopCallbacks);
             if (mStartedUsers.get(userId) != uss) {
                 stopped = false;
-            } else if (uss.mState != UserState.STATE_SHUTDOWN) {
+            } else if (uss.state != UserState.STATE_SHUTDOWN) {
                 stopped = false;
             } else {
                 stopped = true;
@@ -438,8 +484,8 @@
                 Integer oldUserId = mUserLru.get(i);
                 UserState oldUss = mStartedUsers.get(oldUserId);
                 if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId
-                        || oldUss.mState == UserState.STATE_STOPPING
-                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
+                        || oldUss.state == UserState.STATE_STOPPING
+                        || oldUss.state == UserState.STATE_SHUTDOWN) {
                     continue;
                 }
                 UserInfo userInfo = getUserInfo(oldUserId);
@@ -482,18 +528,21 @@
         return userManager;
     }
 
-    private void updateUserUnlockedState(UserState uss) {
-        final IMountService mountService = IMountService.Stub
-                .asInterface(ServiceManager.getService("mount"));
+    private IMountService getMountService() {
+        return IMountService.Stub.asInterface(ServiceManager.getService("mount"));
+    }
+
+    private boolean isUserKeyUnlocked(int userId) {
+        final IMountService mountService = getMountService();
         if (mountService != null) {
             try {
-                uss.unlocked = mountService.isUserKeyUnlocked(uss.mHandle.getIdentifier());
+                return mountService.isUserKeyUnlocked(userId);
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             }
         } else {
-            // System isn't fully booted yet, so guess based on property
-            uss.unlocked = !StorageManager.isFileBasedEncryptionEnabled();
+            Slog.w(TAG, "Mount service not published; guessing locked state based on property");
+            return !StorageManager.isFileBasedEncryptionEnabled();
         }
     }
 
@@ -547,8 +596,6 @@
                 }
 
                 final UserState uss = mStartedUsers.get(userId);
-                updateUserUnlockedState(uss);
-
                 final Integer userIdInt = userId;
                 mUserLru.remove(userIdInt);
                 mUserLru.add(userIdInt);
@@ -572,22 +619,22 @@
 
                 // Make sure user is in the started state.  If it is currently
                 // stopping, we need to knock that off.
-                if (uss.mState == UserState.STATE_STOPPING) {
+                if (uss.state == UserState.STATE_STOPPING) {
                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
                     // so we can just fairly silently bring the user back from
                     // the almost-dead.
-                    uss.mState = UserState.STATE_RUNNING;
+                    uss.setState(uss.lastState);
                     updateStartedUserArrayLocked();
                     needStart = true;
-                } else if (uss.mState == UserState.STATE_SHUTDOWN) {
+                } else if (uss.state == UserState.STATE_SHUTDOWN) {
                     // This means ACTION_SHUTDOWN has been sent, so we will
                     // need to treat this as a new boot of the user.
-                    uss.mState = UserState.STATE_BOOTING;
+                    uss.setState(UserState.STATE_BOOTING);
                     updateStartedUserArrayLocked();
                     needStart = true;
                 }
 
-                if (uss.mState == UserState.STATE_BOOTING) {
+                if (uss.state == UserState.STATE_BOOTING) {
                     // Let user manager propagate user restrictions to other services.
                     getUserManager().onBeforeStartUser(userId);
 
@@ -697,35 +744,40 @@
         }
     }
 
+    /**
+     * Attempt to unlock user without a credential token. This typically
+     * succeeds when the device doesn't have credential-encrypted storage, or
+     * when the the credential-encrypted storage isn't tied to a user-provided
+     * PIN or pattern.
+     */
+    boolean maybeUnlockUser(final int userId) {
+        // Try unlocking storage using empty token
+        return unlockUserCleared(userId, null);
+    }
+
     boolean unlockUserCleared(final int userId, byte[] token) {
         synchronized (mService) {
+            // Bail if already running unlocked
             final UserState uss = mStartedUsers.get(userId);
-            if (uss.unlocked) {
-                // Bail early when already unlocked
-                return true;
+            if (uss.state == UserState.STATE_RUNNING) return true;
+        }
+
+        if (!isUserKeyUnlocked(userId)) {
+            final UserInfo userInfo = getUserInfo(userId);
+            final IMountService mountService = getMountService();
+            try {
+                mountService.unlockUserKey(userId, userInfo.serialNumber, token);
+            } catch (RemoteException | RuntimeException e) {
+                Slog.w(TAG, "Failed to unlock: " + e.getMessage());
+                return false;
             }
         }
 
-        final UserInfo userInfo = getUserInfo(userId);
-        final IMountService mountService = IMountService.Stub
-                .asInterface(ServiceManager.getService("mount"));
-        try {
-            mountService.unlockUserKey(userId, userInfo.serialNumber, token);
-        } catch (RemoteException e) {
-            Slog.w(TAG, "Failed to unlock: " + e.getMessage());
-            return false;
-        }
-
         synchronized (mService) {
             final UserState uss = mStartedUsers.get(userId);
-            updateUserUnlockedState(uss);
+            finishUserUnlock(uss);
         }
 
-        final Intent intent = new Intent(Intent.ACTION_USER_UNLOCKED);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
-        mService.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
-                AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, userId);
-
         return true;
     }
 
@@ -1045,8 +1097,8 @@
         for (int i = 0; i < mStartedUsers.size(); i++) {
             UserState uss = mStartedUsers.valueAt(i);
             // This list does not include stopping users.
-            if (uss.mState != UserState.STATE_STOPPING
-                    && uss.mState != UserState.STATE_SHUTDOWN) {
+            if (uss.state != UserState.STATE_STOPPING
+                    && uss.state != UserState.STATE_SHUTDOWN) {
                 num++;
             }
         }
@@ -1054,8 +1106,8 @@
         num = 0;
         for (int i = 0; i < mStartedUsers.size(); i++) {
             UserState uss = mStartedUsers.valueAt(i);
-            if (uss.mState != UserState.STATE_STOPPING
-                    && uss.mState != UserState.STATE_SHUTDOWN) {
+            if (uss.state != UserState.STATE_STOPPING
+                    && uss.state != UserState.STATE_SHUTDOWN) {
                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
                 num++;
             }
@@ -1065,17 +1117,7 @@
     void sendBootCompletedLocked(IIntentReceiver resultTo) {
         for (int i = 0; i < mStartedUsers.size(); i++) {
             UserState uss = mStartedUsers.valueAt(i);
-            if (uss.mState == UserState.STATE_BOOTING) {
-                uss.mState = UserState.STATE_RUNNING;
-                final int userId = mStartedUsers.keyAt(i);
-                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
-                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
-                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
-                mService.broadcastIntentLocked(null, null, intent, null,
-                        resultTo, 0, null, null,
-                        new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
-                        AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
-            }
+            finishUserBoot(uss, resultTo);
         }
     }
 
@@ -1117,14 +1159,33 @@
         if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
             return true;
         }
-        if ((flags & ActivityManager.FLAG_AND_LOCKED) != 0 && state.unlocked) {
-            return false;
+
+        final boolean unlocked;
+        switch (state.state) {
+            case UserState.STATE_STOPPING:
+            case UserState.STATE_SHUTDOWN:
+            default:
+                return false;
+
+            case UserState.STATE_BOOTING:
+            case UserState.STATE_RUNNING_LOCKED:
+                unlocked = false;
+                break;
+
+            case UserState.STATE_RUNNING:
+                unlocked = true;
+                break;
         }
-        if ((flags & ActivityManager.FLAG_AND_UNLOCKED) != 0 && !state.unlocked) {
-            return false;
+
+        if ((flags & ActivityManager.FLAG_AND_LOCKED) != 0) {
+            return !unlocked;
         }
-        return state.mState != UserState.STATE_STOPPING
-                && state.mState != UserState.STATE_SHUTDOWN;
+        if ((flags & ActivityManager.FLAG_AND_UNLOCKED) != 0) {
+            return unlocked;
+        }
+
+        // One way or another, we're running!
+        return true;
     }
 
     UserInfo getCurrentUser() {
diff --git a/services/core/java/com/android/server/am/UserState.java b/services/core/java/com/android/server/am/UserState.java
index b5b5c1d..7b18a17 100644
--- a/services/core/java/com/android/server/am/UserState.java
+++ b/services/core/java/com/android/server/am/UserState.java
@@ -19,28 +19,37 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
 import android.app.IStopUserCallback;
 import android.os.UserHandle;
 import android.util.ArrayMap;
+import android.util.Slog;
 
 public final class UserState {
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "UserState" : TAG_AM;
+
     // User is first coming up.
     public final static int STATE_BOOTING = 0;
+    // User is in the locked running state.
+    public final static int STATE_RUNNING_LOCKED = 1;
     // User is in the normal running state.
-    public final static int STATE_RUNNING = 1;
+    public final static int STATE_RUNNING = 2;
     // User is in the initial process of being stopped.
-    public final static int STATE_STOPPING = 2;
+    public final static int STATE_STOPPING = 3;
     // User is in the final phase of stopping, sending Intent.ACTION_SHUTDOWN.
-    public final static int STATE_SHUTDOWN = 3;
+    public final static int STATE_SHUTDOWN = 4;
 
     public final UserHandle mHandle;
     public final ArrayList<IStopUserCallback> mStopCallbacks
             = new ArrayList<IStopUserCallback>();
 
-    public int mState = STATE_BOOTING;
+    public int state = STATE_BOOTING;
+    public int lastState = STATE_BOOTING;
     public boolean switching;
     public boolean initializing;
-    public boolean unlocked;
 
     /**
      * The last time that a provider was reported to usage stats as being brought to important
@@ -52,22 +61,32 @@
         mHandle = handle;
     }
 
-    void dump(String prefix, PrintWriter pw) {
-        pw.print(prefix); pw.print("mState=");
-        switch (mState) {
-            case STATE_BOOTING: pw.print("BOOTING"); break;
-            case STATE_RUNNING: pw.print("RUNNING"); break;
-            case STATE_STOPPING: pw.print("STOPPING"); break;
-            case STATE_SHUTDOWN: pw.print("SHUTDOWN"); break;
-            default: pw.print(mState); break; 
+    public void setState(int newState) {
+        if (DEBUG_MU) {
+            Slog.i(TAG, "User " + mHandle.getIdentifier() + " state changed from "
+                    + stateToString(state) + " to " + stateToString(newState));
         }
+        lastState = state;
+        state = newState;
+    }
+
+    private static String stateToString(int state) {
+        switch (state) {
+            case STATE_BOOTING: return "BOOTING";
+            case STATE_RUNNING_LOCKED: return "RUNNING_LOCKED";
+            case STATE_RUNNING: return "RUNNING";
+            case STATE_STOPPING: return "STOPPING";
+            case STATE_SHUTDOWN: return "SHUTDOWN";
+            default: return Integer.toString(state);
+        }
+    }
+
+    void dump(String prefix, PrintWriter pw) {
+        pw.print(prefix);
+        pw.print("state="); pw.print(stateToString(state));
+        pw.print(" lastState="); pw.print(stateToString(lastState));
         if (switching) pw.print(" SWITCHING");
         if (initializing) pw.print(" INITIALIZING");
-        if (unlocked) {
-            pw.print(" UNLOCKED");
-        } else {
-            pw.print(" LOCKED");
-        }
         pw.println();
     }
 }
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 4f53882..a066835 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -422,8 +422,8 @@
 
             if (Intent.ACTION_USER_REMOVED.equals(action)) {
                 onUserRemoved(userId);
-            } else if (Intent.ACTION_USER_STARTING.equals(action)) {
-                onUserStarting(userId);
+            } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
+                onUserUnlocked(userId);
             } else if (Intent.ACTION_USER_STOPPING.equals(action)) {
                 onUserStopping(userId);
             }
@@ -517,7 +517,7 @@
 
         intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_USER_REMOVED);
-        intentFilter.addAction(Intent.ACTION_USER_STARTING);
+        intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
         intentFilter.addAction(Intent.ACTION_USER_STOPPING);
         mContext.registerReceiverAsUser(
                 mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null);
@@ -1292,7 +1292,7 @@
         }
     }
 
-    private void onUserStarting(int userId) {
+    private void onUserUnlocked(int userId) {
         // Make sure that accounts we're about to use are valid
         AccountManagerService.getSingleton().validateAccounts(userId);
 
@@ -2673,21 +2673,20 @@
                 final Iterator<SyncOperation> operationIterator =
                         mSyncQueue.getOperations().iterator();
 
-                final ActivityManager activityManager
-                        = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+                final ActivityManager am = mContext.getSystemService(ActivityManager.class);
                 final Set<Integer> removedUsers = Sets.newHashSet();
                 while (operationIterator.hasNext()) {
                     final SyncOperation op = operationIterator.next();
 
-                    // If the user is not running, skip the request.
-                    if (!activityManager.isUserRunning(op.target.userId)) {
+                    // If the user is not running unlocked, skip the request.
+                    if (!am.isUserRunningAndUnlocked(op.target.userId)) {
                         final UserInfo userInfo = mUserManager.getUserInfo(op.target.userId);
                         if (userInfo == null) {
                             removedUsers.add(op.target.userId);
                         }
                         if (isLoggable) {
                             Log.v(TAG, "    Dropping all sync operations for + "
-                                    + op.target.userId + ": user not running.");
+                                    + op.target.userId + ": user not running unlocked.");
                         }
                         continue;
                     }
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index ae8fca8..f2d0031 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -212,6 +212,7 @@
     private static native String nativeDump(long ptr);
     private static native void nativeMonitor(long ptr);
     private static native void nativeSetPointerIconShape(long ptr, int iconId);
+    private static native void nativeReloadPointerIcons(long ptr);
 
     // Input event injection constants defined in InputDispatcher.h.
     private static final int INPUT_EVENT_INJECTION_SUCCEEDED = 0;
@@ -311,12 +312,14 @@
 
         registerPointerSpeedSettingObserver();
         registerShowTouchesSettingObserver();
+        registerAccessibilityLargePointerSettingObserver();
 
         mContext.registerReceiver(new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
                 updatePointerSpeedFromSettings();
                 updateShowTouchesFromSettings();
+                nativeReloadPointerIcons(mPtr);
             }
         }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
 
@@ -1362,6 +1365,17 @@
                 }, UserHandle.USER_ALL);
     }
 
+    private void registerAccessibilityLargePointerSettingObserver() {
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON), true,
+                new ContentObserver(mHandler) {
+                    @Override
+                    public void onChange(boolean selfChange) {
+                        nativeReloadPointerIcons(mPtr);
+                    }
+                }, UserHandle.USER_ALL);
+    }
+
     private int getShowTouchesSetting(int defaultValue) {
         int result = defaultValue;
         try {
@@ -1431,11 +1445,11 @@
         }
     }
 
-  // Binder call
-  @Override
-  public void setPointerIconShape(int iconId) {
-      nativeSetPointerIconShape(mPtr, iconId);
-  }
+    // Binder call
+    @Override
+    public void setPointerIconShape(int iconId) {
+        nativeSetPointerIconShape(mPtr, iconId);
+    }
 
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index 0004c42..d9f94d0 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -278,6 +278,11 @@
                 // Copy over the jobs so we can release the lock before writing.
                 for (int i=0; i<mJobSet.size(); i++) {
                     JobStatus jobStatus = mJobSet.valueAt(i);
+
+                    if (!jobStatus.isPersisted()){
+                        continue;
+                    }
+
                     JobStatus copy = new JobStatus(jobStatus.getJob(), jobStatus.getUid(),
                             jobStatus.getEarliestRunTime(), jobStatus.getLatestRunTimeElapsed());
                     mStoreCopy.add(copy);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 8ef8276..6f19911 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4868,15 +4868,21 @@
                 // Check for results in the current profile.
                 List<ResolveInfo> result = mActivities.queryIntent(
                         intent, resolvedType, flags, userId);
+                result = filterIfNotSystemUser(result, userId);
 
                 // Check for cross profile results.
+                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
                 xpResolveInfo = queryCrossProfileIntents(
-                        matchingFilters, intent, resolvedType, flags, userId);
+                        matchingFilters, intent, resolvedType, flags, userId,
+                        hasNonNegativePriorityResult);
                 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
-                    result.add(xpResolveInfo);
-                    Collections.sort(result, mResolvePrioritySorter);
+                    boolean isVisibleToUser = filterIfNotSystemUser(
+                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
+                    if (isVisibleToUser) {
+                        result.add(xpResolveInfo);
+                        Collections.sort(result, mResolvePrioritySorter);
+                    }
                 }
-                result = filterIfNotSystemUser(result, userId);
                 if (hasWebURI(intent)) {
                     CrossProfileDomainInfo xpDomainInfo = null;
                     final UserInfo parent = getProfileParent(userId);
@@ -5009,6 +5015,14 @@
         return resolveInfos;
     }
 
+    /**
+     * @param resolveInfos list of resolve infos in descending priority order
+     * @return if the list contains a resolve info with non-negative priority
+     */
+    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
+        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
+    }
+
     private static boolean hasWebURI(Intent intent) {
         if (intent.getData() == null) {
             return false;
@@ -5212,10 +5226,10 @@
         return null;
     }
 
-    // Return matching ResolveInfo if any for skip current profile intent filters.
+    // Return matching ResolveInfo in target user if any.
     private ResolveInfo queryCrossProfileIntents(
             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
-            int flags, int sourceUserId) {
+            int flags, int sourceUserId, boolean matchInCurrentProfile) {
         if (matchingFilters != null) {
             // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
             // match the same intent. For performance reasons, it is better not to
@@ -5225,8 +5239,12 @@
             for (int i = 0; i < size; i++) {
                 CrossProfileIntentFilter filter = matchingFilters.get(i);
                 int targetUserId = filter.getTargetUserId();
-                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0
-                        && !alreadyTriedUserIds.get(targetUserId)) {
+                boolean skipCurrentProfile =
+                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
+                boolean skipCurrentProfileIfNoMatchFound =
+                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
+                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
+                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
                     // Checking if there are activities in the target user that can handle the
                     // intent.
                     ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
diff --git a/services/core/java/com/android/server/policy/BarController.java b/services/core/java/com/android/server/policy/BarController.java
index 051b7fb..0c80ffa 100644
--- a/services/core/java/com/android/server/policy/BarController.java
+++ b/services/core/java/com/android/server/policy/BarController.java
@@ -47,6 +47,7 @@
     private final int mTransientFlag;
     private final int mUnhideFlag;
     private final int mTranslucentFlag;
+    private final int mTransparentFlag;
     private final int mStatusBarManagerId;
     private final int mTranslucentWmFlag;
     protected final Handler mHandler;
@@ -63,13 +64,14 @@
     private boolean mNoAnimationOnNextShow;
 
     public BarController(String tag, int transientFlag, int unhideFlag, int translucentFlag,
-            int statusBarManagerId, int translucentWmFlag) {
+            int statusBarManagerId, int translucentWmFlag, int transparentFlag) {
         mTag = "BarController." + tag;
         mTransientFlag = transientFlag;
         mUnhideFlag = unhideFlag;
         mTranslucentFlag = translucentFlag;
         mStatusBarManagerId = statusBarManagerId;
         mTranslucentWmFlag = translucentWmFlag;
+        mTransparentFlag = transparentFlag;
         mHandler = new Handler();
     }
 
@@ -126,13 +128,13 @@
                     vis &= ~mTranslucentFlag;
                 }
                 if ((fl & WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0) {
-                    vis |= View.SYSTEM_UI_TRANSPARENT;
+                    vis |= mTransparentFlag;
                 } else {
-                    vis &= ~View.SYSTEM_UI_TRANSPARENT;
+                    vis &= ~mTransparentFlag;
                 }
             } else {
                 vis = (vis & ~mTranslucentFlag) | (oldVis & mTranslucentFlag);
-                vis = (vis & ~View.SYSTEM_UI_TRANSPARENT) | (oldVis & View.SYSTEM_UI_TRANSPARENT);
+                vis = (vis & ~mTransparentFlag) | (oldVis & mTransparentFlag);
             }
         }
         return vis;
@@ -247,7 +249,7 @@
             }
         }
         if (mShowTransparent) {
-            vis |= View.SYSTEM_UI_TRANSPARENT;
+            vis |= mTransparentFlag;
             if (mSetUnHideFlagWhenNextTransparent) {
                 vis |= mUnhideFlag;
                 mSetUnHideFlagWhenNextTransparent = false;
@@ -258,7 +260,7 @@
             vis &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;  // never show transient bars in low profile
         }
         if ((vis & mTranslucentFlag) != 0 || (oldVis & mTranslucentFlag) != 0 ||
-                ((vis | oldVis) & View.SYSTEM_UI_TRANSPARENT) != 0) {
+                ((vis | oldVis) & mTransparentFlag) != 0) {
             mLastTranslucent = SystemClock.uptimeMillis();
         }
         return vis;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 9a7d153..fe427d3 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -158,8 +158,7 @@
     static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
 
     // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
-    // No longer recommended for desk docks; still useful in car docks.
-    static final boolean ENABLE_CAR_DOCK_HOME_CAPTURE = true;
+    // No longer recommended for desk docks;
     static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = false;
 
     static final int SHORT_PRESS_POWER_NOTHING = 0;
@@ -210,7 +209,8 @@
             | View.SYSTEM_UI_FLAG_FULLSCREEN
             | View.STATUS_BAR_TRANSLUCENT
             | View.NAVIGATION_BAR_TRANSLUCENT
-            | View.SYSTEM_UI_TRANSPARENT;
+            | View.STATUS_BAR_TRANSPARENT
+            | View.NAVIGATION_BAR_TRANSPARENT;
 
     private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
             .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
@@ -316,6 +316,10 @@
     int[] mNavigationBarHeightForRotation = new int[4];
     int[] mNavigationBarWidthForRotation = new int[4];
 
+    // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
+    // This is for car dock and this is updated from resource.
+    private boolean mEnableCarDockHomeCapture = true;
+
     boolean mBootMessageNeedsHiding;
     KeyguardServiceDelegate mKeyguardDelegate;
     final Runnable mWindowManagerDrawCallback = new Runnable() {
@@ -623,6 +627,8 @@
     private final LogDecelerateInterpolator mLogDecelerateInterpolator
             = new LogDecelerateInterpolator(100, 0);
 
+    private boolean mForceWindowDrawsStatusBarBackground;
+
     private static final int MSG_ENABLE_POINTER_LOCATION = 1;
     private static final int MSG_DISABLE_POINTER_LOCATION = 2;
     private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
@@ -803,7 +809,8 @@
             View.NAVIGATION_BAR_UNHIDE,
             View.NAVIGATION_BAR_TRANSLUCENT,
             StatusBarManager.WINDOW_NAVIGATION_BAR,
-            WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
+            WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
+            View.NAVIGATION_BAR_TRANSPARENT);
 
     private ImmersiveModeConfirmation mImmersiveModeConfirmation;
 
@@ -1398,6 +1405,8 @@
         mHomeIntent.addCategory(Intent.CATEGORY_HOME);
         mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+        mEnableCarDockHomeCapture = context.getResources().getBoolean(
+                com.android.internal.R.bool.config_enableCarDockHomeLaunch);
         mCarDockIntent =  new Intent(Intent.ACTION_MAIN, null);
         mCarDockIntent.addCategory(Intent.CATEGORY_CAR_DOCK);
         mCarDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
@@ -1582,6 +1591,8 @@
 
         mScreenshotChordEnabled = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_enableScreenshotChord);
+        mForceWindowDrawsStatusBarBackground = mContext.getResources().getBoolean(
+                R.bool.config_forceWindowDrawsStatusBarBackground);
 
         mGlobalKeyManager = new GlobalKeyManager(mContext);
 
@@ -2044,10 +2055,14 @@
             attrs.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
         }
 
-        if (ActivityManager.isHighEndGfx()
-                && (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0) {
-            attrs.subtreeSystemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
-                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
+        if (ActivityManager.isHighEndGfx()) {
+            if ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0) {
+                attrs.subtreeSystemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
+            }
+            if ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
+                    || mForceWindowDrawsStatusBarBackground) {
+                attrs.subtreeSystemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+            }
         }
     }
 
@@ -3604,7 +3619,7 @@
             final int sysui = mLastSystemUiFlags;
             boolean navVisible = (sysui & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
             boolean navTranslucent = (sysui
-                    & (View.NAVIGATION_BAR_TRANSLUCENT | View.SYSTEM_UI_TRANSPARENT)) != 0;
+                    & (View.NAVIGATION_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSPARENT)) != 0;
             boolean immersive = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0;
             boolean immersiveSticky = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;
             boolean navAllowedHidden = immersive || immersiveSticky;
@@ -3672,7 +3687,7 @@
 
             boolean statusBarTransient = (sysui & View.STATUS_BAR_TRANSIENT) != 0;
             boolean statusBarTranslucent = (sysui
-                    & (View.STATUS_BAR_TRANSLUCENT | View.SYSTEM_UI_TRANSPARENT)) != 0;
+                    & (View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT)) != 0;
             if (!isKeyguardShowing) {
                 statusBarTranslucent &= areTranslucentBarsAllowed();
             }
@@ -4003,7 +4018,8 @@
                         && (fl & WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0
                         && (fl & WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) == 0
                         && (fl & WindowManager.LayoutParams.
-                                FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0) {
+                                FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
+                        && !mForceWindowDrawsStatusBarBackground) {
                     // Ensure policy decor includes status bar
                     dcf.top = mStableTop;
                 }
@@ -6404,7 +6420,7 @@
      * true:
      * <ul>
      *  <li>The device is not in either car mode or desk mode
-     *  <li>The device is in car mode but ENABLE_CAR_DOCK_HOME_CAPTURE is false
+     *  <li>The device is in car mode but mEnableCarDockHomeCapture is false
      *  <li>The device is in desk mode but ENABLE_DESK_DOCK_HOME_CAPTURE is false
      *  <li>The device is in car mode but there's no CAR_DOCK app with METADATA_DOCK_HOME
      *  <li>The device is in desk mode but there's no DESK_DOCK app with METADATA_DOCK_HOME
@@ -6418,7 +6434,7 @@
         // is, when in car mode you should be taken to car home regardless
         // of whether we are actually in a car dock.
         if (mUiMode == Configuration.UI_MODE_TYPE_CAR) {
-            if (ENABLE_CAR_DOCK_HOME_CAPTURE) {
+            if (mEnableCarDockHomeCapture) {
                 intent = mCarDockIntent;
             }
         } else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) {
@@ -6728,10 +6744,7 @@
         final boolean freeformStackVisible =
                 mWindowManagerInternal.isStackVisible(FREEFORM_WORKSPACE_STACK_ID);
         final boolean forceShowSystemBars = dockedStackVisible || freeformStackVisible;
-        // TODO(multi-window): Update to force opaque independently for status bar and nav bar.
-        // This will require refactoring the code to have separate vis flag for each bar so it can
-        // be adjusted independently.
-        final boolean forceOpaqueSystemBars = forceShowSystemBars;
+        final boolean forceOpaqueSystemBars = forceShowSystemBars && !mForceStatusBarFromKeyguard;
 
         // apply translucent bar vis flags
         WindowState transWin = isStatusBarKeyguard() && !mHideLockScreen
@@ -6761,6 +6774,11 @@
                     | View.SYSTEM_UI_TRANSPARENT);
         }
 
+        if (mForceWindowDrawsStatusBarBackground) {
+            vis |= View.STATUS_BAR_TRANSPARENT;
+            vis &= ~View.STATUS_BAR_TRANSLUCENT;
+        }
+
         // update status bar
         boolean immersiveSticky =
                 (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;
@@ -6938,6 +6956,7 @@
         pw.print(prefix); pw.print("mSupportAutoRotation="); pw.println(mSupportAutoRotation);
         pw.print(prefix); pw.print("mUiMode="); pw.print(mUiMode);
                 pw.print(" mDockMode="); pw.print(mDockMode);
+                pw.print(" mEnableCarDockHomeCapture="); pw.print(mEnableCarDockHomeCapture);
                 pw.print(" mCarDockRotation="); pw.print(mCarDockRotation);
                 pw.print(" mDeskDockRotation="); pw.println(mDeskDockRotation);
         pw.print(prefix); pw.print("mUserRotationMode="); pw.print(mUserRotationMode);
diff --git a/services/core/java/com/android/server/policy/StatusBarController.java b/services/core/java/com/android/server/policy/StatusBarController.java
index b935f5a..9d353c6 100644
--- a/services/core/java/com/android/server/policy/StatusBarController.java
+++ b/services/core/java/com/android/server/policy/StatusBarController.java
@@ -111,7 +111,8 @@
                 View.STATUS_BAR_UNHIDE,
                 View.STATUS_BAR_TRANSLUCENT,
                 StatusBarManager.WINDOW_STATUS_BAR,
-                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
+                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
+                View.STATUS_BAR_TRANSPARENT);
     }
 
     public AppTransitionListener getAppTransitionListener() {
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index df8d5d6..32c9b2a 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -20,8 +20,6 @@
 import android.graphics.Rect;
 import android.os.RemoteException;
 import android.util.Slog;
-import android.util.SparseArray;
-import android.util.SparseIntArray;
 import android.view.IDockDividerVisibilityListener;
 
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
@@ -46,6 +44,7 @@
     private final Rect mLastRect = new Rect();
     private IDockDividerVisibilityListener mListener;
     private boolean mLastVisibility = false;
+    private boolean mForceVisibilityReevaluation;
 
     DockedStackDividerController(Context context, DisplayContent displayContent) {
         mDisplayContent = displayContent;
@@ -69,16 +68,16 @@
 
     void setWindow(WindowState window) {
         mWindow = window;
-        reevaluateVisibility();
+        reevaluateVisibility(false);
     }
 
-    void reevaluateVisibility() {
+    void reevaluateVisibility(boolean force) {
         if (mWindow == null) {
             return;
         }
         TaskStack stack = mDisplayContent.mService.mStackIdToStack.get(DOCKED_STACK_ID);
         final boolean visible = stack != null && stack.isVisibleLocked();
-        if (mLastVisibility == visible) {
+        if (mLastVisibility == visible && !force) {
             return;
         }
         mLastVisibility = visible;
@@ -131,5 +130,6 @@
             throw new IllegalStateException("Dock divider visibility listener already set!");
         }
         mListener = listener;
+        reevaluateVisibility(true);
     }
 }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 22f1d63..e4f6c56 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -252,7 +252,7 @@
         }
 
         int boundsChange = BOUNDS_CHANGE_NONE;
-        if (mBounds.left != bounds.left || mBounds.right != bounds.right) {
+        if (mBounds.left != bounds.left || mBounds.top != bounds.top) {
             boundsChange |= BOUNDS_CHANGE_POSITION;
         }
         if (mBounds.width() != bounds.width() || mBounds.height() != bounds.height()) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 4736c60..de1f4d1 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2517,7 +2517,7 @@
     }
 
     void repositionChild(Session session, IWindow client,
-            int top, int left, int right, int bottom,
+            int left, int top, int right, int bottom,
             long deferTransactionUntilFrame, Rect outFrame) {
         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "repositionChild");
         long origId = Binder.clearCallingIdentity();
@@ -2538,23 +2538,24 @@
                 win.mAttrs.y = top;
                 win.mAttrs.width = right - left;
                 win.mAttrs.height = bottom - top;
-
                 win.setWindowScale(win.mRequestedWidth, win.mRequestedHeight);
 
-                win.mWinAnimator.computeShownFrameLocked();
-
                 if (SHOW_TRANSACTIONS) {
                     Slog.i(TAG, ">>> OPEN TRANSACTION repositionChild");
                 }
 
                 SurfaceControl.openTransaction();
 
+                win.applyGravityAndUpdateFrame();
+                win.mWinAnimator.computeShownFrameLocked();
+
+                win.mWinAnimator.setSurfaceBoundariesLocked(false);
+
                 if (deferTransactionUntilFrame > 0) {
                     win.mWinAnimator.mSurfaceController.deferTransactionUntil(
                             win.mAttachedWindow.mWinAnimator.mSurfaceController.getHandle(),
                             deferTransactionUntilFrame);
                 }
-                win.mWinAnimator.setSurfaceBoundariesLocked(false);
 
                 SurfaceControl.closeTransaction();
                 if (SHOW_TRANSACTIONS) {
@@ -2588,6 +2589,7 @@
             if (win == null) {
                 return 0;
             }
+
             WindowStateAnimator winAnimator = win.mWinAnimator;
             if (viewVisibility != View.GONE) {
                 win.setRequestedSize(requestedWidth, requestedHeight);
@@ -8028,7 +8030,7 @@
                 case UPDATE_DOCKED_STACK_DIVIDER: {
                     synchronized (mWindowMap) {
                         getDefaultDisplayContentLocked().getDockedDividerController()
-                                .reevaluateVisibility();
+                                .reevaluateVisibility(false);
                     }
                 }
                 break;
@@ -10193,7 +10195,7 @@
     public void setReplacingWindow(IBinder token, boolean animate) {
         synchronized (mWindowMap) {
             AppWindowToken appWindowToken = findAppWindowToken(token);
-            if (appWindowToken == null) {
+            if (appWindowToken == null || !appWindowToken.isVisible()) {
                 Slog.w(TAG, "Attempted to set replacing window on non-existing app token " + token);
                 return;
             }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index cfa2bb3..5e38492 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -72,6 +72,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
 import static android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.MATCH_PARENT;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
@@ -618,39 +619,6 @@
         final int pw = mContainingFrame.width();
         final int ph = mContainingFrame.height();
 
-        int w,h;
-        if ((mAttrs.flags & FLAG_SCALED) != 0) {
-            if (mAttrs.width < 0) {
-                w = pw;
-            } else if (mEnforceSizeCompat) {
-                w = (int)(mAttrs.width * mGlobalScale + .5f);
-            } else {
-                w = mAttrs.width;
-            }
-            if (mAttrs.height < 0) {
-                h = ph;
-            } else if (mEnforceSizeCompat) {
-                h = (int)(mAttrs.height * mGlobalScale + .5f);
-            } else {
-                h = mAttrs.height;
-            }
-        } else {
-            if (mAttrs.width == WindowManager.LayoutParams.MATCH_PARENT) {
-                w = pw;
-            } else if (mEnforceSizeCompat) {
-                w = (int)(mRequestedWidth * mGlobalScale + .5f);
-            } else {
-                w = mRequestedWidth;
-            }
-            if (mAttrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
-                h = ph;
-            } else if (mEnforceSizeCompat) {
-                h = (int)(mRequestedHeight * mGlobalScale + .5f);
-            } else {
-                h = mRequestedHeight;
-            }
-        }
-
         if (!mParentFrame.equals(pf)) {
             //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame
             //        + " to " + pf);
@@ -676,28 +644,7 @@
         final int fw = mFrame.width();
         final int fh = mFrame.height();
 
-        float x, y;
-        if (mEnforceSizeCompat) {
-            x = mAttrs.x * mGlobalScale;
-            y = mAttrs.y * mGlobalScale;
-        } else {
-            x = mAttrs.x;
-            y = mAttrs.y;
-        }
-
-        if (nonFullscreenTask) {
-            // Make sure window fits in containing frame since it is in a non-fullscreen stack as
-            // required by {@link Gravity#apply} call.
-            w = Math.min(w, pw);
-            h = Math.min(h, ph);
-        }
-
-        Gravity.apply(mAttrs.gravity, w, h, mContainingFrame,
-                (int) (x + mAttrs.horizontalMargin * pw),
-                (int) (y + mAttrs.verticalMargin * ph), mFrame);
-
-        // Now make sure the window fits in the overall display frame.
-        Gravity.applyDisplay(mAttrs.gravity, mDisplayFrame, mFrame);
+        applyGravityAndUpdateFrame();
 
         // Calculate the outsets before the content frame gets shrinked to the window frame.
         if (hasOutsets) {
@@ -2229,4 +2176,69 @@
             rect.bottom = rect.top + (int)((rect.bottom - rect.top) / mVScale);
         }
     }
+
+    void applyGravityAndUpdateFrame() {
+        final int pw = mContainingFrame.width();
+        final int ph = mContainingFrame.height();
+        final Task task = getTask();
+        final boolean nonFullscreenTask = task != null && !task.isFullscreen();
+
+        float x, y;
+        int w,h;
+
+        if ((mAttrs.flags & FLAG_SCALED) != 0) {
+            if (mAttrs.width < 0) {
+                w = pw;
+            } else if (mEnforceSizeCompat) {
+                w = (int)(mAttrs.width * mGlobalScale + .5f);
+            } else {
+                w = mAttrs.width;
+            }
+            if (mAttrs.height < 0) {
+                h = ph;
+            } else if (mEnforceSizeCompat) {
+                h = (int)(mAttrs.height * mGlobalScale + .5f);
+            } else {
+                h = mAttrs.height;
+            }
+        } else {
+            if (mAttrs.width == MATCH_PARENT) {
+                w = pw;
+            } else if (mEnforceSizeCompat) {
+                w = (int)(mRequestedWidth * mGlobalScale + .5f);
+            } else {
+                w = mRequestedWidth;
+            }
+            if (mAttrs.height == MATCH_PARENT) {
+                h = ph;
+            } else if (mEnforceSizeCompat) {
+                h = (int)(mRequestedHeight * mGlobalScale + .5f);
+            } else {
+                h = mRequestedHeight;
+            }
+        }
+
+        if (mEnforceSizeCompat) {
+            x = mAttrs.x * mGlobalScale;
+            y = mAttrs.y * mGlobalScale;
+        } else {
+            x = mAttrs.x;
+            y = mAttrs.y;
+        }
+
+        if (nonFullscreenTask) {
+            // Make sure window fits in containing frame since it is in a non-fullscreen stack as
+            // required by {@link Gravity#apply} call.
+            w = Math.min(w, pw);
+            h = Math.min(h, ph);
+        }
+
+        // Set mFrame
+        Gravity.apply(mAttrs.gravity, w, h, mContainingFrame,
+                (int) (x + mAttrs.horizontalMargin * pw),
+                (int) (y + mAttrs.verticalMargin * ph), mFrame);
+
+        // Now make sure the window fits in the overall display frame.
+        Gravity.applyDisplay(mAttrs.gravity, mDisplayFrame, mFrame);
+    }
 }
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index b5654ee..9c9a5da 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -205,6 +205,7 @@
     void setInteractive(bool interactive);
     void reloadCalibration();
     void setPointerIconShape(int32_t iconId);
+    void reloadPointerIcons();
 
     /* --- InputReaderPolicyInterface implementation --- */
 
@@ -242,6 +243,7 @@
 
     /* --- PointerControllerPolicyInterface implementation --- */
 
+    virtual void loadPointerIcon(SpriteIcon* icon);
     virtual void loadPointerResources(PointerResources* outResources);
     virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
             std::map<int32_t, PointerAnimation>* outAnimationResources);
@@ -477,22 +479,6 @@
                 v.logicalBottom - v.logicalTop,
                 v.orientation);
 
-        JNIEnv* env = jniEnv();
-        jobject pointerIconObj = env->CallObjectMethod(mServiceObj,
-                gServiceClassInfo.getPointerIcon);
-        if (!checkAndClearExceptionFromCallback(env, "getPointerIcon")) {
-            PointerIcon pointerIcon;
-            status_t status = android_view_PointerIcon_load(env, pointerIconObj,
-                    mContextObj, &pointerIcon);
-            if (!status && !pointerIcon.isNullIcon()) {
-                controller->setPointerIcon(SpriteIcon(pointerIcon.bitmap,
-                        pointerIcon.hotSpotX, pointerIcon.hotSpotY));
-            } else {
-                controller->setPointerIcon(SpriteIcon());
-            }
-            env->DeleteLocalRef(pointerIconObj);
-        }
-
         updateInactivityTimeoutLocked(controller);
     }
     return controller;
@@ -789,12 +775,19 @@
 }
 
 void NativeInputManager::setPointerIconShape(int32_t iconId) {
-  AutoMutex _l(mLock);
-  sp<PointerController> controller = mLocked.pointerController.promote();
-  if (controller != NULL) {
-        // Use 0 (the default icon) for ARROW.
+    AutoMutex _l(mLock);
+    sp<PointerController> controller = mLocked.pointerController.promote();
+    if (controller != NULL) {
         controller->updatePointerShape(iconId);
-  }
+    }
+}
+
+void NativeInputManager::reloadPointerIcons() {
+    AutoMutex _l(mLock);
+    sp<PointerController> controller = mLocked.pointerController.promote();
+    if (controller != NULL) {
+        controller->reloadPointerResources();
+    }
 }
 
 TouchAffineTransformation NativeInputManager::getTouchAffineTransformation(
@@ -1036,6 +1029,25 @@
     return result;
 }
 
+void NativeInputManager::loadPointerIcon(SpriteIcon* icon) {
+    JNIEnv* env = jniEnv();
+
+    ScopedLocalRef<jobject> pointerIconObj(env, env->CallObjectMethod(
+            mServiceObj, gServiceClassInfo.getPointerIcon));
+    if (checkAndClearExceptionFromCallback(env, "getPointerIcon")) {
+        return;
+    }
+
+    PointerIcon pointerIcon;
+    status_t status = android_view_PointerIcon_load(env, pointerIconObj.get(),
+                                                    mContextObj, &pointerIcon);
+    if (!status && !pointerIcon.isNullIcon()) {
+        *icon = SpriteIcon(pointerIcon.bitmap, pointerIcon.hotSpotX, pointerIcon.hotSpotY);
+    } else {
+        *icon = SpriteIcon();
+    }
+}
+
 void NativeInputManager::loadPointerResources(PointerResources* outResources) {
     JNIEnv* env = jniEnv();
 
@@ -1420,6 +1432,11 @@
     im->setPointerIconShape(iconId);
 }
 
+static void nativeReloadPointerIcons(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+    im->reloadPointerIcons();
+}
+
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod gInputManagerMethods[] = {
@@ -1480,6 +1497,8 @@
             (void*) nativeMonitor },
     { "nativeSetPointerIconShape", "(JI)V",
             (void*) nativeSetPointerIconShape },
+    { "nativeReloadPointerIcons", "(J)V",
+            (void*) nativeReloadPointerIcons },
 };
 
 #define FIND_CLASS(var, className) \
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index f9aa124..5b4803b 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -195,8 +195,8 @@
             mServices = new ArrayList<ServiceInfo<AuthenticatorDescription>>();
             AuthenticatorDescription d1 = new AuthenticatorDescription("type1", "p1", 0, 0, 0, 0);
             AuthenticatorDescription d2 = new AuthenticatorDescription("type2", "p2", 0, 0, 0, 0);
-            mServices.add(new ServiceInfo<AuthenticatorDescription>(d1, null, 0));
-            mServices.add(new ServiceInfo<AuthenticatorDescription>(d2, null, 0));
+            mServices.add(new ServiceInfo<AuthenticatorDescription>(d1, null, null));
+            mServices.add(new ServiceInfo<AuthenticatorDescription>(d2, null, null));
         }
 
         @Override
diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
index 0b73beb..312b1b0 100644
--- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
@@ -183,6 +183,28 @@
     }
 
     /**
+     * Test that non persisted job is not written to disk.
+     */
+    public void testNonPersistedTaskIsNotPersisted() throws Exception {
+        JobInfo.Builder b = new Builder(42, mComponent)
+                .setOverrideDeadline(10000)
+                .setPersisted(false);
+        JobStatus jsNonPersisted = new JobStatus(b.build(), SOME_UID);
+        mTaskStoreUnderTest.add(jsNonPersisted);
+        b = new Builder(43, mComponent)
+                .setOverrideDeadline(10000)
+                .setPersisted(true);
+        JobStatus jsPersisted = new JobStatus(b.build(), SOME_UID);
+        mTaskStoreUnderTest.add(jsPersisted);
+        Thread.sleep(IO_WAIT);
+        final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>();
+        mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet);
+        assertEquals("Job count is incorrect.", 1, jobStatusSet.size());
+        JobStatus jobStatus = jobStatusSet.iterator().next();
+        assertEquals("Wrong job persisted.", 43, jobStatus.getJobId());
+    }
+
+    /**
      * Helper function to throw an error if the provided task and TaskStatus objects are not equal.
      */
     private void assertTasksEqual(JobInfo first, JobInfo second) {
diff --git a/services/usb/java/com/android/server/usb/UsbSettingsManager.java b/services/usb/java/com/android/server/usb/UsbSettingsManager.java
index 154cbd3..4786d11 100644
--- a/services/usb/java/com/android/server/usb/UsbSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbSettingsManager.java
@@ -984,7 +984,14 @@
     public boolean hasPermission(UsbDevice device) {
         synchronized (mLock) {
             int uid = Binder.getCallingUid();
-            if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) {
+            int androidMediaUid;
+            try {
+                androidMediaUid = mPackageManager.getApplicationInfo("com.android.mtp", 0).uid;
+            } catch (NameNotFoundException e) {
+                androidMediaUid = -1;
+            }
+            if (uid == Process.SYSTEM_UID || UserHandle.getAppId(uid) == androidMediaUid ||
+                    mDisablePermissionDialogs) {
                 return true;
             }
             SparseBooleanArray uidList = mDevicePermissionMap.get(device.getDeviceName());