Merge "Import translations. DO NOT MERGE" into lmp-dev
diff --git a/api/current.txt b/api/current.txt
index fd2afc5..3ab4ce4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -28073,27 +28073,31 @@
     ctor public Conference(android.telecom.PhoneAccountHandle);
     method public final boolean addConnection(android.telecom.Connection);
     method public final void destroy();
+    method public final android.telecom.AudioState getAudioState();
     method public final int getCapabilities();
     method public final java.util.List<android.telecom.Connection> getConnections();
     method public final android.telecom.PhoneAccountHandle getPhoneAccountHandle();
     method public final int getState();
+    method public void onAudioStateChanged(android.telecom.AudioState);
     method public void onDisconnect();
     method public void onHold();
     method public void onMerge();
+    method public void onPlayDtmfTone(char);
     method public void onSeparate(android.telecom.Connection);
+    method public void onStopDtmfTone();
     method public void onSwap();
     method public void onUnhold();
     method public final void removeConnection(android.telecom.Connection);
     method public final void setActive();
     method public final void setCapabilities(int);
-    method public final void setDisconnected(int, java.lang.String);
+    method public final void setDisconnected(android.telecom.DisconnectCause);
     method public final void setOnHold();
   }
 
   public abstract class Connection {
     ctor public Connection();
     method public static android.telecom.Connection createCanceledConnection();
-    method public static android.telecom.Connection createFailedConnection(int, java.lang.String);
+    method public static android.telecom.Connection createFailedConnection(android.telecom.DisconnectCause);
     method public final void destroy();
     method public final android.net.Uri getAddress();
     method public final int getAddressPresentation();
@@ -28104,8 +28108,7 @@
     method public final int getCallerDisplayNamePresentation();
     method public final android.telecom.Conference getConference();
     method public final java.util.List<android.telecom.Connection> getConferenceableConnections();
-    method public final int getDisconnectCause();
-    method public final java.lang.String getDisconnectMessage();
+    method public final android.telecom.DisconnectCause getDisconnectCause();
     method public final int getState();
     method public final android.telecom.StatusHints getStatusHints();
     method public final boolean isRingbackRequested();
@@ -28130,7 +28133,7 @@
     method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
     method public final void setConnectionService(android.telecom.ConnectionService);
     method public final void setDialing();
-    method public final void setDisconnected(int, java.lang.String);
+    method public final void setDisconnected(android.telecom.DisconnectCause);
     method public final void setInitialized();
     method public final void setInitializing();
     method public final void setOnHold();
@@ -28173,6 +28176,30 @@
     field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.ConnectionService";
   }
 
+  public final class DisconnectCause implements android.os.Parcelable {
+    ctor public DisconnectCause(int);
+    ctor public DisconnectCause(int, java.lang.String);
+    ctor public DisconnectCause(int, java.lang.CharSequence, java.lang.CharSequence, java.lang.String, int);
+    method public int describeContents();
+    method public int getCode();
+    method public java.lang.CharSequence getDescription();
+    method public java.lang.CharSequence getLabel();
+    method public java.lang.String getReason();
+    method public int getTone();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int BUSY = 7; // 0x7
+    field public static final int CANCELED = 4; // 0x4
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int ERROR = 1; // 0x1
+    field public static final int LOCAL = 2; // 0x2
+    field public static final int MISSED = 5; // 0x5
+    field public static final int OTHER = 9; // 0x9
+    field public static final int REJECTED = 6; // 0x6
+    field public static final int REMOTE = 3; // 0x3
+    field public static final int RESTRICTED = 8; // 0x8
+    field public static final int UNKNOWN = 0; // 0x0
+  }
+
   public class GatewayInfo implements android.os.Parcelable {
     method public int describeContents();
     method public android.net.Uri getGatewayAddress();
@@ -28196,7 +28223,6 @@
     method public android.net.Uri getSubscriptionAddress();
     method public java.util.List<java.lang.String> getSupportedUriSchemes();
     method public boolean hasCapabilities(int);
-    method public boolean isEnabled();
     method public boolean supportsUriScheme(java.lang.String);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int CAPABILITY_CONNECTION_MANAGER = 1; // 0x1
@@ -28248,12 +28274,14 @@
     method public void disconnect();
     method public final int getCallCapabilities();
     method public final java.util.List<android.telecom.RemoteConnection> getConnections();
-    method public int getDisconnectCause();
-    method public java.lang.String getDisconnectMessage();
+    method public android.telecom.DisconnectCause getDisconnectCause();
     method public final int getState();
     method public void hold();
+    method public void playDtmfTone(char);
     method public final void registerCallback(android.telecom.RemoteConference.Callback);
     method public void separate(android.telecom.RemoteConnection);
+    method public void setAudioState(android.telecom.AudioState);
+    method public void stopDtmfTone();
     method public void unhold();
     method public final void unregisterCallback(android.telecom.RemoteConference.Callback);
   }
@@ -28264,7 +28292,7 @@
     method public void onConnectionAdded(android.telecom.RemoteConference, android.telecom.RemoteConnection);
     method public void onConnectionRemoved(android.telecom.RemoteConference, android.telecom.RemoteConnection);
     method public void onDestroyed(android.telecom.RemoteConference);
-    method public void onDisconnected(android.telecom.RemoteConference, int, java.lang.String);
+    method public void onDisconnected(android.telecom.RemoteConference, android.telecom.DisconnectCause);
     method public void onStateChanged(android.telecom.RemoteConference, int, int);
   }
 
@@ -28279,10 +28307,7 @@
     method public int getCallerDisplayNamePresentation();
     method public android.telecom.RemoteConference getConference();
     method public java.util.List<android.telecom.RemoteConnection> getConferenceableConnections();
-    method public int getDisconnectCauseCode();
-    method public java.lang.String getDisconnectCauseMessage();
-    method public int getFailureCode();
-    method public java.lang.String getFailureMessage();
+    method public android.telecom.DisconnectCause getDisconnectCause();
     method public int getState();
     method public android.telecom.StatusHints getStatusHints();
     method public void hold();
@@ -28306,7 +28331,7 @@
     method public void onConferenceChanged(android.telecom.RemoteConnection, android.telecom.RemoteConference);
     method public void onConferenceableConnectionsChanged(android.telecom.RemoteConnection, java.util.List<android.telecom.RemoteConnection>);
     method public void onDestroyed(android.telecom.RemoteConnection);
-    method public void onDisconnected(android.telecom.RemoteConnection, int, java.lang.String);
+    method public void onDisconnected(android.telecom.RemoteConnection, android.telecom.DisconnectCause);
     method public void onPostDialWait(android.telecom.RemoteConnection, java.lang.String);
     method public void onRingbackRequested(android.telecom.RemoteConnection, boolean);
     method public void onStateChanged(android.telecom.RemoteConnection, int);
@@ -28331,20 +28356,16 @@
     method public void cancelMissedCallsNotification();
     method public void clearAccounts();
     method public android.telecom.PhoneAccountHandle getConnectionManager();
-    method public android.telecom.PhoneAccountHandle getDefaultOutgoingPhoneAccount(java.lang.String);
-    method public java.util.List<android.telecom.PhoneAccountHandle> getEnabledPhoneAccounts();
     method public android.telecom.PhoneAccount getPhoneAccount(android.telecom.PhoneAccountHandle);
-    method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsSupportingScheme(java.lang.String);
+    method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsForPackage();
     method public boolean handleMmi(java.lang.String);
-    method public boolean hasMultipleEnabledAccounts();
+    method public boolean hasMultipleCallCapableAccounts();
     method public boolean isInCall();
     method public void registerPhoneAccount(android.telecom.PhoneAccount);
     method public void showInCallScreen(boolean);
     method public void unregisterPhoneAccount(android.telecom.PhoneAccountHandle);
     field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
     field public static final java.lang.String ACTION_CONNECTION_SERVICE_CONFIGURE = "android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
-    field public static final java.lang.String ACTION_PHONE_ACCOUNT_DISABLED = "android.telecom.action.PHONE_ACCOUNT_DISABLED";
-    field public static final java.lang.String ACTION_PHONE_ACCOUNT_ENABLED = "android.telecom.action.PHONE_ACCOUNT_ENABLED";
     field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecom.action.SHOW_CALL_SETTINGS";
     field public static final char DTMF_CHARACTER_PAUSE = 44; // 0x002c ','
     field public static final char DTMF_CHARACTER_WAIT = 59; // 0x003b ';'
@@ -28512,57 +28533,6 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
-  public class DisconnectCause {
-    method public static java.lang.String toString(int);
-    field public static final int BUSY = 4; // 0x4
-    field public static final int CALL_BARRED = 20; // 0x14
-    field public static final int CDMA_ACCESS_BLOCKED = 35; // 0x23
-    field public static final int CDMA_ACCESS_FAILURE = 32; // 0x20
-    field public static final int CDMA_CALL_LOST = 41; // 0x29
-    field public static final int CDMA_DROP = 27; // 0x1b
-    field public static final int CDMA_INTERCEPT = 28; // 0x1c
-    field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 26; // 0x1a
-    field public static final int CDMA_NOT_EMERGENCY = 34; // 0x22
-    field public static final int CDMA_PREEMPTED = 33; // 0x21
-    field public static final int CDMA_REORDER = 29; // 0x1d
-    field public static final int CDMA_RETRY_ORDER = 31; // 0x1f
-    field public static final int CDMA_SO_REJECT = 30; // 0x1e
-    field public static final int CONGESTION = 5; // 0x5
-    field public static final int CS_RESTRICTED = 22; // 0x16
-    field public static final int CS_RESTRICTED_EMERGENCY = 24; // 0x18
-    field public static final int CS_RESTRICTED_NORMAL = 23; // 0x17
-    field public static final int DIALED_MMI = 39; // 0x27
-    field public static final int EMERGENCY_ONLY = 37; // 0x25
-    field public static final int ERROR_UNSPECIFIED = 36; // 0x24
-    field public static final int FDN_BLOCKED = 21; // 0x15
-    field public static final int ICC_ERROR = 19; // 0x13
-    field public static final int INCOMING_MISSED = 1; // 0x1
-    field public static final int INCOMING_REJECTED = 16; // 0x10
-    field public static final int INVALID_CREDENTIALS = 10; // 0xa
-    field public static final int INVALID_NUMBER = 7; // 0x7
-    field public static final int LIMIT_EXCEEDED = 15; // 0xf
-    field public static final int LOCAL = 3; // 0x3
-    field public static final int LOST_SIGNAL = 14; // 0xe
-    field public static final int MAXIMUM_VALID_VALUE = 44; // 0x2c
-    field public static final int MINIMUM_VALID_VALUE = 0; // 0x0
-    field public static final int MMI = 6; // 0x6
-    field public static final int NORMAL = 2; // 0x2
-    field public static final int NOT_DISCONNECTED = 0; // 0x0
-    field public static final int NOT_VALID = -1; // 0xffffffff
-    field public static final int NO_PHONE_NUMBER_SUPPLIED = 38; // 0x26
-    field public static final int NUMBER_UNREACHABLE = 8; // 0x8
-    field public static final int OUTGOING_CANCELED = 44; // 0x2c
-    field public static final int OUTGOING_FAILURE = 43; // 0x2b
-    field public static final int OUT_OF_NETWORK = 11; // 0xb
-    field public static final int OUT_OF_SERVICE = 18; // 0x12
-    field public static final int POWER_OFF = 17; // 0x11
-    field public static final int SERVER_ERROR = 12; // 0xc
-    field public static final int SERVER_UNREACHABLE = 9; // 0x9
-    field public static final int TIMED_OUT = 13; // 0xd
-    field public static final int UNOBTAINABLE_NUMBER = 25; // 0x19
-    field public static final int VOICEMAIL_NUMBER_MISSING = 40; // 0x28
-  }
-
   public class IccOpenLogicalChannelResponse implements android.os.Parcelable {
     method public int describeContents();
     method public int getChannel();
@@ -28761,6 +28731,7 @@
     field public static final java.lang.String MMS_CONFIG_UA_PROF_TAG_NAME = "uaProfTagName";
     field public static final java.lang.String MMS_CONFIG_UA_PROF_URL = "uaProfUrl";
     field public static final java.lang.String MMS_CONFIG_USER_AGENT = "userAgent";
+    field public static final int MMS_ERROR_CONFIGURATION_ERROR = 7; // 0x7
     field public static final int MMS_ERROR_HTTP_FAILURE = 4; // 0x4
     field public static final int MMS_ERROR_INVALID_APN = 2; // 0x2
     field public static final int MMS_ERROR_IO_ERROR = 5; // 0x5
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 57c1505..5ba7d50 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -48,6 +48,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.text.TextUtils;
@@ -726,6 +727,7 @@
 
             IActivityManager.WaitResult result = null;
             int res;
+            final long startTime = SystemClock.uptimeMillis();
             if (mWaitOption) {
                 result = mAm.startActivityAndWait(null, null, intent, mimeType,
                             null, null, 0, mStartFlags, profilerInfo, null, mUserId);
@@ -734,6 +736,7 @@
                 res = mAm.startActivityAsUser(null, null, intent, mimeType,
                         null, null, 0, mStartFlags, profilerInfo, null, mUserId);
             }
+            final long endTime = SystemClock.uptimeMillis();
             PrintStream out = mWaitOption ? System.out : System.err;
             boolean launched = false;
             switch (res) {
@@ -811,6 +814,7 @@
                 if (result.totalTime >= 0) {
                     System.out.println("TotalTime: " + result.totalTime);
                 }
+                System.out.println("WaitTime: " + (endTime-startTime));
                 System.out.println("Complete");
             }
             mRepeat--;
diff --git a/cmds/dpm/src/com/android/commands/dpm/Dpm.java b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
index 6a5ecee..3b9a785 100644
--- a/cmds/dpm/src/com/android/commands/dpm/Dpm.java
+++ b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
@@ -39,6 +39,7 @@
     }
 
     private static final String COMMAND_SET_DEVICE_OWNER = "set-device-owner";
+    private static final String COMMAND_SET_PROFILE_OWNER = "set-profile-owner";
 
     private IDevicePolicyManager mDevicePolicyManager;
 
@@ -47,9 +48,13 @@
         out.println(
                 "usage: dpm [subcommand] [options]\n" +
                 "usage: dpm set-device-owner <COMPONENT>\n" +
+                "usage: dpm set-profile-owner <COMPONENT> <USER_ID>\n" +
                 "\n" +
                 "dpm set-device-owner: Sets the given component as active admin, and its\n" +
-                "  package as device owner.\n");
+                "  package as device owner.\n" +
+                "\n" +
+                "dpm set-profile-owner: Sets the given component as active admin and profile" +
+                "  owner for an existing user.\n");
     }
 
     @Override
@@ -64,31 +69,67 @@
         String command = nextArgRequired();
         switch (command) {
             case COMMAND_SET_DEVICE_OWNER:
-                runSetDeviceOwner(nextArgRequired());
+                runSetDeviceOwner();
+                break;
+            case COMMAND_SET_PROFILE_OWNER:
+                runSetProfileOwner();
                 break;
             default:
                 throw new IllegalArgumentException ("unknown command '" + command + "'");
         }
     }
 
-    private void runSetDeviceOwner(String argument) throws Exception {
-        ComponentName component = ComponentName.unflattenFromString(argument);
-        if (component == null) {
-            throw new IllegalArgumentException ("Invalid component " + argument);
-        }
-        mDevicePolicyManager.setActiveAdmin(component, true, UserHandle.USER_OWNER);
+    private void runSetDeviceOwner() throws RemoteException {
+        ComponentName component = parseComponentName(nextArgRequired());
+        mDevicePolicyManager.setActiveAdmin(component, true /*refreshing*/, UserHandle.USER_OWNER);
 
         String packageName = component.getPackageName();
         try {
-            if (!mDevicePolicyManager.setDeviceOwner(packageName, null)) {
-                throw new Exception("Can't set package " + packageName + " as device owner.");
+            if (!mDevicePolicyManager.setDeviceOwner(packageName, null /*ownerName*/)) {
+                throw new RuntimeException(
+                        "Can't set package " + packageName + " as device owner.");
             }
         } catch (Exception e) {
             // Need to remove the admin that we just added.
             mDevicePolicyManager.removeActiveAdmin(component, UserHandle.USER_OWNER);
             throw e;
         }
-        System.out.println("Device owner set to package " + packageName);
+        System.out.println("Success: Device owner set to package " + packageName);
         System.out.println("Active admin set to component " + component.toShortString());
     }
+
+    private void runSetProfileOwner() throws RemoteException {
+        ComponentName component = parseComponentName(nextArgRequired());
+        int userId = parseInt(nextArgRequired());
+        mDevicePolicyManager.setActiveAdmin(component, true /*refreshing*/, userId);
+
+        try {
+            if (!mDevicePolicyManager.setProfileOwner(component, "" /*ownerName*/, userId)) {
+                throw new RuntimeException("Can't set component " + component.toShortString() +
+                        " as profile owner for user " + userId);
+            }
+        } catch (Exception e) {
+            // Need to remove the admin that we just added.
+            mDevicePolicyManager.removeActiveAdmin(component, userId);
+            throw e;
+        }
+        System.out.println("Success: Active admin and profile owner set to "
+                + component.toShortString() + " for user " + userId);
+    }
+
+    private ComponentName parseComponentName(String component) {
+        ComponentName cn = ComponentName.unflattenFromString(component);
+        if (cn == null) {
+            throw new IllegalArgumentException ("Invalid component " + component);
+        }
+        return cn;
+    }
+
+    private int parseInt(String argument) {
+        try {
+            return Integer.parseInt(argument);
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException ("Invalid integer argument '" + argument + "'", e);
+        }
+    }
 }
\ No newline at end of file
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 6d12133..5e9d8f7 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -1190,10 +1190,6 @@
             if (userId < 0) {
                 info = mUm.createUser(name, flags);
             } else {
-                if (Process.myUid() != 0) {
-                    System.err.println("Error: not running as root.");
-                    return;
-                }
                 info = mUm.createProfileForUser(name, flags, userId);
             }
             if (info != null) {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 701ab1d..25c4897 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -745,6 +745,11 @@
         public View findViewById(int id) {
             return Activity.this.findViewById(id);
         }
+        @Override
+        public boolean hasView() {
+            Window window = Activity.this.getWindow();
+            return (window != null && window.peekDecorView() != null);
+        }
     };
 
     // Most recent call to requestVisibleBehind().
@@ -5066,7 +5071,7 @@
     public void setTaskDescription(ActivityManager.TaskDescription taskDescription) {
         ActivityManager.TaskDescription td;
         // Scale the icon down to something reasonable if it is provided
-        if (taskDescription.getIcon() != null) {
+        if (taskDescription.getIconFilename() == null && taskDescription.getIcon() != null) {
             final int size = ActivityManager.getLauncherLargeIconSizeInner(this);
             final Bitmap icon = Bitmap.createScaledBitmap(taskDescription.getIcon(), size, size, true);
             td = new ActivityManager.TaskDescription(taskDescription.getLabel(), icon,
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 9486a72..85d4839 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -56,9 +56,11 @@
 import android.util.DisplayMetrics;
 import android.util.Size;
 import android.util.Slog;
+import org.xmlpull.v1.XmlSerializer;
 
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
@@ -508,8 +510,18 @@
      * Information you can set and retrieve about the current activity within the recent task list.
      */
     public static class TaskDescription implements Parcelable {
+        /** @hide */
+        public static final String ATTR_TASKDESCRIPTION_PREFIX = "task_description_";
+        private static final String ATTR_TASKDESCRIPTIONLABEL =
+                ATTR_TASKDESCRIPTION_PREFIX + "label";
+        private static final String ATTR_TASKDESCRIPTIONCOLOR =
+                ATTR_TASKDESCRIPTION_PREFIX + "color";
+        private static final String ATTR_TASKDESCRIPTIONICONFILENAME =
+                ATTR_TASKDESCRIPTION_PREFIX + "icon_filename";
+
         private String mLabel;
         private Bitmap mIcon;
+        private String mIconFilename;
         private int mColorPrimary;
 
         /**
@@ -529,6 +541,12 @@
             mColorPrimary = colorPrimary;
         }
 
+        /** @hide */
+        public TaskDescription(String label, int colorPrimary, String iconFilename) {
+            this(label, null, colorPrimary);
+            mIconFilename = iconFilename;
+        }
+
         /**
          * Creates the TaskDescription to the specified values.
          *
@@ -559,7 +577,10 @@
          * Creates a copy of another TaskDescription.
          */
         public TaskDescription(TaskDescription td) {
-            this(td.getLabel(), td.getIcon(), td.getPrimaryColor());
+            mLabel = td.mLabel;
+            mIcon = td.mIcon;
+            setPrimaryColor(td.mColorPrimary);
+            mIconFilename = td.mIconFilename;
         }
 
         private TaskDescription(Parcel source) {
@@ -579,7 +600,7 @@
          * @hide
          */
         public void setPrimaryColor(int primaryColor) {
-            mColorPrimary = primaryColor;
+            mColorPrimary = 0xFF000000 | primaryColor;
         }
 
         /**
@@ -591,6 +612,16 @@
         }
 
         /**
+         * Moves the icon bitmap reference from an actual Bitmap to a file containing the
+         * bitmap.
+         * @hide
+         */
+        public void setIconFilename(String iconFilename) {
+            mIconFilename = iconFilename;
+            mIcon = null;
+        }
+
+        /**
          * @return The label and description of the current state of this task.
          */
         public String getLabel() {
@@ -601,7 +632,22 @@
          * @return The icon that represents the current state of this task.
          */
         public Bitmap getIcon() {
-            return mIcon;
+            if (mIcon != null) {
+                return mIcon;
+            }
+            if (mIconFilename != null) {
+                try {
+                    return ActivityManagerNative.getDefault().
+                            getTaskDescriptionIcon(mIconFilename);
+                } catch (RemoteException e) {
+                }
+            }
+            return null;
+        }
+
+        /** @hide */
+        public String getIconFilename() {
+            return mIconFilename;
         }
 
         /**
@@ -611,6 +657,30 @@
             return mColorPrimary;
         }
 
+        /** @hide */
+        public void saveToXml(XmlSerializer out) throws IOException {
+            if (mLabel != null) {
+                out.attribute(null, ATTR_TASKDESCRIPTIONLABEL, mLabel);
+            }
+            if (mColorPrimary != 0) {
+                out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR, Integer.toHexString(mColorPrimary));
+            }
+            if (mIconFilename != null) {
+                out.attribute(null, ATTR_TASKDESCRIPTIONICONFILENAME, mIconFilename);
+            }
+        }
+
+        /** @hide */
+        public void restoreFromXml(String attrName, String attrValue) {
+            if (ATTR_TASKDESCRIPTIONLABEL.equals(attrName)) {
+                setLabel(attrValue);
+            } else if (ATTR_TASKDESCRIPTIONCOLOR.equals(attrName)) {
+                setPrimaryColor((int) Long.parseLong(attrValue, 16));
+            } else if (ATTR_TASKDESCRIPTIONICONFILENAME.equals(attrName)) {
+                setIconFilename(attrValue);
+            }
+        }
+
         @Override
         public int describeContents() {
             return 0;
@@ -631,12 +701,19 @@
                 mIcon.writeToParcel(dest, 0);
             }
             dest.writeInt(mColorPrimary);
+            if (mIconFilename == null) {
+                dest.writeInt(0);
+            } else {
+                dest.writeInt(1);
+                dest.writeString(mIconFilename);
+            }
         }
 
         public void readFromParcel(Parcel source) {
             mLabel = source.readInt() > 0 ? source.readString() : null;
             mIcon = source.readInt() > 0 ? Bitmap.CREATOR.createFromParcel(source) : null;
             mColorPrimary = source.readInt();
+            mIconFilename = source.readInt() > 0 ? source.readString() : null;
         }
 
         public static final Creator<TaskDescription> CREATOR
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 677fcef..11470e3 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2253,6 +2253,20 @@
             return true;
         }
 
+        case GET_TASK_DESCRIPTION_ICON_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            String filename = data.readString();
+            Bitmap icon = getTaskDescriptionIcon(filename);
+            reply.writeNoException();
+            if (icon == null) {
+                reply.writeInt(0);
+            } else {
+                reply.writeInt(1);
+                icon.writeToParcel(reply, 0);
+            }
+            return true;
+        }
+
         case REQUEST_VISIBLE_BEHIND_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
@@ -5241,6 +5255,20 @@
     }
 
     @Override
+    public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeString(filename);
+        mRemote.transact(GET_TASK_DESCRIPTION_ICON_TRANSACTION, data, reply, 0);
+        reply.readException();
+        final Bitmap icon = reply.readInt() == 0 ? null : Bitmap.CREATOR.createFromParcel(reply);
+        data.recycle();
+        reply.recycle();
+        return icon;
+    }
+
+    @Override
     public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b4877de..7d0d27f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -123,7 +123,6 @@
 import libcore.io.EventLogger;
 import libcore.io.IoUtils;
 import libcore.net.event.NetworkEventDispatcher;
-
 import dalvik.system.CloseGuard;
 import dalvik.system.VMDebug;
 import dalvik.system.VMRuntime;
@@ -5088,10 +5087,8 @@
                 mInstrumentation = new Instrumentation();
                 ContextImpl context = ContextImpl.createAppContext(
                         this, getSystemContext().mPackageInfo);
-                Application app = Instrumentation.newApplication(Application.class, context);
-                mAllApplications.add(app);
-                mInitialApplication = app;
-                app.onCreate();
+                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
+                mInitialApplication.onCreate();
             } catch (Exception e) {
                 throw new RuntimeException(
                         "Unable to instantiate Application():" + e.toString(), e);
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 137f77d..540376e 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -219,7 +219,9 @@
 
     protected void viewsReady(ArrayMap<String, View> sharedElements) {
         sharedElements.retainAll(mAllSharedElementNames);
-        mListener.onMapSharedElements(mAllSharedElementNames, sharedElements);
+        if (mListener != null) {
+            mListener.onMapSharedElements(mAllSharedElementNames, sharedElements);
+        }
         mSharedElementNames.addAll(sharedElements.keySet());
         mSharedElements.addAll(sharedElements.values());
         if (getViewsTransition() != null && mTransitioningViews != null) {
@@ -461,7 +463,8 @@
         if (sharedElementState != null) {
             Matrix tempMatrix = new Matrix();
             RectF tempRect = new RectF();
-            for (int i = 0; i < mSharedElementNames.size(); i++) {
+            final int numSharedElements = mSharedElements.size();
+            for (int i = 0; i < numSharedElements; i++) {
                 View sharedElement = mSharedElements.get(i);
                 String name = mSharedElementNames.get(i);
                 SharedElementOriginalState originalState = getOldSharedElementState(sharedElement,
@@ -471,12 +474,16 @@
                         tempMatrix, tempRect, null);
             }
         }
-        mListener.onSharedElementStart(mSharedElementNames, mSharedElements, snapshots);
+        if (mListener != null) {
+            mListener.onSharedElementStart(mSharedElementNames, mSharedElements, snapshots);
+        }
         return originalImageState;
     }
 
     protected void notifySharedElementEnd(ArrayList<View> snapshots) {
-        mListener.onSharedElementEnd(mSharedElementNames, mSharedElements, snapshots);
+        if (mListener != null) {
+            mListener.onSharedElementEnd(mSharedElementNames, mSharedElements, snapshots);
+        }
     }
 
     protected void scheduleSetSharedElementEnd(final ArrayList<View> snapshots) {
@@ -544,7 +551,7 @@
             if (sharedElementBundle != null) {
                 Parcelable parcelable = sharedElementBundle.getParcelable(KEY_SNAPSHOT);
                 View snapshot = null;
-                if (parcelable != null) {
+                if (parcelable != null && mListener != null) {
                     snapshot = mListener.onCreateSnapshotView(context, parcelable);
                 }
                 if (snapshot != null) {
@@ -659,7 +666,11 @@
         sharedElementBundle.putFloat(KEY_TRANSLATION_Z, view.getTranslationZ());
         sharedElementBundle.putFloat(KEY_ELEVATION, view.getElevation());
 
-        Parcelable bitmap = mListener.onCaptureSharedElementSnapshot(view, tempMatrix, tempBounds);
+        Parcelable bitmap = null;
+        if (mListener != null) {
+            bitmap = mListener.onCaptureSharedElementSnapshot(view, tempMatrix, tempBounds);
+        }
+
         if (bitmap != null) {
             sharedElementBundle.putParcelable(KEY_SNAPSHOT, bitmap);
         }
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 832e1e3..8644c3d 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -868,6 +868,9 @@
      */
     private void calculateFragments(SparseArray<Fragment> firstOutFragments,
             SparseArray<Fragment> lastInFragments) {
+        if (!mManager.mContainer.hasView()) {
+            return; // nothing to see, so no transitions
+        }
         Op op = mHead;
         while (op != null) {
             switch (op.cmd) {
@@ -923,6 +926,9 @@
      */
     public void calculateBackFragments(SparseArray<Fragment> firstOutFragments,
             SparseArray<Fragment> lastInFragments) {
+        if (!mManager.mContainer.hasView()) {
+            return; // nothing to see, so no transitions
+        }
         Op op = mHead;
         while (op != null) {
             switch (op.cmd) {
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index 16a3575..216d6ba 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -306,7 +306,9 @@
         ArrayList<String> rejectedNames = new ArrayList<String>(mAllSharedElementNames);
         rejectedNames.removeAll(mSharedElementNames);
         ArrayList<View> rejectedSnapshots = createSnapshots(sharedElementState, rejectedNames);
-        mListener.onRejectSharedElements(rejectedSnapshots);
+        if (mListener != null) {
+            mListener.onRejectSharedElements(rejectedSnapshots);
+        }
         startRejectedAnimations(rejectedSnapshots);
 
         // Now start shared element transition
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index 812dfdb..d4d3eda 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -181,7 +181,10 @@
                 });
         setGhostVisibility(View.INVISIBLE);
         scheduleGhostVisibilityChange(View.INVISIBLE);
-        mListener.onSharedElementEnd(mSharedElementNames, mSharedElements, sharedElementSnapshots);
+        if (mListener != null) {
+            mListener.onSharedElementEnd(mSharedElementNames, mSharedElements,
+                    sharedElementSnapshots);
+        }
         TransitionManager.beginDelayedTransition(decorView, transition);
         scheduleGhostVisibilityChange(View.VISIBLE);
         setGhostVisibility(View.VISIBLE);
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index a95abab..5196834 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -2015,6 +2015,11 @@
                 }
                 return mView.findViewById(id);
             }
+
+            @Override
+            public boolean hasView() {
+                return (mView != null);
+            }
         }, this);
     }
 
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index ef69fdd..fc761fe 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -395,6 +395,7 @@
  */
 interface FragmentContainer {
     public View findViewById(int id);
+    public boolean hasView();
 }
 
 /**
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 8fa1fd5..aa5fea0 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -451,6 +451,7 @@
 
     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription values)
             throws RemoteException;
+    public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException;
 
     public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException;
     public boolean isBackgroundVisibleBehind(IBinder token) throws RemoteException;
@@ -775,4 +776,5 @@
     int RELEASE_ACTIVITY_INSTANCE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+235;
     int RELEASE_SOME_ACTIVITIES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+236;
     int BOOT_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+237;
+    int GET_TASK_DESCRIPTION_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+238;
 }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 13ed8d1..027eb2c 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2571,9 +2571,7 @@
      * application running in the managed profile.
      *
      * <p>The provided {@link Bundle} consists of key-value pairs, where the types of values may be
-     * boolean, int, String, or String[]. The recommended format for keys
-     * is "com.example.packagename/example-setting" to avoid naming conflicts with library
-     * components such as {@link android.webkit.WebView}.
+     * boolean, int, String, or String[].
      *
      * <p>The application restrictions are only made visible to the target application and the
      * profile or device owner.
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index ff9f6ab..53912e1 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -4295,7 +4295,7 @@
                 int j = uri.indexOf(')', i);
                 while (i < j) {
                     int sep = uri.indexOf('!', i);
-                    if (sep < 0) sep = j;
+                    if (sep < 0 || sep > j) sep = j;
                     if (i < sep) {
                         intent.addCategory(uri.substring(i, sep));
                     }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index ffde7ce..3364741 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -4675,6 +4675,28 @@
         return ai;
     }
 
+    public static ApplicationInfo generateApplicationInfo(ApplicationInfo ai, int flags,
+            PackageUserState state, int userId) {
+        if (ai == null) return null;
+        if (!checkUseInstalledOrHidden(flags, state)) {
+            return null;
+        }
+        // This is only used to return the ResolverActivity; we will just always
+        // make a copy.
+        ai = new ApplicationInfo(ai);
+        if (userId != 0) {
+            ai.uid = UserHandle.getUid(userId, ai.uid);
+            ai.dataDir = PackageManager.getDataDirForUser(userId, ai.packageName);
+        }
+        if (state.stopped) {
+            ai.flags |= ApplicationInfo.FLAG_STOPPED;
+        } else {
+            ai.flags &= ~ApplicationInfo.FLAG_STOPPED;
+        }
+        updateApplicationInfo(ai, flags, state);
+        return ai;
+    }
+
     public static final PermissionInfo generatePermissionInfo(
             Permission p, int flags) {
         if (p == null) return null;
@@ -4738,6 +4760,19 @@
         return ai;
     }
 
+    public static final ActivityInfo generateActivityInfo(ActivityInfo ai, int flags,
+            PackageUserState state, int userId) {
+        if (ai == null) return null;
+        if (!checkUseInstalledOrHidden(flags, state)) {
+            return null;
+        }
+        // This is only used to return the ResolverActivity; we will just always
+        // make a copy.
+        ai = new ActivityInfo(ai);
+        ai.applicationInfo = generateApplicationInfo(ai.applicationInfo, flags, state, userId);
+        return ai;
+    }
+
     public final static class Service extends Component<ServiceIntentInfo> {
         public final ServiceInfo info;
 
diff --git a/core/java/android/ddm/DdmHandleViewDebug.java b/core/java/android/ddm/DdmHandleViewDebug.java
index ce83796..3a36b0a 100644
--- a/core/java/android/ddm/DdmHandleViewDebug.java
+++ b/core/java/android/ddm/DdmHandleViewDebug.java
@@ -56,6 +56,9 @@
     /** Capture View Layers. */
     private static final int VURT_CAPTURE_LAYERS = 2;
 
+    /** Dump View Theme. */
+    private static final int VURT_DUMP_THEME = 3;
+
     /**
      * Generic View Operation, first parameter in the packet should be one of the
      * VUOP_* constants below.
@@ -131,6 +134,8 @@
                 return dumpHierarchy(rootView, in);
             else if (op == VURT_CAPTURE_LAYERS)
                 return captureLayers(rootView);
+            else if (op == VURT_DUMP_THEME)
+                return dumpTheme(rootView);
             else
                 return createFailChunk(ERR_INVALID_OP, "Unknown view root operation: " + op);
         }
@@ -258,6 +263,22 @@
         return new Chunk(CHUNK_VURT, data, 0, data.length);
     }
 
+    /**
+     * Returns the Theme dump of the provided view.
+     */
+    private Chunk dumpTheme(View rootView) {
+        ByteArrayOutputStream b = new ByteArrayOutputStream(1024);
+        try {
+            ViewDebug.dumpTheme(rootView, b);
+        } catch (IOException e) {
+            return createFailChunk(1, "Unexpected error while dumping the theme: "
+                    + e.getMessage());
+        }
+
+        byte[] data = b.toByteArray();
+        return new Chunk(CHUNK_VURT, data, 0, data.length);
+    }
+
     private Chunk captureView(View rootView, View targetView) {
         ByteArrayOutputStream b = new ByteArrayOutputStream(1024);
         try {
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 7c69a7d..e3cbef5 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -1402,6 +1402,20 @@
         return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
     }
 
+    /** {@hide */
+    public static final void enforceTetherChangePermission(Context context) {
+        if (context.getResources().getStringArray(
+                com.android.internal.R.array.config_mobile_hotspot_provision_app).length == 2) {
+            // Have a provisioning app - must only let system apps (which check this app)
+            // turn on tethering
+            context.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.CONNECTIVITY_INTERNAL, "ConnectivityService");
+        } else {
+            context.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.CHANGE_NETWORK_STATE, "ConnectivityService");
+        }
+    }
+
     /**
      * Get the set of tetherable, available interfaces.  This list is limited by
      * device configuration and current interface existence.
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 80e5b91..b83198d 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -120,6 +120,25 @@
      */
     public static final int EVENT_UNBLOCK_ADDRESS_FAMILY = BASE + 8;
 
+    /**
+     * Sent by ConnectivitySerice to the NetworkAgent to inform the agent of the
+     * networks status - whether we could use the network or could not, due to
+     * either a bad network configuration (no internet link) or captive portal.
+     *
+     * arg1 = either {@code VALID_NETWORK} or {@code INVALID_NETWORK}
+     */
+    public static final int CMD_REPORT_NETWORK_STATUS = BASE + 9;
+
+    public static final int VALID_NETWORK = 1;
+    public static final int INVALID_NETWORK = 2;
+
+     /**
+     * Sent by the NetworkAgent to ConnectivityService to indicate this network was
+     * explicitly selected.  This should be sent before the NetworkInfo is marked
+     * CONNECTED so it can be given special treatment at that time.
+     */
+    public static final int EVENT_SET_EXPLICITLY_SELECTED = BASE + 10;
+
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score) {
         this(looper, context, logTag, ni, nc, lp, score, null);
@@ -181,6 +200,14 @@
                 log("Unhandled Message " + msg);
                 break;
             }
+            case CMD_REPORT_NETWORK_STATUS: {
+                if (VDBG) {
+                    log("CMD_REPORT_NETWORK_STATUS(" +
+                            (msg.arg1 == VALID_NETWORK ? "VALID)" : "INVALID)"));
+                }
+                networkStatus(msg.arg1);
+                break;
+            }
         }
     }
 
@@ -261,6 +288,15 @@
     }
 
     /**
+     * Called by the bearer to indicate this network was manually selected by the user.
+     * This should be called before the NetworkInfo is marked CONNECTED so that this
+     * Network can be given special treatment at that time.
+     */
+    public void explicitlySelected() {
+        queueOrSendMessage(EVENT_SET_EXPLICITLY_SELECTED, 0);
+    }
+
+    /**
      * Called when ConnectivityService has indicated they no longer want this network.
      * The parent factory should (previously) have received indication of the change
      * as well, either canceling NetworkRequests or altering their score such that this
@@ -268,6 +304,24 @@
      */
     abstract protected void unwanted();
 
+    /**
+     * Called when the system determines the usefulness of this network.
+     *
+     * Networks claiming internet connectivity will have their internet
+     * connectivity verified.
+     *
+     * Currently there are two possible values:
+     * {@code VALID_NETWORK} if the system is happy with the connection,
+     * {@code INVALID_NETWORK} if the system is not happy.
+     * TODO - add indications of captive portal-ness and related success/failure,
+     * ie, CAPTIVE_SUCCESS_NETWORK, CAPTIVE_NETWORK for successful login and detection
+     *
+     * This may be called multiple times as the network status changes and may
+     * generate false negatives if we lose ip connectivity before the link is torn down.
+     */
+    protected void networkStatus(int status) {
+    }
+
     protected void log(String s) {
         Log.d(LOG_TAG, "NetworkAgent: " + s);
     }
diff --git a/core/java/android/net/NetworkMisc.java b/core/java/android/net/NetworkMisc.java
index 34f6cf4..5d2a43d 100644
--- a/core/java/android/net/NetworkMisc.java
+++ b/core/java/android/net/NetworkMisc.java
@@ -25,12 +25,32 @@
  * @hide
  */
 public class NetworkMisc implements Parcelable {
+
     /**
      * If the {@link Network} is a VPN, whether apps are allowed to bypass the VPN. This is set by
      * a {@link VpnService} and used by {@link ConnectivityService} when creating a VPN.
      */
     public boolean allowBypass;
 
+    /**
+     * Set if the network was manually/explicitly connected to by the user either from settings
+     * or a 3rd party app.  For example, turning on cell data is not explicit but tapping on a wifi
+     * ap in the wifi settings to trigger a connection is explicit.  A 3rd party app asking to
+     * connect to a particular access point is also explicit, though this may change in the future
+     * as we want apps to use the multinetwork apis.
+     */
+    public boolean explicitlySelected;
+
+    public NetworkMisc() {
+    }
+
+    public NetworkMisc(NetworkMisc nm) {
+        if (nm != null) {
+            allowBypass = nm.allowBypass;
+            explicitlySelected = nm.explicitlySelected;
+        }
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -39,6 +59,7 @@
     @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(allowBypass ? 1 : 0);
+        out.writeInt(explicitlySelected ? 1 : 0);
     }
 
     public static final Creator<NetworkMisc> CREATOR = new Creator<NetworkMisc>() {
@@ -46,6 +67,7 @@
         public NetworkMisc createFromParcel(Parcel in) {
             NetworkMisc networkMisc = new NetworkMisc();
             networkMisc.allowBypass = in.readInt() != 0;
+            networkMisc.explicitlySelected = in.readInt() != 0;
             return networkMisc;
         }
 
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 54d43d3..ea5dfd1 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -24,6 +24,8 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 
+import libcore.util.EmptyArray;
+
 import java.io.CharArrayWriter;
 import java.io.PrintWriter;
 import java.util.Arrays;
@@ -169,6 +171,15 @@
         } else {
             // Special case for use by NetworkStatsFactory to start out *really* empty.
             this.capacity = 0;
+            this.iface = EmptyArray.STRING;
+            this.uid = EmptyArray.INT;
+            this.set = EmptyArray.INT;
+            this.tag = EmptyArray.INT;
+            this.rxBytes = EmptyArray.LONG;
+            this.rxPackets = EmptyArray.LONG;
+            this.txBytes = EmptyArray.LONG;
+            this.txPackets = EmptyArray.LONG;
+            this.operations = EmptyArray.LONG;
         }
     }
 
diff --git a/core/java/android/nfc/cardemulation/AidGroup.java b/core/java/android/nfc/cardemulation/AidGroup.java
index f440874..4407c9d 100644
--- a/core/java/android/nfc/cardemulation/AidGroup.java
+++ b/core/java/android/nfc/cardemulation/AidGroup.java
@@ -15,10 +15,6 @@
 /**
  * The AidGroup class represents a group of Application Identifiers (AIDs).
  *
- * <p>An instance of this object can be used with
- * {@link CardEmulation#registerAidsForService(android.content.ComponentName, String, java.util.List)}
- * to tell the OS which AIDs are handled by your HCE- or SE-based service.
- *
  * <p>The format of AIDs is defined in the ISO/IEC 7816-4 specification. This class
  * requires the AIDs to be input as a hexadecimal string, with an even amount of
  * hexadecimal characters, e.g. "F014811481".
@@ -60,7 +56,10 @@
         } else {
             this.category = CardEmulation.CATEGORY_OTHER;
         }
-        this.aids = aids;
+        this.aids = new ArrayList<String>(aids.size());
+        for (String aid : aids) {
+            this.aids.add(aid.toUpperCase());
+        }
         this.description = null;
     }
 
@@ -144,7 +143,7 @@
                     if (inGroup) {
                         String aid = parser.getAttributeValue(null, "value");
                         if (aid != null) {
-                            aids.add(aid);
+                            aids.add(aid.toUpperCase());
                         }
                     } else {
                         Log.d(TAG, "Ignoring <aid> tag while not in group");
diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
index 646134e..00b2ee3 100644
--- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -231,7 +231,7 @@
                     String aid = a.getString(com.android.internal.R.styleable.AidFilter_name).
                             toUpperCase();
                     // Add wildcard char to indicate prefix
-                    aid.concat("*");
+                    aid = aid.concat("*");
                     if (CardEmulation.isValidAid(aid) && !currentGroup.aids.contains(aid)) {
                         currentGroup.aids.add(aid);
                     } else {
@@ -311,7 +311,7 @@
     public String getCategoryForAid(String aid) {
         ArrayList<AidGroup> groups = getAidGroups();
         for (AidGroup group : groups) {
-            if (group.aids.contains(aid)) {
+            if (group.aids.contains(aid.toUpperCase())) {
                 return group.category;
             }
         }
@@ -425,7 +425,7 @@
         public ApduServiceInfo createFromParcel(Parcel source) {
             ResolveInfo info = ResolveInfo.CREATOR.createFromParcel(source);
             String description = source.readString();
-            boolean onHost = (source.readInt() != 0) ? true : false;
+            boolean onHost = source.readInt() != 0;
             ArrayList<AidGroup> staticAidGroups = new ArrayList<AidGroup>();
             int numStaticGroups = source.readInt();
             if (numStaticGroups > 0) {
@@ -436,7 +436,7 @@
             if (numDynamicGroups > 0) {
                 source.readTypedList(dynamicAidGroups, AidGroup.CREATOR);
             }
-            boolean requiresUnlock = (source.readInt() != 0) ? true : false;
+            boolean requiresUnlock = source.readInt() != 0;
             int bannerResource = source.readInt();
             int uid = source.readInt();
             return new ApduServiceInfo(info, onHost, description, staticAidGroups,
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index c25278f..82016c3 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -19,6 +19,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -430,7 +431,8 @@
      * @return whether the user making this call is a goat
      */
     public boolean isUserAGoat() {
-        return false;
+        return mContext.getPackageManager()
+                .isPackageAvailable("com.coffeestainstudios.goatsimulator");
     }
 
     /**
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index 8aa2689..ac7d539 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -170,8 +170,7 @@
             = SoundTrigger.RECOGNITION_MODE_USER_IDENTIFICATION;
 
     static final String TAG = "AlwaysOnHotwordDetector";
-    // TODO: Set to false.
-    static final boolean DBG = true;
+    static final boolean DBG = false;
 
     private static final int STATUS_ERROR = SoundTrigger.STATUS_ERROR;
     private static final int STATUS_OK = SoundTrigger.STATUS_OK;
@@ -575,7 +574,7 @@
         int code = STATUS_ERROR;
         try {
             code = mModelManagementService.startRecognition(mVoiceInteractionService,
-                    mKeyphraseMetadata.id, mInternalCallback,
+                    mKeyphraseMetadata.id, mLocale.toLanguageTag(), mInternalCallback,
                     new RecognitionConfig(captureTriggerAudio, allowMultipleTriggers,
                             recognitionExtra, null /* additional data */));
         } catch (RemoteException e) {
@@ -690,7 +689,7 @@
             if (availability == STATE_NOT_READY
                     || availability == STATE_KEYPHRASE_UNENROLLED
                     || availability == STATE_KEYPHRASE_ENROLLED) {
-                enrolled = internalGetIsEnrolled(mKeyphraseMetadata.id);
+                enrolled = internalGetIsEnrolled(mKeyphraseMetadata.id, mLocale);
                 if (!enrolled) {
                     availability = STATE_KEYPHRASE_UNENROLLED;
                 } else {
@@ -741,10 +740,10 @@
         /**
          * @return The corresponding {@link KeyphraseSoundModel} or null if none is found.
          */
-        private boolean internalGetIsEnrolled(int keyphraseId) {
+        private boolean internalGetIsEnrolled(int keyphraseId, Locale locale) {
             try {
                 return mModelManagementService.isEnrolledForKeyphrase(
-                        mVoiceInteractionService, keyphraseId);
+                        mVoiceInteractionService, keyphraseId, locale.toLanguageTag());
             } catch (RemoteException e) {
                 Slog.w(TAG, "RemoteException in listRegisteredKeyphraseSoundModels!", e);
             }
diff --git a/core/java/android/transition/Fade.java b/core/java/android/transition/Fade.java
index 1f9d093..e7857c0 100644
--- a/core/java/android/transition/Fade.java
+++ b/core/java/android/transition/Fade.java
@@ -145,12 +145,21 @@
         private final View mView;
         private boolean mCanceled = false;
         private float mPausedAlpha = -1;
+        private boolean mLayerTypeChanged = false;
 
         public FadeAnimatorListener(View view) {
             mView = view;
         }
 
         @Override
+        public void onAnimationStart(Animator animator) {
+            if (mView.hasOverlappingRendering() && mView.getLayerType() == View.LAYER_TYPE_NONE) {
+                mLayerTypeChanged = true;
+                mView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+            }
+        }
+
+        @Override
         public void onAnimationCancel(Animator animator) {
             mCanceled = true;
             if (mPausedAlpha >= 0) {
@@ -163,6 +172,9 @@
             if (!mCanceled) {
                 mView.setTransitionAlpha(1);
             }
+            if (mLayerTypeChanged) {
+                mView.setLayerType(View.LAYER_TYPE_NONE, null);
+            }
         }
 
         @Override
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index b677888..c850f71 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -814,8 +814,8 @@
             }
         }
         if (mTargetIds.size() == 0 && mTargets.size() == 0 &&
-                (mTargetTypes == null || mTargetTypes.isEmpty() &&
-                (mTargetNames == null || mTargetNames.isEmpty()))) {
+                (mTargetTypes == null || mTargetTypes.isEmpty()) &&
+                (mTargetNames == null || mTargetNames.isEmpty())) {
             return true;
         }
         if (mTargetIds.contains(targetId) || mTargets.contains(target)) {
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 076f1e2..1b57c24 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -725,6 +725,19 @@
             long propCy, long propRadius, long propPaint);
 
     @Override
+    public void drawRoundRect(CanvasProperty<Float> left, CanvasProperty<Float> top,
+            CanvasProperty<Float> right, CanvasProperty<Float> bottom, CanvasProperty<Float> rx,
+            CanvasProperty<Float> ry, CanvasProperty<Paint> paint) {
+        nDrawRoundRect(mRenderer, left.getNativeContainer(), top.getNativeContainer(),
+                right.getNativeContainer(), bottom.getNativeContainer(),
+                rx.getNativeContainer(), ry.getNativeContainer(),
+                paint.getNativeContainer());
+    }
+
+    private static native void nDrawRoundRect(long renderer, long propLeft, long propTop,
+            long propRight, long propBottom, long propRx, long propRy, long propPaint);
+
+    @Override
     public void drawColor(int color) {
         drawColor(color, PorterDuff.Mode.SRC_OVER);
     }
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index c172969..e3eee71 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -113,6 +113,11 @@
     public abstract void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
             CanvasProperty<Float> radius, CanvasProperty<Paint> paint);
 
+    public abstract void drawRoundRect(CanvasProperty<Float> left, CanvasProperty<Float> top,
+            CanvasProperty<Float> right, CanvasProperty<Float> bottom,
+            CanvasProperty<Float> rx, CanvasProperty<Float> ry,
+            CanvasProperty<Paint> paint);
+
     public static void setProperty(String name, String value) {
         GLES20Canvas.setProperty(name, value);
     }
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index d23e115..edb3798 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -339,8 +339,7 @@
      * @param attachInfo AttachInfo tied to the specified view.
      * @param callbacks Callbacks invoked when drawing happens.
      */
-    abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
-            boolean isStartingWindow);
+    abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks);
 
     /**
      * Creates a new hardware layer. A hardware layer built by calling this
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index 577415e..1546877 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -209,7 +209,7 @@
         mFactory = original.mFactory;
         mFactory2 = original.mFactory2;
         mPrivateFactory = original.mPrivateFactory;
-        mFilter = original.mFilter;
+        setFilter(original.mFilter);
     }
     
     /**
@@ -606,9 +606,9 @@
             constructor.setAccessible(true);
             final View view = constructor.newInstance(args);
             if (view instanceof ViewStub) {
-                // always use ourselves when inflating ViewStub later
+                // Use the same context when inflating ViewStub later.
                 final ViewStub viewStub = (ViewStub) view;
-                viewStub.setLayoutInflater(this);
+                viewStub.setLayoutInflater(cloneInContext((Context) args[0]));
             }
             return view;
 
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 3d1332c..5d2822d 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -16,7 +16,6 @@
 
 package android.view;
 
-import android.graphics.Color;
 import com.android.internal.R;
 
 import android.content.Context;
@@ -268,8 +267,7 @@
         view.mRecreateDisplayList = false;
     }
 
-    private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks,
-            boolean isStartingWindow) {
+    private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks) {
         Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
         updateViewTreeDisplayList(view);
 
@@ -281,12 +279,6 @@
                 callbacks.onHardwarePreDraw(canvas);
 
                 canvas.insertReorderBarrier();
-                if (isStartingWindow) {
-                    // Compensate for some situations in which a hw-accelerated surface
-                    // will not be filled with anything by default; this is equivalent
-                    // to the old behavior when the system process was not hw-accelerated
-                    canvas.drawColor(Color.BLACK);
-                }
                 canvas.drawRenderNode(view.getDisplayList());
                 canvas.insertInorderBarrier();
 
@@ -306,8 +298,7 @@
     }
 
     @Override
-    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
-            boolean isStartingWindow) {
+    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {
         attachInfo.mIgnoreDirtyState = true;
         long frameTimeNanos = mChoreographer.getFrameTimeNanos();
         attachInfo.mDrawingTime = frameTimeNanos / TimeUtils.NANOS_PER_MS;
@@ -317,7 +308,7 @@
             recordDuration = System.nanoTime();
         }
 
-        updateRootDisplayList(view, callbacks, isStartingWindow);
+        updateRootDisplayList(view, callbacks);
 
         if (mProfilingEnabled) {
             recordDuration = System.nanoTime() - recordDuration;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index ae6e4e7..43ab4ef 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -711,10 +711,17 @@
             // can be used by code on the system process to escape that and enable
             // HW accelerated drawing.  (This is basically for the lock screen.)
 
+            final boolean fakeHwAccelerated = (attrs.privateFlags &
+                    WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED) != 0;
             final boolean forceHwAccelerated = (attrs.privateFlags &
                     WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED) != 0;
 
-            if (!HardwareRenderer.sRendererDisabled
+            if (fakeHwAccelerated) {
+                // This is exclusively for the preview windows the window manager
+                // shows for launching applications, so they will look more like
+                // the app being launched.
+                mAttachInfo.mHardwareAccelerationRequested = true;
+            } else if (!HardwareRenderer.sRendererDisabled
                     || (HardwareRenderer.sSystemRendererDisabled && forceHwAccelerated)) {
                 if (mAttachInfo.mHardwareRenderer != null) {
                     mAttachInfo.mHardwareRenderer.destroy();
@@ -2479,8 +2486,7 @@
                 dirty.setEmpty();
 
                 mBlockResizeBuffer = false;
-                mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this,
-                        params.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
+                mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this);
             } else {
                 // If we get here with a disabled & requested hardware renderer, something went
                 // wrong (an invalidate posted right before we destroyed the hardware surface
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index 2bfe3b4..9e0719d 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -316,7 +316,6 @@
                     top ? 0 : mSystemWindowInsets.top,
                     right ? 0 : mSystemWindowInsets.right,
                     bottom ? 0 : mSystemWindowInsets.bottom);
-            result.mSystemWindowInsetsConsumed = !hasSystemWindowInsets();
             return result;
         }
         return this;
@@ -336,7 +335,6 @@
             int right, int bottom) {
         final WindowInsets result = new WindowInsets(this);
         result.mSystemWindowInsets = new Rect(left, top, right, bottom);
-        result.mSystemWindowInsetsConsumed = !hasSystemWindowInsets();
         return result;
     }
 
@@ -351,7 +349,6 @@
     public WindowInsets replaceSystemWindowInsets(Rect systemWindowInsets) {
         final WindowInsets result = new WindowInsets(this);
         result.mSystemWindowInsets = new Rect(systemWindowInsets);
-        result.mSystemWindowInsetsConsumed = !hasSystemWindowInsets();
         return result;
     }
 
@@ -376,7 +373,6 @@
                     top ? 0 : mWindowDecorInsets.top,
                     right ? 0 : mWindowDecorInsets.right,
                     bottom ? 0 : mWindowDecorInsets.bottom);
-            result.mWindowDecorInsetsConsumed = !hasWindowDecorInsets();
             return result;
         }
         return this;
@@ -388,7 +384,6 @@
     public WindowInsets replaceWindowDecorInsets(int left, int top, int right, int bottom) {
         final WindowInsets result = new WindowInsets(this);
         result.mWindowDecorInsets = new Rect(left, top, right, bottom);
-        result.mWindowDecorInsetsConsumed = !hasWindowDecorInsets();
         return result;
     }
 
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 273ec9d..47ee52e 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1024,6 +1024,26 @@
         public int flags;
 
         /**
+         * If the window has requested hardware acceleration, but this is not
+         * allowed in the process it is in, then still render it as if it is
+         * hardware accelerated.  This is used for the starting preview windows
+         * in the system process, which don't need to have the overhead of
+         * hardware acceleration (they are just a static rendering), but should
+         * be rendered as such to match the actual window of the app even if it
+         * is hardware accelerated.
+         * Even if the window isn't hardware accelerated, still do its rendering
+         * as if it was.
+         * Like {@link #FLAG_HARDWARE_ACCELERATED} except for trusted system windows
+         * that need hardware acceleration (e.g. LockScreen), where hardware acceleration
+         * is generally disabled. This flag must be specified in addition to 
+         * {@link #FLAG_HARDWARE_ACCELERATED} to enable hardware acceleration for system
+         * windows.
+         * 
+         * @hide
+         */
+        public static final int PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED = 0x00000001;
+
+        /**
          * In the system process, we globally do not use hardware acceleration
          * because there are many threads doing UI there and they conflict.
          * If certain parts of the UI that really do want to use hardware
diff --git a/core/java/android/view/accessibility/CaptioningManager.java b/core/java/android/view/accessibility/CaptioningManager.java
index 334ff43..382a266 100644
--- a/core/java/android/view/accessibility/CaptioningManager.java
+++ b/core/java/android/view/accessibility/CaptioningManager.java
@@ -330,15 +330,30 @@
          */
         public final String mRawTypeface;
 
+        private final boolean mHasForegroundColor;
+        private final boolean mHasBackgroundColor;
+        private final boolean mHasEdgeType;
+        private final boolean mHasEdgeColor;
+        private final boolean mHasWindowColor;
+
+        /** Lazily-created typeface based on the raw typeface string. */
         private Typeface mParsedTypeface;
 
         private CaptionStyle(int foregroundColor, int backgroundColor, int edgeType, int edgeColor,
                 int windowColor, String rawTypeface) {
-            this.foregroundColor = foregroundColor;
-            this.backgroundColor = backgroundColor;
-            this.edgeType = edgeType;
-            this.edgeColor = edgeColor;
-            this.windowColor = windowColor;
+            mHasForegroundColor = foregroundColor != COLOR_UNSPECIFIED;
+            mHasBackgroundColor = backgroundColor != COLOR_UNSPECIFIED;
+            mHasEdgeType = edgeType != EDGE_TYPE_UNSPECIFIED;
+            mHasEdgeColor = edgeColor != COLOR_UNSPECIFIED;
+            mHasWindowColor = windowColor != COLOR_UNSPECIFIED;
+
+            // Always use valid colors, even when no override is specified, to
+            // ensure backwards compatibility with apps targeting KitKat MR2.
+            this.foregroundColor = mHasForegroundColor ? foregroundColor : Color.WHITE;
+            this.backgroundColor = mHasBackgroundColor ? backgroundColor : Color.BLACK;
+            this.edgeType = mHasEdgeType ? edgeType : EDGE_TYPE_NONE;
+            this.edgeColor = mHasEdgeColor ? edgeColor : Color.BLACK;
+            this.windowColor = mHasWindowColor ? windowColor : COLOR_NONE_OPAQUE;
 
             mRawTypeface = rawTypeface;
         }
@@ -375,7 +390,7 @@
          *         otherwise
          */
         public boolean hasBackgroundColor() {
-            return backgroundColor != COLOR_UNSPECIFIED;
+            return mHasBackgroundColor;
         }
 
         /**
@@ -384,7 +399,7 @@
          *         otherwise
          */
         public boolean hasForegroundColor() {
-            return foregroundColor != COLOR_UNSPECIFIED;
+            return mHasForegroundColor;
         }
 
         /**
@@ -393,7 +408,7 @@
          *         otherwise
          */
         public boolean hasEdgeType() {
-            return edgeType != EDGE_TYPE_UNSPECIFIED;
+            return mHasEdgeType;
         }
 
         /**
@@ -402,7 +417,7 @@
          *         otherwise
          */
         public boolean hasEdgeColor() {
-            return edgeColor != COLOR_UNSPECIFIED;
+            return mHasEdgeColor;
         }
 
         /**
@@ -411,7 +426,7 @@
          *         otherwise
          */
         public boolean hasWindowColor() {
-            return windowColor != COLOR_UNSPECIFIED;
+            return mHasWindowColor;
         }
 
         /**
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index 0a8e4b9..11d0f4a 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -27,6 +27,7 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.graphics.drawable.Drawable;
@@ -421,7 +422,7 @@
             }
             final Resources res = context.createPackageContext(getPackageName(), 0).getResources();
             return res.getBoolean(getIsDefaultResourceId());
-        } catch (NameNotFoundException e) {
+        } catch (NameNotFoundException | NotFoundException e) {
             return false;
         }
     }
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 3859e48..af53ec8 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -3323,7 +3323,8 @@
         if (mLastY == Integer.MIN_VALUE) {
             rawDeltaY -= mMotionCorrection;
         }
-        if (dispatchNestedPreScroll(0, -rawDeltaY, mScrollConsumed, mScrollOffset)) {
+        if (dispatchNestedPreScroll(0, mLastY != Integer.MIN_VALUE ? mLastY - y : -rawDeltaY,
+                mScrollConsumed, mScrollOffset)) {
             rawDeltaY += mScrollConsumed[1];
             scrollOffsetCorrection = -mScrollOffset[1];
             scrollConsumedCorrection = mScrollConsumed[1];
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index d77f0b2..3e4eb02 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -392,10 +392,9 @@
         mDelegate.setSpinnersShown(shown);
     }
 
-    // Override so we are in complete control of save / restore for this widget.
     @Override
     protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
-        mDelegate.dispatchRestoreInstanceState(container);
+        dispatchThawSelfOnly(container);
     }
 
     @Override
@@ -406,7 +405,7 @@
 
     @Override
     protected void onRestoreInstanceState(Parcelable state) {
-        SavedState ss = (SavedState) state;
+        BaseSavedState ss = (BaseSavedState) state;
         super.onRestoreInstanceState(ss.getSuperState());
         mDelegate.onRestoreInstanceState(ss);
     }
@@ -452,7 +451,6 @@
 
         void onConfigurationChanged(Configuration newConfig);
 
-        void dispatchRestoreInstanceState(SparseArray<Parcelable> container);
         Parcelable onSaveInstanceState(Parcelable superState);
         void onRestoreInstanceState(Parcelable state);
 
@@ -848,11 +846,6 @@
         }
 
         @Override
-        public void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
-            mDelegator.dispatchThawSelfOnly(container);
-        }
-
-        @Override
         public Parcelable onSaveInstanceState(Parcelable superState) {
             return new SavedState(superState, getYear(), getMonth(), getDayOfMonth());
         }
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index b962962..e71b383 100644
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -529,11 +529,6 @@
     }
 
     @Override
-    public void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
-        // Nothing to do
-    }
-
-    @Override
     public Parcelable onSaveInstanceState(Parcelable superState) {
         final int year = mCurrentDate.get(Calendar.YEAR);
         final int month = mCurrentDate.get(Calendar.MONTH);
@@ -557,7 +552,7 @@
     public void onRestoreInstanceState(Parcelable state) {
         SavedState ss = (SavedState) state;
 
-        mCurrentDate.set(ss.getSelectedDay(), ss.getSelectedMonth(), ss.getSelectedYear());
+        mCurrentDate.set(ss.getSelectedYear(), ss.getSelectedMonth(), ss.getSelectedDay());
         mCurrentView = ss.getCurrentView();
         mMinDate.setTimeInMillis(ss.getMinDate());
         mMaxDate.setTimeInMillis(ss.getMaxDate());
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index 06b7a93..0687905 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -1205,7 +1205,6 @@
         if (!hasSections || !mMatchDragPosition) {
             return (float) firstVisibleItem / (totalItemCount - visibleItemCount);
         }
-
         // Ignore headers.
         firstVisibleItem -= mHeaderCount;
         if (firstVisibleItem < 0) {
@@ -1255,9 +1254,19 @@
         // across the last item account for whatever space is remaining.
         if (firstVisibleItem > 0 && firstVisibleItem + visibleItemCount == totalItemCount) {
             final View lastChild = mList.getChildAt(visibleItemCount - 1);
-            final float lastItemVisible = (float) (mList.getHeight() - mList.getPaddingBottom()
-                    - lastChild.getTop()) / lastChild.getHeight();
-            result += (1 - result) * lastItemVisible;
+            final int bottomPadding = mList.getPaddingBottom();
+            final int maxSize;
+            final int currentVisibleSize;
+            if (mList.getClipToPadding()) {
+                maxSize = lastChild.getHeight();
+                currentVisibleSize = mList.getHeight() - bottomPadding - lastChild.getTop();
+            } else {
+                maxSize = lastChild.getHeight() + bottomPadding;
+                currentVisibleSize = mList.getHeight() - lastChild.getTop();
+            }
+            if (currentVisibleSize > 0 && maxSize > 0) {
+                result += (1 - result) * ((float) currentVisibleSize / maxSize );
+            }
         }
 
         return result;
diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java
index d2f68d0..0460282 100644
--- a/core/java/android/widget/RadialTimePickerView.java
+++ b/core/java/android/widget/RadialTimePickerView.java
@@ -137,6 +137,11 @@
 
     private boolean mIs24HourMode;
     private boolean mShowHours;
+
+    /**
+     * When in 24-hour mode, indicates that the current hour is between
+     * 1 and 12 (inclusive).
+     */
     private boolean mIsOnInnerCircle;
 
     private int mXCenter;
@@ -513,49 +518,53 @@
         mListener = listener;
     }
 
+    /**
+     * Sets the current hour in 24-hour time.
+     *
+     * @param hour the current hour between 0 and 23 (inclusive)
+     */
     public void setCurrentHour(int hour) {
         final int degrees = (hour % 12) * DEGREES_FOR_ONE_HOUR;
         mSelectionDegrees[HOURS] = degrees;
         mSelectionDegrees[HOURS_INNER] = degrees;
-        mAmOrPm = ((hour % 24) < 12) ? AM : PM;
+
+        // 0 is 12 AM (midnight) and 12 is 12 PM (noon).
+        mAmOrPm = (hour == 0 || (hour % 24) < 12) ? AM : PM;
+
         if (mIs24HourMode) {
-            mIsOnInnerCircle = (mAmOrPm == AM);
+            // Inner circle is 1 through 12.
+            mIsOnInnerCircle = hour >= 1 && hour <= 12;
         } else {
             mIsOnInnerCircle = false;
         }
+
         initData();
         updateLayoutData();
         invalidate();
     }
 
-    // Return hours in 0-23 range
+    /**
+     * Returns the current hour in 24-hour time.
+     *
+     * @return the current hour between 0 and 23 (inclusive)
+     */
     public int getCurrentHour() {
-        int hours =
-                mSelectionDegrees[mIsOnInnerCircle ? HOURS_INNER : HOURS] / DEGREES_FOR_ONE_HOUR;
+        int hour = (mSelectionDegrees[mIsOnInnerCircle ?
+                HOURS_INNER : HOURS] / DEGREES_FOR_ONE_HOUR) % 12;
         if (mIs24HourMode) {
-            if (mIsOnInnerCircle) {
-                hours = hours % 12;
-                if (hours == 0) {
-                    hours = 12;
-                }
-            } else {
-                if (hours != 0) {
-                    hours += 12;
-                }
+            // Convert the 12-hour value into 24-hour time based on where the
+            // selector is positioned.
+            if (mIsOnInnerCircle && hour == 0) {
+                // Inner circle is 1 through 12.
+                hour = 12;
+            } else if (hour != 0) {
+                // Outer circle is 13 through 23 and 0.
+                hour += 12;
             }
-        } else {
-            hours = hours % 12;
-            if (hours == 0) {
-                if (mAmOrPm == PM) {
-                    hours = 12;
-                }
-            } else {
-                if (mAmOrPm == PM) {
-                    hours += 12;
-                }
-            }
+        } else if (mAmOrPm == PM) {
+            hour += 12;
         }
-        return hours;
+        return hour;
     }
 
     public void setCurrentMinute(int minute) {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 1509e80..a80d70a 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8182,6 +8182,11 @@
      * @removed
      */
     public static ColorStateList getTextColors(Context context, TypedArray attrs) {
+        if (attrs == null) {
+            // Preserve behavior prior to removal of this API.
+            throw new NullPointerException();
+        }
+
         // It's not safe to use this method from apps. The parameter 'attrs'
         // must have been obtained using the TextView filter array which is not
         // available to the SDK. As such, we grab a default TypedArray with the
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index bf5e49b..dd165ae 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -113,7 +113,7 @@
         }
 
         INotificationManager service = getService();
-        String pkg = mContext.getPackageName();
+        String pkg = mContext.getOpPackageName();
         TN tn = mTN;
         tn.mNextView = mNextView;
 
@@ -387,6 +387,7 @@
                 handleHide();
                 mView = mNextView;
                 Context context = mView.getContext().getApplicationContext();
+                String packageName = mView.getContext().getOpPackageName();
                 if (context == null) {
                     context = mView.getContext();
                 }
@@ -406,6 +407,7 @@
                 mParams.y = mY;
                 mParams.verticalMargin = mVerticalMargin;
                 mParams.horizontalMargin = mHorizontalMargin;
+                mParams.packageName = packageName;
                 if (mView.getParent() != null) {
                     if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this);
                     mWM.removeView(mView);
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index 22ec4be..5a10524 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -33,32 +33,44 @@
     void finish(IBinder token);
 
     /**
-     * Lists the registered Sound model for keyphrase detection.
-     * May be null if no matching sound models exist.
+     * Gets the registered Sound model for keyphrase detection for the current user.
+     * May be null if no matching sound model exists.
+     *
+     * @param keyphraseId The unique identifier for the keyphrase.
+     * @param bcp47Locale The BCP47 language tag  for the keyphrase's locale.
      */
-    SoundTrigger.KeyphraseSoundModel getKeyphraseSoundModel(int keyphraseId);
+    SoundTrigger.KeyphraseSoundModel getKeyphraseSoundModel(int keyphraseId, in String bcp47Locale);
     /**
-     * Updates the given keyphrase sound model. Adds the model if it doesn't exist currently.
+     * Add/Update the given keyphrase sound model.
      */
     int updateKeyphraseSoundModel(in SoundTrigger.KeyphraseSoundModel model);
     /**
-     * Deletes the given keyphrase sound model.
+     * Deletes the given keyphrase sound model for the current user.
+     *
+     * @param keyphraseId The unique identifier for the keyphrase.
+     * @param bcp47Locale The BCP47 language tag  for the keyphrase's locale.
      */
-    int deleteKeyphraseSoundModel(int keyphraseId);
+    int deleteKeyphraseSoundModel(int keyphraseId, in String bcp47Locale);
 
     /**
-     * Indicates if there's a keyphrase sound model available for the given keyphrase ID.
-     */
-    boolean isEnrolledForKeyphrase(IVoiceInteractionService service, int keyphraseId);
-    /**
      * Gets the properties of the DSP hardware on this device, null if not present.
      */
     SoundTrigger.ModuleProperties getDspModuleProperties(in IVoiceInteractionService service);
     /**
+     * Indicates if there's a keyphrase sound model available for the given keyphrase ID.
+     * This performs the check for the current user.
+     *
+     * @param service The current VoiceInteractionService.
+     * @param keyphraseId The unique identifier for the keyphrase.
+     * @param bcp47Locale The BCP47 language tag  for the keyphrase's locale.
+     */
+    boolean isEnrolledForKeyphrase(IVoiceInteractionService service, int keyphraseId,
+            String bcp47Locale);
+    /**
      * Starts a recognition for the given keyphrase.
      */
     int startRecognition(in IVoiceInteractionService service, int keyphraseId,
-            in IRecognitionStatusCallback callback,
+            in String bcp47Locale, in IRecognitionStatusCallback callback,
             in SoundTrigger.RecognitionConfig recognitionConfig);
     /**
      * Stops a recognition for the given keyphrase.
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 107e8c6..22600de 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -491,8 +491,7 @@
     }
 
     private boolean versionNumberAtLeastL(int versionNumber) {
-        // TODO: remove "|| true" once the build code for L is fixed.
-        return versionNumber >= Build.VERSION_CODES.L || true;
+        return versionNumber >= Build.VERSION_CODES.L;
     }
 
     private void setAlwaysButtonEnabled(boolean hasValidSelection, int checkedPos,
diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java
index a8f7bb3..2377c22 100644
--- a/core/java/com/android/internal/app/WindowDecorActionBar.java
+++ b/core/java/com/android/internal/app/WindowDecorActionBar.java
@@ -866,14 +866,7 @@
 
         mDecorToolbar.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
         mContextView.animateToVisibility(toActionMode ? View.VISIBLE : View.GONE);
-        if (mTabScrollView != null && !mDecorToolbar.hasEmbeddedTabs() &&
-                isCollapsed(mDecorToolbar.getViewGroup())) {
-            mTabScrollView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
-        }
-    }
-
-    private boolean isCollapsed(View view) {
-        return view == null || view.getVisibility() == View.GONE || view.getMeasuredHeight() == 0;
+        // mTabScrollView's visibility is not affected by action mode.
     }
 
     public Context getThemedContext() {
diff --git a/core/java/com/android/internal/view/StandaloneActionMode.java b/core/java/com/android/internal/view/StandaloneActionMode.java
index fae7ea1..d5d3602 100644
--- a/core/java/com/android/internal/view/StandaloneActionMode.java
+++ b/core/java/com/android/internal/view/StandaloneActionMode.java
@@ -46,7 +46,8 @@
         mContextView = view;
         mCallback = callback;
 
-        mMenu = new MenuBuilder(context).setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+        mMenu = new MenuBuilder(view.getContext()).setDefaultShowAsAction(
+                MenuItem.SHOW_AS_ACTION_IF_ROOM);
         mMenu.setCallback(this);
         mFocusable = isFocusable;
     }
@@ -126,7 +127,7 @@
 
     @Override
     public MenuInflater getMenuInflater() {
-        return new MenuInflater(mContext);
+        return new MenuInflater(mContextView.getContext());
     }
 
     public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
@@ -141,7 +142,7 @@
             return true;
         }
 
-        new MenuPopupHelper(mContext, subMenu).show();
+        new MenuPopupHelper(mContextView.getContext(), subMenu).show();
         return true;
     }
 
diff --git a/core/java/com/android/internal/widget/ActionBarContainer.java b/core/java/com/android/internal/widget/ActionBarContainer.java
index d24f32f..847a47d 100644
--- a/core/java/com/android/internal/widget/ActionBarContainer.java
+++ b/core/java/com/android/internal/widget/ActionBarContainer.java
@@ -260,6 +260,11 @@
         return view == null || view.getVisibility() == GONE || view.getMeasuredHeight() == 0;
     }
 
+    private int getMeasuredHeightWithMargins(View view) {
+        final LayoutParams lp = (LayoutParams) view.getLayoutParams();
+        return view.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
+    }
+
     @Override
     public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         if (mActionBarView == null &&
@@ -271,26 +276,23 @@
 
         if (mActionBarView == null) return;
 
-        int nonTabMaxHeight = 0;
-        final int childCount = getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            final View child = getChildAt(i);
-            if (child == mTabContainer) {
-                continue;
-            }
-            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-            nonTabMaxHeight = Math.max(nonTabMaxHeight, isCollapsed(child) ? 0 :
-                    child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
-        }
-
         if (mTabContainer != null && mTabContainer.getVisibility() != GONE) {
-            final int mode = MeasureSpec.getMode(heightMeasureSpec);
-            if (mode == MeasureSpec.AT_MOST) {
-                final int maxHeight = MeasureSpec.getSize(heightMeasureSpec);
-                setMeasuredDimension(getMeasuredWidth(),
-                        Math.min(nonTabMaxHeight + mTabContainer.getMeasuredHeight(),
-                                maxHeight));
+            int nonTabMaxHeight = 0;
+            final int childCount = getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                final View child = getChildAt(i);
+                if (child == mTabContainer) {
+                    continue;
+                }
+                nonTabMaxHeight = Math.max(nonTabMaxHeight, isCollapsed(child) ? 0 :
+                        getMeasuredHeightWithMargins(child));
             }
+            final int mode = MeasureSpec.getMode(heightMeasureSpec);
+            final int maxHeight = mode == MeasureSpec.AT_MOST ?
+                    MeasureSpec.getSize(heightMeasureSpec) : Integer.MAX_VALUE;
+            setMeasuredDimension(getMeasuredWidth(),
+                    Math.min(nonTabMaxHeight + getMeasuredHeightWithMargins(mTabContainer),
+                            maxHeight));
         }
     }
 
@@ -303,8 +305,10 @@
 
         if (tabContainer != null && tabContainer.getVisibility() != GONE) {
             final int containerHeight = getMeasuredHeight();
+            final LayoutParams lp = (LayoutParams) tabContainer.getLayoutParams();
             final int tabHeight = tabContainer.getMeasuredHeight();
-            tabContainer.layout(l, containerHeight - tabHeight, r, containerHeight);
+            tabContainer.layout(l, containerHeight - tabHeight - lp.bottomMargin, r,
+                    containerHeight - lp.bottomMargin);
         }
 
         boolean needsInvalidate = false;
diff --git a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
index 63a4843..478c8f2 100644
--- a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
+++ b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
@@ -578,7 +578,7 @@
     @Override
     public void animateToVisibility(int visibility) {
         if (visibility == View.GONE) {
-            mToolbar.animate().translationY(mToolbar.getHeight()).alpha(0)
+            mToolbar.animate().alpha(0)
                     .setListener(new AnimatorListenerAdapter() {
                         private boolean mCanceled = false;
                         @Override
@@ -594,7 +594,7 @@
                         }
                     });
         } else if (visibility == View.VISIBLE) {
-            mToolbar.animate().translationY(0).alpha(1)
+            mToolbar.animate().alpha(1)
                     .setListener(new AnimatorListenerAdapter() {
                         @Override
                         public void onAnimationStart(Animator animation) {
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 1573106..1f4105f 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -905,6 +905,20 @@
     return result;
 }
 
+/** Create a Java string from an ASCII or Latin-1 string */
+jstring AndroidRuntime::NewStringLatin1(JNIEnv* env, const char* bytes) {
+    if (!bytes) return NULL;
+    int length = strlen(bytes);
+    jchar* buffer = (jchar *)alloca(length * sizeof(jchar));
+    if (!buffer) return NULL;
+    jchar* chp = buffer;
+    for (int i = 0; i < length; i++) {
+        *chp++ = *bytes++;
+    }
+    return env->NewString(buffer, length);
+}
+
+
 /*
  * Start the Android runtime.  This involves starting the virtual machine
  * and calling the "static void main(String[] args)" method in the class
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 6080f2a..2e2b23f 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -480,6 +480,20 @@
     renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint);
 }
 
+static void android_view_GLES20Canvas_drawRoundRectProps(JNIEnv* env, jobject clazz,
+        jlong rendererPtr, jlong leftPropPtr, jlong topPropPtr, jlong rightPropPtr,
+        jlong bottomPropPtr, jlong rxPropPtr, jlong ryPropPtr, jlong paintPropPtr) {
+    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
+    CanvasPropertyPrimitive* leftProp = reinterpret_cast<CanvasPropertyPrimitive*>(leftPropPtr);
+    CanvasPropertyPrimitive* topProp = reinterpret_cast<CanvasPropertyPrimitive*>(topPropPtr);
+    CanvasPropertyPrimitive* rightProp = reinterpret_cast<CanvasPropertyPrimitive*>(rightPropPtr);
+    CanvasPropertyPrimitive* bottomProp = reinterpret_cast<CanvasPropertyPrimitive*>(bottomPropPtr);
+    CanvasPropertyPrimitive* rxProp = reinterpret_cast<CanvasPropertyPrimitive*>(rxPropPtr);
+    CanvasPropertyPrimitive* ryProp = reinterpret_cast<CanvasPropertyPrimitive*>(ryPropPtr);
+    CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
+    renderer->drawRoundRect(leftProp, topProp, rightProp, bottomProp, rxProp, ryProp, paintProp);
+}
+
 static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject clazz,
         jlong rendererPtr, jfloat x, jfloat y, jfloat radius, jlong paintPtr) {
     DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
@@ -912,6 +926,7 @@
     { "nDrawRect",          "(JFFFFJ)V",       (void*) android_view_GLES20Canvas_drawRect },
     { "nDrawRects",         "(JJJ)V",          (void*) android_view_GLES20Canvas_drawRegionAsRects },
     { "nDrawRoundRect",     "(JFFFFFFJ)V",     (void*) android_view_GLES20Canvas_drawRoundRect },
+    { "nDrawRoundRect",     "(JJJJJJJJ)V",     (void*) android_view_GLES20Canvas_drawRoundRectProps },
     { "nDrawCircle",        "(JFFFJ)V",        (void*) android_view_GLES20Canvas_drawCircle },
     { "nDrawCircle",        "(JJJJJ)V",        (void*) android_view_GLES20Canvas_drawCircleProps },
     { "nDrawOval",          "(JFFFFJ)V",       (void*) android_view_GLES20Canvas_drawOval },
diff --git a/core/res/res/drawable-hdpi/spinner_textfield_activated_mtrl_alpha.9.png b/core/res/res/drawable-hdpi/spinner_textfield_activated_mtrl_alpha.9.png
deleted file mode 100644
index 5e67395..0000000
--- a/core/res/res/drawable-hdpi/spinner_textfield_activated_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_textfield_default_mtrl_alpha.9.png b/core/res/res/drawable-hdpi/spinner_textfield_default_mtrl_alpha.9.png
deleted file mode 100644
index 9c2ee13..0000000
--- a/core/res/res/drawable-hdpi/spinner_textfield_default_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_textfield_activated_mtrl_alpha.9.png b/core/res/res/drawable-mdpi/spinner_textfield_activated_mtrl_alpha.9.png
deleted file mode 100644
index cb8f78a..0000000
--- a/core/res/res/drawable-mdpi/spinner_textfield_activated_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_textfield_default_mtrl_alpha.9.png b/core/res/res/drawable-mdpi/spinner_textfield_default_mtrl_alpha.9.png
deleted file mode 100644
index 64d4c81..0000000
--- a/core/res/res/drawable-mdpi/spinner_textfield_default_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_textfield_activated_mtrl_alpha.9.png b/core/res/res/drawable-xhdpi/spinner_textfield_activated_mtrl_alpha.9.png
deleted file mode 100644
index 8e7862f..0000000
--- a/core/res/res/drawable-xhdpi/spinner_textfield_activated_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_textfield_default_mtrl_alpha.9.png b/core/res/res/drawable-xhdpi/spinner_textfield_default_mtrl_alpha.9.png
deleted file mode 100644
index 95cb83f..0000000
--- a/core/res/res/drawable-xhdpi/spinner_textfield_default_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_textfield_activated_mtrl_alpha.9.png b/core/res/res/drawable-xxhdpi/spinner_textfield_activated_mtrl_alpha.9.png
deleted file mode 100644
index eb495c6..0000000
--- a/core/res/res/drawable-xxhdpi/spinner_textfield_activated_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_textfield_default_mtrl_alpha.9.png b/core/res/res/drawable-xxhdpi/spinner_textfield_default_mtrl_alpha.9.png
deleted file mode 100644
index c2268af..0000000
--- a/core/res/res/drawable-xxhdpi/spinner_textfield_default_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/spinner_textfield_activated_mtrl_alpha.9.png b/core/res/res/drawable-xxxhdpi/spinner_textfield_activated_mtrl_alpha.9.png
deleted file mode 100644
index fbcd7d4..0000000
--- a/core/res/res/drawable-xxxhdpi/spinner_textfield_activated_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/spinner_textfield_default_mtrl_alpha.9.png b/core/res/res/drawable-xxxhdpi/spinner_textfield_default_mtrl_alpha.9.png
deleted file mode 100644
index ebc9bf7..0000000
--- a/core/res/res/drawable-xxxhdpi/spinner_textfield_default_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/ic_corp_icon_badge.xml b/core/res/res/drawable/ic_corp_icon_badge.xml
index 0b05bf5..538dade 100644
--- a/core/res/res/drawable/ic_corp_icon_badge.xml
+++ b/core/res/res/drawable/ic_corp_icon_badge.xml
@@ -19,27 +19,26 @@
         android:viewportWidth="64.0"
         android:viewportHeight="64.0">
     <path
-        android:pathData="M49.062000,50.000000m-14.000000,0.000000a14.000000,14.000000 0.000000,1.000000 1.000000,28.000000 0.000000a14.000000,14.000000 0.000000,1.000000 1.000000,-28.000000 0.000000"
-        android:fillColor="#FF000000"/>
+        android:fillColor="#FF000000"
+        android:pathData="M49.062,50.0m-14.0,0.0a14.0,14.0 0.0,1.0 1.0,28.0 0.0a14.0,14.0 0.0,1.0 1.0,-28.0 0.0"
+        android:fillAlpha="0.2"/>
     <path
-        android:pathData="M49.000000,49.500000m-14.000000,0.000000a14.000000,14.000000 0.000000,1.000000 1.000000,28.000000 0.000000a14.000000,14.000000 0.000000,1.000000 1.000000,-28.000000 0.000000"
-        android:fillColor="#FF000000"/>
+        android:fillColor="#FF000000"
+        android:pathData="M49.0,49.5m-14.0,0.0a14.0,14.0 0.0,1.0 1.0,28.0 0.0a14.0,14.0 0.0,1.0 1.0,-28.0 0.0"
+        android:fillAlpha="0.2"/>
     <path
-        android:pathData="M49.000000,49.000000m-14.000000,0.000000a14.000000,14.000000 0.000000,1.000000 1.000000,28.000000 0.000000a14.000000,14.000000 0.000000,1.000000 1.000000,-28.000000 0.000000"
+        android:pathData="M49.0,49.0m-14.0,0.0a14.0,14.0 0.0,1.0 1.0,28.0 0.0a14.0,14.0 0.0,1.0 1.0,-28.0 0.0"
         android:fillColor="#FF5722"/>
     <path
-        android:pathData="M55.250000,44.264000l-2.254000,0.000000l0.000000,-1.531000l-1.531000,-1.531000l-4.638000,0.000000l-1.531000,1.531000l0.000000,1.531000l-2.294000,0.000000c-0.846000,0.000000 -1.523000,0.685000 -1.523000,1.531000l-0.008000,8.421000c0.000000,0.846000 0.685000,1.531000 1.531000,1.531000L55.250000,55.746994c0.846000,0.000000 1.531000,-0.685000 1.531000,-1.531000l0.000000,-8.421000C56.782001,44.948002 56.097000,44.264000 55.250000,44.264000zM51.465000,44.264000l-4.638000,0.000000l0.000000,-1.531000l4.638000,0.000000L51.465000,44.264000z"
+        android:pathData="M55.801,43.688l-2.837,-0.001l0.0,-1.137l-1.587,-1.588l-4.72,-0.001l-1.588,1.587l0.0,1.137l-2.867,-0.001c-0.94,0.0 -1.691,0.76 -1.691,1.699L40.5,48.654c0.0,0.94 0.76,1.7 1.699,1.7l5.255,0.001l0.0,-1.271l0.225,0.0l2.589,0.0l0.225,0.0l0.0,1.271l5.303,0.001c0.939,0.0 1.7,-0.76 1.7,-1.699l0.002,-3.269C57.5,44.449 56.74,43.689 55.801,43.688zM51.377,43.687l-4.72,-0.001l0.0,-1.137l4.72,0.001L51.377,43.687z"
         android:fillColor="#FFFFFF"/>
     <path
-        android:pathData="M57.359001,45.373001c0.000000,-0.855000 -0.738000,-1.547000 -1.651000,-1.547000L42.535000,43.826000c-0.913000,0.000000 -1.643000,0.692000 -1.643000,1.547000l0.004000,3.232000c0.000000,0.911000 0.737000,1.648000 1.648000,1.648000l13.162000,0.000000c0.911000,0.000000 1.648000,-0.737000 1.648000,-1.648000L57.359001,45.373001z"
+        android:pathData="M50.494,52.012l-3.04,0.0l0.0,-0.901l-6.417,0.0l0.0,3.172c0.0,0.94 0.741,1.7 1.68,1.7l12.464,0.003c0.939,0.0 1.702,-0.76 1.703,-1.699l0.0,-3.176l-6.39,0.0L50.494,52.012z"
         android:fillColor="#FFFFFF"/>
     <path
         android:pathData="M40.726,40.726 h16.13 v16.13 h-16.13z"
         android:fillColor="#00000000"/>
     <path
-        android:pathData="M40.000000,49.000000l17.000000,0.000000l0.000000,2.000000l-17.000000,0.000000z"
-        android:fillColor="#FF5722"/>
-    <path
-        android:pathData="M47.625000,48.951000l3.003000,0.000000l0.000000,3.002000l-3.003000,0.000000z"
-        android:fillColor="#FF5722"/>
+        android:pathData="M46.657,42.55 h4.72 v1.137 h-4.72z"
+        android:fillColor="#00000000"/>
 </vector>
diff --git a/core/res/res/drawable/ic_corp_statusbar_icon.xml b/core/res/res/drawable/ic_corp_statusbar_icon.xml
new file mode 100644
index 0000000..e742c0b
--- /dev/null
+++ b/core/res/res/drawable/ic_corp_statusbar_icon.xml
@@ -0,0 +1,30 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M20.801,5.981L17.13,5.98l0.001,-1.471l-2.053,-2.055L8.969,2.453L6.915,4.506L6.914,5.977L3.203,5.976c-1.216,0.0 -2.189,0.983 -2.189,2.199L1.0,12.406c0.0,1.216 0.983,2.2 2.199,2.2L10.0,14.608l0.0,-1.644l0.291,0.0l3.351,0.0l0.291,0.0l0.0,1.645l6.863,0.002c1.216,0.0 2.2,-0.983 2.2,-2.199L23.0,8.181C23.0,6.965 22.017,5.981 20.801,5.981zM15.076,5.979L8.968,5.978l0.001,-1.471l6.108,0.001L15.076,5.979z"
+        android:fillColor="#FFFFFF"/>
+    <path
+        android:pathData="M13.911,16.646L9.978,16.646L9.978,15.48L1.673,15.48l0.0,4.105c0.0,1.216 0.959,2.2 2.175,2.2l16.13,0.004c1.216,0.0 2.203,-0.983 2.203,-2.199l0.0,-4.11l-8.27,0.0L13.910999,16.646z"
+        android:fillColor="#FFFFFF"/>
+    <path
+        android:pathData="M23.657,6.55 h4.72 v1.137 h-4.72z"
+        android:fillColor="#00000000"/>
+</vector>
diff --git a/core/res/res/drawable/spinner_textfield_background_material.xml b/core/res/res/drawable/spinner_textfield_background_material.xml
index 5bdff4a..2732d53 100644
--- a/core/res/res/drawable/spinner_textfield_background_material.xml
+++ b/core/res/res/drawable/spinner_textfield_background_material.xml
@@ -17,17 +17,29 @@
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
        android:inset="@dimen/control_inset_material">
     <selector android:autoMirrored="true">
-        <item android:state_checked="true">
-            <nine-patch android:src="@drawable/spinner_textfield_activated_mtrl_alpha"
-                android:tint="?attr/colorControlActivated" />
-        </item>
-        <item android:state_pressed="true">
-            <nine-patch android:src="@drawable/spinner_textfield_activated_mtrl_alpha"
-                android:tint="?attr/colorControlActivated" />
+        <item android:state_checked="false" android:state_pressed="false">
+            <layer-list android:paddingMode="stack">
+                <item>
+                    <nine-patch android:src="@drawable/textfield_default_mtrl_alpha"
+                        android:tint="?attr/colorControlNormal" />
+                </item>
+                <item>
+                    <nine-patch android:src="@drawable/spinner_mtrl_am_alpha"
+                        android:tint="?attr/colorControlNormal" />
+                </item>
+            </layer-list>
         </item>
         <item>
-            <nine-patch android:src="@drawable/spinner_textfield_default_mtrl_alpha"
-                android:tint="?attr/colorControlNormal" />
+            <layer-list android:paddingMode="stack">
+                <item>
+                    <nine-patch android:src="@drawable/textfield_activated_mtrl_alpha"
+                        android:tint="?attr/colorControlActivated" />
+                </item>
+                <item>
+                    <nine-patch android:src="@drawable/spinner_mtrl_am_alpha"
+                        android:tint="?attr/colorControlActivated" />
+                </item>
+            </layer-list>
         </item>
     </selector>
 </inset>
diff --git a/core/res/res/drawable/vector_drawable_progress_bar_large.xml b/core/res/res/drawable/vector_drawable_progress_bar_large.xml
index 3bf3cd7..023f5cc 100644
--- a/core/res/res/drawable/vector_drawable_progress_bar_large.xml
+++ b/core/res/res/drawable/vector_drawable_progress_bar_large.xml
@@ -28,7 +28,7 @@
             android:fillColor="#00000000"
             android:pathData="M0, 0 m 0, -19 a 19,19 0 1,1 0,38 a 19,19 0 1,1 0,-38"
             android:strokeColor="?attr/colorControlActivated"
-            android:strokeLineCap="round"
+            android:strokeLineCap="square"
             android:strokeLineJoin="miter"
             android:strokeWidth="4"
             android:trimPathEnd="0"
diff --git a/core/res/res/drawable/vector_drawable_progress_bar_medium.xml b/core/res/res/drawable/vector_drawable_progress_bar_medium.xml
index 62f9225..e72097e 100644
--- a/core/res/res/drawable/vector_drawable_progress_bar_medium.xml
+++ b/core/res/res/drawable/vector_drawable_progress_bar_medium.xml
@@ -28,7 +28,7 @@
             android:fillColor="#00000000"
             android:pathData="M0, 0 m 0, -19 a 19,19 0 1,1 0,38 a 19,19 0 1,1 0,-38"
             android:strokeColor="?attr/colorControlActivated"
-            android:strokeLineCap="round"
+            android:strokeLineCap="square"
             android:strokeLineJoin="miter"
             android:strokeWidth="4"
             android:trimPathEnd="0"
diff --git a/core/res/res/drawable/vector_drawable_progress_bar_small.xml b/core/res/res/drawable/vector_drawable_progress_bar_small.xml
index 1352cfc..875e7a3 100644
--- a/core/res/res/drawable/vector_drawable_progress_bar_small.xml
+++ b/core/res/res/drawable/vector_drawable_progress_bar_small.xml
@@ -28,7 +28,7 @@
             android:fillColor="#00000000"
             android:pathData="M0, 0 m 0, -19 a 19,19 0 1,1 0,38 a 19,19 0 1,1 0,-38"
             android:strokeColor="?attr/colorControlActivated"
-            android:strokeLineCap="round"
+            android:strokeLineCap="square"
             android:strokeLineJoin="miter"
             android:strokeWidth="4"
             android:trimPathEnd="0"
diff --git a/core/res/res/layout/screen.xml b/core/res/res/layout/screen.xml
index 902a797..403ffd6 100644
--- a/core/res/res/layout/screen.xml
+++ b/core/res/res/layout/screen.xml
@@ -30,7 +30,8 @@
               android:inflatedId="@+id/action_mode_bar"
               android:layout="@layout/action_mode_bar"
               android:layout_width="match_parent"
-              android:layout_height="wrap_content" />
+              android:layout_height="wrap_content"
+              android:theme="?attr/actionBarTheme" />
 
     <!-- Title bar -->
     <RelativeLayout android:id="@android:id/title_container"
diff --git a/core/res/res/layout/screen_custom_title.xml b/core/res/res/layout/screen_custom_title.xml
index b385bed..a3312dc 100644
--- a/core/res/res/layout/screen_custom_title.xml
+++ b/core/res/res/layout/screen_custom_title.xml
@@ -26,7 +26,8 @@
               android:inflatedId="@+id/action_mode_bar"
               android:layout="@layout/action_mode_bar"
               android:layout_width="match_parent"
-              android:layout_height="wrap_content" />
+              android:layout_height="wrap_content"
+              android:theme="?attr/actionBarTheme" />
 
     <FrameLayout android:id="@android:id/title_container" 
         android:layout_width="match_parent" 
diff --git a/core/res/res/layout/screen_progress.xml b/core/res/res/layout/screen_progress.xml
index 1f04d35..e70f2ec 100644
--- a/core/res/res/layout/screen_progress.xml
+++ b/core/res/res/layout/screen_progress.xml
@@ -31,7 +31,8 @@
               android:inflatedId="@+id/action_mode_bar"
               android:layout="@layout/action_mode_bar"
               android:layout_width="match_parent"
-              android:layout_height="wrap_content" />
+              android:layout_height="wrap_content"
+              android:theme="?attr/actionBarTheme" />
 
     <RelativeLayout android:id="@android:id/title_container" 
         style="?android:attr/windowTitleBackgroundStyle"
diff --git a/core/res/res/layout/screen_simple.xml b/core/res/res/layout/screen_simple.xml
index c1914e7..6111348 100644
--- a/core/res/res/layout/screen_simple.xml
+++ b/core/res/res/layout/screen_simple.xml
@@ -30,7 +30,8 @@
               android:inflatedId="@+id/action_mode_bar"
               android:layout="@layout/action_mode_bar"
               android:layout_width="match_parent"
-              android:layout_height="wrap_content" />
+              android:layout_height="wrap_content"
+              android:theme="?attr/actionBarTheme" />
     <FrameLayout
          android:id="@android:id/content"
          android:layout_width="match_parent"
diff --git a/core/res/res/layout/screen_simple_overlay_action_mode.xml b/core/res/res/layout/screen_simple_overlay_action_mode.xml
index c790d10..52b893b 100644
--- a/core/res/res/layout/screen_simple_overlay_action_mode.xml
+++ b/core/res/res/layout/screen_simple_overlay_action_mode.xml
@@ -35,5 +35,6 @@
               android:inflatedId="@+id/action_mode_bar"
               android:layout="@layout/action_mode_bar"
               android:layout_width="match_parent"
-              android:layout_height="wrap_content" />
+              android:layout_height="wrap_content"
+              android:theme="?attr/actionBarTheme" />
 </FrameLayout>
diff --git a/core/res/res/layout/screen_title.xml b/core/res/res/layout/screen_title.xml
index f5134f9..409e9c6 100644
--- a/core/res/res/layout/screen_title.xml
+++ b/core/res/res/layout/screen_title.xml
@@ -27,7 +27,8 @@
               android:inflatedId="@+id/action_mode_bar"
               android:layout="@layout/action_mode_bar"
               android:layout_width="match_parent"
-              android:layout_height="wrap_content" />
+              android:layout_height="wrap_content"
+              android:theme="?attr/actionBarTheme" />
     <FrameLayout
         android:layout_width="match_parent" 
         android:layout_height="?android:attr/windowTitleSize"
diff --git a/core/res/res/layout/screen_title_icons.xml b/core/res/res/layout/screen_title_icons.xml
index b866e57..f145429 100644
--- a/core/res/res/layout/screen_title_icons.xml
+++ b/core/res/res/layout/screen_title_icons.xml
@@ -28,7 +28,8 @@
               android:inflatedId="@+id/action_mode_bar"
               android:layout="@layout/action_mode_bar"
               android:layout_width="match_parent"
-              android:layout_height="wrap_content" />
+              android:layout_height="wrap_content"
+              android:theme="?attr/actionBarTheme"/>
     <RelativeLayout android:id="@android:id/title_container"
         style="?android:attr/windowTitleBackgroundStyle"
         android:layout_width="match_parent"
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 4f906ff..59eef74 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1203,8 +1203,7 @@
     <string name="whichSendApplicationNamed" msgid="2799370240005424391">"Comparteix amb %1$s"</string>
     <string name="whichHomeApplication" msgid="4616420172727326782">"Selecciona una aplicació d\'inici"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Utilitza-ho de manera predeterminada per a aquesta acció."</string>
-    <!-- no translation found for use_a_different_app (8134926230585710243) -->
-    <skip />
+    <string name="use_a_different_app" msgid="8134926230585710243">"Fes servir una altra aplicació"</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Esborra els paràmetres predeterminats a Configuració del sistema &gt; Aplicacions &gt; Baixades."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"Tria una acció"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Tria una aplicació per al dispositiu USB"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 85a8d80..448e072 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1768,7 +1768,7 @@
     <string name="lock_to_app_title" msgid="1682643873107812874">"از پین کردن صفحه استفاده شود؟"</string>
     <string name="lock_to_app_description" msgid="9076084599283282800">"پین کردن صفحه، نمایشگر را در یک نمای واحد قفل می‌کند.\n\nبرای خروج، کلیدهای بازگشت و برنامه‌های اخیر را همزمان لمس کنید و نگه دارید."</string>
     <string name="lock_to_app_description_accessible" msgid="2132076937479670601">"پین کردن صفحه، نمایشگر را در یک نمای واحد قفل می‌کند.\n\nبرای خروج، کلید برنامه‌های اخیر را لمس کنید و نگه دارید."</string>
-    <string name="lock_to_app_negative" msgid="2259143719362732728">"نه، سپاسگزارم"</string>
+    <string name="lock_to_app_negative" msgid="2259143719362732728">"خیر، سپاسگزارم"</string>
     <string name="lock_to_app_positive" msgid="7085139175671313864">"شروع"</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"صفحه پین شد"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"پین صفحه برداشته شد"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index d63be70..64d1f9e 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -1203,7 +1203,7 @@
     <string name="whichSendApplicationNamed" msgid="2799370240005424391">"Տարածել ըստ %1$s"</string>
     <string name="whichHomeApplication" msgid="4616420172727326782">"Ընտրեք հիմնական հավելվածը"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Օգտագործել լռելյայն այս գործողության համար:"</string>
-    <string name="use_a_different_app" msgid="8134926230585710243">"Օգտագործել այլ ծրագիր"</string>
+    <string name="use_a_different_app" msgid="8134926230585710243">"Օգտագործել այլ հավելված"</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Մաքրել լռելյայնը Համակարգի կարգավորումներ &gt; Ծրագրեր &gt;Ներբեռնված էջից:"</string>
     <string name="chooseActivity" msgid="7486876147751803333">"Ընտրել գործողություն"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Ընտրեք հավելված USB սարքի համար"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index a8c8f1c..f1691ef 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -211,7 +211,7 @@
     <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"שינוי הגדרות האודיו."</string>
     <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"השפעה על הסוללה"</string>
     <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"שימוש בתכונות שיכולות לרוקן את הסוללה במהירות."</string>
-    <string name="permgrouplab_calendar" msgid="5863508437783683902">"לוח שנה"</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"יומן"</string>
     <string name="permgroupdesc_calendar" msgid="5777534316982184416">"גישה ישירה ללוח השנה ולאירועים."</string>
     <string name="permgrouplab_dictionary" msgid="4148597128843641379">"קריאת מילון משתמש"</string>
     <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"קריאת מילים במילון משתמש."</string>
@@ -500,11 +500,11 @@
     <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"כתיבה בזרם החברתי שלך"</string>
     <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"מאפשר לאפליקציה להציג עדכונים חברתיים מהחברים שלך. היזהר בעת שיתוף מידע -- הדבר מאפשר לאפליקציה ליצור הודעות שעשויות להיראות כאילו שנשלחו מחבר. שים לב: ייתכן אישור זה לא נאכף בכל הרשתות החברתיות."</string>
     <string name="permlab_readCalendar" msgid="5972727560257612398">"קריאת אירועי יומן וגם מידע סודי"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"מאפשר לאפליקציה לקרוא את כל אירועי לוח השנה המאוחסנים בטאבלט, כולל אלה של חברים ועמיתים לעבודה. הדבר עשוי להתיר לאפליקציה לשתף או לשמור את נתוני לוח השנה שלך, ללא התחשבות בסודיות או ברגישות."</string>
-    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"מאפשר לאפליקציה לקרוא את כל אירועי לוח השנה המאוחסנים בטלפון, כולל אלה של חברים ועמיתים לעבודה. הדבר עשוי להתיר לאפליקציה לשתף או לשמור את נתוני לוח השנה שלך, ללא התחשבות בסודיות או ברגישות."</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"מאפשר לאפליקציה לקרוא את כל אירועי היומן המאוחסנים בטאבלט, כולל אלה של חברים ועמיתים לעבודה. הדבר עשוי להתיר לאפליקציה לשתף או לשמור את נתוני היומן שלך, ללא התחשבות בסודיות או ברגישות."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"מאפשר לאפליקציה לקרוא את כל אירועי היומן המאוחסנים בטלפון, כולל אלה של חברים ועמיתים לעבודה. הדבר עשוי להתיר לאפליקציה לשתף או לשמור את נתוני היומן שלך, ללא התחשבות בסודיות או ברגישות."</string>
     <string name="permlab_writeCalendar" msgid="8438874755193825647">"הוספה ושינוי של אירועי יומן ושליחת דוא\"ל לאורחים ללא ידיעת הבעלים"</string>
-    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"מאפשר לאפליקציה להוסיף, להסיר ולשנות אירועים שאתה יכול לשנות בטאבלט, כולל אלה של חברים או עמיתים לעבודה. הדבר עשוי להתיר לאפליקציה לשלוח הודעות הנראות כאילו שנשלחו מבעלי לוח שנה או לשנות אירועים ללא ידיעת הבעלים."</string>
-    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"מאפשר לאפליקציה להוסיף, להסיר ולשנות אירועים שאתה יכול לשנות בטלפון, כולל אלה של חברים או עמיתים לעבודה. הדבר עשוי להתיר לאפליקציה לשלוח הודעות הנראות כאילו שנשלחו מבעלי לוח שנה או לשנות אירועים ללא ידיעת הבעלים."</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"מאפשר לאפליקציה להוסיף, להסיר ולשנות אירועים שאתה יכול לשנות בטאבלט, כולל אלה של חברים או עמיתים לעבודה. הדבר עשוי להתיר לאפליקציה לשלוח הודעות הנראות כאילו שנשלחו מבעלי יומן או לשנות אירועים ללא ידיעת הבעלים."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"מאפשר לאפליקציה להוסיף, להסיר ולשנות אירועים שאתה יכול לשנות בטלפון, כולל אלה של חברים או עמיתים לעבודה. הדבר עשוי להתיר לאפליקציה לשלוח הודעות הנראות כאילו שנשלחו מבעלי יומן או לשנות אירועים ללא ידיעת הבעלים."</string>
     <string name="permlab_accessMockLocation" msgid="8688334974036823330">"צור מקורות מיקום מדומים לצורך בדיקה"</string>
     <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"‏צור מקורות מיקום מדומים לבדיקה, או התקן ספק מיקום חדש. פעולה זו מאפשרת לאפליקציה לעקוף את המיקום ו/או הסטטוס המוחזרים על ידי מקורות מיקום אחרים כמו GPS או ספקי מיקום."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"גישה לפקודות ספק מיקום נוספות"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 8b13e83..a67eeb9 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -397,8 +397,8 @@
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Ļauj īpašniekam izveidot savienojumu ar drukāšanas pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
     <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"izveidot savienojumu ar drukas spolētāja pakalpojumu"</string>
     <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Ļauj īpašniekam izveidot savienojumu ar drukas spolētāja pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
-    <string name="permlab_bindNfcService" msgid="2752731300419410724">"Saistīt ar TDLS pakalpojumu"</string>
-    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Ļauj īpašniekam saistīt lietojumprogrammas, kas emulē TDLS kartes. Parastajām lietotnēm šī atļauja nav nepieciešama."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"Saistīt ar NFC pakalpojumu"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Ļauj īpašniekam saistīt lietojumprogrammas, kas emulē NFC kartes. Parastajām lietotnēm šī atļauja nav nepieciešama."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"saistīt ar īsziņu pakalpojumu"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Ļauj īpašniekam veikt saistīšanu ar īsziņu pakalpojuma augstākā līmeņa saskarni (piem., SpellCheckerService). Parastajām lietotnēm tas nekad nav nepieciešams."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"saistīt ar VPN pakalpojumu"</string>
diff --git a/core/res/res/values-mcc238-mnc06/config.xml b/core/res/res/values-mcc238-mnc06/config.xml
new file mode 100644
index 0000000..afc0cc4
--- /dev/null
+++ b/core/res/res/values-mcc238-mnc06/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- SIM does not save, but the voice mail number to be changed. -->
+    <bool name="editable_voicemailnumber">true</bool>
+</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 36465c9..746eb4f 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1071,7 +1071,7 @@
   </plurals>
   <plurals name="num_hours_ago">
     <item quantity="one" msgid="9150797944610821849">"godzinę temu"</item>
-    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> godzin temu"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> godz. temu"</item>
   </plurals>
   <plurals name="last_num_days">
     <item quantity="other" msgid="3069992808164318268">"Ostatnie (<xliff:g id="COUNT">%d</xliff:g>) dni"</item>
@@ -1199,8 +1199,8 @@
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Otwórz w aplikacji %1$s"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Edytuj w aplikacji"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Edytuj w aplikacji %1$s"</string>
-    <string name="whichSendApplication" msgid="6902512414057341668">"Udostępnij w aplikacji"</string>
-    <string name="whichSendApplicationNamed" msgid="2799370240005424391">"Udostępnij w aplikacji %1$s"</string>
+    <string name="whichSendApplication" msgid="6902512414057341668">"Udostępnij przez"</string>
+    <string name="whichSendApplicationNamed" msgid="2799370240005424391">"Udostępnij przez %1$s"</string>
     <string name="whichHomeApplication" msgid="4616420172727326782">"Wybierz aplikację ekranu głównego"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Domyślne dla tej czynności"</string>
     <string name="use_a_different_app" msgid="8134926230585710243">"Użyj innej aplikacji"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 12c6661..48d4920 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -300,8 +300,8 @@
     <string name="permdesc_receiveBluetoothMap" msgid="8656755936919466345">"Permite aplicației să primească și să proceseze mesaje MAP prin Bluetooth. Aceasta înseamnă că aplicația ar putea monitoriza sau șterge mesajele trimise pe dispozitiv fără a le afișa."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"preluare aplicaţii care rulează"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Permite aplicaţiei să preia informaţiile despre activităţile care rulează în prezent şi care au rulat recent. În acest fel, aplicaţia poate descoperi informaţii despre aplicaţiile care sunt utilizate pe dispozitiv."</string>
-    <string name="permlab_startTasksFromRecents" msgid="8990073877885690623">"start a task from recents"</string>
-    <string name="permdesc_startTasksFromRecents" msgid="7382133554871222235">"Allows the app to use an ActivityManager.RecentTaskInfo object to launch a defunct task that was returned from ActivityManager.getRecentTaskList()."</string>
+    <string name="permlab_startTasksFromRecents" msgid="8990073877885690623">"începeți o sarcină din activități recente"</string>
+    <string name="permdesc_startTasksFromRecents" msgid="7382133554871222235">"Permite aplicației să utilizeze obiectul ActivityManager.RecentTaskInfo pentru a lansa o sarcină eșuată, readusă din ActivityManager.getRecentTaskList()."</string>
     <string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"interacţiune între utilizatori"</string>
     <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permite aplicaţiei să efectueze acţiuni pentru diferiţi utilizatori pe dispozitiv. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a încălca protecţia între utilizatori."</string>
     <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"licenţă completă pentru interacţiune între utilizatori"</string>
@@ -1766,8 +1766,8 @@
     <string name="lock_to_app_toast_accessible" msgid="3340628918851844044">"Pentru a anula fixarea acestui ecran, atingeți și țineți apăsat pe Recente."</string>
     <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"Ecranul este fixat. Anularea fixării nu este permisă de organizația dvs."</string>
     <string name="lock_to_app_title" msgid="1682643873107812874">"Utilizați fixarea ecranului?"</string>
-    <string name="lock_to_app_description" msgid="9076084599283282800">"Fixarea ecranului îl blochează pe acesta într-un display unic.\n\nPentru a ieși, atingeți și țineți apăsat pe Înapoi și Recente în același timp."</string>
-    <string name="lock_to_app_description_accessible" msgid="2132076937479670601">"Fixarea ecranului îl blochează pe acesta într-un display unic.\n\nPentru a ieși, atingeți și țineți apăsat Recente."</string>
+    <string name="lock_to_app_description" msgid="9076084599283282800">"Dacă fixați ecranul, rămâne o singură vizualizare.\n\nPentru a ieși, atingeți și țineți apăsat pe Înapoi și Recente în același timp."</string>
+    <string name="lock_to_app_description_accessible" msgid="2132076937479670601">"Dacă fixați ecranul, rămâne o singură vizualizare.\n\nPentru a ieși, atingeți și țineți apăsat pe Recente."</string>
     <string name="lock_to_app_negative" msgid="2259143719362732728">"NU, MULȚUMESC"</string>
     <string name="lock_to_app_positive" msgid="7085139175671313864">"PORNIȚI"</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"Ecran fixat"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 3a0e500..d2cee98 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1213,9 +1213,9 @@
     <string name="aerr_process" msgid="4507058997035697579">"Kwa bahati mbaya, mchakato wa <xliff:g id="PROCESS">%1$s</xliff:g> umekoma."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
     <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> haifanyi kazi.\n\nUnataka kuifunga?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Shughuli <xliff:g id="ACTIVITY">%1$s</xliff:g> haijibu. \n\n Unataka kuifunga?"</string>
-    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> haijibu. Unataka kufunga?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Mchakato <xliff:g id="PROCESS">%1$s</xliff:g> haijibu. \n\n Unataka kuifunga?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Shughuli ya <xliff:g id="ACTIVITY">%1$s</xliff:g> haifanyi kazi.\n\nJe, ungependa kuifunga?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> haifanyi kazi. Je, ungependa kuifunga?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Mchakato wa <xliff:g id="PROCESS">%1$s</xliff:g> haufanyi kazi. \n\nJe, ungependa kuifunga?"</string>
     <string name="force_close" msgid="8346072094521265605">"Sawa"</string>
     <string name="report" msgid="4060218260984795706">"Ripoti"</string>
     <string name="wait" msgid="7147118217226317732">"Subiri"</string>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 64638ba..2f17e75 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -1203,8 +1203,7 @@
     <string name="whichSendApplicationNamed" msgid="2799370240005424391">"‏%1$s کے ساتھ اشتراک کریں"</string>
     <string name="whichHomeApplication" msgid="4616420172727326782">"ایک ہوم ایپ منتخب کریں"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"اس کارروائی کیلئے بطور ڈیفالٹ استعمال کریں۔"</string>
-    <!-- no translation found for use_a_different_app (8134926230585710243) -->
-    <skip />
+    <string name="use_a_different_app" msgid="8134926230585710243">"ایک مختلف ایپ استعمال کریں"</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"‏سسٹم ترتیبات &gt; ایپس &gt; ڈاؤن لوڈ کردہ میں ڈیفالٹ صاف کریں۔"</string>
     <string name="chooseActivity" msgid="7486876147751803333">"ایک کارروائی منتخب کریں"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"‏USB آلہ کیلئے ایک ایپ منتخب کریں"</string>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 5a7e168..cbaf54f 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -148,10 +148,10 @@
     <color name="battery_saver_mode_color">#fff4511e</color><!-- deep orange 600 -->
 
     <!-- Default user icon colors -->
-    <color name="user_icon_1">#ffe91e63</color><!-- pink 500 -->
+    <color name="user_icon_1">#ff00bcd4</color><!-- teal 500 -->
     <color name="user_icon_2">#ff3f51b5</color><!-- indigo 500 -->
     <color name="user_icon_3">#ff4285f4</color><!-- blue 500 -->
-    <color name="user_icon_4">#ff00bcd4</color><!-- teal 500 -->
+    <color name="user_icon_4">#ffe91e63</color><!-- pink 500 -->
     <color name="user_icon_5">#ff0f9d58</color><!-- green 500 -->
     <color name="user_icon_6">#ff8bc34a</color><!-- light green 500 -->
     <color name="user_icon_7">#ffff9800</color><!-- orange 500 -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 855c63a..949c38c 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -355,9 +355,9 @@
 
     <!-- Integer parameters of the wifi to cellular handover feature
          wifi should not stick to bad networks -->
-    <integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz">-60</integer>
+    <integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz">-82</integer>
     <integer translatable="false" name="config_wifi_framework_wifi_score_low_rssi_threshold_5GHz">-72</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_good_rssi_threshold_5GHz">-82</integer>
+    <integer translatable="false" name="config_wifi_framework_wifi_score_good_rssi_threshold_5GHz">-60</integer>
     <integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz">-87</integer>
     <integer translatable="false" name="config_wifi_framework_wifi_score_low_rssi_threshold_24GHz">-77</integer>
     <integer translatable="false" name="config_wifi_framework_wifi_score_good_rssi_threshold_24GHz">-65</integer>
@@ -612,13 +612,13 @@
     <!-- Vibrator pattern for feedback when selecting an hour/minute tick of a Clock -->
     <integer-array name="config_clockTickVibePattern">
         <item>125</item>
-        <item>5</item>
+        <item>30</item>
     </integer-array>
 
     <!-- Vibrator pattern for feedback when selecting a day/month/year date of a Calendar -->
     <integer-array name="config_calendarDateVibePattern">
         <item>125</item>
-        <item>5</item>
+        <item>30</item>
     </integer-array>
 
     <!-- Vibrator pattern for feedback about booting with safe mode disabled -->
@@ -1791,6 +1791,7 @@
         <item>SUPL_PORT=7275</item>
         <item>NTP_SERVER=north-america.pool.ntp.org</item>
         <item>SUPL_VER=0x20000</item>
+        <item>SUPL_MODE=0x01</item>
     </string-array>
 
     <!-- If there is no preload VM number in the sim card, carriers such as
@@ -1810,4 +1811,7 @@
 
     <!-- Sprint need a 70 ms delay for 3way call -->
     <integer name="config_cdma_3waycall_flash_delay">0</integer>
+
+    <!--SIM does not save, but the voice mail number to be changed. -->
+    <bool name="editable_voicemailnumber">false</bool>
 </resources>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index 2b49ba2..ac5890a 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -45,8 +45,8 @@
     <dimen name="text_size_title_material_toolbar">@dimen/text_size_title_material</dimen>
     <dimen name="text_size_subtitle_material_toolbar">@dimen/text_size_subhead_material</dimen>
     <dimen name="text_size_menu_material">16sp</dimen>
-    <dimen name="text_size_body_2_material">16sp</dimen>
-    <dimen name="text_size_body_1_material">16sp</dimen>
+    <dimen name="text_size_body_2_material">14sp</dimen>
+    <dimen name="text_size_body_1_material">14sp</dimen>
     <dimen name="text_size_caption_material">12sp</dimen>
     <dimen name="text_size_button_material">14sp</dimen>
 
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 4bc1ff3..bbd40a1 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2101,485 +2101,485 @@
 <!-- ===============================================================
      Resources added in version 21 of the platform
      =============================================================== -->
-  <eat-comment />
+    <eat-comment />
 
-  <public type="attr" name="fastScrollStyle" />
-  <public type="attr" name="windowContentTransitions" />
-  <public type="attr" name="windowContentTransitionManager" />
-  <public type="attr" name="translationZ" />
-  <public type="attr" name="tintMode" />
-  <public type="attr" name="controlX1" />
-  <public type="attr" name="controlY1" />
-  <public type="attr" name="controlX2" />
-  <public type="attr" name="controlY2" />
-  <public type="attr" name="transitionName" />
-  <public type="attr" name="transitionGroup" />
-  <public type="attr" name="viewportWidth" />
-  <public type="attr" name="viewportHeight" />
-  <public type="attr" name="fillColor" />
-  <public type="attr" name="pathData" />
-  <public type="attr" name="strokeColor" />
-  <public type="attr" name="strokeWidth" />
-  <public type="attr" name="trimPathStart" />
-  <public type="attr" name="trimPathEnd" />
-  <public type="attr" name="trimPathOffset" />
-  <public type="attr" name="strokeLineCap" />
-  <public type="attr" name="strokeLineJoin" />
-  <public type="attr" name="strokeMiterLimit" />
-  <public type="attr" name="colorControlNormal" id="0x1010429"/>
-  <public type="attr" name="colorControlActivated" />
-  <public type="attr" name="colorButtonNormal" />
-  <public type="attr" name="colorControlHighlight" />
-  <public type="attr" name="persistableMode" />
-  <public type="attr" name="titleTextAppearance" />
-  <public type="attr" name="subtitleTextAppearance" />
-  <public type="attr" name="slideEdge" />
-  <public type="attr" name="actionBarTheme" />
-  <public type="attr" name="textAppearanceListItemSecondary" />
-  <public type="attr" name="colorPrimary" />
-  <public type="attr" name="colorPrimaryDark" />
-  <public type="attr" name="colorAccent" />
-  <public type="attr" name="nestedScrollingEnabled" />
-  <public type="attr" name="windowEnterTransition" />
-  <public type="attr" name="windowExitTransition" />
-  <public type="attr" name="windowSharedElementEnterTransition" />
-  <public type="attr" name="windowSharedElementExitTransition" />
-  <public type="attr" name="windowAllowReturnTransitionOverlap" />
-  <public type="attr" name="windowAllowEnterTransitionOverlap" />
-  <public type="attr" name="sessionService" />
-  <public type="attr" name="stackViewStyle" />
-  <public type="attr" name="switchStyle" />
-  <public type="attr" name="elevation" />
-  <public type="attr" name="excludeId" />
-  <public type="attr" name="excludeClass" />
-  <public type="attr" name="hideOnContentScroll" />
-  <public type="attr" name="actionOverflowMenuStyle" />
-  <public type="attr" name="documentLaunchMode" />
-  <public type="attr" name="maxRecents" />
-  <public type="attr" name="autoRemoveFromRecents" />
-  <public type="attr" name="stateListAnimator" />
-  <public type="attr" name="toId" />
-  <public type="attr" name="fromId" />
-  <public type="attr" name="reversible" />
-  <public type="attr" name="splitTrack" />
-  <public type="attr" name="targetName" />
-  <public type="attr" name="excludeName" />
-  <public type="attr" name="matchOrder" />
-  <public type="attr" name="windowDrawsSystemBarBackgrounds" />
-  <public type="attr" name="statusBarColor"/>
-  <public type="attr" name="navigationBarColor"/>
-  <public type="attr" name="contentInsetStart" />
-  <public type="attr" name="contentInsetEnd" />
-  <public type="attr" name="contentInsetLeft" />
-  <public type="attr" name="contentInsetRight" />
-  <public type="attr" name="paddingMode" />
-  <public type="attr" name="layout_rowWeight" />
-  <public type="attr" name="layout_columnWeight" />
-  <public type="attr" name="translateX" />
-  <public type="attr" name="translateY" />
-  <public type="attr" name="selectableItemBackgroundBorderless" />
-  <public type="attr" name="elegantTextHeight" />
-  <public type="attr" name="searchKeyphraseId" />
-  <public type="attr" name="searchKeyphrase" />
-  <public type="attr" name="searchKeyphraseSupportedLocales" />
-  <public type="attr" name="windowTransitionBackgroundFadeDuration" />
-  <public type="attr" name="overlapAnchor" />
-  <public type="attr" name="progressTint" />
-  <public type="attr" name="progressTintMode" />
-  <public type="attr" name="progressBackgroundTint" />
-  <public type="attr" name="progressBackgroundTintMode" />
-  <public type="attr" name="secondaryProgressTint" />
-  <public type="attr" name="secondaryProgressTintMode" />
-  <public type="attr" name="indeterminateTint" />
-  <public type="attr" name="indeterminateTintMode" />
-  <public type="attr" name="backgroundTint" />
-  <public type="attr" name="backgroundTintMode" />
-  <public type="attr" name="foregroundTint" />
-  <public type="attr" name="foregroundTintMode" />
-  <public type="attr" name="buttonTint" />
-  <public type="attr" name="buttonTintMode" />
-  <public type="attr" name="thumbTint" />
-  <public type="attr" name="thumbTintMode" />
-  <public type="attr" name="fullBackupOnly" />
-  <public type="attr" name="propertyXName" />
-  <public type="attr" name="propertyYName" />
-  <public type="attr" name="relinquishTaskIdentity" />
-  <public type="attr" name="tileModeX" />
-  <public type="attr" name="tileModeY" />
-  <public type="attr" name="actionModeShareDrawable" />
-  <public type="attr" name="actionModeFindDrawable" />
-  <public type="attr" name="actionModeWebSearchDrawable" />
-  <public type="attr" name="transitionVisibilityMode" />
-  <public type="attr" name="minimumHorizontalAngle" />
-  <public type="attr" name="minimumVerticalAngle" />
-  <public type="attr" name="maximumAngle" />
-  <public type="attr" name="searchViewStyle" />
-  <public type="attr" name="closeIcon" />
-  <public type="attr" name="goIcon" />
-  <public type="attr" name="searchIcon" />
-  <public type="attr" name="voiceIcon" />
-  <public type="attr" name="commitIcon" />
-  <public type="attr" name="suggestionRowLayout" />
-  <public type="attr" name="queryBackground" />
-  <public type="attr" name="submitBackground" />
-  <public type="attr" name="buttonBarPositiveButtonStyle" />
-  <public type="attr" name="buttonBarNeutralButtonStyle" />
-  <public type="attr" name="buttonBarNegativeButtonStyle" />
-  <public type="attr" name="popupElevation" />
-  <public type="attr" name="actionBarPopupTheme" />
-  <public type="attr" name="multiArch" />
-  <public type="attr" name="touchscreenBlocksFocus" />
-  <public type="attr" name="windowElevation" />
-  <public type="attr" name="launchTaskBehindTargetAnimation" />
-  <public type="attr" name="launchTaskBehindSourceAnimation" />
-  <public type="attr" name="restrictionType" />
-  <public type="attr" name="dayOfWeekBackground" />
-  <public type="attr" name="dayOfWeekTextAppearance" />
-  <public type="attr" name="headerMonthTextAppearance" />
-  <public type="attr" name="headerDayOfMonthTextAppearance" />
-  <public type="attr" name="headerYearTextAppearance" />
-  <public type="attr" name="yearListItemTextAppearance" />
-  <public type="attr" name="yearListSelectorColor" />
-  <public type="attr" name="calendarTextColor" />
-  <public type="attr" name="recognitionService" />
-  <public type="attr" name="timePickerStyle" />
-  <public type="attr" name="timePickerDialogTheme" />
-  <public type="attr" name="headerTimeTextAppearance" />
-  <public type="attr" name="headerAmPmTextAppearance" />
-  <public type="attr" name="numbersTextColor" />
-  <public type="attr" name="numbersBackgroundColor" />
-  <public type="attr" name="numbersSelectorColor" />
-  <public type="attr" name="amPmTextColor" />
-  <public type="attr" name="amPmBackgroundColor" />
-  <public type="attr" name="searchKeyphraseRecognitionFlags" />
-  <public type="attr" name="checkMarkTint" />
-  <public type="attr" name="checkMarkTintMode" />
-  <public type="attr" name="popupTheme" />
-  <public type="attr" name="toolbarStyle" />
-  <public type="attr" name="windowClipToOutline" />
-  <public type="attr" name="datePickerDialogTheme" />
-  <public type="attr" name="showText" />
-  <public type="attr" name="windowReturnTransition" />
-  <public type="attr" name="windowReenterTransition" />
-  <public type="attr" name="windowSharedElementReturnTransition" />
-  <public type="attr" name="windowSharedElementReenterTransition" />
-  <public type="attr" name="resumeWhilePausing" />
-  <public type="attr" name="datePickerMode"/>
-  <public type="attr" name="timePickerMode"/>
-  <public type="attr" name="inset" />
-  <public type="attr" name="letterSpacing" />
-  <public type="attr" name="fontFeatureSettings" />
-  <public type="attr" name="outlineProvider" />
-  <public type="attr" name="contentAgeHint" />
-  <public type="attr" name="country" />
-  <public type="attr" name="windowSharedElementsUseOverlay" />
-  <public type="attr" name="reparent" />
-  <public type="attr" name="reparentWithOverlay" />
-  <public type="attr" name="ambientShadowAlpha" />
-  <public type="attr" name="spotShadowAlpha" />
-  <public type="attr" name="navigationIcon" />
-  <public type="attr" name="navigationContentDescription" />
-  <public type="attr" name="fragmentExitTransition" />
-  <public type="attr" name="fragmentEnterTransition" />
-  <public type="attr" name="fragmentSharedElementEnterTransition" />
-  <public type="attr" name="fragmentReturnTransition" />
-  <public type="attr" name="fragmentSharedElementReturnTransition" />
-  <public type="attr" name="fragmentReenterTransition" />
-  <public type="attr" name="fragmentAllowEnterTransitionOverlap" />
-  <public type="attr" name="fragmentAllowReturnTransitionOverlap" />
-  <public type="attr" name="patternPathData" />
-  <public type="attr" name="strokeAlpha" />
-  <public type="attr" name="fillAlpha" />
-  <public type="attr" name="windowActivityTransitions" />
+    <public type="attr" name="fastScrollStyle" id="0x010103f7" />
+    <public type="attr" name="windowContentTransitions" id="0x010103f8" />
+    <public type="attr" name="windowContentTransitionManager" id="0x010103f9" />
+    <public type="attr" name="translationZ" id="0x010103fa" />
+    <public type="attr" name="tintMode" id="0x010103fb" />
+    <public type="attr" name="controlX1" id="0x010103fc" />
+    <public type="attr" name="controlY1" id="0x010103fd" />
+    <public type="attr" name="controlX2" id="0x010103fe" />
+    <public type="attr" name="controlY2" id="0x010103ff" />
+    <public type="attr" name="transitionName" id="0x01010400" />
+    <public type="attr" name="transitionGroup" id="0x01010401" />
+    <public type="attr" name="viewportWidth" id="0x01010402" />
+    <public type="attr" name="viewportHeight" id="0x01010403" />
+    <public type="attr" name="fillColor" id="0x01010404" />
+    <public type="attr" name="pathData" id="0x01010405" />
+    <public type="attr" name="strokeColor" id="0x01010406" />
+    <public type="attr" name="strokeWidth" id="0x01010407" />
+    <public type="attr" name="trimPathStart" id="0x01010408" />
+    <public type="attr" name="trimPathEnd" id="0x01010409" />
+    <public type="attr" name="trimPathOffset" id="0x0101040a" />
+    <public type="attr" name="strokeLineCap" id="0x0101040b" />
+    <public type="attr" name="strokeLineJoin" id="0x0101040c" />
+    <public type="attr" name="strokeMiterLimit" id="0x0101040d" />
+    <public type="attr" name="colorControlNormal" id="0x01010429" />
+    <public type="attr" name="colorControlActivated" id="0x0101042a" />
+    <public type="attr" name="colorButtonNormal" id="0x0101042b" />
+    <public type="attr" name="colorControlHighlight" id="0x0101042c" />
+    <public type="attr" name="persistableMode" id="0x0101042d" />
+    <public type="attr" name="titleTextAppearance" id="0x0101042e" />
+    <public type="attr" name="subtitleTextAppearance" id="0x0101042f" />
+    <public type="attr" name="slideEdge" id="0x01010430" />
+    <public type="attr" name="actionBarTheme" id="0x01010431" />
+    <public type="attr" name="textAppearanceListItemSecondary" id="0x01010432" />
+    <public type="attr" name="colorPrimary" id="0x01010433" />
+    <public type="attr" name="colorPrimaryDark" id="0x01010434" />
+    <public type="attr" name="colorAccent" id="0x01010435" />
+    <public type="attr" name="nestedScrollingEnabled" id="0x01010436" />
+    <public type="attr" name="windowEnterTransition" id="0x01010437" />
+    <public type="attr" name="windowExitTransition" id="0x01010438" />
+    <public type="attr" name="windowSharedElementEnterTransition" id="0x01010439" />
+    <public type="attr" name="windowSharedElementExitTransition" id="0x0101043a" />
+    <public type="attr" name="windowAllowReturnTransitionOverlap" id="0x0101043b" />
+    <public type="attr" name="windowAllowEnterTransitionOverlap" id="0x0101043c" />
+    <public type="attr" name="sessionService" id="0x0101043d" />
+    <public type="attr" name="stackViewStyle" id="0x0101043e" />
+    <public type="attr" name="switchStyle" id="0x0101043f" />
+    <public type="attr" name="elevation" id="0x01010440" />
+    <public type="attr" name="excludeId" id="0x01010441" />
+    <public type="attr" name="excludeClass" id="0x01010442" />
+    <public type="attr" name="hideOnContentScroll" id="0x01010443" />
+    <public type="attr" name="actionOverflowMenuStyle" id="0x01010444" />
+    <public type="attr" name="documentLaunchMode" id="0x01010445" />
+    <public type="attr" name="maxRecents" id="0x01010446" />
+    <public type="attr" name="autoRemoveFromRecents" id="0x01010447" />
+    <public type="attr" name="stateListAnimator" id="0x01010448" />
+    <public type="attr" name="toId" id="0x01010449" />
+    <public type="attr" name="fromId" id="0x0101044a" />
+    <public type="attr" name="reversible" id="0x0101044b" />
+    <public type="attr" name="splitTrack" id="0x0101044c" />
+    <public type="attr" name="targetName" id="0x0101044d" />
+    <public type="attr" name="excludeName" id="0x0101044e" />
+    <public type="attr" name="matchOrder" id="0x0101044f" />
+    <public type="attr" name="windowDrawsSystemBarBackgrounds" id="0x01010450" />
+    <public type="attr" name="statusBarColor" id="0x01010451" />
+    <public type="attr" name="navigationBarColor" id="0x01010452" />
+    <public type="attr" name="contentInsetStart" id="0x01010453" />
+    <public type="attr" name="contentInsetEnd" id="0x01010454" />
+    <public type="attr" name="contentInsetLeft" id="0x01010455" />
+    <public type="attr" name="contentInsetRight" id="0x01010456" />
+    <public type="attr" name="paddingMode" id="0x01010457" />
+    <public type="attr" name="layout_rowWeight" id="0x01010458" />
+    <public type="attr" name="layout_columnWeight" id="0x01010459" />
+    <public type="attr" name="translateX" id="0x0101045a" />
+    <public type="attr" name="translateY" id="0x0101045b" />
+    <public type="attr" name="selectableItemBackgroundBorderless" id="0x0101045c" />
+    <public type="attr" name="elegantTextHeight" id="0x0101045d" />
+    <public type="attr" name="searchKeyphraseId" id="0x0101045e" />
+    <public type="attr" name="searchKeyphrase" id="0x0101045f" />
+    <public type="attr" name="searchKeyphraseSupportedLocales" id="0x01010460" />
+    <public type="attr" name="windowTransitionBackgroundFadeDuration" id="0x01010461" />
+    <public type="attr" name="overlapAnchor" id="0x01010462" />
+    <public type="attr" name="progressTint" id="0x01010463" />
+    <public type="attr" name="progressTintMode" id="0x01010464" />
+    <public type="attr" name="progressBackgroundTint" id="0x01010465" />
+    <public type="attr" name="progressBackgroundTintMode" id="0x01010466" />
+    <public type="attr" name="secondaryProgressTint" id="0x01010467" />
+    <public type="attr" name="secondaryProgressTintMode" id="0x01010468" />
+    <public type="attr" name="indeterminateTint" id="0x01010469" />
+    <public type="attr" name="indeterminateTintMode" id="0x0101046a" />
+    <public type="attr" name="backgroundTint" id="0x0101046b" />
+    <public type="attr" name="backgroundTintMode" id="0x0101046c" />
+    <public type="attr" name="foregroundTint" id="0x0101046d" />
+    <public type="attr" name="foregroundTintMode" id="0x0101046e" />
+    <public type="attr" name="buttonTint" id="0x0101046f" />
+    <public type="attr" name="buttonTintMode" id="0x01010470" />
+    <public type="attr" name="thumbTint" id="0x01010471" />
+    <public type="attr" name="thumbTintMode" id="0x01010472" />
+    <public type="attr" name="fullBackupOnly" id="0x01010473" />
+    <public type="attr" name="propertyXName" id="0x01010474" />
+    <public type="attr" name="propertyYName" id="0x01010475" />
+    <public type="attr" name="relinquishTaskIdentity" id="0x01010476" />
+    <public type="attr" name="tileModeX" id="0x01010477" />
+    <public type="attr" name="tileModeY" id="0x01010478" />
+    <public type="attr" name="actionModeShareDrawable" id="0x01010479" />
+    <public type="attr" name="actionModeFindDrawable" id="0x0101047a" />
+    <public type="attr" name="actionModeWebSearchDrawable" id="0x0101047b" />
+    <public type="attr" name="transitionVisibilityMode" id="0x0101047c" />
+    <public type="attr" name="minimumHorizontalAngle" id="0x0101047d" />
+    <public type="attr" name="minimumVerticalAngle" id="0x0101047e" />
+    <public type="attr" name="maximumAngle" id="0x0101047f" />
+    <public type="attr" name="searchViewStyle" id="0x01010480" />
+    <public type="attr" name="closeIcon" id="0x01010481" />
+    <public type="attr" name="goIcon" id="0x01010482" />
+    <public type="attr" name="searchIcon" id="0x01010483" />
+    <public type="attr" name="voiceIcon" id="0x01010484" />
+    <public type="attr" name="commitIcon" id="0x01010485" />
+    <public type="attr" name="suggestionRowLayout" id="0x01010486" />
+    <public type="attr" name="queryBackground" id="0x01010487" />
+    <public type="attr" name="submitBackground" id="0x01010488" />
+    <public type="attr" name="buttonBarPositiveButtonStyle" id="0x01010489" />
+    <public type="attr" name="buttonBarNeutralButtonStyle" id="0x0101048a" />
+    <public type="attr" name="buttonBarNegativeButtonStyle" id="0x0101048b" />
+    <public type="attr" name="popupElevation" id="0x0101048c" />
+    <public type="attr" name="actionBarPopupTheme" id="0x0101048d" />
+    <public type="attr" name="multiArch" id="0x0101048e" />
+    <public type="attr" name="touchscreenBlocksFocus" id="0x0101048f" />
+    <public type="attr" name="windowElevation" id="0x01010490" />
+    <public type="attr" name="launchTaskBehindTargetAnimation" id="0x01010491" />
+    <public type="attr" name="launchTaskBehindSourceAnimation" id="0x01010492" />
+    <public type="attr" name="restrictionType" id="0x01010493" />
+    <public type="attr" name="dayOfWeekBackground" id="0x01010494" />
+    <public type="attr" name="dayOfWeekTextAppearance" id="0x01010495" />
+    <public type="attr" name="headerMonthTextAppearance" id="0x01010496" />
+    <public type="attr" name="headerDayOfMonthTextAppearance" id="0x01010497" />
+    <public type="attr" name="headerYearTextAppearance" id="0x01010498" />
+    <public type="attr" name="yearListItemTextAppearance" id="0x01010499" />
+    <public type="attr" name="yearListSelectorColor" id="0x0101049a" />
+    <public type="attr" name="calendarTextColor" id="0x0101049b" />
+    <public type="attr" name="recognitionService" id="0x0101049c" />
+    <public type="attr" name="timePickerStyle" id="0x0101049d" />
+    <public type="attr" name="timePickerDialogTheme" id="0x0101049e" />
+    <public type="attr" name="headerTimeTextAppearance" id="0x0101049f" />
+    <public type="attr" name="headerAmPmTextAppearance" id="0x010104a0" />
+    <public type="attr" name="numbersTextColor" id="0x010104a1" />
+    <public type="attr" name="numbersBackgroundColor" id="0x010104a2" />
+    <public type="attr" name="numbersSelectorColor" id="0x010104a3" />
+    <public type="attr" name="amPmTextColor" id="0x010104a4" />
+    <public type="attr" name="amPmBackgroundColor" id="0x010104a5" />
+    <public type="attr" name="searchKeyphraseRecognitionFlags" id="0x010104a6" />
+    <public type="attr" name="checkMarkTint" id="0x010104a7" />
+    <public type="attr" name="checkMarkTintMode" id="0x010104a8" />
+    <public type="attr" name="popupTheme" id="0x010104a9" />
+    <public type="attr" name="toolbarStyle" id="0x010104aa" />
+    <public type="attr" name="windowClipToOutline" id="0x010104ab" />
+    <public type="attr" name="datePickerDialogTheme" id="0x010104ac" />
+    <public type="attr" name="showText" id="0x010104ad" />
+    <public type="attr" name="windowReturnTransition" id="0x010104ae" />
+    <public type="attr" name="windowReenterTransition" id="0x010104af" />
+    <public type="attr" name="windowSharedElementReturnTransition" id="0x010104b0" />
+    <public type="attr" name="windowSharedElementReenterTransition" id="0x010104b1" />
+    <public type="attr" name="resumeWhilePausing" id="0x010104b2" />
+    <public type="attr" name="datePickerMode" id="0x010104b3" />
+    <public type="attr" name="timePickerMode" id="0x010104b4" />
+    <public type="attr" name="inset" id="0x010104b5" />
+    <public type="attr" name="letterSpacing" id="0x010104b6" />
+    <public type="attr" name="fontFeatureSettings" id="0x010104b7" />
+    <public type="attr" name="outlineProvider" id="0x010104b8" />
+    <public type="attr" name="contentAgeHint" id="0x010104b9" />
+    <public type="attr" name="country" id="0x010104ba" />
+    <public type="attr" name="windowSharedElementsUseOverlay" id="0x010104bb" />
+    <public type="attr" name="reparent" id="0x010104bc" />
+    <public type="attr" name="reparentWithOverlay" id="0x010104bd" />
+    <public type="attr" name="ambientShadowAlpha" id="0x010104be" />
+    <public type="attr" name="spotShadowAlpha" id="0x010104bf" />
+    <public type="attr" name="navigationIcon" id="0x010104c0" />
+    <public type="attr" name="navigationContentDescription" id="0x010104c1" />
+    <public type="attr" name="fragmentExitTransition" id="0x010104c2" />
+    <public type="attr" name="fragmentEnterTransition" id="0x010104c3" />
+    <public type="attr" name="fragmentSharedElementEnterTransition" id="0x010104c4" />
+    <public type="attr" name="fragmentReturnTransition" id="0x010104c5" />
+    <public type="attr" name="fragmentSharedElementReturnTransition" id="0x010104c6" />
+    <public type="attr" name="fragmentReenterTransition" id="0x010104c7" />
+    <public type="attr" name="fragmentAllowEnterTransitionOverlap" id="0x010104c8" />
+    <public type="attr" name="fragmentAllowReturnTransitionOverlap" id="0x010104c9" />
+    <public type="attr" name="patternPathData" id="0x010104ca" />
+    <public type="attr" name="strokeAlpha" id="0x010104cb" />
+    <public type="attr" name="fillAlpha" id="0x010104cc" />
+    <public type="attr" name="windowActivityTransitions" id="0x010104cd" />
 
-  <public type="id" name="mask" />
-  <public type="id" name="statusBarBackground" />
-  <public type="id" name="navigationBarBackground" />
+    <public type="id" name="mask" id="0x0102002e" />
+    <public type="id" name="statusBarBackground" id="0x0102002f" />
+    <public type="id" name="navigationBarBackground" id="0x01020030" />
 
-  <public type="style" name="Widget.FastScroll" />
-  <public type="style" name="Widget.StackView" />
-  <public type="style" name="Widget.Toolbar" />
-  <public type="style" name="Widget.Toolbar.Button.Navigation" />
+    <public type="style" name="Widget.FastScroll" id="0x010301e5" />
+    <public type="style" name="Widget.StackView" id="0x010301e6" />
+    <public type="style" name="Widget.Toolbar" id="0x010301e7" />
+    <public type="style" name="Widget.Toolbar.Button.Navigation" id="0x010301e8" />
 
-  <public type="style" name="Widget.DeviceDefault.FastScroll" />
-  <public type="style" name="Widget.DeviceDefault.StackView" />
-  <public type="style" name="Widget.DeviceDefault.Light.FastScroll" />
-  <public type="style" name="Widget.DeviceDefault.Light.StackView" />
+    <public type="style" name="Widget.DeviceDefault.FastScroll" id="0x010301e9" />
+    <public type="style" name="Widget.DeviceDefault.StackView" id="0x010301ea" />
+    <public type="style" name="Widget.DeviceDefault.Light.FastScroll" id="0x010301eb" />
+    <public type="style" name="Widget.DeviceDefault.Light.StackView" id="0x010301ec" />
 
-  <public type="style" name="TextAppearance.Material" />
-  <public type="style" name="TextAppearance.Material.Button" />
-  <public type="style" name="TextAppearance.Material.Body2" />
-  <public type="style" name="TextAppearance.Material.Body1" />
-  <public type="style" name="TextAppearance.Material.Caption" />
-  <public type="style" name="TextAppearance.Material.DialogWindowTitle" />
-  <public type="style" name="TextAppearance.Material.Display4" />
-  <public type="style" name="TextAppearance.Material.Display3" />
-  <public type="style" name="TextAppearance.Material.Display2" />
-  <public type="style" name="TextAppearance.Material.Display1" />
-  <public type="style" name="TextAppearance.Material.Headline" />
-  <public type="style" name="TextAppearance.Material.Inverse" />
-  <public type="style" name="TextAppearance.Material.Large" />
-  <public type="style" name="TextAppearance.Material.Large.Inverse" />
-  <public type="style" name="TextAppearance.Material.Medium" />
-  <public type="style" name="TextAppearance.Material.Medium.Inverse" />
-  <public type="style" name="TextAppearance.Material.Menu" />
-  <public type="style" name="TextAppearance.Material.Notification" />
-  <public type="style" name="TextAppearance.Material.Notification.Emphasis" />
-  <public type="style" name="TextAppearance.Material.Notification.Info" />
-  <public type="style" name="TextAppearance.Material.Notification.Line2" />
-  <public type="style" name="TextAppearance.Material.Notification.Time" />
-  <public type="style" name="TextAppearance.Material.Notification.Title" />
-  <public type="style" name="TextAppearance.Material.SearchResult.Subtitle" />
-  <public type="style" name="TextAppearance.Material.SearchResult.Title" />
-  <public type="style" name="TextAppearance.Material.Small" />
-  <public type="style" name="TextAppearance.Material.Small.Inverse" />
-  <public type="style" name="TextAppearance.Material.Subhead" />
-  <public type="style" name="TextAppearance.Material.Title" />
-  <public type="style" name="TextAppearance.Material.WindowTitle" />
+    <public type="style" name="TextAppearance.Material" id="0x010301ed" />
+    <public type="style" name="TextAppearance.Material.Button" id="0x010301ee" />
+    <public type="style" name="TextAppearance.Material.Body2" id="0x010301ef" />
+    <public type="style" name="TextAppearance.Material.Body1" id="0x010301f0" />
+    <public type="style" name="TextAppearance.Material.Caption" id="0x010301f1" />
+    <public type="style" name="TextAppearance.Material.DialogWindowTitle" id="0x010301f2" />
+    <public type="style" name="TextAppearance.Material.Display4" id="0x010301f3" />
+    <public type="style" name="TextAppearance.Material.Display3" id="0x010301f4" />
+    <public type="style" name="TextAppearance.Material.Display2" id="0x010301f5" />
+    <public type="style" name="TextAppearance.Material.Display1" id="0x010301f6" />
+    <public type="style" name="TextAppearance.Material.Headline" id="0x010301f7" />
+    <public type="style" name="TextAppearance.Material.Inverse" id="0x010301f8" />
+    <public type="style" name="TextAppearance.Material.Large" id="0x010301f9" />
+    <public type="style" name="TextAppearance.Material.Large.Inverse" id="0x010301fa" />
+    <public type="style" name="TextAppearance.Material.Medium" id="0x010301fb" />
+    <public type="style" name="TextAppearance.Material.Medium.Inverse" id="0x010301fc" />
+    <public type="style" name="TextAppearance.Material.Menu" id="0x010301fd" />
+    <public type="style" name="TextAppearance.Material.Notification" id="0x010301fe" />
+    <public type="style" name="TextAppearance.Material.Notification.Emphasis" id="0x010301ff" />
+    <public type="style" name="TextAppearance.Material.Notification.Info" id="0x01030200" />
+    <public type="style" name="TextAppearance.Material.Notification.Line2" id="0x01030201" />
+    <public type="style" name="TextAppearance.Material.Notification.Time" id="0x01030202" />
+    <public type="style" name="TextAppearance.Material.Notification.Title" id="0x01030203" />
+    <public type="style" name="TextAppearance.Material.SearchResult.Subtitle" id="0x01030204" />
+    <public type="style" name="TextAppearance.Material.SearchResult.Title" id="0x01030205" />
+    <public type="style" name="TextAppearance.Material.Small" id="0x01030206" />
+    <public type="style" name="TextAppearance.Material.Small.Inverse" id="0x01030207" />
+    <public type="style" name="TextAppearance.Material.Subhead" id="0x01030208" />
+    <public type="style" name="TextAppearance.Material.Title" id="0x01030209" />
+    <public type="style" name="TextAppearance.Material.WindowTitle" id="0x0103020a" />
 
-  <public type="style" name="TextAppearance.Material.Widget" />
-  <public type="style" name="TextAppearance.Material.Widget.ActionBar.Menu" />
-  <public type="style" name="TextAppearance.Material.Widget.ActionBar.Subtitle" />
-  <public type="style" name="TextAppearance.Material.Widget.ActionBar.Subtitle.Inverse" />
-  <public type="style" name="TextAppearance.Material.Widget.ActionBar.Title" />
-  <public type="style" name="TextAppearance.Material.Widget.ActionBar.Title.Inverse" />
-  <public type="style" name="TextAppearance.Material.Widget.ActionMode.Subtitle" />
-  <public type="style" name="TextAppearance.Material.Widget.ActionMode.Subtitle.Inverse" />
-  <public type="style" name="TextAppearance.Material.Widget.ActionMode.Title" />
-  <public type="style" name="TextAppearance.Material.Widget.ActionMode.Title.Inverse" />
-  <public type="style" name="TextAppearance.Material.Widget.Button" />
-  <public type="style" name="TextAppearance.Material.Widget.DropDownHint" />
-  <public type="style" name="TextAppearance.Material.Widget.DropDownItem" />
-  <public type="style" name="TextAppearance.Material.Widget.EditText" />
-  <public type="style" name="TextAppearance.Material.Widget.IconMenu.Item" />
-  <public type="style" name="TextAppearance.Material.Widget.PopupMenu" />
-  <public type="style" name="TextAppearance.Material.Widget.PopupMenu.Large" />
-  <public type="style" name="TextAppearance.Material.Widget.PopupMenu.Small" />
-  <public type="style" name="TextAppearance.Material.Widget.TabWidget" />
-  <public type="style" name="TextAppearance.Material.Widget.TextView" />
-  <public type="style" name="TextAppearance.Material.Widget.TextView.PopupMenu" />
-  <public type="style" name="TextAppearance.Material.Widget.TextView.SpinnerItem" />
-  <public type="style" name="TextAppearance.Material.Widget.Toolbar.Subtitle" />
-  <public type="style" name="TextAppearance.Material.Widget.Toolbar.Title" />
+    <public type="style" name="TextAppearance.Material.Widget" id="0x0103020b" />
+    <public type="style" name="TextAppearance.Material.Widget.ActionBar.Menu" id="0x0103020c" />
+    <public type="style" name="TextAppearance.Material.Widget.ActionBar.Subtitle" id="0x0103020d" />
+    <public type="style" name="TextAppearance.Material.Widget.ActionBar.Subtitle.Inverse" id="0x0103020e" />
+    <public type="style" name="TextAppearance.Material.Widget.ActionBar.Title" id="0x0103020f" />
+    <public type="style" name="TextAppearance.Material.Widget.ActionBar.Title.Inverse" id="0x01030210" />
+    <public type="style" name="TextAppearance.Material.Widget.ActionMode.Subtitle" id="0x01030211" />
+    <public type="style" name="TextAppearance.Material.Widget.ActionMode.Subtitle.Inverse" id="0x01030212" />
+    <public type="style" name="TextAppearance.Material.Widget.ActionMode.Title" id="0x01030213" />
+    <public type="style" name="TextAppearance.Material.Widget.ActionMode.Title.Inverse" id="0x01030214" />
+    <public type="style" name="TextAppearance.Material.Widget.Button" id="0x01030215" />
+    <public type="style" name="TextAppearance.Material.Widget.DropDownHint" id="0x01030216" />
+    <public type="style" name="TextAppearance.Material.Widget.DropDownItem" id="0x01030217" />
+    <public type="style" name="TextAppearance.Material.Widget.EditText" id="0x01030218" />
+    <public type="style" name="TextAppearance.Material.Widget.IconMenu.Item" id="0x01030219" />
+    <public type="style" name="TextAppearance.Material.Widget.PopupMenu" id="0x0103021a" />
+    <public type="style" name="TextAppearance.Material.Widget.PopupMenu.Large" id="0x0103021b" />
+    <public type="style" name="TextAppearance.Material.Widget.PopupMenu.Small" id="0x0103021c" />
+    <public type="style" name="TextAppearance.Material.Widget.TabWidget" id="0x0103021d" />
+    <public type="style" name="TextAppearance.Material.Widget.TextView" id="0x0103021e" />
+    <public type="style" name="TextAppearance.Material.Widget.TextView.PopupMenu" id="0x0103021f" />
+    <public type="style" name="TextAppearance.Material.Widget.TextView.SpinnerItem" id="0x01030220" />
+    <public type="style" name="TextAppearance.Material.Widget.Toolbar.Subtitle" id="0x01030221" />
+    <public type="style" name="TextAppearance.Material.Widget.Toolbar.Title" id="0x01030222" />
 
-  <public type="style" name="Theme.DeviceDefault.Settings" />
+    <public type="style" name="Theme.DeviceDefault.Settings" id="0x01030223" />
 
-  <public type="style" name="Theme.Material" />
-  <public type="style" name="Theme.Material.Dialog" />
-  <public type="style" name="Theme.Material.Dialog.Alert" />
-  <public type="style" name="Theme.Material.Dialog.MinWidth" />
-  <public type="style" name="Theme.Material.Dialog.NoActionBar" />
-  <public type="style" name="Theme.Material.Dialog.NoActionBar.MinWidth" />
-  <public type="style" name="Theme.Material.Dialog.Presentation" />
-  <public type="style" name="Theme.Material.DialogWhenLarge" />
-  <public type="style" name="Theme.Material.DialogWhenLarge.NoActionBar" />
-  <public type="style" name="Theme.Material.InputMethod" />
-  <public type="style" name="Theme.Material.NoActionBar" />
-  <public type="style" name="Theme.Material.NoActionBar.Fullscreen" />
-  <public type="style" name="Theme.Material.NoActionBar.Overscan" />
-  <public type="style" name="Theme.Material.NoActionBar.TranslucentDecor" />
-  <public type="style" name="Theme.Material.Panel" />
-  <public type="style" name="Theme.Material.Settings" />
-  <public type="style" name="Theme.Material.Voice" />
-  <public type="style" name="Theme.Material.Wallpaper" />
-  <public type="style" name="Theme.Material.Wallpaper.NoTitleBar" />
+    <public type="style" name="Theme.Material" id="0x01030224" />
+    <public type="style" name="Theme.Material.Dialog" id="0x01030225" />
+    <public type="style" name="Theme.Material.Dialog.Alert" id="0x01030226" />
+    <public type="style" name="Theme.Material.Dialog.MinWidth" id="0x01030227" />
+    <public type="style" name="Theme.Material.Dialog.NoActionBar" id="0x01030228" />
+    <public type="style" name="Theme.Material.Dialog.NoActionBar.MinWidth" id="0x01030229" />
+    <public type="style" name="Theme.Material.Dialog.Presentation" id="0x0103022a" />
+    <public type="style" name="Theme.Material.DialogWhenLarge" id="0x0103022b" />
+    <public type="style" name="Theme.Material.DialogWhenLarge.NoActionBar" id="0x0103022c" />
+    <public type="style" name="Theme.Material.InputMethod" id="0x0103022d" />
+    <public type="style" name="Theme.Material.NoActionBar" id="0x0103022e" />
+    <public type="style" name="Theme.Material.NoActionBar.Fullscreen" id="0x0103022f" />
+    <public type="style" name="Theme.Material.NoActionBar.Overscan" id="0x01030230" />
+    <public type="style" name="Theme.Material.NoActionBar.TranslucentDecor" id="0x01030231" />
+    <public type="style" name="Theme.Material.Panel" id="0x01030232" />
+    <public type="style" name="Theme.Material.Settings" id="0x01030233" />
+    <public type="style" name="Theme.Material.Voice" id="0x01030234" />
+    <public type="style" name="Theme.Material.Wallpaper" id="0x01030235" />
+    <public type="style" name="Theme.Material.Wallpaper.NoTitleBar" id="0x01030236" />
 
-  <public type="style" name="Theme.Material.Light" />
-  <public type="style" name="Theme.Material.Light.DarkActionBar" />
-  <public type="style" name="Theme.Material.Light.Dialog" />
-  <public type="style" name="Theme.Material.Light.Dialog.Alert" />
-  <public type="style" name="Theme.Material.Light.Dialog.MinWidth" />
-  <public type="style" name="Theme.Material.Light.Dialog.NoActionBar" />
-  <public type="style" name="Theme.Material.Light.Dialog.NoActionBar.MinWidth" />
-  <public type="style" name="Theme.Material.Light.Dialog.Presentation" />
-  <public type="style" name="Theme.Material.Light.DialogWhenLarge" />
-  <public type="style" name="Theme.Material.Light.DialogWhenLarge.NoActionBar" />
-  <public type="style" name="Theme.Material.Light.NoActionBar" />
-  <public type="style" name="Theme.Material.Light.NoActionBar.Fullscreen" />
-  <public type="style" name="Theme.Material.Light.NoActionBar.Overscan" />
-  <public type="style" name="Theme.Material.Light.NoActionBar.TranslucentDecor" />
-  <public type="style" name="Theme.Material.Light.Panel" />
-  <public type="style" name="Theme.Material.Light.Voice" />
+    <public type="style" name="Theme.Material.Light" id="0x01030237" />
+    <public type="style" name="Theme.Material.Light.DarkActionBar" id="0x01030238" />
+    <public type="style" name="Theme.Material.Light.Dialog" id="0x01030239" />
+    <public type="style" name="Theme.Material.Light.Dialog.Alert" id="0x0103023a" />
+    <public type="style" name="Theme.Material.Light.Dialog.MinWidth" id="0x0103023b" />
+    <public type="style" name="Theme.Material.Light.Dialog.NoActionBar" id="0x0103023c" />
+    <public type="style" name="Theme.Material.Light.Dialog.NoActionBar.MinWidth" id="0x0103023d" />
+    <public type="style" name="Theme.Material.Light.Dialog.Presentation" id="0x0103023e" />
+    <public type="style" name="Theme.Material.Light.DialogWhenLarge" id="0x0103023f" />
+    <public type="style" name="Theme.Material.Light.DialogWhenLarge.NoActionBar" id="0x01030240" />
+    <public type="style" name="Theme.Material.Light.NoActionBar" id="0x01030241" />
+    <public type="style" name="Theme.Material.Light.NoActionBar.Fullscreen" id="0x01030242" />
+    <public type="style" name="Theme.Material.Light.NoActionBar.Overscan" id="0x01030243" />
+    <public type="style" name="Theme.Material.Light.NoActionBar.TranslucentDecor" id="0x01030244" />
+    <public type="style" name="Theme.Material.Light.Panel" id="0x01030245" />
+    <public type="style" name="Theme.Material.Light.Voice" id="0x01030246" />
 
-  <public type="style" name="ThemeOverlay" />
-  <public type="style" name="ThemeOverlay.Material" />
-  <public type="style" name="ThemeOverlay.Material.ActionBar" />
-  <public type="style" name="ThemeOverlay.Material.Light" />
-  <public type="style" name="ThemeOverlay.Material.Dark" />
-  <public type="style" name="ThemeOverlay.Material.Dark.ActionBar" />
+    <public type="style" name="ThemeOverlay" id="0x01030247" />
+    <public type="style" name="ThemeOverlay.Material" id="0x01030248" />
+    <public type="style" name="ThemeOverlay.Material.ActionBar" id="0x01030249" />
+    <public type="style" name="ThemeOverlay.Material.Light" id="0x0103024a" />
+    <public type="style" name="ThemeOverlay.Material.Dark" id="0x0103024b" />
+    <public type="style" name="ThemeOverlay.Material.Dark.ActionBar" id="0x0103024c" />
 
-  <public type="style" name="Widget.Material" />
-  <public type="style" name="Widget.Material.ActionBar" />
-  <public type="style" name="Widget.Material.ActionBar.Solid" />
-  <public type="style" name="Widget.Material.ActionBar.TabBar" />
-  <public type="style" name="Widget.Material.ActionBar.TabText" />
-  <public type="style" name="Widget.Material.ActionBar.TabView" />
-  <public type="style" name="Widget.Material.ActionButton" />
-  <public type="style" name="Widget.Material.ActionButton.CloseMode" />
-  <public type="style" name="Widget.Material.ActionButton.Overflow" />
-  <public type="style" name="Widget.Material.ActionMode" />
-  <public type="style" name="Widget.Material.AutoCompleteTextView" />
-  <public type="style" name="Widget.Material.Button" />
-  <public type="style" name="Widget.Material.Button.Borderless" />
-  <public type="style" name="Widget.Material.Button.Borderless.Colored" />
-  <public type="style" name="Widget.Material.Button.Borderless.Small" />
-  <public type="style" name="Widget.Material.Button.Inset" />
-  <public type="style" name="Widget.Material.Button.Small" />
-  <public type="style" name="Widget.Material.Button.Toggle" />
-  <public type="style" name="Widget.Material.ButtonBar" />
-  <public type="style" name="Widget.Material.ButtonBar.AlertDialog" />
-  <public type="style" name="Widget.Material.CalendarView" />
-  <public type="style" name="Widget.Material.CheckedTextView" />
-  <public type="style" name="Widget.Material.CompoundButton.CheckBox" />
-  <public type="style" name="Widget.Material.CompoundButton.RadioButton" />
-  <public type="style" name="Widget.Material.CompoundButton.Star" />
-  <public type="style" name="Widget.Material.DatePicker" />
-  <public type="style" name="Widget.Material.DropDownItem" />
-  <public type="style" name="Widget.Material.DropDownItem.Spinner" />
-  <public type="style" name="Widget.Material.EditText" />
-  <public type="style" name="Widget.Material.ExpandableListView" />
-  <public type="style" name="Widget.Material.FastScroll" />
-  <public type="style" name="Widget.Material.GridView" />
-  <public type="style" name="Widget.Material.HorizontalScrollView" />
-  <public type="style" name="Widget.Material.ImageButton" />
-  <public type="style" name="Widget.Material.ListPopupWindow" />
-  <public type="style" name="Widget.Material.ListView" />
-  <public type="style" name="Widget.Material.ListView.DropDown" />
-  <public type="style" name="Widget.Material.MediaRouteButton" />
-  <public type="style" name="Widget.Material.PopupMenu" />
-  <public type="style" name="Widget.Material.PopupMenu.Overflow" />
-  <public type="style" name="Widget.Material.PopupWindow" />
-  <public type="style" name="Widget.Material.ProgressBar" />
-  <public type="style" name="Widget.Material.ProgressBar.Horizontal" />
-  <public type="style" name="Widget.Material.ProgressBar.Large" />
-  <public type="style" name="Widget.Material.ProgressBar.Small" />
-  <public type="style" name="Widget.Material.ProgressBar.Small.Title" />
-  <public type="style" name="Widget.Material.RatingBar" />
-  <public type="style" name="Widget.Material.RatingBar.Indicator" />
-  <public type="style" name="Widget.Material.RatingBar.Small" />
-  <public type="style" name="Widget.Material.ScrollView" />
-  <public type="style" name="Widget.Material.SearchView" />
-  <public type="style" name="Widget.Material.SeekBar" />
-  <public type="style" name="Widget.Material.SegmentedButton" />
-  <public type="style" name="Widget.Material.StackView" />
-  <public type="style" name="Widget.Material.Spinner" />
-  <public type="style" name="Widget.Material.Spinner.Underlined" />
-  <public type="style" name="Widget.Material.Tab" />
-  <public type="style" name="Widget.Material.TabWidget" />
-  <public type="style" name="Widget.Material.TextView" />
-  <public type="style" name="Widget.Material.TextView.SpinnerItem" />
-  <public type="style" name="Widget.Material.TimePicker" />
-  <public type="style" name="Widget.Material.Toolbar" />
-  <public type="style" name="Widget.Material.Toolbar.Button.Navigation" />
-  <public type="style" name="Widget.Material.WebTextView" />
-  <public type="style" name="Widget.Material.WebView" />
+    <public type="style" name="Widget.Material" id="0x0103024d" />
+    <public type="style" name="Widget.Material.ActionBar" id="0x0103024e" />
+    <public type="style" name="Widget.Material.ActionBar.Solid" id="0x0103024f" />
+    <public type="style" name="Widget.Material.ActionBar.TabBar" id="0x01030250" />
+    <public type="style" name="Widget.Material.ActionBar.TabText" id="0x01030251" />
+    <public type="style" name="Widget.Material.ActionBar.TabView" id="0x01030252" />
+    <public type="style" name="Widget.Material.ActionButton" id="0x01030253" />
+    <public type="style" name="Widget.Material.ActionButton.CloseMode" id="0x01030254" />
+    <public type="style" name="Widget.Material.ActionButton.Overflow" id="0x01030255" />
+    <public type="style" name="Widget.Material.ActionMode" id="0x01030256" />
+    <public type="style" name="Widget.Material.AutoCompleteTextView" id="0x01030257" />
+    <public type="style" name="Widget.Material.Button" id="0x01030258" />
+    <public type="style" name="Widget.Material.Button.Borderless" id="0x01030259" />
+    <public type="style" name="Widget.Material.Button.Borderless.Colored" id="0x0103025a" />
+    <public type="style" name="Widget.Material.Button.Borderless.Small" id="0x0103025b" />
+    <public type="style" name="Widget.Material.Button.Inset" id="0x0103025c" />
+    <public type="style" name="Widget.Material.Button.Small" id="0x0103025d" />
+    <public type="style" name="Widget.Material.Button.Toggle" id="0x0103025e" />
+    <public type="style" name="Widget.Material.ButtonBar" id="0x0103025f" />
+    <public type="style" name="Widget.Material.ButtonBar.AlertDialog" id="0x01030260" />
+    <public type="style" name="Widget.Material.CalendarView" id="0x01030261" />
+    <public type="style" name="Widget.Material.CheckedTextView" id="0x01030262" />
+    <public type="style" name="Widget.Material.CompoundButton.CheckBox" id="0x01030263" />
+    <public type="style" name="Widget.Material.CompoundButton.RadioButton" id="0x01030264" />
+    <public type="style" name="Widget.Material.CompoundButton.Star" id="0x01030265" />
+    <public type="style" name="Widget.Material.DatePicker" id="0x01030266" />
+    <public type="style" name="Widget.Material.DropDownItem" id="0x01030267" />
+    <public type="style" name="Widget.Material.DropDownItem.Spinner" id="0x01030268" />
+    <public type="style" name="Widget.Material.EditText" id="0x01030269" />
+    <public type="style" name="Widget.Material.ExpandableListView" id="0x0103026a" />
+    <public type="style" name="Widget.Material.FastScroll" id="0x0103026b" />
+    <public type="style" name="Widget.Material.GridView" id="0x0103026c" />
+    <public type="style" name="Widget.Material.HorizontalScrollView" id="0x0103026d" />
+    <public type="style" name="Widget.Material.ImageButton" id="0x0103026e" />
+    <public type="style" name="Widget.Material.ListPopupWindow" id="0x0103026f" />
+    <public type="style" name="Widget.Material.ListView" id="0x01030270" />
+    <public type="style" name="Widget.Material.ListView.DropDown" id="0x01030271" />
+    <public type="style" name="Widget.Material.MediaRouteButton" id="0x01030272" />
+    <public type="style" name="Widget.Material.PopupMenu" id="0x01030273" />
+    <public type="style" name="Widget.Material.PopupMenu.Overflow" id="0x01030274" />
+    <public type="style" name="Widget.Material.PopupWindow" id="0x01030275" />
+    <public type="style" name="Widget.Material.ProgressBar" id="0x01030276" />
+    <public type="style" name="Widget.Material.ProgressBar.Horizontal" id="0x01030277" />
+    <public type="style" name="Widget.Material.ProgressBar.Large" id="0x01030278" />
+    <public type="style" name="Widget.Material.ProgressBar.Small" id="0x01030279" />
+    <public type="style" name="Widget.Material.ProgressBar.Small.Title" id="0x0103027a" />
+    <public type="style" name="Widget.Material.RatingBar" id="0x0103027b" />
+    <public type="style" name="Widget.Material.RatingBar.Indicator" id="0x0103027c" />
+    <public type="style" name="Widget.Material.RatingBar.Small" id="0x0103027d" />
+    <public type="style" name="Widget.Material.ScrollView" id="0x0103027e" />
+    <public type="style" name="Widget.Material.SearchView" id="0x0103027f" />
+    <public type="style" name="Widget.Material.SeekBar" id="0x01030280" />
+    <public type="style" name="Widget.Material.SegmentedButton" id="0x01030281" />
+    <public type="style" name="Widget.Material.StackView" id="0x01030282" />
+    <public type="style" name="Widget.Material.Spinner" id="0x01030283" />
+    <public type="style" name="Widget.Material.Spinner.Underlined" id="0x01030284" />
+    <public type="style" name="Widget.Material.Tab" id="0x01030285" />
+    <public type="style" name="Widget.Material.TabWidget" id="0x01030286" />
+    <public type="style" name="Widget.Material.TextView" id="0x01030287" />
+    <public type="style" name="Widget.Material.TextView.SpinnerItem" id="0x01030288" />
+    <public type="style" name="Widget.Material.TimePicker" id="0x01030289" />
+    <public type="style" name="Widget.Material.Toolbar" id="0x0103028a" />
+    <public type="style" name="Widget.Material.Toolbar.Button.Navigation" id="0x0103028b" />
+    <public type="style" name="Widget.Material.WebTextView" id="0x0103028c" />
+    <public type="style" name="Widget.Material.WebView" id="0x0103028d" />
 
-  <public type="style" name="Widget.Material.Light" />
-  <public type="style" name="Widget.Material.Light.ActionBar" />
-  <public type="style" name="Widget.Material.Light.ActionBar.Solid" />
-  <public type="style" name="Widget.Material.Light.ActionBar.TabBar" />
-  <public type="style" name="Widget.Material.Light.ActionBar.TabText" />
-  <public type="style" name="Widget.Material.Light.ActionBar.TabView" />
-  <public type="style" name="Widget.Material.Light.ActionButton" />
-  <public type="style" name="Widget.Material.Light.ActionButton.CloseMode" />
-  <public type="style" name="Widget.Material.Light.ActionButton.Overflow" />
-  <public type="style" name="Widget.Material.Light.ActionMode" />
-  <public type="style" name="Widget.Material.Light.AutoCompleteTextView" />
-  <public type="style" name="Widget.Material.Light.Button" />
-  <public type="style" name="Widget.Material.Light.Button.Borderless" />
-  <public type="style" name="Widget.Material.Light.Button.Borderless.Colored" />
-  <public type="style" name="Widget.Material.Light.Button.Borderless.Small" />
-  <public type="style" name="Widget.Material.Light.Button.Inset" />
-  <public type="style" name="Widget.Material.Light.Button.Small" />
-  <public type="style" name="Widget.Material.Light.Button.Toggle" />
-  <public type="style" name="Widget.Material.Light.ButtonBar" />
-  <public type="style" name="Widget.Material.Light.ButtonBar.AlertDialog" />
-  <public type="style" name="Widget.Material.Light.CalendarView" />
-  <public type="style" name="Widget.Material.Light.CheckedTextView" />
-  <public type="style" name="Widget.Material.Light.CompoundButton.CheckBox" />
-  <public type="style" name="Widget.Material.Light.CompoundButton.RadioButton" />
-  <public type="style" name="Widget.Material.Light.CompoundButton.Star" />
-  <public type="style" name="Widget.Material.Light.DatePicker" />
-  <public type="style" name="Widget.Material.Light.DropDownItem" />
-  <public type="style" name="Widget.Material.Light.DropDownItem.Spinner" />
-  <public type="style" name="Widget.Material.Light.EditText" />
-  <public type="style" name="Widget.Material.Light.ExpandableListView" />
-  <public type="style" name="Widget.Material.Light.FastScroll" />
-  <public type="style" name="Widget.Material.Light.GridView" />
-  <public type="style" name="Widget.Material.Light.HorizontalScrollView" />
-  <public type="style" name="Widget.Material.Light.ImageButton" />
-  <public type="style" name="Widget.Material.Light.ListPopupWindow" />
-  <public type="style" name="Widget.Material.Light.ListView" />
-  <public type="style" name="Widget.Material.Light.ListView.DropDown" />
-  <public type="style" name="Widget.Material.Light.MediaRouteButton" />
-  <public type="style" name="Widget.Material.Light.PopupMenu" />
-  <public type="style" name="Widget.Material.Light.PopupMenu.Overflow" />
-  <public type="style" name="Widget.Material.Light.PopupWindow" />
-  <public type="style" name="Widget.Material.Light.ProgressBar" />
-  <public type="style" name="Widget.Material.Light.ProgressBar.Horizontal" />
-  <public type="style" name="Widget.Material.Light.ProgressBar.Inverse" />
-  <public type="style" name="Widget.Material.Light.ProgressBar.Large" />
-  <public type="style" name="Widget.Material.Light.ProgressBar.Large.Inverse" />
-  <public type="style" name="Widget.Material.Light.ProgressBar.Small" />
-  <public type="style" name="Widget.Material.Light.ProgressBar.Small.Inverse" />
-  <public type="style" name="Widget.Material.Light.ProgressBar.Small.Title" />
-  <public type="style" name="Widget.Material.Light.RatingBar" />
-  <public type="style" name="Widget.Material.Light.RatingBar.Indicator" />
-  <public type="style" name="Widget.Material.Light.RatingBar.Small" />
-  <public type="style" name="Widget.Material.Light.ScrollView" />
-  <public type="style" name="Widget.Material.Light.SearchView" />
-  <public type="style" name="Widget.Material.Light.SeekBar" />
-  <public type="style" name="Widget.Material.Light.SegmentedButton" />
-  <public type="style" name="Widget.Material.Light.StackView" />
-  <public type="style" name="Widget.Material.Light.Spinner" />
-  <public type="style" name="Widget.Material.Light.Spinner.Underlined" />
-  <public type="style" name="Widget.Material.Light.Tab" />
-  <public type="style" name="Widget.Material.Light.TabWidget" />
-  <public type="style" name="Widget.Material.Light.TextView" />
-  <public type="style" name="Widget.Material.Light.TextView.SpinnerItem" />
-  <public type="style" name="Widget.Material.Light.TimePicker" />
-  <public type="style" name="Widget.Material.Light.WebTextView" />
-  <public type="style" name="Widget.Material.Light.WebView" />
+    <public type="style" name="Widget.Material.Light" id="0x0103028e" />
+    <public type="style" name="Widget.Material.Light.ActionBar" id="0x0103028f" />
+    <public type="style" name="Widget.Material.Light.ActionBar.Solid" id="0x01030290" />
+    <public type="style" name="Widget.Material.Light.ActionBar.TabBar" id="0x01030291" />
+    <public type="style" name="Widget.Material.Light.ActionBar.TabText" id="0x01030292" />
+    <public type="style" name="Widget.Material.Light.ActionBar.TabView" id="0x01030293" />
+    <public type="style" name="Widget.Material.Light.ActionButton" id="0x01030294" />
+    <public type="style" name="Widget.Material.Light.ActionButton.CloseMode" id="0x01030295" />
+    <public type="style" name="Widget.Material.Light.ActionButton.Overflow" id="0x01030296" />
+    <public type="style" name="Widget.Material.Light.ActionMode" id="0x01030297" />
+    <public type="style" name="Widget.Material.Light.AutoCompleteTextView" id="0x01030298" />
+    <public type="style" name="Widget.Material.Light.Button" id="0x01030299" />
+    <public type="style" name="Widget.Material.Light.Button.Borderless" id="0x0103029a" />
+    <public type="style" name="Widget.Material.Light.Button.Borderless.Colored" id="0x0103029b" />
+    <public type="style" name="Widget.Material.Light.Button.Borderless.Small" id="0x0103029c" />
+    <public type="style" name="Widget.Material.Light.Button.Inset" id="0x0103029d" />
+    <public type="style" name="Widget.Material.Light.Button.Small" id="0x0103029e" />
+    <public type="style" name="Widget.Material.Light.Button.Toggle" id="0x0103029f" />
+    <public type="style" name="Widget.Material.Light.ButtonBar" id="0x010302a0" />
+    <public type="style" name="Widget.Material.Light.ButtonBar.AlertDialog" id="0x010302a1" />
+    <public type="style" name="Widget.Material.Light.CalendarView" id="0x010302a2" />
+    <public type="style" name="Widget.Material.Light.CheckedTextView" id="0x010302a3" />
+    <public type="style" name="Widget.Material.Light.CompoundButton.CheckBox" id="0x010302a4" />
+    <public type="style" name="Widget.Material.Light.CompoundButton.RadioButton" id="0x010302a5" />
+    <public type="style" name="Widget.Material.Light.CompoundButton.Star" id="0x010302a6" />
+    <public type="style" name="Widget.Material.Light.DatePicker" id="0x010302a7" />
+    <public type="style" name="Widget.Material.Light.DropDownItem" id="0x010302a8" />
+    <public type="style" name="Widget.Material.Light.DropDownItem.Spinner" id="0x010302a9" />
+    <public type="style" name="Widget.Material.Light.EditText" id="0x010302aa" />
+    <public type="style" name="Widget.Material.Light.ExpandableListView" id="0x010302ab" />
+    <public type="style" name="Widget.Material.Light.FastScroll" id="0x010302ac" />
+    <public type="style" name="Widget.Material.Light.GridView" id="0x010302ad" />
+    <public type="style" name="Widget.Material.Light.HorizontalScrollView" id="0x010302ae" />
+    <public type="style" name="Widget.Material.Light.ImageButton" id="0x010302af" />
+    <public type="style" name="Widget.Material.Light.ListPopupWindow" id="0x010302b0" />
+    <public type="style" name="Widget.Material.Light.ListView" id="0x010302b1" />
+    <public type="style" name="Widget.Material.Light.ListView.DropDown" id="0x010302b2" />
+    <public type="style" name="Widget.Material.Light.MediaRouteButton" id="0x010302b3" />
+    <public type="style" name="Widget.Material.Light.PopupMenu" id="0x010302b4" />
+    <public type="style" name="Widget.Material.Light.PopupMenu.Overflow" id="0x010302b5" />
+    <public type="style" name="Widget.Material.Light.PopupWindow" id="0x010302b6" />
+    <public type="style" name="Widget.Material.Light.ProgressBar" id="0x010302b7" />
+    <public type="style" name="Widget.Material.Light.ProgressBar.Horizontal" id="0x010302b8" />
+    <public type="style" name="Widget.Material.Light.ProgressBar.Inverse" id="0x010302b9" />
+    <public type="style" name="Widget.Material.Light.ProgressBar.Large" id="0x010302ba" />
+    <public type="style" name="Widget.Material.Light.ProgressBar.Large.Inverse" id="0x010302bb" />
+    <public type="style" name="Widget.Material.Light.ProgressBar.Small" id="0x010302bc" />
+    <public type="style" name="Widget.Material.Light.ProgressBar.Small.Inverse" id="0x010302bd" />
+    <public type="style" name="Widget.Material.Light.ProgressBar.Small.Title" id="0x010302be" />
+    <public type="style" name="Widget.Material.Light.RatingBar" id="0x010302bf" />
+    <public type="style" name="Widget.Material.Light.RatingBar.Indicator" id="0x010302c0" />
+    <public type="style" name="Widget.Material.Light.RatingBar.Small" id="0x010302c1" />
+    <public type="style" name="Widget.Material.Light.ScrollView" id="0x010302c2" />
+    <public type="style" name="Widget.Material.Light.SearchView" id="0x010302c3" />
+    <public type="style" name="Widget.Material.Light.SeekBar" id="0x010302c4" />
+    <public type="style" name="Widget.Material.Light.SegmentedButton" id="0x010302c5" />
+    <public type="style" name="Widget.Material.Light.StackView" id="0x010302c6" />
+    <public type="style" name="Widget.Material.Light.Spinner" id="0x010302c7" />
+    <public type="style" name="Widget.Material.Light.Spinner.Underlined" id="0x010302c8" />
+    <public type="style" name="Widget.Material.Light.Tab" id="0x010302c9" />
+    <public type="style" name="Widget.Material.Light.TabWidget" id="0x010302ca" />
+    <public type="style" name="Widget.Material.Light.TextView" id="0x010302cb" />
+    <public type="style" name="Widget.Material.Light.TextView.SpinnerItem" id="0x010302cc" />
+    <public type="style" name="Widget.Material.Light.TimePicker" id="0x010302cd" />
+    <public type="style" name="Widget.Material.Light.WebTextView" id="0x010302ce" />
+    <public type="style" name="Widget.Material.Light.WebView" id="0x010302cf" />
 
-  <!-- @hide This really shouldn't be public; clients using it should use @* to ref it.  -->
-  <public type="style" name="Theme.Leanback.FormWizard"/>
+    <!-- @hide This really shouldn't be public; clients using it should use @* to ref it.  -->
+    <public type="style" name="Theme.Leanback.FormWizard" id="0x010302d0" />
 
-  <public type="string" name="config_webSettingsDefaultTextEncoding" />
+    <public type="string" name="config_webSettingsDefaultTextEncoding" id="0x01040018" />
 
-  <public type="array" name="config_keySystemUuidMapping" />
+    <public type="array" name="config_keySystemUuidMapping" id="0x01070005" />
 
-  <!-- An interpolator which accelerates fast but decelerates slowly. -->
-  <public type="interpolator" name="fast_out_slow_in" />
-  <!-- An interpolator which starts with a peak non-zero velocity and decelerates slowly. -->
-  <public type="interpolator" name="linear_out_slow_in" />
-  <!-- An interpolator which accelerates fast and keeps accelerating until the end. -->
-  <public type="interpolator" name="fast_out_linear_in" />
+    <!-- An interpolator which accelerates fast but decelerates slowly. -->
+    <public type="interpolator" name="fast_out_slow_in" id="0x010c000d" />
+    <!-- An interpolator which starts with a peak non-zero velocity and decelerates slowly. -->
+    <public type="interpolator" name="linear_out_slow_in" id="0x010c000e" />
+    <!-- An interpolator which accelerates fast and keeps accelerating until the end. -->
+    <public type="interpolator" name="fast_out_linear_in" id="0x010c000f" />
 
-  <!-- Used for Activity Transitions, this transition indicates that no Transition
-       should be used. -->
-  <public type="transition" name="no_transition" id="0x010f0000"/>
-  <!-- A transition that moves and resizes a view -->
-  <public type="transition" name="move"/>
-  <!-- A transition that fades views in and out. -->
-  <public type="transition" name="fade"/>
-  <!-- A transition that moves views in or out of the scene to or from the edges when
-       a view visibility changes. -->
-  <public type="transition" name="explode"/>
-  <!-- A transition that moves views in or out of the scene to or from the bottom edge when
-       a view visibility changes. -->
-  <public type="transition" name="slide_bottom"/>
-  <!-- A transition that moves views in or out of the scene to or from the top edge when
-       a view visibility changes. -->
-  <public type="transition" name="slide_top"/>
-  <!-- A transition that moves views in or out of the scene to or from the right edge when
-       a view visibility changes. -->
-  <public type="transition" name="slide_right"/>
-  <!-- A transition that moves views in or out of the scene to or from the left edge when
-       a view visibility changes. -->
-  <public type="transition" name="slide_left"/>
+    <!-- Used for Activity Transitions, this transition indicates that no Transition
+         should be used. -->
+    <public type="transition" name="no_transition" id="0x010f0000" />
+    <!-- A transition that moves and resizes a view -->
+    <public type="transition" name="move" id="0x010f0001" />
+    <!-- A transition that fades views in and out. -->
+    <public type="transition" name="fade" id="0x010f0002" />
+    <!-- A transition that moves views in or out of the scene to or from the edges when
+         a view visibility changes. -->
+    <public type="transition" name="explode" id="0x010f0003" />
+    <!-- A transition that moves views in or out of the scene to or from the bottom edge when
+         a view visibility changes. -->
+    <public type="transition" name="slide_bottom" id="0x010f0004" />
+    <!-- A transition that moves views in or out of the scene to or from the top edge when
+         a view visibility changes. -->
+    <public type="transition" name="slide_top" id="0x010f0005" />
+    <!-- A transition that moves views in or out of the scene to or from the right edge when
+         a view visibility changes. -->
+    <public type="transition" name="slide_right" id="0x010f0006" />
+    <!-- A transition that moves views in or out of the scene to or from the left edge when
+         a view visibility changes. -->
+    <public type="transition" name="slide_left" id="0x010f0007" />
 
-  <!-- WebView error page for when the load fails. @hide @SystemApi -->
-  <public type="raw" name="loaderror" id="0x01100000"/>
-  <!-- WebView error page for when domain lookup fails. @hide @SystemApi -->
-  <public type="raw" name="nodomain"/>
+    <!-- WebView error page for when the load fails. @hide @SystemApi -->
+    <public type="raw" name="loaderror" id="0x01100000" />
+    <!-- WebView error page for when domain lookup fails. @hide @SystemApi -->
+    <public type="raw" name="nodomain" id="0x01100001" />
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 9d77309..ed43faf 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -322,6 +322,7 @@
   <java-symbol type="integer" name="config_wifi_framework_wifi_score_bad_link_speed_5" />
   <java-symbol type="integer" name="config_wifi_framework_wifi_score_good_link_speed_24" />
   <java-symbol type="integer" name="config_wifi_framework_wifi_score_good_link_speed_5" />
+  <java-symbol type="bool" name="editable_voicemailnumber" />
 
   <java-symbol type="bool" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment" />
   <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_tx_packet_threshold" />
@@ -1192,6 +1193,7 @@
   <java-symbol type="drawable" name="ic_corp_badge" />
   <java-symbol type="drawable" name="ic_corp_icon_badge" />
   <java-symbol type="drawable" name="ic_corp_icon" />
+  <java-symbol type="drawable" name="ic_corp_statusbar_icon" />
   <java-symbol type="drawable" name="emulator_circular_window_overlay" />
 
   <java-symbol type="drawable" name="sim_light_blue" />
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index a984cfa..ebff965 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -316,6 +316,8 @@
         <item name="actionBarStyle">@style/Widget.Material.ActionBar.Solid</item>
         <item name="actionBarSize">@dimen/action_bar_default_height_material</item>
         <item name="actionModePopupWindowStyle">@style/Widget.Material.PopupWindow.ActionMode</item>
+        <item name="actionMenuTextAppearance">@style/TextAppearance.Material.Widget.ActionBar.Menu</item>
+        <item name="actionMenuTextColor">?attr/textColorPrimary</item>
         <item name="actionBarWidgetTheme">@null</item>
         <item name="actionBarPopupTheme">@null</item>
         <item name="actionBarTheme">@style/ThemeOverlay.Material.ActionBar</item>
diff --git a/core/tests/coretests/src/android/net/NetworkStatsTest.java b/core/tests/coretests/src/android/net/NetworkStatsTest.java
index 6331964..9ee4e20 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsTest.java
@@ -310,6 +310,16 @@
         assertEquals(128L + 512L, clone.getTotalBytes());
     }
 
+    public void testAddWhenEmpty() throws Exception {
+        final NetworkStats red = new NetworkStats(TEST_START, -1);
+        final NetworkStats blue = new NetworkStats(TEST_START, 5)
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
+                .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L);
+
+        // We're mostly checking that we don't crash
+        red.combineAllValues(blue);
+    }
+
     private static void assertValues(NetworkStats stats, int index, String iface, int uid, int set,
             int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
         final NetworkStats.Entry entry = stats.getValues(index, null);
diff --git a/data/keyboards/Vendor_0a5c_Product_8502.kl b/data/keyboards/Vendor_0a5c_Product_8502.kl
deleted file mode 100644
index 2f07328..0000000
--- a/data/keyboards/Vendor_0a5c_Product_8502.kl
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Rhodi
-
-key 304 BUTTON_A
-key 305 BUTTON_B
-key 307 BUTTON_X
-key 308 BUTTON_Y
-key 310 BUTTON_L1
-key 311 BUTTON_R1
-key 316 BUTTON_MODE
-key 317 BUTTON_THUMBL
-key 318 BUTTON_THUMBR
-
-key 158 BACK
-key 172 HOME
-
-axis 0x00 X
-axis 0x01 Y
-axis 0x02 Z
-axis 0x05 RZ
-axis 0x09 RTRIGGER
-axis 0x0a LTRIGGER
-axis 0x10 HAT_X
-axis 0x11 HAT_Y
-
-led 0x00 CONTROLLER_1
-led 0x01 CONTROLLER_2
-led 0x02 CONTROLLER_3
-led 0x03 CONTROLLER_4
diff --git a/data/sounds/AudioPackage10.mk b/data/sounds/AudioPackage10.mk
index 68a87f2..5a5eea6 100644
--- a/data/sounds/AudioPackage10.mk
+++ b/data/sounds/AudioPackage10.mk
@@ -23,7 +23,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressInvalid_48k.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn_48k.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/VideoRecord_48k.ogg:system/media/audio/ui/VideoRecord.ogg \
-	$(LOCAL_PATH)/effects/ogg/camera_click_48k.ogg:system/media/audio/ui/camera_click.ogg \
+	$(LOCAL_PATH)/effects/material/ogg/camera_click_48k.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/LowBattery_48k.ogg:system/media/audio/ui/LowBattery.ogg \
 	$(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
diff --git a/data/sounds/AudioPackage11.mk b/data/sounds/AudioPackage11.mk
index f19ed30..0f85b33 100644
--- a/data/sounds/AudioPackage11.mk
+++ b/data/sounds/AudioPackage11.mk
@@ -23,7 +23,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressInvalid_48k.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn_48k.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/VideoRecord_48k.ogg:system/media/audio/ui/VideoRecord.ogg \
-	$(LOCAL_PATH)/effects/ogg/camera_click_48k.ogg:system/media/audio/ui/camera_click.ogg \
+	$(LOCAL_PATH)/effects/material/ogg/camera_click_48k.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/LowBattery_48k.ogg:system/media/audio/ui/LowBattery.ogg \
 	$(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
diff --git a/data/sounds/AudioPackage12.mk b/data/sounds/AudioPackage12.mk
index c13689d..4251332 100644
--- a/data/sounds/AudioPackage12.mk
+++ b/data/sounds/AudioPackage12.mk
@@ -12,8 +12,8 @@
 NOTIFICATION_FILES := Ariel Ceres Carme Elara Europa Iapetus Io Rhea Salacia Titan Tethys
 RINGTONE_FILES := Callisto Dione Ganymede Luna Oberon Phobos Sedna Titania Triton Umbriel
 EFFECT_FILES := Effect_Tick KeypressReturn KeypressInvalid KeypressDelete KeypressSpacebar KeypressStandard \
-	camera_click camera_focus Dock Undock Lock Unlock Trusted
-MATERIAL_EFFECT_FILES := VideoRecord LowBattery WirelessChargingStarted
+	camera_focus Dock Undock Lock Unlock Trusted
+MATERIAL_EFFECT_FILES := camera_click VideoRecord LowBattery WirelessChargingStarted
 
 PRODUCT_COPY_FILES += $(foreach fn,$(ALARM_FILES),\
 	$(LOCAL_PATH)/alarms/ogg/$(fn).ogg:system/media/audio/alarms/$(fn).ogg)
diff --git a/data/sounds/AudioPackage12_48.mk b/data/sounds/AudioPackage12_48.mk
index 6d86baf..70e68d3 100644
--- a/data/sounds/AudioPackage12_48.mk
+++ b/data/sounds/AudioPackage12_48.mk
@@ -12,8 +12,8 @@
 NOTIFICATION_FILES := Ariel Ceres Carme Elara Europa Iapetus Io Rhea Salacia Titan Tethys
 RINGTONE_FILES := Callisto Dione Ganymede Luna Oberon Phobos Sedna Titania Triton Umbriel
 EFFECT_FILES := Effect_Tick KeypressReturn KeypressInvalid KeypressDelete KeypressSpacebar KeypressStandard \
-	camera_click Lock Unlock Trusted
-MATERIAL_EFFECT_FILES := VideoRecord LowBattery WirelessChargingStarted
+	Lock Unlock Trusted
+MATERIAL_EFFECT_FILES := camera_click VideoRecord LowBattery WirelessChargingStarted
 
 # Alarms not yet available in 48 kHz
 PRODUCT_COPY_FILES += $(foreach fn,$(ALARM_FILES),\
@@ -34,4 +34,4 @@
 PRODUCT_COPY_FILES += \
     $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
     $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
-    $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg
\ No newline at end of file
+    $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg
diff --git a/data/sounds/AudioPackage13.mk b/data/sounds/AudioPackage13.mk
index 9bbfa7f..cec7280 100644
--- a/data/sounds/AudioPackage13.mk
+++ b/data/sounds/AudioPackage13.mk
@@ -13,8 +13,8 @@
 RINGTONE_FILES := Atria Callisto Dione Ganymede Luna Oberon Phobos Pyxis Sedna Titania Triton \
 	Umbriel
 EFFECT_FILES := Effect_Tick KeypressReturn KeypressInvalid KeypressDelete KeypressSpacebar KeypressStandard \
-	camera_click camera_focus Dock Undock Lock Unlock Trusted
-MATERIAL_EFFECT_FILES := VideoRecord WirelessChargingStarted LowBattery
+	camera_focus Dock Undock Lock Unlock Trusted
+MATERIAL_EFFECT_FILES := camera_click VideoRecord WirelessChargingStarted LowBattery
 
 PRODUCT_COPY_FILES += $(foreach fn,$(ALARM_FILES),\
 	$(LOCAL_PATH)/alarms/material/ogg/$(fn).ogg:system/media/audio/alarms/$(fn).ogg)
diff --git a/data/sounds/AudioPackage13_48.mk b/data/sounds/AudioPackage13_48.mk
index b90cd00..d1b17c8 100644
--- a/data/sounds/AudioPackage13_48.mk
+++ b/data/sounds/AudioPackage13_48.mk
@@ -13,8 +13,8 @@
 RINGTONE_FILES := Atria Callisto Dione Ganymede Luna Oberon Phobos Pyxis Sedna Titania Triton \
 	Umbriel
 EFFECT_FILES := Effect_Tick KeypressReturn KeypressInvalid KeypressDelete KeypressSpacebar KeypressStandard \
-	camera_click Lock Unlock Trusted
-MATERIAL_EFFECT_FILES := VideoRecord WirelessChargingStarted LowBattery
+	Lock Unlock Trusted
+MATERIAL_EFFECT_FILES := camera_click VideoRecord WirelessChargingStarted LowBattery
 
 PRODUCT_COPY_FILES += $(foreach fn,$(ALARM_FILES),\
 	$(LOCAL_PATH)/alarms/material/ogg/$(fn)_48k.ogg:system/media/audio/alarms/$(fn).ogg)
@@ -34,4 +34,4 @@
 PRODUCT_COPY_FILES += \
     $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
     $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
-    $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg
\ No newline at end of file
+    $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg
diff --git a/data/sounds/AudioPackage6.mk b/data/sounds/AudioPackage6.mk
index 89b5f1b..c843fdc 100644
--- a/data/sounds/AudioPackage6.mk
+++ b/data/sounds/AudioPackage6.mk
@@ -19,7 +19,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
-	$(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+	$(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
 	$(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
diff --git a/data/sounds/AudioPackage7.mk b/data/sounds/AudioPackage7.mk
index 065fb84..ce82651 100644
--- a/data/sounds/AudioPackage7.mk
+++ b/data/sounds/AudioPackage7.mk
@@ -21,7 +21,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressInvalid_120.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
-	$(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+	$(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
 	$(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
diff --git a/data/sounds/AudioPackage7alt.mk b/data/sounds/AudioPackage7alt.mk
index 9c35a2e..db468f3 100644
--- a/data/sounds/AudioPackage7alt.mk
+++ b/data/sounds/AudioPackage7alt.mk
@@ -21,7 +21,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressInvalid_120.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
-	$(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+	$(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
 	$(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
 	$(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
diff --git a/data/sounds/AudioPackage8.mk b/data/sounds/AudioPackage8.mk
index 070381d..4112c18 100644
--- a/data/sounds/AudioPackage8.mk
+++ b/data/sounds/AudioPackage8.mk
@@ -23,7 +23,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
-	$(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+	$(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
 	$(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
diff --git a/data/sounds/AudioPackage9.mk b/data/sounds/AudioPackage9.mk
index 0673811..1b430c0 100644
--- a/data/sounds/AudioPackage9.mk
+++ b/data/sounds/AudioPackage9.mk
@@ -23,7 +23,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
-	$(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+	$(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
 	$(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
diff --git a/data/sounds/effects/material/ogg/camera_click.ogg b/data/sounds/effects/material/ogg/camera_click.ogg
new file mode 100644
index 0000000..2528ef6
--- /dev/null
+++ b/data/sounds/effects/material/ogg/camera_click.ogg
Binary files differ
diff --git a/data/sounds/effects/material/ogg/camera_click_48k.ogg b/data/sounds/effects/material/ogg/camera_click_48k.ogg
new file mode 100644
index 0000000..01f3a05
--- /dev/null
+++ b/data/sounds/effects/material/ogg/camera_click_48k.ogg
Binary files differ
diff --git a/docs/html/distribute/googleplay/edu/start.jd b/docs/html/distribute/googleplay/edu/start.jd
index 067a15f..3c3a175 100644
--- a/docs/html/distribute/googleplay/edu/start.jd
+++ b/docs/html/distribute/googleplay/edu/start.jd
@@ -9,27 +9,23 @@
 <div id="qv-wrapper"><div id="qv">
 <h2>Steps to Join</h2>
 <ol>
-<li><a href="#register">Register for a Publisher Account</li>
+<li><a href="#register">Register for a Publisher Account</a></li>
 <li><a href="#prepare">Prepare Your Apps</a></li>
 <li><a href="#publish">Publish Your Apps</a></li>
 <li><a href="#related-resources">Related Resources</a></li>
 </ol>
 </div></div>
 <p>
-  If you've got great Android apps for education and want to reach even more teachers
+  If you've got great Android and Chrome apps for education and want to reach even more teachers
   and students, you can join the <strong>Google Play for Education</strong>
   program in a few simple steps. You do everything using the familiar tools and
-  processes in Google Play.
+  processes you currently use to manage your Android or Chrome apps.
 </p>
 
 <p>
 Note that Google Play for Education is currently available to <strong>K-12 schools in the United
 States</strong> only.</p>
 
-<p>If you have an educational Chrome app instead of an Android app, you can learn more about
-Chrome Apps in Google Play for Education at <a href=
-"https://developers.google.com/edu">developers.google.com/edu</a>.
-</p>
 
 <img src="{@docRoot}images/gpfe-start-0.jpg" style=
   "border:1px solid #ddd;padding:0px" width="760" height="403">
@@ -43,23 +39,20 @@
 </div>
 
 <p>
-  If you’re new to Google Play, review the information on <a href=
+  To publish an Android app in Google Play for Education, review the information on <a href=
   "{@docRoot}distribute/googleplay/start.html">getting started</a> with
   publishing on Google Play. You’ll gain access to the <a href=
   "{@docRoot}distribute/googleplay/developer-console.html">Developer
   Console</a>, where you’ll manage your details, apps, and payments.
 </p>
 
+<p>To publish a Chrome app in Google Play for Education, you'll need a
+<a href="https://developer.chrome.com/webstore/publish">Chrome Web Store account</a>.</p>
+
 <div class="headerLine">
   <h2 id="prepare">
     Prepare Your Apps
   </h2>
-
-
-</div>
-
-<div class="figure-right">
-  <img src="{@docRoot}images/gp-edu-process.png">
 </div>
 
 <p>
@@ -77,13 +70,13 @@
   To prepare for a launch on Google Play for Education, start by reviewing the
   guidelines for educational apps in Google Play and the policies that apply to
   your apps. See the <a href=
-  "{@docRoot}distribute/essentials/gpfe-guidelines.html">Education
+  "https://developers.google.com/edu/guidelines">Education
   Guidelines</a> for details.
 </p>
 
 <p>
   Also, make sure that you're familiar with the policies that your app must
-  comply with, including <a href=
+  comply with. For Android, they include <a href=
   "http://play.google.com/about/developer-content-policy.html">content
   policies</a>, the <a href=
   "http://play.google.com/about/developer-distribution-agreement.html">Developer
@@ -91,6 +84,14 @@
   "https://play.google.com/about/developer-distribution-agreement-addendum.html">
   Google Play for Education Addendum</a>.
 </p>
+<p>For Chrome, they include <a href=
+  "https://developer.chrome.com/webstore/program_policies">content
+  policies</a>, the <a href=
+  "https://developer.chrome.com/webstore/terms">Developer
+  Distribution Agreement</a>, and <a href=
+  "https://developers.google.com/edu/chrome-d-d-a-addendum">
+  Google Play for Education Addendum</a>.
+</p>
 
 <h3>
   Design and develop a great app for education
@@ -105,7 +106,7 @@
 
 <p>
   Assess your app against the criteria listed in the <a href=
-  "{@docRoot}distribute/essentials/gpfe-guidelines.html">Education
+  "https://developers.google.com/edu/guidelines">Education
   Guidelines</a> and plan on supporting them to the greatest extent possible.
   In some cases you might need to modify the app’s features or UI to support
   classroom requirements. It's a good idea to identify any changes early in
@@ -113,7 +114,7 @@
 </p>
 
 <p>
-  With Google Play for Education, optimizing your apps for tablets is crucial.
+  With Google Play for Education, optimizing your Android apps for tablets is crucial.
   A variety of resources are available to help you understand what you need to
   do — a good starting point is the <a href=
   "{@docRoot}distribute/essentials/quality/tablets.html">Tablet App Quality</a>
@@ -132,6 +133,11 @@
 </p>
 
 <p>
+For Chrome apps, optimizing your apps for mouse, keyboard, and touch is just as important.
+Some students will use touch as their primary input method, and some will have Chromebooks
+without touch. Make sure your app works for all students.
+</p>
+<p>
   Comprehensive testing and quality assurance are key aspects of delivering
   great apps for teachers and students. Make sure you set up a <a href=
   "{@docRoot}distribute/essentials/gpfe-guidelines.html#test-environment">proper
@@ -160,15 +166,13 @@
     apps.
   </li>
 
-  <li>Publish your apps in the Developer Console as normal, but opt-in to
+  <li>Publish your apps in the Developer Console (for Android apps) or the Chrome Web Store
+  (for Chrome apps) as normal, but opt-in to
   Google Play for Education.
   </li>
 </ul>
 
-<h3 id="opt-in">
-  Opt-in to Google Play for Education and publish
-</h3>
-
+<h3>Opt-in to Google Play for Education and publish Android apps</h3>
 <p>
   Once you've built your release-ready APK upload it to the Developer Console,
   create your store listing, and set distribution options. If you aren't
@@ -231,7 +235,7 @@
   will be shown to educators when they are browsing your app.
   </li>
 
-  <li>Click <strong>Save</strong>f to save your Pricing and Distribution
+  <li>Click <strong>Save</strong> to save your Pricing and Distribution
   changes.
   </li>
 </ol>
@@ -247,58 +251,55 @@
 </div>
 
 <p>
-  Once you save changes and publish your app, the app will be submitted to our
-  third-party educator network for review and approval. If the app is already
-  published, it will be submitted for review as soon as you opt-in and save
-  your changes.
+  Once you save changes and publish your app, the app will be available on Google Play for
+  Education. We may submit your app to our
+  third-party educator network for additional review and to be featured and badged as
+  Educator-approved.
 </p>
 
 <p class="note">
   <strong>Note</strong>: Google Play for Education is part of Google Play. When
-  you publish an app that's opted-in to Google Play for Education, the app
-  becomes available to users in Google Play right away. After the app is
-  <a href="{@docRoot}distribute/essentials/gpfe-guidelines.html#e-value">review
-  and approval</a>, it then becomes available to educators in Google Play for
-  Education.
+  you publish an Android app that's opted-in to Google Play for Education, the app
+  becomes available to users in Google Play.
 </p>
 
-<h3>
-  Track your review and approval
-</h3>
-
+<h3>Opt-in to Google Play for Education and publish Chrome apps</h3>
 <p>
-  As soon as you opt-in to Google Play for Education and publish, your apps are
-  queued for review by our third-party educator network. The review and
-  approval process can take four weeks or more. You'll receive notification by
-  email (to your developer account address) when the review is complete, with a
-  summary of the review results.
+Once you've uploaded your app or extension to the Developer Dashboard, create your store listing
+and set distribution options.
 </p>
-
 <p>
-  At any time, you can check the review and approval status of your app in the
-  Developer Console, under "Google Play for Education" in the app's Pricing and
-  Distribution page. There are three approval states:
+When your apps are ready to publish, you opt-in to Google Play for Education directly from the
+<a href="https://chrome.google.com/webstore/developer/dashboard">Developer Dashboard</a>.
+Opt-in means that you want your apps to be made available to educators
+through Google Play for Education, including review, classification, and approval by our
+third-party educator network.
+</p>
+<p>
+Opt-in also confirms that your app complies with
+<a href="https://developer.chrome.com/webstore/program_policies">Chrome Web Store Program Policies</a>
+and the <a href="https://developer.chrome.com/webstore/terms">Terms of Service</a>, including a
+<a href="https://developers.google.com/edu/chrome-d-d-a-addendum">Google Play for Education Addendum</a>.
+If you are not familiar with these
+policy documents or the Addendum, make sure to read them before opting-in.
 </p>
 
-<ul>
-  <li>
-    <em>Pending</em> &mdash; Your app was sent for review and the review isn't
-    yet complete.
-  </li>
+<p>Here's how to opt-in to Google Play for Education for a specific app or extension:</p>
+<ol>
+<li>In the Developer Dashboard, click <b>Edit</b> on the app you want to opt-in.</li>
+<li>Scroll down to <b>Google Play for Education</b> and review the additional
+Developer Terms and Conditions.</li>
+<li>Select the checkbox to opt-in to include this item in Google Play for Education.</li>
+<li>Click <b>Publish Changes</b> to save your changes and submit your application.
+Once you save changes and publish your app, the app will be available on Google Play for Education.
+We may submit your app to our third-party educator network for additional review, and to be
+featured and badged as Educator-approved.</li>
+<p class="note"><b>Note:</b>
+When you publish an app that's opted-in to Google Play for Education,
+the app becomes available to users in the Chrome Web Store.
+</p>
+</ol>
 
-  <li>
-    <em>Approved</em> &mdash; Your app was reviewed and approved. The app will
-    be made available directly to educators through Google Play for Education.
-    Once your app is approved, you can update it at your convenience without
-    needing another full review.
-  </li>
-
-  <li>
-    <em>Not approved</em> &mdash; Your app was reviewed and not approved. Check
-    the notification email send for information about why the app wasn’t
-    approved. You can address any issues and opt-in again for another review.
-  </li>
-</ul>
 <div class="headerLine">
 <h2 id="related-resources">Related Resources</h2>
 </div>
diff --git a/docs/html/google/play/billing/billing_subscriptions.jd b/docs/html/google/play/billing/billing_subscriptions.jd
index 2b78ab3..b9b77df 100644
--- a/docs/html/google/play/billing/billing_subscriptions.jd
+++ b/docs/html/google/play/billing/billing_subscriptions.jd
@@ -11,25 +11,32 @@
 <div id="qv">
   <h2>Quickview</h2>
   <ul>
-     <li>Users purchase your subscriptions from inside your apps, rather than 
-directly from Google Play.</li>
-     <li>Subscriptions let you sell products with automated, recurring billing
-(monthly or annual).</li>
-     <li>You can offer a configurable trial period for any subscription.</li>
-
+    <li>Subscriptions let you sell products with automated, recurring billing
+        at a variety of intervals.</li>
+    <li>You can offer a configurable trial period for monthly and
+        annual subscriptions.</li>
+    <li>You can manage subscriptions through the Developer Console, or by using
+        the
+        <a href="https://developers.google.com/android-publisher/">Google Play
+        Developer API</a>.</li>
+    <li>Users purchase your subscriptions from inside your apps, rather than
+        directly from Google Play.</li>
+    <li>You can defer billing for a particular user's subscription, to manage
+        accounts or offer rewards.</li>
   </ul>
   <h2>In this document</h2>
   <ol>
-    <li><a href="#overview">Overview</a></li>
+    <li><a href="#overview">Overview of Subscriptions</a></li>
     <li><a href="#administering">Configuring Subscriptions Items</a></li>
-    <li><a href="#cancellation">Cancellation</a></li>
-    <li><a href="#payment">Payment Processing</a></li>
+    <li><a href="#cancellation">Subscription Cancellation</a></li>
+    <li><a href="#payment">Payment Processing and Policies</a></li>
     <li><a href="#strategies">Purchase Verification Strategies</a></li>
+    <li><a href="#play-dev-api">Google Play Developer API</a></li>
   </ol>
   <h2>See also</h2>
   <ol>
     <li><a href="{@docRoot}google/play/billing/billing_integrate.html#Subs">Implementing Subscriptions (V3)</a></li>
-    <li><a href="https://developers.google.com/android-publisher/v1_1/">Google Play Android Developer API</a></li>
+    <li><a href="https://developers.google.com/android-publisher/">Google Play Developer API</a></li>
   </ol>
 </div>
 </div>
@@ -44,14 +51,15 @@
 <h2 id="overview">Overview of Subscriptions</h2>
 <p>A <em>subscription</em> is a product type offered in In-app Billing that 
 lets you sell content, services, or features to users from inside your app with 
-recurring monthly or annual billing. You can sell subscriptions to almost any 
+recurring, automated billing at the interval you specify. You can sell subscriptions to almost
+any
 type of digital content, from any type of app or game.</p>
 
 <p>As with other in-app products, you configure and publish subscriptions using
 the Developer Console and then sell them from inside apps installed on 
 Android devices. In the Developer console, you create subscription
 products and add them to a product list, then set a price and optional trial
-period for each, choose a billing interval (monthly or annual), and then 
+period for each, choose a billing interval, and then
 publish. For more information about using the Developer Console, see 
 <a href="#administering">Configuring Subscription Items</a>.</p>
 
@@ -63,17 +71,17 @@
 
 <img src="{@docRoot}images/in-app-billing/v3/billing_subscription_v3.png" style="float:right; border:4px solid ddd;">
 
-<p>After users have purchase subscriptions, they can view the subscriptions and 
+<p>After users have purchased subscriptions, they can view the subscriptions and 
 cancel them from the <strong>My Apps</strong> screen in the Play Store app or 
 from the app's product details page in the Play Store app. For more information 
 about handling user cancellations, see <a href="#cancellation">Subscription Cancellation</a>.</p>
 
-<p>In adddition to client-side API calls, you can use the server-side API for 
+<p>In addition to client-side API calls, you can use the server-side API for 
 In-app Billing to provide subscription purchasers with extended access to 
 content (for example, from your web site or another service).
 The server-side API lets you validate the status of a subscription when users
 sign into your other services. For more information about the API, see <a
-href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Purchase Status API</a>. </p>
+href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google Play Developer API</a>. </p>
 
 <p>You can also build on your existing external subscriber base from inside your
 Android apps.</p>
@@ -102,8 +110,10 @@
 subscriptions, see the <a href="{@docRoot}google/play/billing/versions.html#Subs">Version Notes</a>.</p>
 
 <h2 id="administering">Configuring Subscription Items</h2>
-<p>To create and manage subscriptions, use the Developer Console to set up a 
-product list for the app then configure these attributes for each subscription 
+
+<p>To create and manage subscriptions, you can use the Developer Console to set
+up a
+product list for the app, then configure these attributes for each subscription 
 product:</p>
 
 <ul>
@@ -113,8 +123,8 @@
 <li>Language: The default language for displaying the subscription</li>
 <li>Title: The title of the subscription product</li>
 <li>Description: Details that tell the user about the subscription</li>
-<li>Price: USD price of subscription per recurrence</li>
-<li>Recurrence: monthly or yearly</li>
+<li>Price: Default price of subscription per recurrence</li>
+<li>Recurrence: Interval of billing recurrence</li>
 <li>Additional currency pricing (can be auto-filled)</li>
 </ul>
 
@@ -122,6 +132,10 @@
 see <a href="{@docRoot}google/play/billing/billing_admin.html">Administering
 In-app Billing</a>.</p>
 
+<p>You can also create and manage subscriptions using the
+<a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">
+Google Play Developer API</a>.</p>
+
 <h3 id="pricing">Subscription pricing</h3>
 
 <p>When you create a subscription in the Developer Console, you can set a price
@@ -139,20 +153,30 @@
 <h3 id="user-billing">User billing</h3>
 
 <p>In the Developer Console, you can configure subscription products with 
-automated recurring billing at either of two intervals:</p>
+automated recurring billing at your choice of intervals:</p>
 
 <ul>
   <li>Monthly &mdash; Google Play bills the customer’s Google Wallet account at
   the time of purchase and monthly subsequent to the purchase date (exact billing
-  intervals can vary slightly over time)</li>
+  intervals can vary slightly over time).</li>
   <li>Annually &mdash; Google Play bills the customer's Google Wallet account at
   the time of purchase and again on the same date in subsequent years.</li>
+
+  <li>Seasonal &mdash; Google Play bills the customer's Google Wallet account at
+  the beginning of each "season" (you specify the season beginning and end
+  dates). This
+  is intended for annual purchases of seasonal content (such as sports-related
+  content). The subscription runs through the end of the season, and restarts
+  the next year at the start of the season.</li>
+
 </ul>
 
 <p>Billing continues indefinitely at the interval and price specified for the
 subscription. At each subscription renewal, Google Play charges the user account
-automatically, then notifies the user of the charges afterward by email. Billing
-cycles will always match subscription cycles, based on the purchase date.</p>
+automatically, then notifies the user of the charges afterward by email. For
+monthly and annual subscriptions, billing cycles will always match subscription
+cycles, based on the purchase date. (Seasonal subscriptions are charged
+annually, on the first day of the season.)</p>
 
 <p>Over the life of a subscription, the form of payment billed remains the same
 &mdash; Google Play always bills the same form of payment (such as credit card
@@ -164,7 +188,7 @@
 API. Your apps can store the token locally or pass it to your backend servers, 
 which can then use it to validate or cancel the subscription remotely using the
 <a
-href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Purchase Status API</a>.</p>
+href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google Play Developer API</a>.</p>
 
 <p>If a recurring payment fails (for example, because the customer’s credit
 card has become invalid), the subscription does not renew. How your app is 
@@ -182,18 +206,57 @@
 billing errors that may occur. Your backend servers can use the server-side API 
 to query and update your records and follow up with customers directly, if needed.</p>
 
+<h3 id="deferred-billing">Deferred Billing</h3>
+
+<p>Using the
+<a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google
+Play Developer API</a>, you can defer the next billing date for a
+subscriber. The user continues to be subscribed to the content, and has full
+access to it, but is not charged during the deferral period. This allows you
+to do things like:</p>
+
+<ul>
+  <li>Give users free access as part of a bundle or a special offer (for
+    example, giving free access to web content to users who subscribe to a
+    print magazine)</li>
+  <li>Give free access to customers as a goodwill gesture</li>
+</ul>
+
+<p>The longest you can defer billing is for one year per call. Of course, you
+can call the API again before the year is up to defer billing further.</p>
+
+<p>For example, Darcy has a monthly subscription to online content for the
+<em>Fishing Gentleman</em> app. He is normally
+billed £1.25 on the first of each month.
+On March 10, he participates in an online survey for the app publisher. The
+publisher rewards him by deferring his next payment until June 1. Darcy is not
+charged on April 1 or May 1, but still has access to the content as normal. On
+June 1, he is charged his normal £1.25 subscription fee.</p>
+
+<p class="note"><strong>Note:</strong> The API always defers the billing date
+by a whole number of days. If you request a deferral period that includes a
+fractional number of days, the API rounds the period up to the next full day.
+For example, if a user's subscription is set to renew on 15 June 2015 at
+14:00:00 UTC, and you use the API to defer the renewal date to 15 August 2015 at
+02:00:00 UTC, the API will round up to the next full day and set the renewal
+date to 15 August 2015 14:00:00 UTC.</p>
+
+<p>You can also offer free trials to new subscribers, as described in
+<a href="#trials">Free trials</a>.</p>
+
 <h3 id="trials">Free trials</h3>
 
 <p>In the Developer Console, you can set up a free trial period that lets users
 try your subscription content before buying it. The trial period runs for the 
 period of time that you set and then automatically converts to a full 
 subscription managed according to the subscription's billing interval and 
-price.</p>
+price. Free trials are supported for monthly and annual subscriptions only, and are not supported for seasonal subscriptions.</p>
 
 <p>To take advantage of a free trial, a user must "purchase" the full
 subscription through the standard In-app Billing flow, providing a valid form of
 payment to use for billing and completing the normal purchase transaction.
-However, the user is not charged any money, since the initial period corresponds
+However, the user is not charged any money, because the initial period
+corresponds
 to the free trial. Instead, Google Play records a transaction of $0.00 and the
 subscription is marked as purchased for the duration of the trial period or
 until cancellation. When the transaction is complete, Google Play notifies users
@@ -220,8 +283,10 @@
 period per subscription product.</p>
 
 <h3 id="publishing">Subscription publishing</h3>
+
 <p>When you have finished configuring your subscription product details in the
-Developer Console, you can publish the subscription in the app product list.</p>
+Developer Console or via the API,
+you can publish the subscription in the app product list.</p>
 
 <p>In the product list, you can add subscriptions, in-app products, or both. You
 can add multiple subscriptions that give access to different content or
@@ -263,10 +328,13 @@
 
 <p class="caution"><strong>Important:</strong> In all cases, you must continue
 to offer the content that your subscribers have purchased through their
-subscriptions, for as long any users are able to access it. That is, you must
-not remove any subscriber’s content while any user still has an active
+subscriptions, as long any user is able to access it. That is, you must
+not remove any content while any user still has an active
 subscription to it, even if that subscription will terminate at the end of the
-current billing cycle. Removing content that a subscriber is entitled to access
+current billing cycle. Alternatively, you can use the <a href="#refunds">refund
+and revoke</a> API to revoke each subscriber's subscription (one by one) and
+refund their subscription payments.
+Removing content that any subscriber is entitled to access
 will result in penalties. Please see the <a
 href="http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&answer=140504">policies document</a> for more information. </p>
 
@@ -280,19 +348,26 @@
 screen of the Play Store app. If the user chooses to cancel the uninstallation, 
 the app and subscriptions remain as they were.</p>
 
-<h3 id="refunds">Refunds</h3>
+<h3 id="refunds">Refunding and revoking subscriptions</h3>
 
-<p>With subscriptions, Google Play does not provide a refund window, so users 
-will need to contact you directly to request a refund.
+<p>With subscriptions, Google Play does not provide a refund window, so users
+will need to request a refund. They can request a refund from the <strong>My
+Orders</strong> page in the Play Store, or by contacting you directly.</p>
 
-<p>If you receive requests for refunds, you can use the server-side API to
-cancel the subscription or verify that it is already cancelled. However, keep in
-mind that Google Play considers cancelled subscriptions valid until the end of
-their current billing cycles, so even if you grant a refund and cancel the
-subscription, the user will still have access to the content.
+<p>If you receive requests for refunds, you can use the
+<a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google Play
+Developer API</a> or the Merchant Center to cancel the subscription, verify that it
+is already cancelled, or refund the user's payment without cancelling it. You
+can also use the
+<a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google
+Play Developer API</a> to <em>refund and revoke</em> a
+user's subscription. If you refund and revoke a subscription, the user's
+subscription is immediately cancelled, and the user's most recent subscription
+payment is refunded. (If you want to refund more than the most recent payment,
+you can process additional refunds through the Merchant Center.)</p>
 
-<p class="caution"><strong>Important:</strong> Partial refunds for canceled
-subscriptions are not available at this time.</p>
+<p class="caution"><strong>Important:</strong> Partial refunds are not available
+at this time.</p>
 
 <h2 id="payment">Payment Processing and Policies</h2>
 
@@ -317,9 +392,9 @@
 each recurring transaction by appending an integer as follows: </p>
 
 <p><span style="color:#777"><code style="color:#777">12999556515565155651.5565135565155651</code> (base order number)</span><br />
-<code>12999556515565155651.5565135565155651..0</code> (initial purchase orderID)<br />
-<code>12999556515565155651.5565135565155651..1</code> (first recurrence orderID)<br />
-<code>12999556515565155651.5565135565155651..2</code> (second recurrence orderID)<br />
+<code>12999556515565155651.5565135565155651..0</code> (first recurrence orderID)<br />
+<code>12999556515565155651.5565135565155651..1</code> (second recurrence orderID)<br />
+<code>12999556515565155651.5565135565155651..2</code> (third recurrence orderID)<br />
 ...<br /></p>
 
 <p>Google Play provides the order number as the value of the 
@@ -334,19 +409,28 @@
 
 <p>To verify a purchase, the app passes the purchase token and other details up
 to your backend servers, which verifies them directly with Google Play using the
-Purchase Status API.  If the backend server determines that the purchase is
+Google Play Developer API.  If the backend server determines that the purchase is
 valid, it notifies the app and grants access to the content.</p>
 
 <p>Keep in mind that users will want the ability to use your app at any time,
 including when there may be no network connection available. Make sure that your
 approach to purchase verification accounts for the offline use-case.</p>
 
-<h2 id="play-dev-api">Google Play Android Developer API</h2>
+<h2 id="play-dev-api">Google Play Developer API</h2>
 
-<p>Google Play offers an HTTP-based API that lets you remotely query the
-validity of a specific subscription at any time or cancel a subscription. The
-API is designed to be used from your backend servers as a way of securely
+<p>Google Play offers an HTTP-based API that lets you perform such tasks as:</p>
+  <ul>
+    <li>Remotely query the validity of a specific subscription at any time</li>
+    <li>Cancel a subscription</li>
+    <li>Defer a subscription's next billing date</li>
+    <li>Refund a subscription payment without cancelling the subscription</li>
+    <li>Refund and revoke a subscription</li>
+  </ul>
+
+<p>The API is designed to be used from your backend servers as a way of securely
 managing subscriptions, as well as extending and integrating subscriptions with
 other services.</p>
 
-<p>For complete information, see <a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Purchase Status API</a>.</p>
+<p>For complete information, see
+<a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google Play
+Developer API</a>.</p>
diff --git a/docs/html/google/play/billing/index.jd b/docs/html/google/play/billing/index.jd
index 875271f..bdbf5c7 100644
--- a/docs/html/google/play/billing/index.jd
+++ b/docs/html/google/play/billing/index.jd
@@ -14,21 +14,35 @@
 <div class="sidebox">
   <h2><strong>New in In-App Billing</strong></h2>
   <ul>
+  <li><strong>IAB v2 shutdown</strong>&mdash;In-app Billing v2 API is deprecated and will be shut down in January 2015. If your app is still using In-app Billing v2, please migrate to the v3 API as soon as possible.</li>
+  <li><strong>Seasonal subscriptions</strong>&mdash;You can now set up a
+    recurring <a href="billing_subscriptions.html#user-billing">seasonal
+    subscription</a> that starts and ends on the same date each year (for
+    example, a sports subscription that starts every September 1 and ends every
+    April 10).</li>
+  <li><strong>Deferred subscription billing</strong>&mdash;You can
+    <a href="billing_subscriptions.html#deferred-billing">defer</a> a
+    subscriber's next billing date until the date you choose. The user still has
+    access to the content but is not charged during the deferral period.</li>
   <li><strong>Google Play Developer API</strong>&mdash;The
     <a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google
     Play Developer API</a> allows you to perform a number of publishing and
     app-management tasks. It includes the functionality previously known as the
     <em>Purchase Status API.</em> </li>
+  <li><strong>Refund/Revoke subscription</strong>&mdash;You can use the
+    Google Play Developer API to <a href="billing_subscriptions.html#refunds">refund
+    and revoke</a> a user's subscription. If you do this, the user's
+    subscription ends
+    immediately, and his or her most recent subscription payment is
+    refunded.</li>
   <li><strong>In-app Billing Version 3</strong>&mdash;The <a href="{@docRoot}google/play/billing/api.html">latest version</a> of In-app Billing features a synchronous API that is easier to implement and lets you manage in-app products and subscriptions more effectively.</li>
-  <li><strong>Subscriptions now supported in Version 3</strong>&mdash;You can query and launch purchase flows for subscription items using the V3 API.</li>
-  <li><strong>Free trials</strong>&mdash;You can now offer users a configurable <a href="/google/play/billing/v2/billing_subscriptions.html#trials">free trial period</a> for your in-app subscriptions. You can set up trials with a simple change in the Developer Console&mdash;no change to your app code is needed.</li>
  </ul>
 </div>
 </div>
 
 <ul>
 <li>Standard in-app products (one-time billing), or</li>
-<li>Subscriptions, (recurring, automated billing)</li>
+<li>Subscriptions (recurring, automated billing)</li>
 </ul>
 
 <p>When you use the in-app billing service to sell an item,
diff --git a/docs/html/google/play/billing/v2/api.jd b/docs/html/google/play/billing/v2/api.jd
index 9501555..36a9017 100644
--- a/docs/html/google/play/billing/v2/api.jd
+++ b/docs/html/google/play/billing/v2/api.jd
@@ -2,7 +2,28 @@
 excludeFromSuggestions=true
 @jd:body
 
-<div style="background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;">In-app Billing Version 2 is superseded. Please <a href="{@docRoot}google/play/billing/billing_overview.html#migration">migrate to Version 3</a> at your earliest convenience.</div>
+<p class="caution" style=
+"background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;">
+  The <strong>In-app Billing Version 2 API</strong> has been deprecated in
+  favor of the Version 3 API. If your app is using In-app Billing, please
+  <strong>make sure that it is using the Version 3 API</strong>. If your app is
+  still using the Version 2 API, you must <strong>migrate to the Version 3 API
+  as soon as possible</strong>.<br>
+  <br>
+  We plan to turn off the In-app Billing Version 2 service on <strong>January
+  27, 2015</strong>, after which time users will <strong>no longer be able to
+  purchase in-app items and subscriptions through the Version 2 API</strong>.
+  We strongly encourage and recommend you migrate your apps to use Version 3
+  API by November 2014, to provide ample time for users to update their apps to
+  the new version.<br>
+  <br>
+  For more information, please see the <a href=
+  "http://support.google.com/googleplay/android-developer/answer/6090268">Help Center
+  article</a>. For common questions about transitioning your implementation to
+  In-app Billing Version 3, please see <a href=
+  "{@docRoot}google/play/billing/billing_overview.html#migration">Migration
+  Considerations</a>.
+</p>
     <div id="qv-wrapper" style="margin-top:0;">
 <div id="qv">
 
diff --git a/docs/html/google/play/billing/v2/billing_integrate.jd b/docs/html/google/play/billing/v2/billing_integrate.jd
index 5eb17d5..c264271 100644
--- a/docs/html/google/play/billing/v2/billing_integrate.jd
+++ b/docs/html/google/play/billing/v2/billing_integrate.jd
@@ -2,7 +2,28 @@
 excludeFromSuggestions=true
 @jd:body
 
-<div style="background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;">In-app Billing Version 2 is superseded. Please <a href="{@docRoot}google/play/billing/billing_overview.html#migration">migrate to Version 3</a> at your earliest convenience.</div>
+<p class="caution" style=
+"background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;">
+  The <strong>In-app Billing Version 2 API</strong> has been deprecated in
+  favor of the Version 3 API. If your app is using In-app Billing, please
+  <strong>make sure that it is using the Version 3 API</strong>. If your app is
+  still using the Version 2 API, you must <strong>migrate to the Version 3 API
+  as soon as possible</strong>.<br>
+  <br>
+  We plan to turn off the In-app Billing Version 2 service on <strong>January
+  27, 2015</strong>, after which time users will <strong>no longer be able to
+  purchase in-app items and subscriptions through the Version 2 API</strong>.
+  We strongly encourage and recommend you migrate your apps to use Version 3
+  API by November 2014, to provide ample time for users to update their apps to
+  the new version.<br>
+  <br>
+  For more information, please see the <a href=
+  "http://support.google.com/googleplay/android-developer/answer/6090268">Help Center
+  article</a>. For common questions about transitioning your implementation to
+  In-app Billing Version 3, please see <a href=
+  "{@docRoot}google/play/billing/billing_overview.html#migration">Migration
+  Considerations</a>.
+</p>
     <div id="qv-wrapper" style="margin-top:0;">
 <div id="qv">
   <h2>In this document</h2>
diff --git a/docs/html/google/play/billing/v2/billing_reference.jd b/docs/html/google/play/billing/v2/billing_reference.jd
index 4587dee..32e00cf 100644
--- a/docs/html/google/play/billing/v2/billing_reference.jd
+++ b/docs/html/google/play/billing/v2/billing_reference.jd
@@ -2,7 +2,28 @@
 excludeFromSuggestions=true
 @jd:body
 
-<div style="background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;">In-app Billing Version 2 is superseded. Please <a href="{@docRoot}google/play/billing/billing_overview.html#migration">migrate to Version 3</a> at your earliest convenience.</div>
+<p class="caution" style=
+"background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;">
+  The <strong>In-app Billing Version 2 API</strong> has been deprecated in
+  favor of the Version 3 API. If your app is using In-app Billing, please
+  <strong>make sure that it is using the Version 3 API</strong>. If your app is
+  still using the Version 2 API, you must <strong>migrate to the Version 3 API
+  as soon as possible</strong>.<br>
+  <br>
+  We plan to turn off the In-app Billing Version 2 service on <strong>January
+  27, 2015</strong>, after which time users will <strong>no longer be able to
+  purchase in-app items and subscriptions through the Version 2 API</strong>.
+  We strongly encourage and recommend you migrate your apps to use Version 3
+  API by November 2014, to provide ample time for users to update their apps to
+  the new version.<br>
+  <br>
+  For more information, please see the <a href=
+  "http://support.google.com/googleplay/android-developer/answer/6090268">Help Center
+  article</a>. For common questions about transitioning your implementation to
+  In-app Billing Version 3, please see <a href=
+  "{@docRoot}google/play/billing/billing_overview.html#migration">Migration
+  Considerations</a>.
+</p>
     <div id="qv-wrapper" style="margin-top:0;">
 <div id="qv">
 <h2>In this document</h2>
diff --git a/docs/html/google/play/billing/v2/billing_subscriptions.jd b/docs/html/google/play/billing/v2/billing_subscriptions.jd
index f8051a9..01e39ac 100644
--- a/docs/html/google/play/billing/v2/billing_subscriptions.jd
+++ b/docs/html/google/play/billing/v2/billing_subscriptions.jd
@@ -2,7 +2,28 @@
 excludeFromSuggestions=true
 @jd:body
 
-<div style="background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;">In-app Billing Version 2 is superseded. Please <a href="{@docRoot}google/play/billing/billing_overview.html#migration">migrate to Version 3</a> at your earliest convenience.</div>
+<p class="caution" style=
+"background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;">
+  The <strong>In-app Billing Version 2 API</strong> has been deprecated in
+  favor of the Version 3 API. If your app is using In-app Billing, please
+  <strong>make sure that it is using the Version 3 API</strong>. If your app is
+  still using the Version 2 API, you must <strong>migrate to the Version 3 API
+  as soon as possible</strong>.<br>
+  <br>
+  We plan to turn off the In-app Billing Version 2 service on <strong>January
+  27, 2015</strong>, after which time users will <strong>no longer be able to
+  purchase in-app items and subscriptions through the Version 2 API</strong>.
+  We strongly encourage and recommend you migrate your apps to use Version 3
+  API by November 2014, to provide ample time for users to update their apps to
+  the new version.<br>
+  <br>
+  For more information, please see the <a href=
+  "http://support.google.com/googleplay/android-developer/answer/6090268">Help Center
+  article</a>. For common questions about transitioning your implementation to
+  In-app Billing Version 3, please see <a href=
+  "{@docRoot}google/play/billing/billing_overview.html#migration">Migration
+  Considerations</a>.
+</p>
     <div id="qv-wrapper" style="margin-top:0;">
 <div id="qv">
   <h2>In this document</h2>
diff --git a/docs/html/training/wearables/data-layer/index.jd b/docs/html/training/wearables/data-layer/index.jd
index bac7d3e..39d6561 100644
--- a/docs/html/training/wearables/data-layer/index.jd
+++ b/docs/html/training/wearables/data-layer/index.jd
@@ -28,7 +28,7 @@
 
   <dt><b>Messages</b></dt>
   <dd>The <a href="{@docRoot}reference/com/google/android/gms/wearable/MessageApi.html"><code>MessageApi</code></a> class
-  can send messages designed for "fire-and-forget" commands, such as controlling a handheld's
+  can send messages and is good for remote procedure calls (RPC), such as controlling a handheld's
   media player from the wearable or starting an intent on the wearable from the handheld.
   The system always delivers the message when the handheld and wearable are connected and delivers
   an error when the devices are disconnected. Messages are great for one-way requests or for a
diff --git a/docs/html/training/wearables/data-layer/messages.jd b/docs/html/training/wearables/data-layer/messages.jd
index 15e552d..71f1bb1 100644
--- a/docs/html/training/wearables/data-layer/messages.jd
+++ b/docs/html/training/wearables/data-layer/messages.jd
@@ -23,8 +23,8 @@
 </ul>
 <p>
 Unlike data items, there is no syncing between the handheld and wearable apps.
-Messages are a one-way communication mechanism that's meant for
-"fire-and-forget" tasks, such as sending a message to the wearable
+Messages are a one-way communication mechanism that's good for remote procedure calls (RPC),
+such as sending a message to the wearable
 to start an activity. You can also use messages in request/response model
 where one side of the connection sends a message, does some work,
 sends back a response message.</p>
diff --git a/include/android_runtime/AndroidRuntime.h b/include/android_runtime/AndroidRuntime.h
index f3cfd97..fc33b7e 100644
--- a/include/android_runtime/AndroidRuntime.h
+++ b/include/android_runtime/AndroidRuntime.h
@@ -113,6 +113,9 @@
     /** return a new string corresponding to 'className' with all '.'s replaced by '/'s. */
     static char* toSlashClassName(const char* className);
 
+    /** Create a Java string from an ASCII or Latin-1 string */
+    static jstring NewStringLatin1(JNIEnv* env, const char* bytes);
+
 private:
     static int startReg(JNIEnv* env);
     bool parseRuntimeOption(const char* property,
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 5ff7b7f..cb3ef9b 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -1105,6 +1105,34 @@
     float mRy;
 };
 
+class DrawRoundRectPropsOp : public DrawOp {
+public:
+    DrawRoundRectPropsOp(float* left, float* top, float* right, float* bottom,
+            float *rx, float *ry, const SkPaint* paint)
+            : DrawOp(paint), mLeft(left), mTop(top), mRight(right), mBottom(bottom),
+            mRx(rx), mRy(ry) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+        return renderer.drawRoundRect(*mLeft, *mTop, *mRight, *mBottom,
+                *mRx, *mRy, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t logFlags) const {
+        OP_LOG("Draw RoundRect Props " RECT_STRING ", rx %f, ry %f",
+                *mLeft, *mTop, *mRight, *mBottom, *mRx, *mRy);
+    }
+
+    virtual const char* name() { return "DrawRoundRectProps"; }
+
+private:
+    float* mLeft;
+    float* mTop;
+    float* mRight;
+    float* mBottom;
+    float* mRx;
+    float* mRy;
+};
+
 class DrawCircleOp : public DrawStrokableOp {
 public:
     DrawCircleOp(float x, float y, float radius, const SkPaint* paint)
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 7ee83e6..1f70921 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -275,6 +275,23 @@
     return DrawGlInfo::kStatusDone;
 }
 
+status_t DisplayListRenderer::drawRoundRect(
+        CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
+        CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
+        CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
+        CanvasPropertyPaint* paint) {
+    mDisplayListData->refProperty(left);
+    mDisplayListData->refProperty(top);
+    mDisplayListData->refProperty(right);
+    mDisplayListData->refProperty(bottom);
+    mDisplayListData->refProperty(rx);
+    mDisplayListData->refProperty(ry);
+    mDisplayListData->refProperty(paint);
+    addDrawOp(new (alloc()) DrawRoundRectPropsOp(&left->value, &top->value,
+            &right->value, &bottom->value, &rx->value, &ry->value, &paint->value));
+    return DrawGlInfo::kStatusDone;
+}
+
 status_t DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint* paint) {
     paint = refPaint(paint);
     addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint));
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index e9c937c..3a3fc3a 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -123,6 +123,10 @@
     virtual status_t drawRects(const float* rects, int count, const SkPaint* paint);
     virtual status_t drawRoundRect(float left, float top, float right, float bottom,
             float rx, float ry, const SkPaint* paint);
+    virtual status_t drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
+                CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
+                CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
+                CanvasPropertyPaint* paint);
     virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint);
     virtual status_t drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
                 CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 25ea729..ce1d09f 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -134,6 +134,8 @@
         , mExtensions(Extensions::getInstance())
         , mRenderState(renderState)
         , mScissorOptimizationDisabled(false)
+        , mSuppressTiling(false)
+        , mFirstFrameAfterResize(true)
         , mCountOverdraw(false)
         , mLightCenter((Vector3){FLT_MIN, FLT_MIN, FLT_MIN})
         , mLightRadius(FLT_MIN)
@@ -179,6 +181,7 @@
     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 
     glEnableVertexAttribArray(Program::kBindingPosition);
+    mFirstFrameAfterResize = true;
 }
 
 void OpenGLRenderer::setupFrameState(float left, float top,
@@ -202,7 +205,9 @@
     // Functors break the tiling extension in pretty spectacular ways
     // This ensures we don't use tiling when a functor is going to be
     // invoked during the frame
-    mSuppressTiling = mCaches.hasRegisteredFunctors();
+    mSuppressTiling = mCaches.hasRegisteredFunctors()
+            || mFirstFrameAfterResize;
+    mFirstFrameAfterResize = false;
 
     startTilingCurrentClip(true);
 
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index e295b1a..47ef1a9 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -1013,6 +1013,7 @@
 
     // No-ops start/endTiling when set
     bool mSuppressTiling;
+    bool mFirstFrameAfterResize;
 
     // If true, this renderer will setup drawing to emulate
     // an increment stencil buffer in the color buffer
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index a8b8b16..06353c0 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -327,8 +327,10 @@
         // None
         "",
         // Matrix
+        "    fragColor.rgb /= (fragColor.a + 0.0019);\n" // un-premultiply
         "    fragColor *= colorMatrix;\n"
-        "    fragColor += colorMatrixVector;\n",
+        "    fragColor += colorMatrixVector;\n"
+        "    fragColor.rgb *= (fragColor.a + 0.0019);\n", // re-premultiply
         // PorterDuff
         "    fragColor = blendColors(colorBlend, fragColor);\n"
 };
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index feaee8e..7eb9a32 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -227,7 +227,7 @@
 #define DEFAULT_PATCH_CACHE_SIZE 128 // in kB
 #define DEFAULT_GRADIENT_CACHE_SIZE 0.5f
 #define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f
-#define DEFAULT_FBO_CACHE_SIZE 16
+#define DEFAULT_FBO_CACHE_SIZE 0
 
 #define DEFAULT_TEXTURE_CACHE_FLUSH_RATE 0.6f
 
diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h
index 6d4bb4a..3681637 100644
--- a/libs/hwui/Renderer.h
+++ b/libs/hwui/Renderer.h
@@ -70,6 +70,7 @@
     // TODO: move to a method on android:Paint
     static inline bool paintWillNotDraw(const SkPaint& paint) {
         return paint.getAlpha() == 0
+                && !paint.getColorFilter()
                 && getXfermode(paint.getXfermode()) != SkXfermode::kClear_Mode;
     }
 
@@ -77,6 +78,7 @@
     static inline bool paintWillNotDrawText(const SkPaint& paint) {
         return paint.getAlpha() == 0
                 && paint.getLooper() == NULL
+                && !paint.getColorFilter()
                 && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode;
     }
 // ----------------------------------------------------------------------------
diff --git a/libs/hwui/StatefulBaseRenderer.cpp b/libs/hwui/StatefulBaseRenderer.cpp
index 12b8c8d..88d6f68 100644
--- a/libs/hwui/StatefulBaseRenderer.cpp
+++ b/libs/hwui/StatefulBaseRenderer.cpp
@@ -49,6 +49,13 @@
     mHeight = height;
     mFirstSnapshot->initializeViewport(width, height);
     onViewportInitialized();
+
+    // create a temporary 1st snapshot, so old snapshots are released,
+    // and viewport can be queried safely.
+    // TODO: remove, combine viewport + save stack initialization
+    mSnapshot = new Snapshot(mFirstSnapshot,
+            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+    mSaveCount = 1;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 5e6796c..1c416a7 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -91,7 +91,9 @@
 }
 
 void CanvasContext::swapBuffers() {
-    mEglManager.swapBuffers(mEglSurface);
+    if (CC_UNLIKELY(!mEglManager.swapBuffers(mEglSurface))) {
+        setSurface(NULL);
+    }
     mHaveNewSurface = false;
 }
 
@@ -102,8 +104,8 @@
 }
 
 bool CanvasContext::initialize(ANativeWindow* window) {
-    if (mCanvas) return false;
     setSurface(window);
+    if (mCanvas) return false;
     mCanvas = new OpenGLRenderer(mRenderThread.renderState());
     mCanvas->initProperties();
     return true;
@@ -117,10 +119,10 @@
     stopDrawing();
 }
 
+// TODO: don't pass viewport size, it's automatic via EGL
 void CanvasContext::setup(int width, int height, const Vector3& lightCenter, float lightRadius,
         uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
     if (!mCanvas) return;
-    mCanvas->setViewport(width, height);
     mCanvas->initLight(lightCenter, lightRadius, ambientShadowAlpha, spotShadowAlpha);
 }
 
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index e030cdb..a87834e 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -254,11 +254,23 @@
     eglBeginFrame(mEglDisplay, surface);
 }
 
-void EglManager::swapBuffers(EGLSurface surface) {
+bool EglManager::swapBuffers(EGLSurface surface) {
     eglSwapBuffers(mEglDisplay, surface);
     EGLint err = eglGetError();
-    LOG_ALWAYS_FATAL_IF(err != EGL_SUCCESS,
-            "Encountered EGL error %d %s during rendering", err, egl_error_str(err));
+    if (CC_LIKELY(err == EGL_SUCCESS)) {
+        return true;
+    }
+    if (err == EGL_BAD_SURFACE) {
+        // For some reason our surface was destroyed out from under us
+        // This really shouldn't happen, but if it does we can recover easily
+        // by just not trying to use the surface anymore
+        ALOGW("swapBuffers encountered EGL_BAD_SURFACE on %p, halting rendering...", surface);
+        return false;
+    }
+    LOG_ALWAYS_FATAL("Encountered EGL error %d %s during rendering",
+            err, egl_error_str(err));
+    // Impossible to hit this, but the compiler doesn't know that
+    return false;
 }
 
 bool EglManager::enableDirtyRegions(EGLSurface surface) {
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index a844cfc..71213fb 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -47,7 +47,7 @@
     // Returns true if the current surface changed, false if it was already current
     bool makeCurrent(EGLSurface surface);
     void beginFrame(EGLSurface surface, EGLint* width, EGLint* height);
-    void swapBuffers(EGLSurface surface);
+    bool swapBuffers(EGLSurface surface);
 
     bool enableDirtyRegions(EGLSurface surface);
 
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 2c805bb..0445869 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.location.ProviderProperties;
 
+import android.annotation.SystemApi;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
@@ -808,6 +809,7 @@
      *
      * @hide
      */
+    @SystemApi
     public void requestLocationUpdates(LocationRequest request, LocationListener listener,
             Looper looper) {
         checkListener(listener);
@@ -835,6 +837,7 @@
      *
      * @hide
      */
+    @SystemApi
     public void requestLocationUpdates(LocationRequest request, PendingIntent intent) {
         checkPendingIntent(intent);
         requestLocationUpdates(request, null, null, intent);
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 40d45ea..71a05ab 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -1351,6 +1351,16 @@
             streamType = AudioSystem.STREAM_NOTIFICATION;
         }
 
+        // If Hdmi-CEC system audio mode is on, show volume bar
+        // only when TV receives volume notification from Audio Receiver.
+        if (mHdmiTvClient != null && streamType == AudioSystem.STREAM_MUSIC) {
+            synchronized (mHdmiTvClient) {
+                if (mHdmiSystemAudioSupported &&
+                        ((flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) == 0)) {
+                    flags &= ~AudioManager.FLAG_SHOW_UI;
+                }
+            }
+        }
         mVolumeController.postVolumeChanged(streamType, flags);
 
         if ((flags & AudioManager.FLAG_FIXED_VOLUME) == 0) {
diff --git a/media/java/android/media/ToneGenerator.java b/media/java/android/media/ToneGenerator.java
index 713f147..4661226 100644
--- a/media/java/android/media/ToneGenerator.java
+++ b/media/java/android/media/ToneGenerator.java
@@ -34,6 +34,12 @@
      * the enum in ToneGenerator C++ class.     */
 
     /**
+     * Default value for an unknown or unspecified tone.
+     * @hide
+     */
+    public static final int TONE_UNKNOWN = -1;
+
+    /**
      * DTMF tone for key 0: 1336Hz, 941Hz, continuous</p>
      *
      * @see #ToneGenerator(int, int)
diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml
index 7693da3..04692f6 100644
--- a/packages/DocumentsUI/res/values/styles.xml
+++ b/packages/DocumentsUI/res/values/styles.xml
@@ -27,6 +27,8 @@
         <item name="android:colorPrimary">@*android:color/material_blue_grey_800</item>
         <item name="android:colorAccent">@*android:color/material_deep_teal_500</item>
 
+        <item name="android:listDivider">@*android:drawable/list_divider_material</item>
+
         <item name="android:windowActionBar">false</item>
         <item name="android:windowActionModeOverlay">true</item>
         <item name="android:windowNoTitle">true</item>
diff --git a/packages/PrintSpooler/res/values-es-rUS/strings.xml b/packages/PrintSpooler/res/values-es-rUS/strings.xml
index 167f7d8..e194f55 100644
--- a/packages/PrintSpooler/res/values-es-rUS/strings.xml
+++ b/packages/PrintSpooler/res/values-es-rUS/strings.xml
@@ -38,7 +38,7 @@
     <string name="print_dialog" msgid="32628687461331979">"Cuadro de diálogo de impresión"</string>
     <string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
     <string name="page_description_template" msgid="6831239682256197161">"Página <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> de <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
-    <string name="summary_template" msgid="8899734908625669193">"Resumen, <xliff:g id="COPIES">%1$s</xliff:g> copias, tamaño de papel <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+    <string name="summary_template" msgid="8899734908625669193">"Resumen, copias <xliff:g id="COPIES">%1$s</xliff:g>, tamaño de papel <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
     <string name="expand_handle" msgid="7282974448109280522">"Controlador para expandir"</string>
     <string name="collapse_handle" msgid="6886637989442507451">"Controlador para contraer"</string>
     <string name="print_button" msgid="645164566271246268">"Imprimir"</string>
diff --git a/packages/PrintSpooler/res/values-eu-rES/strings.xml b/packages/PrintSpooler/res/values-eu-rES/strings.xml
index b2c2b9c..4f0f8fc 100644
--- a/packages/PrintSpooler/res/values-eu-rES/strings.xml
+++ b/packages/PrintSpooler/res/values-eu-rES/strings.xml
@@ -43,8 +43,8 @@
     <string name="collapse_handle" msgid="6886637989442507451">"Tolestu heldulekua"</string>
     <string name="print_button" msgid="645164566271246268">"Inprimatu"</string>
     <string name="savetopdf_button" msgid="2976186791686924743">"Gorde PDF gisa"</string>
-    <string name="print_options_expanded" msgid="6944679157471691859">"Inprimaketa-aukerak zabalduta daude"</string>
-    <string name="print_options_collapsed" msgid="7455930445670414332">"Inprimaketa-aukerak tolestuta daude"</string>
+    <string name="print_options_expanded" msgid="6944679157471691859">"Inprimatzeko aukerak zabalduta daude"</string>
+    <string name="print_options_collapsed" msgid="7455930445670414332">"Inprimatzeko aukerak tolestuta daude"</string>
     <string name="search" msgid="5421724265322228497">"Bilatu"</string>
     <string name="all_printers_label" msgid="3178848870161526399">"Inprimagailu guztiak"</string>
     <string name="add_print_service_label" msgid="5356702546188981940">"Gehitu zerbitzua"</string>
diff --git a/packages/PrintSpooler/res/values-lo-rLA/strings.xml b/packages/PrintSpooler/res/values-lo-rLA/strings.xml
index 349ac31..3a3f6bb 100644
--- a/packages/PrintSpooler/res/values-lo-rLA/strings.xml
+++ b/packages/PrintSpooler/res/values-lo-rLA/strings.xml
@@ -37,9 +37,9 @@
     <string name="all_printers" msgid="5018829726861876202">"ທຸກເຄື່ອງພິມ..."</string>
     <string name="print_dialog" msgid="32628687461331979">"ໜ້າຕ່າງການພິມ"</string>
     <string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
-    <string name="page_description_template" msgid="6831239682256197161">"ໜ້າທີ <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> ໃນ <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
-    <string name="summary_template" msgid="8899734908625669193">"ສະ​ຫຼຸບ​, ສໍາ​ເນົາ <xliff:g id="COPIES">%1$s</xliff:g> , ຂະ​ຫນາດ <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
-    <string name="expand_handle" msgid="7282974448109280522">"ຂະ​ຫຍາຍ​ໂຕ​ຈັບ"</string>
+    <string name="page_description_template" msgid="6831239682256197161">"ໜ້າທີ <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> ​ຈາກ​ທັງ​ໝົດ <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+    <string name="summary_template" msgid="8899734908625669193">"ສະ​ຫຼຸບ​, ສໍາ​ເນົາ <xliff:g id="COPIES">%1$s</xliff:g>, ຂະ​ຫນາດ <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+    <string name="expand_handle" msgid="7282974448109280522">"​ຂະ​ຫຍາຍ​ໂຕ​ຈັດ​ການ"</string>
     <string name="collapse_handle" msgid="6886637989442507451">"ປິດ​ໂຕ​ຈັດ​ການ"</string>
     <string name="print_button" msgid="645164566271246268">"ພິມ"</string>
     <string name="savetopdf_button" msgid="2976186791686924743">"ບັນທຶກເປັນ PDF"</string>
diff --git a/packages/PrintSpooler/res/values-pt-rPT/strings.xml b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
index d115b29..7b47f4c 100644
--- a/packages/PrintSpooler/res/values-pt-rPT/strings.xml
+++ b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
@@ -38,7 +38,7 @@
     <string name="print_dialog" msgid="32628687461331979">"Caixa de diálogo de impressão"</string>
     <string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
     <string name="page_description_template" msgid="6831239682256197161">"Página <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> de <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
-    <string name="summary_template" msgid="8899734908625669193">"Resumo, cópias <xliff:g id="COPIES">%1$s</xliff:g>, tamanho do papel <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+    <string name="summary_template" msgid="8899734908625669193">"Resumo, <xliff:g id="COPIES">%1$s</xliff:g> cópias, tamanho do papel <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
     <string name="expand_handle" msgid="7282974448109280522">"Expandir alça"</string>
     <string name="collapse_handle" msgid="6886637989442507451">"Fechar alça"</string>
     <string name="print_button" msgid="645164566271246268">"Imprimir"</string>
diff --git a/packages/PrintSpooler/res/values-ro/strings.xml b/packages/PrintSpooler/res/values-ro/strings.xml
index 3f5cb3c..1446a53 100644
--- a/packages/PrintSpooler/res/values-ro/strings.xml
+++ b/packages/PrintSpooler/res/values-ro/strings.xml
@@ -37,21 +37,14 @@
     <string name="all_printers" msgid="5018829726861876202">"Toate imprimantele..."</string>
     <string name="print_dialog" msgid="32628687461331979">"Caseta de dialog de printare"</string>
     <string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
-    <!-- no translation found for page_description_template (6831239682256197161) -->
-    <skip />
-    <!-- no translation found for summary_template (8899734908625669193) -->
-    <skip />
-    <!-- no translation found for expand_handle (7282974448109280522) -->
-    <skip />
-    <!-- no translation found for collapse_handle (6886637989442507451) -->
-    <skip />
+    <string name="page_description_template" msgid="6831239682256197161">"Pagina <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> din <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+    <string name="summary_template" msgid="8899734908625669193">"Rezumat, copii <xliff:g id="COPIES">%1$s</xliff:g>, dimensiunea paginii <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+    <string name="expand_handle" msgid="7282974448109280522">"Ghidaj de extindere"</string>
+    <string name="collapse_handle" msgid="6886637989442507451">"Ghidaj de restrângere"</string>
     <string name="print_button" msgid="645164566271246268">"Printați"</string>
-    <!-- no translation found for savetopdf_button (2976186791686924743) -->
-    <skip />
-    <!-- no translation found for print_options_expanded (6944679157471691859) -->
-    <skip />
-    <!-- no translation found for print_options_collapsed (7455930445670414332) -->
-    <skip />
+    <string name="savetopdf_button" msgid="2976186791686924743">"Salvați în format PDF"</string>
+    <string name="print_options_expanded" msgid="6944679157471691859">"Opțiuni de printare extinse"</string>
+    <string name="print_options_collapsed" msgid="7455930445670414332">"Opțiuni de printare restrânse"</string>
     <string name="search" msgid="5421724265322228497">"Căutați"</string>
     <string name="all_printers_label" msgid="3178848870161526399">"Toate imprimantele"</string>
     <string name="add_print_service_label" msgid="5356702546188981940">"Adăugați un serviciu"</string>
diff --git a/packages/PrintSpooler/res/values-zh-rCN/strings.xml b/packages/PrintSpooler/res/values-zh-rCN/strings.xml
index 7a000c5..77ecb21 100644
--- a/packages/PrintSpooler/res/values-zh-rCN/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rCN/strings.xml
@@ -37,21 +37,14 @@
     <string name="all_printers" msgid="5018829726861876202">"所有打印机…"</string>
     <string name="print_dialog" msgid="32628687461331979">"打印对话框"</string>
     <string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> / <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
-    <!-- no translation found for page_description_template (6831239682256197161) -->
-    <skip />
-    <!-- no translation found for summary_template (8899734908625669193) -->
-    <skip />
-    <!-- no translation found for expand_handle (7282974448109280522) -->
-    <skip />
-    <!-- no translation found for collapse_handle (6886637989442507451) -->
-    <skip />
+    <string name="page_description_template" msgid="6831239682256197161">"第<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>页,共<xliff:g id="PAGE_COUNT">%2$d</xliff:g>页"</string>
+    <string name="summary_template" msgid="8899734908625669193">"摘要,<xliff:g id="COPIES">%1$s</xliff:g>份,纸张尺寸为<xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+    <string name="expand_handle" msgid="7282974448109280522">"展开手柄"</string>
+    <string name="collapse_handle" msgid="6886637989442507451">"收起手柄"</string>
     <string name="print_button" msgid="645164566271246268">"打印"</string>
-    <!-- no translation found for savetopdf_button (2976186791686924743) -->
-    <skip />
-    <!-- no translation found for print_options_expanded (6944679157471691859) -->
-    <skip />
-    <!-- no translation found for print_options_collapsed (7455930445670414332) -->
-    <skip />
+    <string name="savetopdf_button" msgid="2976186791686924743">"保存为PDF格式"</string>
+    <string name="print_options_expanded" msgid="6944679157471691859">"已展开打印选项"</string>
+    <string name="print_options_collapsed" msgid="7455930445670414332">"已收起打印选项"</string>
     <string name="search" msgid="5421724265322228497">"搜索"</string>
     <string name="all_printers_label" msgid="3178848870161526399">"所有打印机"</string>
     <string name="add_print_service_label" msgid="5356702546188981940">"添加服务"</string>
diff --git a/packages/PrintSpooler/res/values-zh-rTW/strings.xml b/packages/PrintSpooler/res/values-zh-rTW/strings.xml
index eb28f8a..3e26a5e 100644
--- a/packages/PrintSpooler/res/values-zh-rTW/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rTW/strings.xml
@@ -38,7 +38,7 @@
     <string name="print_dialog" msgid="32628687461331979">"印表機對話方塊"</string>
     <string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
     <string name="page_description_template" msgid="6831239682256197161">"第 <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> 頁,共 <xliff:g id="PAGE_COUNT">%2$d</xliff:g> 頁"</string>
-    <string name="summary_template" msgid="8899734908625669193">"摘要,<xliff:g id="COPIES">%1$s</xliff:g> 份,<xliff:g id="PAPER_SIZE">%2$s</xliff:g> 紙張大小"</string>
+    <string name="summary_template" msgid="8899734908625669193">"摘要,<xliff:g id="COPIES">%1$s</xliff:g> 份,紙張為 <xliff:g id="PAPER_SIZE">%2$s</xliff:g> 大小"</string>
     <string name="expand_handle" msgid="7282974448109280522">"展開控點"</string>
     <string name="collapse_handle" msgid="6886637989442507451">"收合控點"</string>
     <string name="print_button" msgid="645164566271246268">"列印"</string>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
index 14c41da..a4555f1 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
@@ -64,9 +64,6 @@
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
 
-    private final ArrayMap<Integer, PageContentProvider> mPageContentProviders =
-            new ArrayMap<>();
-
     private final AsyncRenderer mRenderer;
 
     private RenderSpec mLastRenderSpec;
@@ -141,10 +138,6 @@
         return mRenderer.getPageCount();
     }
 
-    public PageContentProvider peekPageContentProvider(int pageIndex) {
-        return mPageContentProviders.get(pageIndex);
-    }
-
     public PageContentProvider acquirePageContentProvider(int pageIndex, View owner) {
         throwIfDestroyed();
 
@@ -152,15 +145,7 @@
             Log.i(LOG_TAG, "Acquiring provider for page: " + pageIndex);
         }
 
-        if (mPageContentProviders.get(pageIndex)!= null) {
-            throw new IllegalStateException("Already acquired for page: " + pageIndex);
-        }
-
-        PageContentProvider provider = new PageContentProvider(pageIndex, owner);
-
-        mPageContentProviders.put(pageIndex, provider);
-
-        return provider;
+        return new PageContentProvider(pageIndex, owner);
     }
 
     public void releasePageContentProvider(PageContentProvider provider) {
@@ -170,10 +155,6 @@
             Log.i(LOG_TAG, "Releasing provider for page: " + provider.mPageIndex);
         }
 
-        if (mPageContentProviders.remove(provider.mPageIndex) == null) {
-            throw new IllegalStateException("Not acquired");
-        }
-
         provider.cancelLoad();
     }
 
@@ -526,7 +507,7 @@
                         callback.run();
                     }
                 }
-            }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
+            }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
         }
 
         public void close(final Runnable callback) {
@@ -552,7 +533,7 @@
                         callback.run();
                     }
                 }
-            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+            }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
         }
 
         public void destroy() {
@@ -571,7 +552,7 @@
                     mPageContentCache.invalidate();
                     mPageContentCache.clear();
                 }
-            }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
+            }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
         }
 
         public void startPreload(int firstShownPage, int lastShownPage, RenderSpec renderSpec) {
@@ -687,7 +668,7 @@
             // Oh well, we will have work to do...
             renderTask = new RenderPageTask(pageIndex, renderSpec, callback);
             mPageToRenderTaskMap.put(pageIndex, renderTask);
-            renderTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
+            renderTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
         }
 
         public void cancelRendering(int pageIndex) {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
index 369c453..da8160a 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
@@ -274,9 +274,7 @@
     @Override
     public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         View page = mLayoutInflater.inflate(R.layout.preview_page, parent, false);
-        ViewHolder holder = new MyViewHolder(page);
-        holder.setIsRecyclable(true);
-        return holder;
+        return new MyViewHolder(page);
     }
 
     @Override
@@ -314,14 +312,8 @@
                         + ", pageIndexInFile: " + pageIndexInFile);
             }
 
-            // OK, there are bugs in recycler view which tries to bind views
-            // without recycling them which would give us a chance to clean up.
-            PageContentProvider boundProvider = mPageContentRepository
-                    .peekPageContentProvider(pageIndexInFile);
-            if (boundProvider != null) {
-                PageContentView owner = (PageContentView) boundProvider.getOwner();
-                owner.init(null, mEmptyState, mMediaSize, mMinMargins);
-                mPageContentRepository.releasePageContentProvider(boundProvider);
+            if (provider != null && provider.getPageIndex() != pageIndexInFile) {
+                mPageContentRepository.releasePageContentProvider(provider);
             }
 
             provider = mPageContentRepository.acquirePageContentProvider(
@@ -732,7 +724,7 @@
     private void recyclePageView(PageContentView page, int pageIndexInAdapter) {
         PageContentProvider provider = page.getPageContentProvider();
         if (provider != null) {
-            page.init(null, null, null, null);
+            page.init(null, mEmptyState, mMediaSize, mMinMargins);
             mPageContentRepository.releasePageContentProvider(provider);
         }
         mBoundPagesInAdapter.remove(pageIndexInAdapter);
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 693e5ac..c4b3262 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -312,6 +312,14 @@
     }
 
     @Override
+    public void onResume() {
+        super.onResume();
+        if (mState != STATE_INITIALIZING && mCurrentPrinter != null) {
+            mPrinterRegistry.setTrackedPrinter(mCurrentPrinter.getId());
+        }
+    }
+
+    @Override
     public void onPause() {
         PrintSpoolerService spooler = mSpoolerProvider.getSpooler();
 
@@ -347,6 +355,7 @@
         }
 
         mPrinterAvailabilityDetector.cancel();
+        mPrinterRegistry.setTrackedPrinter(null);
 
         super.onPause();
     }
@@ -586,7 +595,7 @@
                 }
             });
         } else if (resultCode == RESULT_CANCELED) {
-            setState(STATE_CONFIGURING);
+            mState = STATE_CONFIGURING;
             updateOptionsUi();
         } else {
             setState(STATE_CREATE_FILE_FAILED);
@@ -816,6 +825,9 @@
     }
 
     private void ensureProgressUiShown() {
+        if (isFinishing()) {
+            return;
+        }
         if (mUiState != UI_STATE_PROGRESS) {
             mUiState = UI_STATE_PROGRESS;
             mPrintPreviewController.setUiShown(false);
@@ -825,6 +837,9 @@
     }
 
     private void ensurePreviewUiShown() {
+        if (isFinishing()) {
+            return;
+        }
         if (mUiState != UI_STATE_PREVIEW) {
             mUiState = UI_STATE_PREVIEW;
             mPrintPreviewController.setUiShown(true);
@@ -833,6 +848,9 @@
     }
 
     private void ensureErrorUiShown(CharSequence message, int action) {
+        if (isFinishing()) {
+            return;
+        }
         if (mUiState != UI_STATE_ERROR) {
             mUiState = UI_STATE_ERROR;
             mPrintPreviewController.setUiShown(false);
@@ -935,7 +953,7 @@
             // When the update is done we update the print preview.
             mProgressMessageController.post();
             return true;
-        } else  {
+        } else if (!willUpdate) {
             // Update preview.
             updatePrintPreviewController(false);
         }
@@ -2317,7 +2335,7 @@
                     mContext.unbindService(PageShredder.this);
                     mCallback.run();
                 }
-            }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
+            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
         }
 
         @Override
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java
index b999866..0d45352 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java
@@ -77,6 +77,7 @@
         mRecyclerView = (RecyclerView) activity.findViewById(R.id.preview_content);
         mRecyclerView.setLayoutManager(mLayoutManger);
         mRecyclerView.setAdapter(mPageAdapter);
+        mRecyclerView.setItemViewCacheSize(0);
         mPreloadController = new PreloadController(mRecyclerView);
         mRecyclerView.setOnScrollListener(mPreloadController);
 
@@ -348,8 +349,7 @@
 
         public void startPreloadContent() {
             PageAdapter pageAdapter = (PageAdapter) mRecyclerView.getAdapter();
-
-            if (pageAdapter.isOpened()) {
+            if (pageAdapter != null && pageAdapter.isOpened()) {
                 PageRange shownPages = computeShownPages();
                 if (shownPages != null) {
                     pageAdapter.startPreloadContent(shownPages);
@@ -359,8 +359,7 @@
 
         public void stopPreloadContent() {
             PageAdapter pageAdapter = (PageAdapter) mRecyclerView.getAdapter();
-
-            if (pageAdapter.isOpened()) {
+            if (pageAdapter != null && pageAdapter.isOpened()) {
                 pageAdapter.stopPreloadContent();
             }
         }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java b/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java
index 1000117..b792789 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java
@@ -52,12 +52,12 @@
 
     @Override
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        mContentRequested = false;
         requestPageContentIfNeeded();
     }
 
     @Override
     public void onPageContentAvailable(BitmapDrawable content) {
-        assert (getBackground() != content);
         setBackground(content);
     }
 
@@ -70,7 +70,7 @@
         final boolean providerChanged = (mProvider == null)
                 ? provider != null : !mProvider.equals(provider);
         final boolean loadingDrawableChanged = (mEmptyState == null)
-                ? mEmptyState != null : !mEmptyState.equals(emptyState);
+                ? emptyState != null : !mEmptyState.equals(emptyState);
         final boolean mediaSizeChanged = (mMediaSize == null)
                 ? mediaSize != null : !mMediaSize.equals(mediaSize);
         final boolean marginsChanged = (mMinMargins == null)
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index b94a258..bddd691 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -199,7 +199,7 @@
                   android:excludeFromRecents="true"
                   android:stateNotNeeded="true"
                   android:resumeWhilePausing="true"
-                  android:theme="@style/RecentsTheme">
+                  android:theme="@style/config_recents_activity_theme">
             <intent-filter>
                 <action android:name="com.android.systemui.recents.TOGGLE_RECENTS" />
             </intent-filter>
@@ -283,6 +283,21 @@
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".egg.LLandActivity"
+                  android:theme="@android:style/Theme.Material.Light.NoActionBar.TranslucentDecor"
+                  android:exported="true"
+                  android:label="@string/lland"
+                  android:hardwareAccelerated="true"
+                  android:launchMode="singleInstance"
+                  android:screenOrientation="locked"
+                  android:process=":sweetsweetdesserts"
+                  android:excludeFromRecents="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="com.android.internal.category.PLATLOGO" />
             </intent-filter>
         </activity>
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index c9e1618..47e24e8 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -1,8 +1,11 @@
 -keep class com.android.systemui.statusbar.policy.KeyButtonView {
   public float getDrawingAlpha();
+  public void setDrawingAlpha(float);
+}
+
+-keep class com.android.systemui.statusbar.policy.KeyButtonRipple {
   public float getGlowAlpha();
   public float getGlowScale();
-  public void setDrawingAlpha(float);
   public void setGlowAlpha(float);
   public void setGlowScale(float);
 }
diff --git a/packages/SystemUI/res/drawable/android.xml b/packages/SystemUI/res/drawable/android.xml
new file mode 100644
index 0000000..750de05
--- /dev/null
+++ b/packages/SystemUI/res/drawable/android.xml
@@ -0,0 +1,37 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2 (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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48dp"
+        android:height="48dp"
+        android:viewportWidth="48"
+        android:viewportHeight="48">
+    <path
+        android:name="torso"
+        android:pathData="M12,36c0,1.1 0.9,2 2,2l2,0l0,7c0,1.7 1.3,3 3,3c1.7,0 3,-1.3 3,-3l0,-7l4,0l0,7c0,1.7 1.3,3 3,3c1.7,0 3,-1.3 3,-3l0,-7l2,0c1.1,0 2,-0.9 2,-2L36,16L12,16L12,36z"
+        android:fillColor="#FFFFFF"/>
+    <path
+        android:name="leftArm"
+        android:pathData="M7,16c-1.7,0 -3,1.3 -3,3l0,14c0,1.7 1.3,3 3,3c1.7,0 3,-1.3 3,-3L10,19C10,17.3 8.7,16 7,16z"
+        android:fillColor="#FFFFFF"/>
+    <path
+        android:name="rightArm"
+        android:pathData="M41,16c-1.7,0 -3,1.3 -3,3l0,14c0,1.7 1.3,3 3,3c1.7,0 3,-1.3 3,-3L44,19C44,17.3 42.7,16 41,16z"
+        android:fillColor="#FFFFFF"/>
+    <path
+        android:name="illFormTheHead"
+        android:pathData="M31.1,4.3l2.6,-2.6c0.4,-0.4 0.4,-1 0,-1.4c-0.4,-0.4 -1,-0.4 -1.4,0l-3,3C27.7,2.5 25.9,2 24,2c-1.9,0 -3.7,0.5 -5.3,1.3l-3,-3c-0.4,-0.4 -1,-0.4 -1.4,0c-0.4,0.4 -0.4,1 0,1.4l2.6,2.6C13.9,6.5 12,10 12,14l24,0C36,10 34.1,6.5 31.1,4.3zM20.31,9c0,0.72 -0.59,1.31 -1.31,1.31c-0.72,0 -1.31,-0.59 -1.31,-1.31c0,-0.72 0.59,-1.31 1.31,-1.31C19.72,7.69 20.31,8.28 20.31,9zM30.31,9c0,0.72 -0.59,1.31 -1.31,1.31c-0.73,0 -1.31,-0.59 -1.31,-1.31c0,-0.72 0.59,-1.31 1.31,-1.31C29.72,7.69 30.31,8.28 30.31,9z"
+        android:fillColor="#FFFFFF"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/cloud.xml b/packages/SystemUI/res/drawable/cloud.xml
new file mode 100644
index 0000000..17e4ad2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/cloud.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48.0dp"
+        android:height="48.0dp"
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0">
+    <path
+        android:pathData="M38.700001,20.100000C37.299999,13.200000 31.299999,8.000000 24.000000,8.000000c-5.800000,0.000000 -10.800000,3.300000 -13.300000,8.100000C4.700000,16.700001 0.000000,21.799999 0.000000,28.000000c0.000000,6.600000 5.400000,12.000000 12.000000,12.000000l26.000000,0.000000c5.500000,0.000000 10.000000,-4.500000 10.000000,-10.000000C48.000000,24.700001 43.900002,20.400000 38.700001,20.100000z"
+        android:fillColor="#FFFFFF"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/cloud_off.xml b/packages/SystemUI/res/drawable/cloud_off.xml
new file mode 100644
index 0000000..b15ea5f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/cloud_off.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M19.400000,10.000000c-0.700000,-3.400000 -3.700000,-6.000000 -7.400000,-6.000000c-1.500000,0.000000 -2.900000,0.400000 -4.000000,1.200000l1.500000,1.500000C10.200000,6.200000 11.100000,6.000000 12.000000,6.000000c3.000000,0.000000 5.500000,2.500000 5.500000,5.500000L17.500000,12.000000L19.000000,12.000000c1.700000,0.000000 3.000000,1.300000 3.000000,3.000000c0.000000,1.100000 -0.600000,2.100000 -1.600000,2.600000l1.500000,1.500000c1.300000,-0.900000 2.100000,-2.400000 2.100000,-4.100000C24.000000,12.400000 21.900000,10.200000 19.400000,10.000000zM3.000000,5.300000L5.800000,8.000000C2.600000,8.200000 0.000000,10.800000 0.000000,14.000000c0.000000,3.300000 2.700000,6.000000 6.000000,6.000000l11.700000,0.000000l2.000000,2.000000l1.300000,-1.300000L4.300000,4.000000L3.000000,5.300000zM7.700000,10.000000l8.000000,8.000000L6.000000,18.000000c-2.200000,0.000000 -4.000000,-1.800000 -4.000000,-4.000000c0.000000,-2.200000 1.800000,-4.000000 4.000000,-4.000000L7.700000,10.000000z"
+        android:fillColor="#FFFFFF"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/moon.xml b/packages/SystemUI/res/drawable/moon.xml
new file mode 100644
index 0000000..4ee6286
--- /dev/null
+++ b/packages/SystemUI/res/drawable/moon.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48.0dp"
+        android:height="48.0dp"
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0">
+    <path
+        android:pathData="M18.000000,4.000000c-2.100000,0.000000 -4.100000,0.300000 -6.000000,0.900000C20.100000,7.500000 26.000000,15.000000 26.000000,24.000000s-5.900000,16.500000 -14.000000,19.100000c1.900000,0.600000 3.900000,0.900000 6.000000,0.900000c11.000000,0.000000 20.000000,-9.000000 20.000000,-20.000000S29.000000,4.000000 18.000000,4.000000z"
+        android:fillColor="#FFF2F2FF"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/placeholder.xml b/packages/SystemUI/res/drawable/placeholder.xml
new file mode 100644
index 0000000..1933145
--- /dev/null
+++ b/packages/SystemUI/res/drawable/placeholder.xml
@@ -0,0 +1,51 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="100dp"
+        android:height="400dp"
+        android:viewportWidth="100"
+        android:viewportHeight="400">
+
+    <!-- future site of real artwork -->
+
+    <path android:fillColor="#FFFFFF00"
+        android:pathData="M 0,0 L 100,0 L 100,400 L 0,400 z" />
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M 0,0 L 100,25 L 100,50 L 0,25 z" />
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M 0,50 L 100,75 L 100,100 L 0,75 z" />
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M 0,100 L 100,125 L 100,150 L 0,125 z" />
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M 0,150 L 100,175 L 100,200 L 0,175 z" />
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M 0,200 L 100,225 L 100,250 L 0,225 z" />
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M 0,250 L 100,275 L 100,300 L 0,275 z" />
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M 0,300 L 100,325 L 100,350 L 0,325 z" />
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M 0,350 L 100,375 L 100,400 L 0,375 z" />
+</vector>
+
diff --git a/packages/SystemUI/res/drawable/recents_task_view_header_bg_color.xml b/packages/SystemUI/res/drawable/recents_task_view_header_bg_color.xml
new file mode 100644
index 0000000..5f9341c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/recents_task_view_header_bg_color.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <corners android:topLeftRadius="@dimen/recents_task_view_rounded_corners_radius"
+             android:topRightRadius="@dimen/recents_task_view_rounded_corners_radius"/>
+    <solid android:color="#00000000" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/scorecard.xml b/packages/SystemUI/res/drawable/scorecard.xml
new file mode 100644
index 0000000..707449a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/scorecard.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle"
+    >
+    <corners
+        android:radius="8dp" />
+    <solid
+        android:color="#ffffffff" />
+</shape>
diff --git a/packages/SystemUI/res/drawable/scorecard_gameover.xml b/packages/SystemUI/res/drawable/scorecard_gameover.xml
new file mode 100644
index 0000000..f663a66
--- /dev/null
+++ b/packages/SystemUI/res/drawable/scorecard_gameover.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle"
+    >
+    <corners
+        android:radius="8dp" />
+    <solid
+        android:color="#ffff0000" />
+</shape>
diff --git a/packages/SystemUI/res/drawable/star.xml b/packages/SystemUI/res/drawable/star.xml
new file mode 100644
index 0000000..73ca04a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/star.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48.0dp"
+        android:height="48.0dp"
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0">
+    <path
+        android:pathData="M30.250000,17.750000L24.000000,4.000000l-6.250000,13.750000L4.000000,24.000000l13.750000,6.250000L24.000000,44.000000l6.250000,-13.750000L44.000000,24.000000L30.250000,17.750000z"
+        android:fillColor="#FFFFFF"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/sun.xml b/packages/SystemUI/res/drawable/sun.xml
new file mode 100644
index 0000000..3e4a233
--- /dev/null
+++ b/packages/SystemUI/res/drawable/sun.xml
@@ -0,0 +1,29 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48.0dp"
+        android:height="48.0dp"
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0">
+    <group>
+        <path
+            android:pathData="M 24,8 A 16,16 0 1,0 24.0001,8 z"
+            android:fillColor="#FFFFFFCC" />
+        <path
+            android:pathData="M40.0,30.6l6.6,-6.6L40.0,17.4L40.0,8.0l-9.4,0.0L24.0,1.4L17.4,8.0L8.0,8.0l0.0,9.4L1.4,24.0L8.0,30.6L8.0,40.0l9.4,0.0l6.6,6.6l6.6,-6.6L40.0,40.0L40.0,30.6zM24.0,36.0c-6.6,0.0 -12.0,-5.4 -12.0,-12.0s5.4,-12.0 12.0,-12.0c6.6,0.0 12.0,5.4 12.0,12.0S30.6,36.0 24.0,36.0z"
+            android:fillColor="#FFFFFF40"/>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/sun2.xml b/packages/SystemUI/res/drawable/sun2.xml
new file mode 100644
index 0000000..6d2d504
--- /dev/null
+++ b/packages/SystemUI/res/drawable/sun2.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48.0dp"
+        android:height="48.0dp"
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0">
+    <path
+        android:pathData="M40.000000,17.400000L40.000000,8.000000l-9.400000,0.000000L24.000000,1.400000L17.400000,8.000000L8.000000,8.000000l0.000000,9.400000L1.400000,24.000000L8.000000,30.600000L8.000000,40.000000l9.400000,0.000000l6.600000,6.600000l6.600000,-6.600000L40.000000,40.000000l0.000000,-9.400000l6.600000,-6.600000L40.000000,17.400000zM24.000000,36.000000c-6.600000,0.000000 -12.000000,-5.400000 -12.000000,-12.000000s5.400000,-12.000000 12.000000,-12.000000c6.600000,0.000000 12.000000,5.400000 12.000000,12.000000S30.600000,36.000000 24.000000,36.000000zM24.000000,16.000000c-4.400000,0.000000 -8.000000,3.600000 -8.000000,8.000000c0.000000,4.400000 3.600000,8.000000 8.000000,8.000000s8.000000,-3.600000 8.000000,-8.000000C32.000000,19.600000 28.400000,16.000000 24.000000,16.000000z"
+        android:fillColor="#FF000000"/>
+</vector>
diff --git a/packages/SystemUI/res/layout/lland.xml b/packages/SystemUI/res/layout/lland.xml
new file mode 100644
index 0000000..053225d
--- /dev/null
+++ b/packages/SystemUI/res/layout/lland.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+        >
+    <com.android.systemui.egg.LLand
+            android:id="@+id/world"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+    </com.android.systemui.egg.LLand>
+    <TextView
+            android:id="@+id/score"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textSize="32sp"
+            android:textColor="#FFAAAAAA"
+            android:layout_marginTop="32dp"
+            android:layout_marginLeft="16dp"
+            android:layout_gravity="top|left"
+            android:paddingLeft="16dp"
+            android:paddingRight="16dp"
+            android:paddingTop="8dp"
+            android:paddingBottom="8dp"
+            android:background="@drawable/scorecard"
+            />
+    <TextView
+            android:id="@+id/welcome"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textSize="30sp"
+            android:textColor="#FFFFFFFF"
+            android:layout_gravity="center"
+            android:layout_marginTop="70dp"
+            android:visibility="gone"
+            />
+</FrameLayout>
+
diff --git a/packages/SystemUI/res/layout/recents_task_view.xml b/packages/SystemUI/res/layout/recents_task_view.xml
index 4cb8498..d1d3828 100644
--- a/packages/SystemUI/res/layout/recents_task_view.xml
+++ b/packages/SystemUI/res/layout/recents_task_view.xml
@@ -15,30 +15,34 @@
 -->
 <com.android.systemui.recents.views.TaskView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent" 
+    android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:focusable="true"
-    android:background="#FFffffff">
-    <com.android.systemui.recents.views.TaskViewThumbnail
-        android:id="@+id/task_view_thumbnail"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent" />
-    <include layout="@layout/recents_task_view_header" />
+    android:focusable="true">
     <FrameLayout
-        android:id="@+id/lock_to_app_fab"
-        android:layout_width="48dp"
-        android:layout_height="48dp"
-        android:layout_gravity="bottom|right"
-        android:layout_marginRight="15dp"
-        android:layout_marginBottom="15dp"
-        android:translationZ="3dp"
-        android:contentDescription="@string/recents_lock_to_app_button_label"
-        android:background="@drawable/recents_lock_to_task_button_bg">
-        <ImageView
-            android:layout_width="24dp"
-            android:layout_height="24dp"
-            android:layout_gravity="center"
-            android:src="@drawable/recents_lock_to_app_pin" />
+        android:id="@+id/task_view_content"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <com.android.systemui.recents.views.TaskViewThumbnail
+            android:id="@+id/task_view_thumbnail"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+        <include layout="@layout/recents_task_view_header" />
+        <FrameLayout
+            android:id="@+id/lock_to_app_fab"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            android:layout_gravity="bottom|right"
+            android:layout_marginRight="15dp"
+            android:layout_marginBottom="15dp"
+            android:translationZ="2dp"
+            android:contentDescription="@string/recents_lock_to_app_button_label"
+            android:background="@drawable/recents_lock_to_task_button_bg">
+            <ImageView
+                android:layout_width="24dp"
+                android:layout_height="24dp"
+                android:layout_gravity="center"
+                android:src="@drawable/recents_lock_to_app_pin" />
+        </FrameLayout>
     </FrameLayout>
 </com.android.systemui.recents.views.TaskView>
 
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
index 14bf10e..bfeac9d 100644
--- a/packages/SystemUI/res/layout/zen_mode_panel.xml
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -40,7 +40,7 @@
             android:clipChildren="false" />
     </FrameLayout>
 
-    <FrameLayout
+    <RelativeLayout
         android:id="@+id/zen_subhead"
         android:layout_width="match_parent"
         android:layout_height="62dp"
@@ -73,13 +73,14 @@
             android:id="@+id/zen_more_settings"
             android:layout_width="48dp"
             android:layout_height="48dp"
-            android:layout_gravity="end|center_vertical"
+            android:layout_alignParentEnd="true"
             android:background="@drawable/btn_borderless_rect"
             android:clickable="true"
             android:contentDescription="@null"
             android:scaleType="center"
             android:src="@drawable/ic_settings" />
-    </FrameLayout>
+
+    </RelativeLayout>
 
     <LinearLayout
         android:id="@+id/zen_conditions"
diff --git a/packages/SystemUI/res/values-af/config.xml b/packages/SystemUI/res/values-af/config.xml
index 3a66eab..38497cf 100644
--- a/packages/SystemUI/res/values-af/config.xml
+++ b/packages/SystemUI/res/values-af/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1 s,10 s,30 s,60 s,120 s"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/config.xml b/packages/SystemUI/res/values-am/config.xml
index 3a66eab..97e30c9 100644
--- a/packages/SystemUI/res/values-am/config.xml
+++ b/packages/SystemUI/res/values-am/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1s፣10s፣30s፣60s፣120s"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/config.xml b/packages/SystemUI/res/values-ar/config.xml
index 3a66eab..4bbdea2 100644
--- a/packages/SystemUI/res/values-ar/config.xml
+++ b/packages/SystemUI/res/values-ar/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1s,10s,30s,60s,120s"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/config.xml b/packages/SystemUI/res/values-bg/config.xml
similarity index 87%
copy from packages/SystemUI/res/values-sl/config.xml
copy to packages/SystemUI/res/values-bg/config.xml
index cd49028..3a6872f 100644
--- a/packages/SystemUI/res/values-sl/config.xml
+++ b/packages/SystemUI/res/values-bg/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000, 300000:30000, 1800000:60000, 0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1 с, 10 с, 30 с, 60 с, 120 с"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/config.xml b/packages/SystemUI/res/values-bn-rBD/config.xml
index 947fde9..be49df5 100644
--- a/packages/SystemUI/res/values-bn-rBD/config.xml
+++ b/packages/SystemUI/res/values-bn-rBD/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"৬০০০০:১০০০০,৩০০০০০:৩০০০০,১৮০০০০০:৬০০০০,০"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"১সে.,১০সে.,৩০সে.,৬০সে.,১২০সে."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/config.xml b/packages/SystemUI/res/values-ca/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-ca/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index c6a381c..c9d1cf5 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -214,10 +214,8 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"S\'ha establert la ubicació per GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Sol·licituds d\'ubicació actives"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Esborra totes les notificacions."</string>
-    <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
-    <skip />
-    <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
-    <skip />
+    <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configuració de les notificacions"</string>
+    <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configuració de l\'aplicació <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girarà automàticament."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"La pantalla està bloquejada en orientació horitzontal."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"La pantalla està bloquejada en orientació vertical."</string>
@@ -323,7 +321,7 @@
     <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"Torna a començar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"Sí, continua"</string>
     <string name="user_add_user_title" msgid="4553596395824132638">"Vols afegir un usuari nou?"</string>
-    <string name="user_add_user_message_short" msgid="2161624834066214559">"Quan s\'afegeix un usuari nou, aquest usuari ha de configurar el seu espai.\n\nQualsevol usuari pot actualitzar les aplicacions dels altres usuaris."</string>
+    <string name="user_add_user_message_short" msgid="2161624834066214559">"Quan s\'afegeix un usuari nou, aquest usuari ha de configurar-se l\'espai.\n\nQualsevol usuari pot actualitzar les aplicacions de la resta d\'usuaris."</string>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Estalvi de bateria activada"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"Redueix el rendiment i l\'ús de les dades en segon pla."</string>
     <string name="battery_saver_notification_action_text" msgid="109158658238110382">"Desactiva l\'estalvi de bateria"</string>
diff --git a/packages/SystemUI/res/values-cs/config.xml b/packages/SystemUI/res/values-cs/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-cs/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-da/config.xml b/packages/SystemUI/res/values-da/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-da/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-de/config.xml b/packages/SystemUI/res/values-de/config.xml
index 3a66eab..4bbdea2 100644
--- a/packages/SystemUI/res/values-de/config.xml
+++ b/packages/SystemUI/res/values-de/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1s,10s,30s,60s,120s"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/config.xml b/packages/SystemUI/res/values-el/config.xml
index 3a66eab..f3cccde 100644
--- a/packages/SystemUI/res/values-el/config.xml
+++ b/packages/SystemUI/res/values-el/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1 δ, 10 δ, 30 δ, 60 δ, 120 δ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/config.xml b/packages/SystemUI/res/values-en-rGB/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-en-rGB/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/config.xml b/packages/SystemUI/res/values-en-rIN/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-en-rIN/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/config.xml b/packages/SystemUI/res/values-es-rUS/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-es-rUS/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-es/config.xml b/packages/SystemUI/res/values-es/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-es/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-et-rEE/config.xml b/packages/SystemUI/res/values-et-rEE/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-et-rEE/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-eu-rES/config.xml b/packages/SystemUI/res/values-eu-rES/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-eu-rES/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-fa/config.xml b/packages/SystemUI/res/values-fa/config.xml
deleted file mode 100644
index a4a7ca2..0000000
--- a/packages/SystemUI/res/values-fa/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"۶۰۰۰۰:۱۰۰۰۰,۳۰۰۰۰۰:۳۰۰۰۰,۱۸۰۰۰۰۰:۶۰۰۰۰,۰"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 11e6241..7130c89 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -70,7 +70,7 @@
     <string name="screenshot_saving_title" msgid="8242282144535555697">"در حال ذخیره تصویر صفحه..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"تصویر صفحه ذخیره شد."</string>
     <string name="screenshot_saved_title" msgid="6461865960961414961">"تصویر صفحه گرفته شد."</string>
-    <string name="screenshot_saved_text" msgid="1152839647677558815">"برای مشاهده تصویر صفحه خود، لمس کنید."</string>
+    <string name="screenshot_saved_text" msgid="1152839647677558815">"برای مشاهده عکس صفحه‌نمایشتان، لمس کنید."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"تصویر صفحه گرفته نشد."</string>
     <string name="screenshot_failed_text" msgid="1260203058661337274">"به دلیل فضای ذخیره‌سازی کم یا عدم اجازه برنامه یا سازمانتان، نمی‌توان از صفحه عکس گرفت."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"‏گزینه‌های انتقال فایل USB"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/config.xml b/packages/SystemUI/res/values-fr-rCA/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-fr-rCA/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-fr/config.xml b/packages/SystemUI/res/values-fr/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-fr/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-gl-rES/config.xml b/packages/SystemUI/res/values-gl-rES/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-gl-rES/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index 68d3af4..c94e04f 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -301,9 +301,9 @@
     <string name="keyguard_unlock" msgid="8043466894212841998">"Pasa o dedo cara arriba para desbloquear"</string>
     <string name="phone_hint" msgid="3101468054914424646">"Pasa o dedo cara á dereita para acceder ao teléfono"</string>
     <string name="camera_hint" msgid="5241441720959174226">"Pasa o dedo cara á esquerda para abrir a cámara"</string>
-    <string name="interruption_level_none" msgid="3831278883136066646">"Nunca"</string>
+    <string name="interruption_level_none" msgid="3831278883136066646">"Ningún"</string>
     <string name="interruption_level_priority" msgid="6517366750688942030">"Prioridade"</string>
-    <string name="interruption_level_all" msgid="1330581184930945764">"Sempre"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Todas"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Cargando (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para finalizar a carga)"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Cambiar usuario"</string>
     <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Cambiar usuario, usuario actual: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-hi/config.xml b/packages/SystemUI/res/values-hi/config.xml
index 3a66eab..000d96f 100644
--- a/packages/SystemUI/res/values-hi/config.xml
+++ b/packages/SystemUI/res/values-hi/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1 से,10 से, 30 से, 60 से, 120 से"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/config.xml b/packages/SystemUI/res/values-hr/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-hr/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-hu/config.xml b/packages/SystemUI/res/values-hu/config.xml
index 3a66eab..f5ccf75 100644
--- a/packages/SystemUI/res/values-hu/config.xml
+++ b/packages/SystemUI/res/values-hu/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1, 10, 30, 60, 120"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index c84e380..9901c88 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -318,8 +318,8 @@
     <string name="guest_wipe_session_message" msgid="8476238178270112811">"Դուք ցանկանու՞մ եք շարունակել ձեր գործողությունը:"</string>
     <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"Սկսել"</string>
     <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"Այո, շարունակել"</string>
-    <string name="user_add_user_title" msgid="4553596395824132638">"Ավելացնե՞լ նոր օգտվող:"</string>
-    <string name="user_add_user_message_short" msgid="2161624834066214559">"Երբ նոր օգտվող եք ավելացնում, նա պետք է կարգավորի իր տարածքը:\n\nՑանկացած օգտվող կարող է թարմացնել ծրագրերը՝ մյուս բոլոր օգտվողների համար:"</string>
+    <string name="user_add_user_title" msgid="4553596395824132638">"Ավելացնե՞լ նոր պրոֆիլ:"</string>
+    <string name="user_add_user_message_short" msgid="2161624834066214559">"Երբ նոր օգտվող եք ավելացնում, նա պետք է կարգավորի իր պրոֆիլը:\n\nՑանկացած օգտվող կարող է թարմացնել հավելվածները մյուս բոլոր հաշիվների համար:"</string>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Մարտկոցի տնտեսումը միացված է"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"Նվազեցնում է ծանրաբեռնվածությունը և ֆոնային տվյալները"</string>
     <string name="battery_saver_notification_action_text" msgid="109158658238110382">"Անջատել մարտկոցի տնտեսումը"</string>
diff --git a/packages/SystemUI/res/values-in/config.xml b/packages/SystemUI/res/values-in/config.xml
index 3a66eab..2aa4b09 100644
--- a/packages/SystemUI/res/values-in/config.xml
+++ b/packages/SystemUI/res/values-in/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1dtk,10dtk,30dtk,60dtk,120dtk"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-is-rIS/config.xml b/packages/SystemUI/res/values-is-rIS/config.xml
index 3a66eab..46f7456 100644
--- a/packages/SystemUI/res/values-is-rIS/config.xml
+++ b/packages/SystemUI/res/values-is-rIS/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1 sek.,10 sek., 30 sek., 60 sek.,120 sek."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/config.xml b/packages/SystemUI/res/values-it/config.xml
index 3a66eab..f87a0a3 100644
--- a/packages/SystemUI/res/values-it/config.xml
+++ b/packages/SystemUI/res/values-it/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1 s, 10 s, 30 s, 60 s, 120 s"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/config.xml b/packages/SystemUI/res/values-iw/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-iw/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-ja/config.xml b/packages/SystemUI/res/values-ja/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-ja/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/config.xml b/packages/SystemUI/res/values-kk-rKZ/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-kk-rKZ/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-km-rKH/config.xml b/packages/SystemUI/res/values-km-rKH/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-km-rKH/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-kn-rIN/config.xml b/packages/SystemUI/res/values-kn-rIN/config.xml
index 3a66eab..4bbdea2 100644
--- a/packages/SystemUI/res/values-kn-rIN/config.xml
+++ b/packages/SystemUI/res/values-kn-rIN/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1s,10s,30s,60s,120s"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/config.xml b/packages/SystemUI/res/values-ky-rKG/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-ky-rKG/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-sl/config.xml b/packages/SystemUI/res/values-lt/config.xml
similarity index 87%
copy from packages/SystemUI/res/values-sl/config.xml
copy to packages/SystemUI/res/values-lt/config.xml
index cd49028..edfec94 100644
--- a/packages/SystemUI/res/values-sl/config.xml
+++ b/packages/SystemUI/res/values-lt/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000, 300000:30000, 1800000:60000, 0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1 sek., 10 sek., 30 sek., 60 sek., 120 sek."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/config.xml b/packages/SystemUI/res/values-lv/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-lv/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-sl/config.xml b/packages/SystemUI/res/values-mk-rMK/config.xml
similarity index 87%
rename from packages/SystemUI/res/values-sl/config.xml
rename to packages/SystemUI/res/values-mk-rMK/config.xml
index cd49028..024f528 100644
--- a/packages/SystemUI/res/values-sl/config.xml
+++ b/packages/SystemUI/res/values-mk-rMK/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000, 300000:30000, 1800000:60000, 0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1сек., 10 сек., 30 сек., 60 сек., 120 сек."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/config.xml b/packages/SystemUI/res/values-ml-rIN/config.xml
index 3a66eab..d2d29f9 100644
--- a/packages/SystemUI/res/values-ml-rIN/config.xml
+++ b/packages/SystemUI/res/values-ml-rIN/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1സെ,10സെ,30സെ,60സെ,120സെ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/config.xml b/packages/SystemUI/res/values-mn-rMN/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-mn-rMN/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index bc58845..7d53269 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -212,10 +212,8 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS байршил"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Байршлын хүсэлтүүд идэвхтэй"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Бүх мэдэгдлийг цэвэрлэх."</string>
-    <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
-    <skip />
-    <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
-    <skip />
+    <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Мэдэгдлийн тохиргоо"</string>
+    <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> тохиргоо"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Дэлгэц автоматаар эргэнэ."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Дэлгэц хэвтээ чиглэлд түгжигдсэн."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Дэлгэц босоо чиглэлээр түгжигдсэн."</string>
diff --git a/packages/SystemUI/res/values-mr-rIN/config.xml b/packages/SystemUI/res/values-mr-rIN/config.xml
index 3a66eab..4bbdea2 100644
--- a/packages/SystemUI/res/values-mr-rIN/config.xml
+++ b/packages/SystemUI/res/values-mr-rIN/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1s,10s,30s,60s,120s"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my-rMM/config.xml b/packages/SystemUI/res/values-my-rMM/config.xml
index 3a26007..805d893 100644
--- a/packages/SystemUI/res/values-my-rMM/config.xml
+++ b/packages/SystemUI/res/values-my-rMM/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"၆၀၀၀၀:၁၀၀၀၀၊ ၃၀၀၀၀၀:၃၀၀၀၀၊ ၁၈၀၀၀၀၀:၆၀၀၀၀,၀"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"၁စက္ကန့်၊ ၁၀စက္ကန့်၊ ၃၀စက္ကန့်၊ 60စက္ကန့်၊ ၁၂၀စက္ကန့်"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/config.xml b/packages/SystemUI/res/values-ne-rNP/config.xml
deleted file mode 100644
index 5fbf1d8..0000000
--- a/packages/SystemUI/res/values-ne-rNP/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"६००००:१००००,३०००००:३००००,  १८०००००:६००००,०"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-nl/config.xml b/packages/SystemUI/res/values-nl/config.xml
index 3a66eab..4bbdea2 100644
--- a/packages/SystemUI/res/values-nl/config.xml
+++ b/packages/SystemUI/res/values-nl/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1s,10s,30s,60s,120s"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/config.xml b/packages/SystemUI/res/values-pl/config.xml
index 3a66eab..f87a0a3 100644
--- a/packages/SystemUI/res/values-pl/config.xml
+++ b/packages/SystemUI/res/values-pl/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1 s, 10 s, 30 s, 60 s, 120 s"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/config.xml b/packages/SystemUI/res/values-pt-rPT/config.xml
index 3a66eab..f87a0a3 100644
--- a/packages/SystemUI/res/values-pt-rPT/config.xml
+++ b/packages/SystemUI/res/values-pt-rPT/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1 s, 10 s, 30 s, 60 s, 120 s"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/config.xml b/packages/SystemUI/res/values-pt/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-pt/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index d784317..4e8880e 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -314,7 +314,7 @@
     <string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"Ștergeți invitatul?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"Toate aplicațiile și datele din această sesiune vor fi șterse."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"Ștergeți"</string>
-    <string name="guest_wipe_session_title" msgid="6419439912885956132">"Welcome back, guest!"</string>
+    <string name="guest_wipe_session_title" msgid="6419439912885956132">"Bine ați revenit în sesiunea pentru invitați!"</string>
     <string name="guest_wipe_session_message" msgid="8476238178270112811">"Vreți să continuați sesiunea?"</string>
     <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"Începeți din nou"</string>
     <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"Da, continuați"</string>
diff --git a/packages/SystemUI/res/values-sk/config.xml b/packages/SystemUI/res/values-sk/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-sk/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-sr/config.xml b/packages/SystemUI/res/values-sr/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-sr/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-sv/config.xml b/packages/SystemUI/res/values-sv/config.xml
index 3a66eab..3b683a8 100644
--- a/packages/SystemUI/res/values-sv/config.xml
+++ b/packages/SystemUI/res/values-sv/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1 sek,10 sek, 30 sek, 60 sek,120 sek"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/config.xml b/packages/SystemUI/res/values-sw/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-sw/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-ta-rIN/config.xml b/packages/SystemUI/res/values-ta-rIN/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-ta-rIN/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-te-rIN/config.xml b/packages/SystemUI/res/values-te-rIN/config.xml
index 3a66eab..7a4c0cb 100644
--- a/packages/SystemUI/res/values-te-rIN/config.xml
+++ b/packages/SystemUI/res/values-te-rIN/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1సె,10సె,30సె,60సె,120సె"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/config.xml b/packages/SystemUI/res/values-th/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-th/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-tl/config.xml b/packages/SystemUI/res/values-tl/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-tl/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-uk/config.xml b/packages/SystemUI/res/values-uk/config.xml
index 3a66eab..3a6872f 100644
--- a/packages/SystemUI/res/values-uk/config.xml
+++ b/packages/SystemUI/res/values-uk/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1 с, 10 с, 30 с, 60 с, 120 с"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index dccf861..13fad3f 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -212,10 +212,8 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"‏مقام متعین کیا گیا بذریعہ GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"مقام کی درخواستیں فعال ہیں"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"سبھی اطلاعات صاف کریں۔"</string>
-    <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
-    <skip />
-    <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
-    <skip />
+    <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"اطلاع کی ترتیبات"</string>
+    <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ترتیبات"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"اسکرین خود بخود گردش کرے گی۔"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"اسکرین لینڈ اسکیپ سمت بندی میں مقفل ہے۔"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"اسکرین پورٹریٹ سمت بندی میں مقفل ہے۔"</string>
@@ -321,7 +319,7 @@
     <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"دوبارہ شروع کریں"</string>
     <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"ہاں، جاری رکھیں"</string>
     <string name="user_add_user_title" msgid="4553596395824132638">"نیا صارف شامل کریں؟"</string>
-    <string name="user_add_user_message_short" msgid="2161624834066214559">"جب آپ ایک نیا صارف شامل کرتے ہیں تو اس شخص کو اپنی جگہ کو ترتیب دینے کی ضرورت ہوتی ہے\n\nکوئی بھی صارف دیگر سبھی صارفین کیلئے ایپس کو اپ ڈیٹ کر سکتا ہے۔"</string>
+    <string name="user_add_user_message_short" msgid="2161624834066214559">"جب آپ ایک نیا صارف شامل کرتے ہیں تو اس شخص کو اپنی جگہ کو ترتیب دینے کی ضرورت ہوتی ہے۔\n\nکوئی بھی صارف دیگر سبھی صارفین کیلئے ایپس کو اپ ڈیٹ کر سکتا ہے۔"</string>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"بیٹری سیور آن ہے"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"کارکردگی اور پس منظر کا ڈیٹا کم کر دیتا ہے"</string>
     <string name="battery_saver_notification_action_text" msgid="109158658238110382">"بیٹری کی بچت آف کریں"</string>
diff --git a/packages/SystemUI/res/values-uz-rUZ/config.xml b/packages/SystemUI/res/values-uz-rUZ/config.xml
deleted file mode 100644
index 3a66eab..0000000
--- a/packages/SystemUI/res/values-uz-rUZ/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-zu/config.xml b/packages/SystemUI/res/values-zu/config.xml
index 3a66eab..4bbdea2 100644
--- a/packages/SystemUI/res/values-zu/config.xml
+++ b/packages/SystemUI/res/values-zu/config.xml
@@ -22,5 +22,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pulse_period_function" msgid="3632386860508136337">"60000:10000,300000:30000,1800000:60000,0"</string>
+    <string name="doze_pulse_schedule" msgid="1301215615981695214">"1s,10s,30s,60s,120s"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index d5b0f17..82dccd2 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -117,4 +117,10 @@
 
     <!-- The color of the navigation bar icons. Need to be in sync with ic_sysbar_* -->
     <color name="navigation_bar_icon_color">#E5FFFFFF</color>
+
+    <!-- Shadow color for the first pixels around the fake shadow for recents. -->
+    <color name="fake_shadow_start_color">#44000000</color>
+
+    <!-- Shadow color for the furthest pixels around the fake shadow for recents. -->
+    <color name="fake_shadow_end_color">#03000000</color>
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index a8c95c1..9346906 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -29,12 +29,22 @@
      ImageView -->
     <bool name="config_recents_thumbnail_image_fits_to_xy">false</bool>
 
+    <!-- Whether recents should use hardware layers for its taskviews. This flag can be enabled
+    for devices where the java drawing of round rects may be slow -->
+    <bool name="config_recents_use_hardware_layers">false</bool>
+
     <!-- The number of app thumbnails we keep in memory -->
     <integer name="config_recents_max_thumbnail_count">10</integer>
 
     <!-- The number of app icons we keep in memory -->
     <integer name="config_recents_max_icon_count">20</integer>
 
+    <!-- Whether to use cheap, less good looking shadows for recents -->
+    <bool name="config_recents_fake_shadows">false</bool>
+
+    <!-- The theme to use for RecentsActivity. -->
+    <item type="style" name="config_recents_activity_theme">@style/RecentsTheme.Wallpaper</item>
+
     <!-- Control whether status bar should distinguish HSPA data icon form UMTS
     data icon on devices -->
     <bool name="config_hspa_data_distinguishable">false</bool>
@@ -144,9 +154,12 @@
      duration of the transition in to recents from home. -->
     <integer name="recents_animate_task_enter_from_home_delay">150</integer>
     <!-- The min animation duration for animating the task in when transitioning from home. -->
-    <integer name="recents_animate_task_enter_from_home_duration">275</integer>
-    <!-- The animation stagger to apply to each task animation when transitioning from home. -->
-    <integer name="recents_animate_task_enter_from_home_stagger_delay">10</integer>
+    <integer name="recents_animate_task_enter_from_home_duration">200</integer>
+    <!-- The total animation stagger delay when entering from home. -->
+    <integer name="recents_animate_task_enter_from_home_stagger_delay">110</integer>
+    <!-- The total animation duration added to the last card when entering from home.
+    This value is partialy also added to the previous tasks -->
+    <integer name="recents_animate_task_enter_from_home_stagger_duration">72</integer>
     <!-- The short duration when animating in/out the lock to app button. -->
     <integer name="recents_animate_lock_to_app_button_short_duration">150</integer>
     <!-- The long duration when animating in/out the lock to app button. -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 8fe0af8..c690ef4 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -292,7 +292,7 @@
     <dimen name="unlock_falsing_threshold">80dp</dimen>
 
     <!-- Lockscreen falsing threshold for quick settings. -->
-    <dimen name="qs_falsing_threshold">80dp</dimen>
+    <dimen name="qs_falsing_threshold">40dp</dimen>
 
     <!-- Falsing threshold used when dismissing notifications from the lockscreen. -->
     <dimen name="swipe_helper_falsing_threshold">70dp</dimen>
@@ -452,10 +452,14 @@
     <!-- How far the user needs to drag up to invoke search. -->
     <dimen name="search_panel_threshold">100dp</dimen>
 
-    <!-- The width/height of the phone/camera/unlock icon on keyguard. -->
+    <!-- The width/height of the phone/camera/unlock icon view on keyguard. -->
     <dimen name="keyguard_affordance_height">56dp</dimen>
     <dimen name="keyguard_affordance_width">56dp</dimen>
 
+    <!-- The width/height of the phone/camera/unlock icon drawable on keyguard. -->
+    <dimen name="keyguard_affordance_icon_height">24dp</dimen>
+    <dimen name="keyguard_affordance_icon_width">24dp</dimen>
+
     <dimen name="keyguard_indication_margin_bottom">65dp</dimen>
 
     <!-- The text size for battery level -->
@@ -489,4 +493,13 @@
     <!-- Extra padding between the mobile data type icon and the strength indicator when the data
          type icon is wide for the tile in quick settings. -->
     <dimen name="wide_type_icon_start_padding_qs">3dp</dimen>
+
+    <!-- The maximum width of the navigation bar ripples. -->
+    <dimen name="key_button_ripple_max_width">95dp</dimen>
+    
+    <!-- Inset shadow for FakeShadowDrawable. It is used to avoid gaps between the card
+         and the shadow. -->
+    <dimen name="fake_shadow_inset">1dp</dimen>
+
+    <dimen name="fake_shadow_size">8dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/lland_config.xml b/packages/SystemUI/res/values/lland_config.xml
new file mode 100644
index 0000000..56125a5
--- /dev/null
+++ b/packages/SystemUI/res/values/lland_config.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources>
+    <dimen name="obstacle_spacing">380dp</dimen>
+    <dimen name="translation_per_sec">100dp</dimen>
+    <dimen name="boost_dv">600dp</dimen>
+    <dimen name="player_hit_size">40dp</dimen>
+    <dimen name="player_size">40dp</dimen>
+    <dimen name="obstacle_width">80dp</dimen>
+    <dimen name="obstacle_gap">170dp</dimen>
+    <dimen name="obstacle_height_min">40dp</dimen>
+    <dimen name="building_width_min">20dp</dimen>
+    <dimen name="building_width_max">250dp</dimen>
+    <dimen name="building_height_min">20dp</dimen>
+    <dimen name="cloud_size_min">10dp</dimen>
+    <dimen name="cloud_size_max">100dp</dimen>
+    <dimen name="sun_size">45dp</dimen>
+    <dimen name="moon_size">30dp</dimen>
+    <dimen name="star_size_min">3dp</dimen>
+    <dimen name="star_size_max">5dp</dimen>
+    <dimen name="G">30dp</dimen>
+    <dimen name="max_v">1000dp</dimen>
+    <dimen name="scenery_z">6dp</dimen>
+    <dimen name="obstacle_z">15dp</dimen>
+    <dimen name="player_z">15dp</dimen>
+    <dimen name="player_z_boost">18dp</dimen>
+    <dimen name="hud_z">35dp</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values/lland_strings.xml b/packages/SystemUI/res/values/lland_strings.xml
new file mode 100644
index 0000000..ce88157
--- /dev/null
+++ b/packages/SystemUI/res/values/lland_strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Name of the L Land easter egg. DO NOT TRANSLATE -->
+    <string name="lland">L Land</string>
+</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 0445fe8..e9a1acf 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -670,6 +670,8 @@
     <string name="recents_lock_to_app_button_label">lock to app</string>
     <!-- Recents: Temporary string for the button in the recents search bar. [CHAR LIMIT=NONE] -->
     <string name="recents_search_bar_label">search</string>
+    <!-- Recents: Launch error string. [CHAR LIMIT=NONE] -->
+    <string name="recents_launch_error_message">Could not start <xliff:g id="app" example="Calendar">%s</xliff:g>.</string>
 
 
     <!-- Expanded Status Bar Header: Battery Charged [CHAR LIMIT=40] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 0456c82..46e7587 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -20,14 +20,9 @@
         <item name="android:windowAnimationStyle">@style/Animation.RecentsActivity</item>
     </style>
 
-    <!-- Alternate Recents theme -->
     <style name="RecentsTheme" parent="@android:style/Theme">
         <!-- NoTitle -->
         <item name="android:windowNoTitle">true</item>
-        <!-- Wallpaper -->
-        <item name="android:windowBackground">@color/transparent</item>
-        <item name="android:colorBackgroundCacheHint">@null</item>
-        <item name="android:windowShowWallpaper">true</item>
         <!-- Misc -->
         <item name="android:statusBarColor">@android:color/transparent</item>
         <item name="android:navigationBarColor">@android:color/transparent</item>
@@ -36,6 +31,20 @@
         <item name="android:ambientShadowAlpha">0.35</item>
     </style>
 
+
+    <!-- Alternate Recents theme -->
+    <style name="RecentsTheme.Wallpaper">
+        <!-- Wallpaper -->
+        <item name="android:windowBackground">@color/transparent</item>
+        <item name="android:colorBackgroundCacheHint">@null</item>
+        <item name="android:windowShowWallpaper">true</item>
+    </style>
+
+    <!-- Performance optimized alternate Recents theme (no wallpaper) -->
+    <style name="RecentsTheme.NoWallpaper">
+        <item name="android:windowBackground">@android:color/black</item>
+    </style>
+
     <!-- Animations for a non-full-screen window or activity. -->
     <style name="Animation.RecentsActivity" parent="@android:style/Animation.Activity">
         <item name="android:activityOpenEnterAnimation">@anim/recents_launch_from_launcher_enter</item>
diff --git a/packages/SystemUI/src/com/android/systemui/egg/LLand.java b/packages/SystemUI/src/com/android/systemui/egg/LLand.java
new file mode 100644
index 0000000..d1c02dd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/egg/LLand.java
@@ -0,0 +1,748 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.egg;
+
+import android.animation.TimeAnimator;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.*;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.*;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+import com.android.systemui.R;
+
+public class LLand extends FrameLayout {
+    public static final String TAG = "LLand";
+
+    public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    public static final boolean DEBUG_DRAW = false && DEBUG;
+
+    public static final void L(String s, Object ... objects) {
+        if (DEBUG) {
+            Log.d(TAG, String.format(s, objects));
+        }
+    }
+
+    public static final boolean AUTOSTART = true;
+    public static final boolean HAVE_STARS = true;
+
+    public static final float DEBUG_SPEED_MULTIPLIER = 1f; // 0.1f;
+    public static final boolean DEBUG_IDDQD = false;
+
+    private static class Params {
+        public float TRANSLATION_PER_SEC;
+        public int OBSTACLE_SPACING, OBSTACLE_PERIOD;
+        public int BOOST_DV;
+        public int PLAYER_HIT_SIZE;
+        public int PLAYER_SIZE;
+        public int OBSTACLE_WIDTH;
+        public int OBSTACLE_GAP;
+        public int OBSTACLE_MIN;
+        public int BUILDING_WIDTH_MIN, BUILDING_WIDTH_MAX;
+        public int BUILDING_HEIGHT_MIN;
+        public int CLOUD_SIZE_MIN, CLOUD_SIZE_MAX;
+        public int STAR_SIZE_MIN, STAR_SIZE_MAX;
+        public int G;
+        public int MAX_V;
+            public float SCENERY_Z, OBSTACLE_Z, PLAYER_Z, PLAYER_Z_BOOST, HUD_Z;
+        public Params(Resources res) {
+            TRANSLATION_PER_SEC = res.getDimension(R.dimen.translation_per_sec);
+            OBSTACLE_SPACING = res.getDimensionPixelSize(R.dimen.obstacle_spacing);
+            OBSTACLE_PERIOD = (int) (OBSTACLE_SPACING / TRANSLATION_PER_SEC);
+            BOOST_DV = res.getDimensionPixelSize(R.dimen.boost_dv);
+            PLAYER_HIT_SIZE = res.getDimensionPixelSize(R.dimen.player_hit_size);
+            PLAYER_SIZE = res.getDimensionPixelSize(R.dimen.player_size);
+            OBSTACLE_WIDTH = res.getDimensionPixelSize(R.dimen.obstacle_width);
+            OBSTACLE_GAP = res.getDimensionPixelSize(R.dimen.obstacle_gap);
+            OBSTACLE_MIN = res.getDimensionPixelSize(R.dimen.obstacle_height_min);
+            BUILDING_HEIGHT_MIN = res.getDimensionPixelSize(R.dimen.building_height_min);
+            BUILDING_WIDTH_MIN = res.getDimensionPixelSize(R.dimen.building_width_min);
+            BUILDING_WIDTH_MAX = res.getDimensionPixelSize(R.dimen.building_width_max);
+            CLOUD_SIZE_MIN = res.getDimensionPixelSize(R.dimen.cloud_size_min);
+            CLOUD_SIZE_MAX = res.getDimensionPixelSize(R.dimen.cloud_size_max);
+            STAR_SIZE_MIN = res.getDimensionPixelSize(R.dimen.star_size_min);
+            STAR_SIZE_MAX = res.getDimensionPixelSize(R.dimen.star_size_max);
+
+            G = res.getDimensionPixelSize(R.dimen.G);
+            MAX_V = res.getDimensionPixelSize(R.dimen.max_v);
+
+            SCENERY_Z = res.getDimensionPixelSize(R.dimen.scenery_z);
+            OBSTACLE_Z = res.getDimensionPixelSize(R.dimen.obstacle_z);
+            PLAYER_Z = res.getDimensionPixelSize(R.dimen.player_z);
+            PLAYER_Z_BOOST = res.getDimensionPixelSize(R.dimen.player_z_boost);
+            HUD_Z = res.getDimensionPixelSize(R.dimen.hud_z);
+        }
+    }
+
+    private TimeAnimator mAnim;
+
+    private TextView mScoreField;
+    private View mSplash;
+
+    private Player mDroid;
+    private ArrayList<Obstacle> mObstaclesInPlay = new ArrayList<Obstacle>();
+
+    private float t, dt;
+
+    private int mScore;
+    private float mLastPipeTime; // in sec
+    private int mWidth, mHeight;
+    private boolean mAnimating, mPlaying;
+    private boolean mFrozen; // after death, a short backoff
+
+    private int mTimeOfDay;
+    private static final int DAY = 0, NIGHT = 1, TWILIGHT = 2, SUNSET = 3;
+    private static final int[][] SKIES = {
+            { 0xFFc0c0FF, 0xFFa0a0FF }, // DAY
+            { 0xFF000010, 0xFF000000 }, // NIGHT
+            { 0xFF000040, 0xFF000010 }, // TWILIGHT
+            { 0xFF805010, 0xFF202080 }, // SUNSET
+    };
+
+    private static Params PARAMS;
+
+    public LLand(Context context) {
+        this(context, null);
+    }
+
+    public LLand(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public LLand(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        setFocusable(true);
+        PARAMS = new Params(getResources());
+        mTimeOfDay = irand(0, SKIES.length);
+    }
+
+    @Override
+    public boolean willNotDraw() {
+        return !DEBUG;
+    }
+
+    public int getGameWidth() { return mWidth; }
+    public int getGameHeight() { return mHeight; }
+    public float getGameTime() { return t; }
+    public float getLastTimeStep() { return dt; }
+
+    public void setScoreField(TextView tv) {
+        mScoreField = tv;
+        if (tv != null) {
+            tv.setTranslationZ(PARAMS.HUD_Z);
+            if (!(mAnimating && mPlaying)) {
+                tv.setTranslationY(-500);
+            }
+        }
+    }
+
+    public void setSplash(View v) {
+        mSplash = v;
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        stop();
+        reset();
+        if (AUTOSTART) {
+            start(false);
+        }
+    }
+
+    final float hsv[] = {0, 0, 0};
+
+    private void reset() {
+        L("reset");
+        final Drawable sky = new GradientDrawable(
+                GradientDrawable.Orientation.BOTTOM_TOP,
+                SKIES[mTimeOfDay]
+        );
+        sky.setDither(true);
+        setBackground(sky);
+
+        setScaleX(frand() > 0.5f ? 1 : -1);
+
+        setScore(0);
+
+        int i = getChildCount();
+        while (i-->0) {
+            final View v = getChildAt(i);
+            if (v instanceof GameView) {
+                removeViewAt(i);
+            }
+        }
+
+        mObstaclesInPlay.clear();
+
+        mWidth = getWidth();
+        mHeight = getHeight();
+
+        boolean showingSun = (mTimeOfDay == DAY || mTimeOfDay == SUNSET) && frand() > 0.25;
+        if (showingSun) {
+            final Star sun = new Star(getContext());
+            sun.setBackgroundResource(R.drawable.sun);
+            final int w = getResources().getDimensionPixelSize(R.dimen.sun_size);
+            sun.setTranslationX(frand(w, mWidth-w));
+            if (mTimeOfDay == DAY) {
+                sun.setTranslationY(frand(w, (mHeight * 0.66f)));
+                sun.getBackground().setTint(0);
+            } else {
+                sun.setTranslationY(frand(mHeight * 0.66f, mHeight - w));
+                sun.getBackground().setTintMode(PorterDuff.Mode.SRC_ATOP);
+                sun.getBackground().setTint(0xC0FF8000);
+
+            }
+            addView(sun, new LayoutParams(w, w));
+        }
+        if (!showingSun) {
+            final boolean dark = mTimeOfDay == NIGHT || mTimeOfDay == TWILIGHT;
+            final float ff = frand();
+            if ((dark && ff < 0.75f) || ff < 0.5f) {
+                final Star moon = new Star(getContext());
+                moon.setBackgroundResource(R.drawable.moon);
+                moon.getBackground().setAlpha(dark ? 255 : 128);
+                moon.setScaleX(frand() > 0.5 ? -1 : 1);
+                moon.setRotation(moon.getScaleX() * frand(5, 30));
+                final int w = getResources().getDimensionPixelSize(R.dimen.sun_size);
+                moon.setTranslationX(frand(w, mWidth - w));
+                moon.setTranslationY(frand(w, mHeight - w));
+                addView(moon, new LayoutParams(w, w));
+            }
+        }
+
+        final int mh = mHeight / 6;
+        final boolean cloudless = frand() < 0.25;
+        final int N = 20;
+        for (i=0; i<N; i++) {
+            final float r1 = frand();
+            final Scenery s;
+            if (HAVE_STARS && r1 < 0.3 && mTimeOfDay != DAY) {
+                s = new Star(getContext());
+            } else if (r1 < 0.6 && !cloudless) {
+                s = new Cloud(getContext());
+            } else {
+                s = new Building(getContext());
+
+                s.z = (float)i/N;
+                s.setTranslationZ(PARAMS.SCENERY_Z * (1+s.z));
+                s.v = 0.85f * s.z; // buildings move proportional to their distance
+                hsv[0] = 175;
+                hsv[1] = 0.25f;
+                hsv[2] = 1 * s.z;
+                s.setBackgroundColor(Color.HSVToColor(hsv));
+                s.h = irand(PARAMS.BUILDING_HEIGHT_MIN, mh);
+            }
+            final LayoutParams lp = new LayoutParams(s.w, s.h);
+            if (s instanceof Building) {
+                lp.gravity = Gravity.BOTTOM;
+            } else {
+                lp.gravity = Gravity.TOP;
+                final float r = frand();
+                if (s instanceof Star) {
+                    lp.topMargin = (int) (r * r * mHeight);
+                } else {
+                    lp.topMargin = (int) (1 - r*r * mHeight/2) + mHeight/2;
+                }
+            }
+
+            addView(s, lp);
+            s.setTranslationX(frand(-lp.width, mWidth + lp.width));
+        }
+
+        mDroid = new Player(getContext());
+        mDroid.setX(mWidth / 2);
+        mDroid.setY(mHeight / 2);
+        addView(mDroid, new LayoutParams(PARAMS.PLAYER_SIZE, PARAMS.PLAYER_SIZE));
+        if (mAnim != null) {
+            Log.wtf(TAG, "reseting while animating??!?");
+        }
+        mAnim = new TimeAnimator();
+        mAnim.setTimeListener(new TimeAnimator.TimeListener() {
+            @Override
+            public void onTimeUpdate(TimeAnimator timeAnimator, long t, long dt) {
+                step(t, dt);
+            }
+        });
+    }
+
+    private void setScore(int score) {
+        mScore = score;
+        if (mScoreField != null) mScoreField.setText(String.valueOf(score));
+    }
+
+    private void addScore(int incr) {
+        setScore(mScore + incr);
+    }
+
+    private void start(boolean startPlaying) {
+        L("start(startPlaying=%s)", startPlaying?"true":"false");
+        if (startPlaying) {
+            mPlaying = true;
+
+            t = 0;
+            mLastPipeTime = getGameTime() - PARAMS.OBSTACLE_PERIOD; // queue up a obstacle
+
+            if (mSplash != null && mSplash.getAlpha() > 0f) {
+                mSplash.setTranslationZ(PARAMS.HUD_Z);
+                mSplash.animate().alpha(0).translationZ(0).setDuration(400);
+
+                mScoreField.animate().translationY(0)
+                        .setInterpolator(new DecelerateInterpolator())
+                        .setDuration(1500);
+            }
+
+            mScoreField.setTextColor(0xFFAAAAAA);
+            mScoreField.setBackgroundResource(R.drawable.scorecard);
+            mDroid.setVisibility(View.VISIBLE);
+            mDroid.setX(mWidth / 2);
+            mDroid.setY(mHeight / 2);
+        } else {
+            mDroid.setVisibility(View.GONE);
+        }
+        if (!mAnimating) {
+            mAnim.start();
+            mAnimating = true;
+        }
+    }
+
+    private void stop() {
+        if (mAnimating) {
+            mAnim.cancel();
+            mAnim = null;
+            mAnimating = false;
+            mScoreField.setTextColor(0xFFFFFFFF);
+            mScoreField.setBackgroundResource(R.drawable.scorecard_gameover);
+            mTimeOfDay = irand(0, SKIES.length); // for next reset
+            mFrozen = true;
+            postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        mFrozen = false;
+                    }
+                }, 250);
+        }
+    }
+
+    public static final float lerp(float x, float a, float b) {
+        return (b - a) * x + a;
+    }
+
+    public static final float rlerp(float v, float a, float b) {
+        return (v - a) / (b - a);
+    }
+
+    public static final float clamp(float f) {
+        return f < 0f ? 0f : f > 1f ? 1f : f;
+    }
+
+    public static final float frand() {
+        return (float) Math.random();
+    }
+
+    public static final float frand(float a, float b) {
+        return lerp(frand(), a, b);
+    }
+
+    public static final int irand(int a, int b) {
+        return (int) lerp(frand(), (float) a, (float) b);
+    }
+
+    private void step(long t_ms, long dt_ms) {
+        t = t_ms / 1000f; // seconds
+        dt = dt_ms / 1000f;
+
+        if (DEBUG) {
+            t *= DEBUG_SPEED_MULTIPLIER;
+            dt *= DEBUG_SPEED_MULTIPLIER;
+        }
+
+        // 1. Move all objects and update bounds
+        final int N = getChildCount();
+        int i = 0;
+        for (; i<N; i++) {
+            final View v = getChildAt(i);
+            if (v instanceof GameView) {
+                ((GameView) v).step(t_ms, dt_ms, t, dt);
+            }
+        }
+
+        // 2. Check for altitude
+        if (mPlaying && mDroid.below(mHeight)) {
+            if (DEBUG_IDDQD) {
+                poke();
+            } else {
+                L("player hit the floor");
+                stop();
+            }
+        }
+
+        // 3. Check for obstacles
+        boolean passedBarrier = false;
+        for (int j = mObstaclesInPlay.size(); j-->0;) {
+            final Obstacle ob = mObstaclesInPlay.get(j);
+            if (mPlaying && ob.intersects(mDroid) && !DEBUG_IDDQD) {
+                L("player hit an obstacle");
+                stop();
+            } else if (ob.cleared(mDroid)) {
+                passedBarrier = true;
+                mObstaclesInPlay.remove(j);
+            }
+        }
+
+        if (mPlaying && passedBarrier) {
+            addScore(1);
+        }
+
+        // 4. Handle edge of screen
+        // Walk backwards to make sure removal is safe
+        while (i-->0) {
+            final View v = getChildAt(i);
+            if (v instanceof Obstacle) {
+                if (v.getTranslationX() + v.getWidth() < 0) {
+                    removeViewAt(i);
+                }
+            } else if (v instanceof Scenery) {
+                final Scenery s = (Scenery) v;
+                if (v.getTranslationX() + s.w < 0) {
+                    v.setTranslationX(getWidth());
+                }
+            }
+        }
+
+        // 3. Time for more obstacles!
+        if (mPlaying && (t - mLastPipeTime) > PARAMS.OBSTACLE_PERIOD) {
+            mLastPipeTime = t;
+            final int obstacley = (int) (Math.random()
+                    * (mHeight - 2*PARAMS.OBSTACLE_MIN - PARAMS.OBSTACLE_GAP)) + PARAMS.OBSTACLE_MIN;
+
+            final Obstacle p1 = new Obstacle(getContext(), obstacley);
+            addView(p1, new LayoutParams(
+                    PARAMS.OBSTACLE_WIDTH,
+                    mHeight,
+                    Gravity.TOP|Gravity.LEFT));
+            p1.setTranslationX(mWidth);
+            p1.setTranslationY(-mHeight);
+            p1.setTranslationZ(0);
+            p1.animate()
+                    .translationY(-mHeight+p1.h)
+                    .translationZ(PARAMS.OBSTACLE_Z)
+                    .setStartDelay(irand(0,250))
+                    .setDuration(250);
+            mObstaclesInPlay.add(p1);
+
+            final Obstacle p2 = new Obstacle(getContext(),
+                    mHeight - obstacley - PARAMS.OBSTACLE_GAP);
+            addView(p2, new LayoutParams(
+                    PARAMS.OBSTACLE_WIDTH,
+                    mHeight,
+                    Gravity.TOP|Gravity.LEFT));
+            p2.setTranslationX(mWidth);
+            p2.setTranslationY(mHeight);
+            p2.setTranslationZ(0);
+            p2.animate()
+                    .translationY(mHeight-p2.h)
+                    .translationZ(PARAMS.OBSTACLE_Z)
+                    .setStartDelay(irand(0,100))
+                    .setDuration(400);
+            mObstaclesInPlay.add(p2);
+        }
+
+        if (DEBUG) {
+            final Rect r = new Rect();
+            mDroid.getHitRect(r);
+            r.inset(-4, -4);
+            invalidate(r);
+        }
+    }
+    
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if (DEBUG) L("touch: %s", ev);
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            poke();
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onTrackballEvent(MotionEvent ev) {
+        if (DEBUG) L("trackball: %s", ev);
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            poke();
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent ev) {
+        if (DEBUG) L("keyDown: %d", keyCode);
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_DPAD_CENTER:
+            case KeyEvent.KEYCODE_DPAD_UP:
+            case KeyEvent.KEYCODE_SPACE:
+            case KeyEvent.KEYCODE_ENTER:
+            case KeyEvent.KEYCODE_BUTTON_A:
+                poke();
+                return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onGenericMotionEvent (MotionEvent ev) {
+        if (DEBUG) L("generic: %s", ev);
+        return false;
+    }
+
+    private void poke() {
+        L("poke");
+        if (mFrozen) return;
+        if (!mAnimating) {
+            reset();
+            start(true);
+        } else if (!mPlaying) {
+            start(true);
+        }
+        mDroid.boost();
+        if (DEBUG) {
+            mDroid.dv *= DEBUG_SPEED_MULTIPLIER;
+            mDroid.animate().setDuration((long) (200/DEBUG_SPEED_MULTIPLIER));
+        }
+    }
+
+    @Override
+    public void onDraw(Canvas c) {
+        super.onDraw(c);
+
+        if (!DEBUG_DRAW) return;
+
+        final Paint pt = new Paint();
+        pt.setColor(0xFFFFFFFF);
+        final int L = mDroid.corners.length;
+        final int N = L/2;
+        for (int i=0; i<N; i++) {
+            final int x = (int) mDroid.corners[i*2];
+            final int y = (int) mDroid.corners[i*2+1];
+            c.drawCircle(x, y, 4, pt);
+            c.drawLine(x, y,
+                    mDroid.corners[(i*2+2)%L],
+                    mDroid.corners[(i*2+3)%L],
+                    pt);
+        }
+
+        final int M = getChildCount();
+        pt.setColor(0x6000FF00);
+        for (int i=0; i<M; i++) {
+            final View v = getChildAt(i);
+            if (v == mDroid) continue;
+            if (!(v instanceof GameView)) continue;
+            final Rect r = new Rect();
+            v.getHitRect(r);
+            c.drawRect(r, pt);
+        }
+
+        pt.setColor(Color.BLACK);
+        final StringBuilder sb = new StringBuilder("obstacles: ");
+        for (Obstacle ob : mObstaclesInPlay) {
+            sb.append(ob.hitRect.toShortString());
+            sb.append(" ");
+        }
+        pt.setTextSize(20f);
+        c.drawText(sb.toString(), 20, 100, pt);
+    }
+
+    static final Rect sTmpRect = new Rect();
+
+    private interface GameView {
+        public void step(long t_ms, long dt_ms, float t, float dt);
+    }
+
+    private class Player extends ImageView implements GameView {
+        public float dv;
+
+        private final float[] sHull = new float[] {
+                0.3f,  0f,    // left antenna
+                0.7f,  0f,    // right antenna
+                0.92f, 0.33f, // off the right shoulder of Orion
+                0.92f, 0.75f, // right hand (our right, not his right)
+                0.6f,  1f,    // right foot
+                0.4f,  1f,    // left foot BLUE!
+                0.08f, 0.75f, // sinistram
+                0.08f, 0.33f,  // cold shoulder
+        };
+        public final float[] corners = new float[sHull.length];
+
+        public Player(Context context) {
+            super(context);
+
+            setBackgroundResource(R.drawable.android);
+            getBackground().setTintMode(PorterDuff.Mode.SRC_ATOP);
+            getBackground().setTint(0xFF00FF00);
+            setOutlineProvider(new ViewOutlineProvider() {
+                @Override
+                public void getOutline(View view, Outline outline) {
+                    final int w = view.getWidth();
+                    final int h = view.getHeight();
+                    final int ix = (int) (w * 0.3f);
+                    final int iy = (int) (h * 0.2f);
+                    outline.setRect(ix, iy, w - ix, h - iy);
+                }
+            });
+        }
+
+        public void prepareCheckIntersections() {
+            final int inset = (PARAMS.PLAYER_SIZE - PARAMS.PLAYER_HIT_SIZE)/2;
+            final int scale = PARAMS.PLAYER_HIT_SIZE;
+            final int N = sHull.length/2;
+            for (int i=0; i<N; i++) {
+                corners[i*2]   = scale * sHull[i*2]   + inset;
+                corners[i*2+1] = scale * sHull[i*2+1] + inset;
+            }
+            final Matrix m = getMatrix();
+            m.mapPoints(corners);
+        }
+
+        public boolean below(int h) {
+            final int N = corners.length/2;
+            for (int i=0; i<N; i++) {
+                final int y = (int) corners[i*2+1];
+                if (y >= h) return true;
+            }
+            return false;
+        }
+
+        public void step(long t_ms, long dt_ms, float t, float dt) {
+            if (getVisibility() != View.VISIBLE) return; // not playing yet
+
+            dv += PARAMS.G;
+            if (dv < -PARAMS.MAX_V) dv = -PARAMS.MAX_V;
+            else if (dv > PARAMS.MAX_V) dv = PARAMS.MAX_V;
+
+            final float y = getTranslationY() + dv * dt;
+            setTranslationY(y < 0 ? 0 : y);
+            setRotation(
+                    90 + lerp(clamp(rlerp(dv, PARAMS.MAX_V, -1 * PARAMS.MAX_V)), 90, -90));
+
+            prepareCheckIntersections();
+        }
+
+        public void boost() {
+            dv = -PARAMS.BOOST_DV;
+            setTranslationZ(PARAMS.PLAYER_Z_BOOST);
+            setScaleX(1.25f);
+            setScaleY(1.25f);
+            animate()
+                .scaleX(1f)
+                .scaleY(1f)
+                .translationZ(PARAMS.PLAYER_Z)
+                .setDuration(200);
+        }
+    }
+
+    private class Obstacle extends View implements GameView {
+        public float h;
+
+        public final Rect hitRect = new Rect();
+
+        public Obstacle(Context context, float h) {
+            super(context);
+            setBackgroundResource(R.drawable.placeholder);
+            this.h = h;
+        }
+
+        public boolean intersects(Player p) {
+            final int N = p.corners.length/2;
+            for (int i=0; i<N; i++) {
+                final int x = (int) p.corners[i*2];
+                final int y = (int) p.corners[i*2+1];
+                if (hitRect.contains(x, y)) return true;
+            }
+            return false;
+        }
+
+        public boolean cleared(Player p) {
+            final int N = p.corners.length/2;
+            for (int i=0; i<N; i++) {
+                final int x = (int) p.corners[i*2];
+                if (hitRect.right >= x) return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void step(long t_ms, long dt_ms, float t, float dt) {
+            setTranslationX(getTranslationX()-PARAMS.TRANSLATION_PER_SEC*dt);
+            getHitRect(hitRect);
+        }
+    }
+
+    private class Scenery extends FrameLayout implements GameView {
+        public float z;
+        public float v;
+        public int h, w;
+        public Scenery(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void step(long t_ms, long dt_ms, float t, float dt) {
+            setTranslationX(getTranslationX() - PARAMS.TRANSLATION_PER_SEC * dt * v);
+        }
+    }
+
+    private class Building extends Scenery {
+        public Building(Context context) {
+            super(context);
+
+            w = irand(PARAMS.BUILDING_WIDTH_MIN, PARAMS.BUILDING_WIDTH_MAX);
+            h = 0; // will be setup later, along with z
+
+            setTranslationZ(PARAMS.SCENERY_Z);
+        }
+    }
+
+    private class Cloud extends Scenery {
+        public Cloud(Context context) {
+            super(context);
+            setBackgroundResource(frand() < 0.01f ? R.drawable.cloud_off : R.drawable.cloud);
+            getBackground().setAlpha(0x40);
+            w = h = irand(PARAMS.CLOUD_SIZE_MIN, PARAMS.CLOUD_SIZE_MAX);
+            z = 0;
+            v = frand(0.15f,0.5f);
+        }
+    }
+
+    private class Star extends Scenery {
+        public Star(Context context) {
+            super(context);
+            setBackgroundResource(R.drawable.star);
+            w = h = irand(PARAMS.STAR_SIZE_MIN, PARAMS.STAR_SIZE_MAX);
+            v = z = 0;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/egg/LLandActivity.java b/packages/SystemUI/src/com/android/systemui/egg/LLandActivity.java
new file mode 100644
index 0000000..88fd952
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/egg/LLandActivity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.egg;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+
+public class LLandActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.lland);
+        LLand world = (LLand) findViewById(R.id.world);
+        world.setScoreField((TextView) findViewById(R.id.score));
+        world.setSplash(findViewById(R.id.welcome));
+        Log.v(LLand.TAG, "focus: " + world.requestFocus());
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 9af893d..4af8499 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -170,6 +170,8 @@
     private boolean mSwitchingUser;
 
     private boolean mSystemReady;
+    private boolean mBootCompleted;
+    private boolean mBootSendUserPresent;
 
     // Whether the next call to playSounds() should be skipped.  Defaults to
     // true because the first lock (on boot) should be silent.
@@ -1145,8 +1147,14 @@
     }
 
     private void sendUserPresentBroadcast() {
-        final UserHandle currentUser = new UserHandle(mLockPatternUtils.getCurrentUser());
-        mContext.sendBroadcastAsUser(USER_PRESENT_INTENT, currentUser);
+        synchronized (this) {
+            if (mBootCompleted) {
+                final UserHandle currentUser = new UserHandle(mLockPatternUtils.getCurrentUser());
+                mContext.sendBroadcastAsUser(USER_PRESENT_INTENT, currentUser);
+            } else {
+                mBootSendUserPresent = true;
+            }
+        }
     }
 
     /**
@@ -1406,6 +1414,12 @@
 
     public void onBootCompleted() {
         mUpdateMonitor.dispatchBootCompleted();
+        synchronized (this) {
+            mBootCompleted = true;
+            if (mBootSendUserPresent) {
+                sendUserPresentBroadcast();
+            }
+        }
     }
 
     public StatusBarKeyguardViewManager registerStatusBar(PhoneStatusBar phoneStatusBar,
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index 787de4e..5caf1ac 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -19,6 +19,7 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
+import android.appwidget.AppWidgetHost;
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
@@ -32,6 +33,7 @@
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.UserHandle;
+import android.util.Pair;
 import android.view.LayoutInflater;
 import android.view.View;
 import com.android.systemui.R;
@@ -118,6 +120,22 @@
         // Load the header bar layout
         reloadHeaderBarLayout();
         mBootCompleted = true;
+
+        // Try and pre-emptively bind the search widget on startup to ensure that we
+        // have the right thumbnail bounds to animate to.
+        if (Constants.DebugFlags.App.EnableSearchLayout) {
+            // If there is no id, then bind a new search app widget
+            if (mConfig.searchBarAppWidgetId < 0) {
+                AppWidgetHost host = new RecentsAppWidgetHost(mContext,
+                        Constants.Values.App.AppWidgetHostId);
+                Pair<Integer, AppWidgetProviderInfo> widgetInfo =
+                        mSystemServicesProxy.bindSearchAppWidget(host);
+                if (widgetInfo != null) {
+                    // Save the app widget id into the settings
+                    mConfig.updateSearchBarAppWidgetId(mContext, widgetInfo.first);
+                }
+            }
+        }
     }
 
     /** Shows the recents */
@@ -222,9 +240,8 @@
             // Bring an active task to the foreground
             mSystemServicesProxy.moveTaskToFront(toTask.key.id, launchOpts);
         } else {
-            try {
-                mSystemServicesProxy.startActivityFromRecents(toTask.key.id, launchOpts);
-            } catch (ActivityNotFoundException anfe) {}
+            mSystemServicesProxy.startActivityFromRecents(mContext, toTask.key.id,
+                    toTask.activityLabel, launchOpts);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index 52ec54b..103f96f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -32,15 +32,13 @@
             // Enables the filtering of tasks according to their grouping
             public static final boolean EnableTaskFiltering = false;
             // Enables clipping of tasks against each other
-            public static final boolean EnableTaskStackClipping = false;
+            public static final boolean EnableTaskStackClipping = true;
             // Enables tapping on the TaskBar to launch the task
             public static final boolean EnableTaskBarTouchEvents = true;
             // Enables app-info pane on long-pressing the icon
             public static final boolean EnableDevAppInfoOnLongPress = true;
             // Enables the search bar layout
             public static final boolean EnableSearchLayout = true;
-            // Enables the dynamic shadows behind each task
-            public static final boolean EnableShadows = true;
             // Enables the thumbnail alpha on the front-most task
             public static final boolean EnableThumbnailAlphaOnFrontmost = false;
             // This disables the bitmap and icon caches
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 8f92027..a49bbf9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -405,6 +405,22 @@
             mConfig.updateOnConfigurationChange();
             onConfigurationChange();
         }
+
+        // Start listening for widget package changes if there is one bound, post it since we don't
+        // want it stalling the startup
+        if (mConfig.searchBarAppWidgetId >= 0) {
+            final WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks> callback =
+                    new WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks>(this);
+            mRecentsView.post(new Runnable() {
+                @Override
+                public void run() {
+                    RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks cb = callback.get();
+                    if (cb != null) {
+                        mAppWidgetHost.startListening(cb);
+                    }
+                }
+            });
+        }
     }
 
     /** Inflates the debug overlay if debug mode is enabled. */
@@ -464,22 +480,6 @@
     protected void onResume() {
         super.onResume();
 
-        // Start listening for widget package changes if there is one bound, post it since we don't
-        // want it stalling the startup
-        if (mConfig.searchBarAppWidgetId >= 0) {
-            final WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks> callback =
-                    new WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks>(this);
-            mRecentsView.postDelayed(new Runnable() {
-                @Override
-                public void run() {
-                    RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks cb = callback.get();
-                    if (cb != null) {
-                        mAppWidgetHost.startListening(cb);
-                    }
-                }
-            }, 1);
-        }
-
         // Mark Recents as visible
         mVisible = true;
     }
@@ -496,11 +496,6 @@
 
         // Unregister any broadcast receivers for the task loader
         RecentsTaskLoader.getInstance().unregisterReceivers();
-
-        // Stop listening for widget package changes if there was one bound
-        if (mAppWidgetHost.isListening()) {
-            mAppWidgetHost.stopListening();
-        }
     }
 
     @Override
@@ -509,6 +504,11 @@
 
         // Unregister the system broadcast receivers
         unregisterReceiver(mSystemBroadcastReceiver);
+
+        // Stop listening for widget package changes if there was one bound
+        if (mAppWidgetHost.isListening()) {
+            mAppWidgetHost.stopListening();
+        }
     }
 
     @Override
@@ -614,6 +614,12 @@
     }
 
     @Override
+    public void onTaskLaunchFailed() {
+        // Return to Home
+        dismissRecentsToHomeRaw(true);
+    }
+
+    @Override
     public void onAllTaskViewsDismissed() {
         mFinishLaunchHomeRunnable.run();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 2a2caa0..4696c82 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -78,6 +78,7 @@
     public int taskViewEnterFromHomeDelay;
     public int taskViewEnterFromHomeDuration;
     public int taskViewEnterFromHomeStaggerDelay;
+    public int taskViewEnterFromHomeStaggerDuration;
     public int taskViewExitToHomeDuration;
     public int taskViewRemoveAnimDuration;
     public int taskViewRemoveAnimTranslationXPx;
@@ -119,7 +120,9 @@
     public int launchedToTaskId;
 
     /** Misc **/
+    public boolean useHardwareLayers;
     public int altTabKeyDelay;
+    public boolean fakeShadows;
 
     /** Dev options and global settings */
     public boolean lockToAppEnabled;
@@ -217,6 +220,8 @@
                 res.getInteger(R.integer.recents_animate_task_enter_from_home_duration);
         taskViewEnterFromHomeStaggerDelay =
                 res.getInteger(R.integer.recents_animate_task_enter_from_home_stagger_delay);
+        taskViewEnterFromHomeStaggerDuration =
+                res.getInteger(R.integer.recents_animate_task_enter_from_home_stagger_duration);
         taskViewExitToHomeDuration =
                 res.getInteger(R.integer.recents_animate_task_exit_to_home_duration);
         taskViewRemoveAnimDuration =
@@ -271,7 +276,9 @@
                 res.getInteger(R.integer.recents_nav_bar_scrim_enter_duration);
 
         // Misc
+        useHardwareLayers = res.getBoolean(R.bool.config_recents_use_hardware_layers);
         altTabKeyDelay = res.getInteger(R.integer.recents_alt_tab_key_delay);
+        fakeShadows = res.getBoolean(R.bool.config_recents_fake_shadows);
     }
 
     /** Updates the system insets */
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 11b7b8b..9554f01 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -57,6 +57,7 @@
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
+import com.android.systemui.R;
 import com.android.systemui.recents.Constants;
 
 import java.io.IOException;
@@ -515,12 +516,18 @@
         return takeScreenshot();
     }
 
-    public void startActivityFromRecents(int taskId, ActivityOptions options) {
+    /** Starts an activity from recents. */
+    public boolean startActivityFromRecents(Context context, int taskId, String taskName,
+            ActivityOptions options) {
         if (mIam != null) {
             try {
                 mIam.startActivityFromRecents(taskId, options == null ? null : options.toBundle());
-            } catch (RemoteException e) {
+                return true;
+            } catch (Exception e) {
+                Console.logError(context,
+                        context.getString(R.string.recents_launch_error_message, taskName));
             }
         }
+        return false;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
index 4c6b389..f01d17c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
@@ -18,11 +18,14 @@
 
 import android.content.Intent;
 import android.graphics.Color;
+import android.graphics.Matrix;
 import android.graphics.Rect;
+import android.view.View;
 import com.android.systemui.recents.RecentsConfiguration;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
 
 /* Common code */
 public class Utilities {
@@ -68,6 +71,80 @@
         }
     }
 
+    /** Maps a coorindate in a descendant view into the parent. */
+    public static float mapCoordInDescendentToSelf(View descendant, View root,
+            float[] coord, boolean includeRootScroll) {
+        ArrayList<View> ancestorChain = new ArrayList<View>();
+
+        float[] pt = {coord[0], coord[1]};
+
+        View v = descendant;
+        while(v != root && v != null) {
+            ancestorChain.add(v);
+            v = (View) v.getParent();
+        }
+        ancestorChain.add(root);
+
+        float scale = 1.0f;
+        int count = ancestorChain.size();
+        for (int i = 0; i < count; i++) {
+            View v0 = ancestorChain.get(i);
+            // For TextViews, scroll has a meaning which relates to the text position
+            // which is very strange... ignore the scroll.
+            if (v0 != descendant || includeRootScroll) {
+                pt[0] -= v0.getScrollX();
+                pt[1] -= v0.getScrollY();
+            }
+
+            v0.getMatrix().mapPoints(pt);
+            pt[0] += v0.getLeft();
+            pt[1] += v0.getTop();
+            scale *= v0.getScaleX();
+        }
+
+        coord[0] = pt[0];
+        coord[1] = pt[1];
+        return scale;
+    }
+
+    /** Maps a coordinate in the root to a descendent. */
+    public static float mapCoordInSelfToDescendent(View descendant, View root,
+            float[] coord, Matrix tmpInverseMatrix) {
+        ArrayList<View> ancestorChain = new ArrayList<View>();
+
+        float[] pt = {coord[0], coord[1]};
+
+        View v = descendant;
+        while(v != root) {
+            ancestorChain.add(v);
+            v = (View) v.getParent();
+        }
+        ancestorChain.add(root);
+
+        float scale = 1.0f;
+        int count = ancestorChain.size();
+        tmpInverseMatrix.set(Matrix.IDENTITY_MATRIX);
+        for (int i = count - 1; i >= 0; i--) {
+            View ancestor = ancestorChain.get(i);
+            View next = i > 0 ? ancestorChain.get(i-1) : null;
+
+            pt[0] += ancestor.getScrollX();
+            pt[1] += ancestor.getScrollY();
+
+            if (next != null) {
+                pt[0] -= next.getLeft();
+                pt[1] -= next.getTop();
+                next.getMatrix().invert(tmpInverseMatrix);
+                tmpInverseMatrix.mapPoints(pt);
+                scale *= next.getScaleX();
+            }
+        }
+
+        coord[0] = pt[0];
+        coord[1] = pt[1];
+        return scale;
+    }
+
     /** Calculates the constrast between two colors, using the algorithm provided by the WCAG v2. */
     public static float computeContrastBetweenColors(int bg, int fg) {
         float bgR = Color.red(bg) / 255f;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index e5c06fd..d4b403d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -204,7 +204,8 @@
                     if (!mCancelled) {
                         // Notify that the task data has changed
                         final Drawable newIcon = cachedIcon;
-                        final Bitmap newThumbnail = cachedThumbnail;
+                        final Bitmap newThumbnail = cachedThumbnail == mDefaultThumbnail
+                                ? null : cachedThumbnail;
                         mMainThreadHandler.post(new Runnable() {
                             @Override
                             public void run() {
@@ -252,7 +253,6 @@
 
     BitmapDrawable mDefaultApplicationIcon;
     Bitmap mDefaultThumbnail;
-    Bitmap mLoadingThumbnail;
 
     /** Private Constructor */
     private RecentsTaskLoader(Context context) {
@@ -271,9 +271,6 @@
         mDefaultThumbnail = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
         mDefaultThumbnail.setHasAlpha(false);
         mDefaultThumbnail.eraseColor(0xFFffffff);
-        mLoadingThumbnail = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
-        mLoadingThumbnail.setHasAlpha(false);
-        mLoadingThumbnail.eraseColor(0xFFffffff);
         mDefaultApplicationIcon = new BitmapDrawable(context.getResources(), icon);
 
         // Initialize the proxy, cache and loaders
@@ -500,17 +497,16 @@
         // use the default assets in their place until they load
         boolean requiresLoad = (applicationIcon == null) || (thumbnail == null);
         applicationIcon = applicationIcon != null ? applicationIcon : mDefaultApplicationIcon;
-        thumbnail = thumbnail != null ? thumbnail : mDefaultThumbnail;
         if (requiresLoad) {
             mLoadQueue.addTask(t);
         }
-        t.notifyTaskDataLoaded(thumbnail, applicationIcon);
+        t.notifyTaskDataLoaded(thumbnail == mDefaultThumbnail ? null : thumbnail, applicationIcon);
     }
 
     /** Releases the task resource data back into the pool. */
     public void unloadTaskData(Task t) {
         mLoadQueue.removeTask(t);
-        t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultApplicationIcon);
+        t.notifyTaskDataUnloaded(null, mDefaultApplicationIcon);
     }
 
     /** Completely removes the resource data from the pool. */
@@ -519,7 +515,7 @@
         mThumbnailCache.remove(t.key);
         mApplicationIconCache.remove(t.key);
         if (notifyTaskDataUnloaded) {
-            t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultApplicationIcon);
+            t.notifyTaskDataUnloaded(null, mDefaultApplicationIcon);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
index d6889d0..d2fdaff 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
@@ -22,6 +22,7 @@
 import android.graphics.Rect;
 import android.view.View;
 import android.view.ViewOutlineProvider;
+
 import com.android.systemui.recents.RecentsConfiguration;
 
 /* An outline provider that has a clip and outline that can be animated. */
@@ -29,8 +30,10 @@
 
     RecentsConfiguration mConfig;
 
-    View mSourceView;
+    TaskView mSourceView;
+    Rect mTmpRect = new Rect();
     Rect mClipRect = new Rect();
+    Rect mClipBounds = new Rect();
     Rect mOutlineClipRect = new Rect();
     int mCornerRadius;
     float mAlpha = 1f;
@@ -40,11 +43,10 @@
     ObjectAnimator mClipRightAnimator;
     ObjectAnimator mClipBottomAnimator;
 
-    public AnimateableViewBounds(View source, int cornerRadius) {
+    public AnimateableViewBounds(TaskView source, int cornerRadius) {
         mConfig = RecentsConfiguration.getInstance();
         mSourceView = source;
         mCornerRadius = cornerRadius;
-        mSourceView.setClipToOutline(true);
         setClipTop(getClipTop());
         setClipRight(getClipRight());
         setClipBottom(getClipBottom());
@@ -56,8 +58,8 @@
         outline.setAlpha(mMinAlpha + mAlpha / (1f - mMinAlpha));
         outline.setRoundRect(Math.max(mClipRect.left, mOutlineClipRect.left),
                 Math.max(mClipRect.top, mOutlineClipRect.top),
-                mSourceView.getMeasuredWidth() - Math.max(mClipRect.right, mOutlineClipRect.right),
-                mSourceView.getMeasuredHeight() - Math.max(mClipRect.bottom, mOutlineClipRect.bottom),
+                mSourceView.getWidth() - Math.max(mClipRect.right, mOutlineClipRect.right),
+                mSourceView.getHeight() - Math.max(mClipRect.bottom, mOutlineClipRect.bottom),
                 mCornerRadius);
     }
 
@@ -89,6 +91,7 @@
         if (top != mClipRect.top) {
             mClipRect.top = top;
             mSourceView.invalidateOutline();
+            updateClipBounds();
         }
     }
 
@@ -114,6 +117,7 @@
         if (right != mClipRect.right) {
             mClipRect.right = right;
             mSourceView.invalidateOutline();
+            updateClipBounds();
         }
     }
 
@@ -139,6 +143,11 @@
         if (bottom != mClipRect.bottom) {
             mClipRect.bottom = bottom;
             mSourceView.invalidateOutline();
+            updateClipBounds();
+            if (!mConfig.useHardwareLayers) {
+                mSourceView.mThumbnailView.updateVisibility(
+                        bottom - mSourceView.getPaddingBottom());
+            }
         }
     }
 
@@ -159,4 +168,11 @@
     public int getOutlineClipBottom() {
         return mOutlineClipRect.bottom;
     }
+
+    private void updateClipBounds() {
+        mClipBounds.set(mClipRect.left, mClipRect.top,
+                mSourceView.getWidth() - mClipRect.right,
+                mSourceView.getHeight() - mClipRect.bottom);
+        mSourceView.setClipBounds(mClipBounds);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FakeShadowDrawable.java b/packages/SystemUI/src/com/android/systemui/recents/views/FakeShadowDrawable.java
new file mode 100644
index 0000000..72f9001
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/FakeShadowDrawable.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.systemui.recents.views;
+
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PixelFormat;
+import android.graphics.RadialGradient;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+
+import com.android.systemui.R;
+import com.android.systemui.recents.RecentsConfiguration;
+
+/**
+ * A rounded rectangle drawable which also includes a shadow around. This is mostly copied from
+ * frameworks/support/v7/cardview/eclair-mr1/android/support/v7/widget/
+ * RoundRectDrawableWithShadow.java revision c42ba8c000d1e6ce85e152dfc17089a0a69e739f with a few
+ * modifications to suit our needs in SystemUI.
+ */
+class FakeShadowDrawable extends Drawable {
+    // used to calculate content padding
+    final static double COS_45 = Math.cos(Math.toRadians(45));
+
+    final static float SHADOW_MULTIPLIER = 1.5f;
+
+    final float mInsetShadow; // extra shadow to avoid gaps between card and shadow
+
+    Paint mCornerShadowPaint;
+
+    Paint mEdgeShadowPaint;
+
+    final RectF mCardBounds;
+
+    float mCornerRadius;
+
+    Path mCornerShadowPath;
+
+    // updated value with inset
+    float mMaxShadowSize;
+
+    // actual value set by developer
+    float mRawMaxShadowSize;
+
+    // multiplied value to account for shadow offset
+    float mShadowSize;
+
+    // actual value set by developer
+    float mRawShadowSize;
+
+    private boolean mDirty = true;
+
+    private final int mShadowStartColor;
+
+    private final int mShadowEndColor;
+
+    private boolean mAddPaddingForCorners = true;
+
+    /**
+     * If shadow size is set to a value above max shadow, we print a warning
+     */
+    private boolean mPrintedShadowClipWarning = false;
+
+    public FakeShadowDrawable(Resources resources, RecentsConfiguration config) {
+        mShadowStartColor = resources.getColor(R.color.fake_shadow_start_color);
+        mShadowEndColor = resources.getColor(R.color.fake_shadow_end_color);
+        mInsetShadow = resources.getDimension(R.dimen.fake_shadow_inset);
+        setShadowSize(resources.getDimensionPixelSize(R.dimen.fake_shadow_size),
+                resources.getDimensionPixelSize(R.dimen.fake_shadow_size));
+        mCornerShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
+        mCornerShadowPaint.setStyle(Paint.Style.FILL);
+        mCornerShadowPaint.setDither(true);
+        mCornerRadius = config.taskViewRoundedCornerRadiusPx;
+        mCardBounds = new RectF();
+        mEdgeShadowPaint = new Paint(mCornerShadowPaint);
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        mCornerShadowPaint.setAlpha(alpha);
+        mEdgeShadowPaint.setAlpha(alpha);
+    }
+
+    @Override
+    protected void onBoundsChange(Rect bounds) {
+        super.onBoundsChange(bounds);
+        mDirty = true;
+    }
+
+    void setShadowSize(float shadowSize, float maxShadowSize) {
+        if (shadowSize < 0 || maxShadowSize < 0) {
+            throw new IllegalArgumentException("invalid shadow size");
+        }
+        if (shadowSize > maxShadowSize) {
+            shadowSize = maxShadowSize;
+            if (!mPrintedShadowClipWarning) {
+                Log.w("CardView", "Shadow size is being clipped by the max shadow size. See "
+                        + "{CardView#setMaxCardElevation}.");
+                mPrintedShadowClipWarning = true;
+            }
+        }
+        if (mRawShadowSize == shadowSize && mRawMaxShadowSize == maxShadowSize) {
+            return;
+        }
+        mRawShadowSize = shadowSize;
+        mRawMaxShadowSize = maxShadowSize;
+        mShadowSize = shadowSize * SHADOW_MULTIPLIER + mInsetShadow;
+        mMaxShadowSize = maxShadowSize + mInsetShadow;
+        mDirty = true;
+        invalidateSelf();
+    }
+
+    @Override
+    public boolean getPadding(Rect padding) {
+        int vOffset = (int) Math.ceil(calculateVerticalPadding(mRawMaxShadowSize, mCornerRadius,
+                mAddPaddingForCorners));
+        int hOffset = (int) Math.ceil(calculateHorizontalPadding(mRawMaxShadowSize, mCornerRadius,
+                mAddPaddingForCorners));
+        padding.set(hOffset, vOffset, hOffset, vOffset);
+        return true;
+    }
+
+    static float calculateVerticalPadding(float maxShadowSize, float cornerRadius,
+            boolean addPaddingForCorners) {
+        if (addPaddingForCorners) {
+            return (float) (maxShadowSize * SHADOW_MULTIPLIER + (1 - COS_45) * cornerRadius);
+        } else {
+            return maxShadowSize * SHADOW_MULTIPLIER;
+        }
+    }
+
+    static float calculateHorizontalPadding(float maxShadowSize, float cornerRadius,
+            boolean addPaddingForCorners) {
+        if (addPaddingForCorners) {
+            return (float) (maxShadowSize + (1 - COS_45) * cornerRadius);
+        } else {
+            return maxShadowSize;
+        }
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter cf) {
+        mCornerShadowPaint.setColorFilter(cf);
+        mEdgeShadowPaint.setColorFilter(cf);
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.OPAQUE;
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        if (mDirty) {
+            buildComponents(getBounds());
+            mDirty = false;
+        }
+        canvas.translate(0, mRawShadowSize / 4);
+        drawShadow(canvas);
+        canvas.translate(0, -mRawShadowSize / 4);
+    }
+
+    private void drawShadow(Canvas canvas) {
+        final float edgeShadowTop = -mCornerRadius - mShadowSize;
+        final float inset = mCornerRadius + mInsetShadow + mRawShadowSize / 2;
+        final boolean drawHorizontalEdges = mCardBounds.width() - 2 * inset > 0;
+        final boolean drawVerticalEdges = mCardBounds.height() - 2 * inset > 0;
+        // LT
+        int saved = canvas.save();
+        canvas.translate(mCardBounds.left + inset, mCardBounds.top + inset);
+        canvas.drawPath(mCornerShadowPath, mCornerShadowPaint);
+        if (drawHorizontalEdges) {
+            canvas.drawRect(0, edgeShadowTop,
+                    mCardBounds.width() - 2 * inset, -mCornerRadius,
+                    mEdgeShadowPaint);
+        }
+        canvas.restoreToCount(saved);
+        // RB
+        saved = canvas.save();
+        canvas.translate(mCardBounds.right - inset, mCardBounds.bottom - inset);
+        canvas.rotate(180f);
+        canvas.drawPath(mCornerShadowPath, mCornerShadowPaint);
+        if (drawHorizontalEdges) {
+            canvas.drawRect(0, edgeShadowTop,
+                    mCardBounds.width() - 2 * inset, -mCornerRadius + mShadowSize,
+                    mEdgeShadowPaint);
+        }
+        canvas.restoreToCount(saved);
+        // LB
+        saved = canvas.save();
+        canvas.translate(mCardBounds.left + inset, mCardBounds.bottom - inset);
+        canvas.rotate(270f);
+        canvas.drawPath(mCornerShadowPath, mCornerShadowPaint);
+        if (drawVerticalEdges) {
+            canvas.drawRect(0, edgeShadowTop,
+                    mCardBounds.height() - 2 * inset, -mCornerRadius, mEdgeShadowPaint);
+        }
+        canvas.restoreToCount(saved);
+        // RT
+        saved = canvas.save();
+        canvas.translate(mCardBounds.right - inset, mCardBounds.top + inset);
+        canvas.rotate(90f);
+        canvas.drawPath(mCornerShadowPath, mCornerShadowPaint);
+        if (drawVerticalEdges) {
+            canvas.drawRect(0, edgeShadowTop,
+                    mCardBounds.height() - 2 * inset, -mCornerRadius, mEdgeShadowPaint);
+        }
+        canvas.restoreToCount(saved);
+    }
+
+    private void buildShadowCorners() {
+        RectF innerBounds = new RectF(-mCornerRadius, -mCornerRadius, mCornerRadius, mCornerRadius);
+        RectF outerBounds = new RectF(innerBounds);
+        outerBounds.inset(-mShadowSize, -mShadowSize);
+
+        if (mCornerShadowPath == null) {
+            mCornerShadowPath = new Path();
+        } else {
+            mCornerShadowPath.reset();
+        }
+        mCornerShadowPath.setFillType(Path.FillType.EVEN_ODD);
+        mCornerShadowPath.moveTo(-mCornerRadius, 0);
+        mCornerShadowPath.rLineTo(-mShadowSize, 0);
+        // outer arc
+        mCornerShadowPath.arcTo(outerBounds, 180f, 90f, false);
+        // inner arc
+        mCornerShadowPath.arcTo(innerBounds, 270f, -90f, false);
+        mCornerShadowPath.close();
+
+        float startRatio = mCornerRadius / (mCornerRadius + mShadowSize);
+        mCornerShadowPaint.setShader(new RadialGradient(0, 0, mCornerRadius + mShadowSize,
+                new int[]{mShadowStartColor, mShadowStartColor, mShadowEndColor},
+                new float[]{0f, startRatio, 1f}
+                , Shader.TileMode.CLAMP));
+
+        // we offset the content shadowSize/2 pixels up to make it more realistic.
+        // this is why edge shadow shader has some extra space
+        // When drawing bottom edge shadow, we use that extra space.
+        mEdgeShadowPaint.setShader(new LinearGradient(0, -mCornerRadius + mShadowSize, 0,
+                -mCornerRadius - mShadowSize,
+                new int[]{mShadowStartColor, mShadowStartColor, mShadowEndColor},
+                new float[]{0f, .5f, 1f}, Shader.TileMode.CLAMP));
+    }
+
+    private void buildComponents(Rect bounds) {
+        // Card is offset SHADOW_MULTIPLIER * maxShadowSize to account for the shadow shift.
+        // We could have different top-bottom offsets to avoid extra gap above but in that case
+        // center aligning Views inside the CardView would be problematic.
+        final float verticalOffset = mMaxShadowSize * SHADOW_MULTIPLIER;
+        mCardBounds.set(bounds.left + mMaxShadowSize, bounds.top + verticalOffset,
+                bounds.right - mMaxShadowSize, bounds.bottom - verticalOffset);
+        buildShadowCorners();
+    }
+
+    float getMinWidth() {
+        final float content = 2 *
+                Math.max(mRawMaxShadowSize, mCornerRadius + mInsetShadow + mRawMaxShadowSize / 2);
+        return content + (mRawMaxShadowSize + mInsetShadow) * 2;
+    }
+
+    float getMinHeight() {
+        final float content = 2 * Math.max(mRawMaxShadowSize, mCornerRadius + mInsetShadow
+                        + mRawMaxShadowSize * SHADOW_MULTIPLIER / 2);
+        return content + (mRawMaxShadowSize * SHADOW_MULTIPLIER + mInsetShadow) * 2;
+    }
+}
\ No newline at end of file
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 1bfb41f..6c22a3b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -56,6 +56,7 @@
     /** The RecentsView callbacks */
     public interface RecentsViewCallbacks {
         public void onTaskViewClicked();
+        public void onTaskLaunchFailed();
         public void onAllTaskViewsDismissed();
         public void onExitToHomeAnimationTriggered();
     }
@@ -393,7 +394,7 @@
 
         // Upfront the processing of the thumbnail
         TaskViewTransform transform = new TaskViewTransform();
-        View sourceView = tv;
+        View sourceView;
         int offsetX = 0;
         int offsetY = 0;
         float stackScroll = stackView.getScroller().getStackScroll();
@@ -406,6 +407,7 @@
             offsetX = transform.rect.left;
             offsetY = mConfig.displayRect.height();
         } else {
+            sourceView = tv.mThumbnailView;
             transform = stackView.getStackAlgorithm().getStackTransform(task, stackScroll, transform, null);
         }
 
@@ -470,13 +472,18 @@
                     // Bring an active task to the foreground
                     ssp.moveTaskToFront(task.key.id, launchOpts);
                 } else {
-                    try {
-                        ssp.startActivityFromRecents(task.key.id, launchOpts);
+                    if (ssp.startActivityFromRecents(getContext(), task.key.id,
+                            task.activityLabel, launchOpts)) {
                         if (launchOpts == null && lockToTask) {
                             ssp.lockCurrentTask();
                         }
-                    } catch (ActivityNotFoundException anfe) {
-                        Console.logError(getContext(), "Could not start Activity");
+                    } else {
+                        // Dismiss the task and return the user to home if we fail to
+                        // launch the task
+                        onTaskViewDismissed(task);
+                        if (mCb != null) {
+                            mCb.onTaskLaunchFailed();
+                        }
                     }
                 }
             }
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 895b9d1..e1e4068 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -16,21 +16,23 @@
 
 package com.android.systemui.recents.views;
 
+import android.animation.ValueAnimator;
 import android.content.ComponentName;
 import android.content.Context;
+import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewTreeObserver;
 import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.FrameLayout;
 import com.android.systemui.R;
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.misc.DozeTrigger;
 import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.misc.Utilities;
 import com.android.systemui.recents.model.RecentsPackageMonitor;
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.model.Task;
@@ -76,15 +78,28 @@
     // Optimizations
     int mStackViewsAnimationDuration;
     boolean mStackViewsDirty = true;
+    boolean mStackViewsClipDirty = true;
     boolean mAwaitingFirstLayout = true;
     boolean mStartEnterAnimationRequestedAfterLayout;
     boolean mStartEnterAnimationCompleted;
     ViewAnimation.TaskViewEnterContext mStartEnterAnimationContext;
     int[] mTmpVisibleRange = new int[2];
+    float[] mTmpCoord = new float[2];
+    Matrix mTmpMatrix = new Matrix();
+    Rect mTmpRect = new Rect();
     TaskViewTransform mTmpTransform = new TaskViewTransform();
     HashMap<Task, TaskView> mTmpTaskViewMap = new HashMap<Task, TaskView>();
     LayoutInflater mInflater;
 
+    // A convenience update listener to request updating clipping of tasks
+    ValueAnimator.AnimatorUpdateListener mRequestUpdateClippingListener =
+            new ValueAnimator.AnimatorUpdateListener() {
+        @Override
+        public void onAnimationUpdate(ValueAnimator animation) {
+            requestUpdateStackViewsClip();
+        }
+    };
+
     // A convenience runnable to return all views to the pool
     Runnable mReturnAllViewsToPoolRunnable = new Runnable() {
         @Override
@@ -151,6 +166,14 @@
         }
     }
 
+    /** Requests that the views clipping be updated. */
+    void requestUpdateStackViewsClip() {
+        if (!mStackViewsClipDirty) {
+            invalidate();
+            mStackViewsClipDirty = true;
+        }
+    }
+
     /** Finds the child view given a specific task. */
     public TaskView getChildViewForTask(Task t) {
         int childCount = getChildCount();
@@ -300,7 +323,7 @@
 
                 // Animate the task into place
                 tv.updateViewPropertiesToTaskTransform(mCurrentTaskTransforms.get(taskIndex),
-                        mStackViewsAnimationDuration);
+                        mStackViewsAnimationDuration, mRequestUpdateClippingListener);
 
                 // Request accessibility focus on the next view if we removed the task
                 // that previously held accessibility focus
@@ -318,6 +341,7 @@
             // Reset the request-synchronize params
             mStackViewsAnimationDuration = 0;
             mStackViewsDirty = false;
+            mStackViewsClipDirty = true;
             return true;
         }
         return false;
@@ -348,10 +372,13 @@
                     // stacked and we can make assumptions about the visibility of the this
                     // task relative to the ones in front of it.
                     if (nextTv != null) {
-                        // We can reuse the current task transforms to find the task rects
-                        TaskViewTransform transform = mCurrentTaskTransforms.get(mStack.indexOfTask(tv.getTask()));
-                        TaskViewTransform nextTransform = mCurrentTaskTransforms.get(mStack.indexOfTask(nextTv.getTask()));
-                        clipBottom = transform.rect.bottom - nextTransform.rect.top;
+                        // Map the top edge of next task view into the local space of the current
+                        // task view to find the clip amount in local space
+                        mTmpCoord[0] = mTmpCoord[1] = 0;
+                        Utilities.mapCoordInDescendentToSelf(nextTv, this, mTmpCoord, false);
+                        Utilities.mapCoordInSelfToDescendent(tv, this, mTmpCoord, mTmpMatrix);
+                        clipBottom = (int) Math.floor(tv.getMeasuredHeight() - mTmpCoord[1]
+                                - nextTv.getPaddingTop() - 1);
                     }
                 }
                 tv.getViewBounds().setClipBottom(clipBottom);
@@ -362,6 +389,7 @@
                 tv.getViewBounds().setClipBottom(0);
             }
         }
+        mStackViewsClipDirty = false;
     }
 
     /** The stack insets to apply to the stack contents */
@@ -537,10 +565,17 @@
             if (tv.isFullScreenView()) {
                 tv.measure(widthMeasureSpec, heightMeasureSpec);
             } else {
+                if (tv.getBackground() != null) {
+                    tv.getBackground().getPadding(mTmpRect);
+                } else {
+                    mTmpRect.setEmpty();
+                }
                 tv.measure(
-                    MeasureSpec.makeMeasureSpec(mLayoutAlgorithm.mTaskRect.width(),
+                    MeasureSpec.makeMeasureSpec(
+                            mLayoutAlgorithm.mTaskRect.width() + mTmpRect.left + mTmpRect.right,
                             MeasureSpec.EXACTLY),
-                    MeasureSpec.makeMeasureSpec(mLayoutAlgorithm.mTaskRect.height() +
+                    MeasureSpec.makeMeasureSpec(
+                            mLayoutAlgorithm.mTaskRect.height() + mTmpRect.top + mTmpRect.bottom +
                             tv.getMaxFooterHeight(), MeasureSpec.EXACTLY));
             }
         }
@@ -562,8 +597,15 @@
             if (tv.isFullScreenView()) {
                 tv.layout(left, top, left + tv.getMeasuredWidth(), top + tv.getMeasuredHeight());
             } else {
-                tv.layout(mLayoutAlgorithm.mTaskRect.left, mLayoutAlgorithm.mTaskRect.top,
-                        mLayoutAlgorithm.mTaskRect.right, mLayoutAlgorithm.mTaskRect.bottom +
+                if (tv.getBackground() != null) {
+                    tv.getBackground().getPadding(mTmpRect);
+                } else {
+                    mTmpRect.setEmpty();
+                }
+                tv.layout(mLayoutAlgorithm.mTaskRect.left - mTmpRect.left,
+                        mLayoutAlgorithm.mTaskRect.top - mTmpRect.top,
+                        mLayoutAlgorithm.mTaskRect.right + mTmpRect.right,
+                        mLayoutAlgorithm.mTaskRect.bottom + mTmpRect.bottom +
                                 tv.getMaxFooterHeight());
             }
         }
@@ -650,6 +692,7 @@
                 ctx.currentTaskRect = mLayoutAlgorithm.mTaskRect;
                 ctx.currentTaskOccludesLaunchTarget = (launchTargetTask != null) &&
                         launchTargetTask.group.isTaskAboveTask(task, launchTargetTask);
+                ctx.updateListener = mRequestUpdateClippingListener;
                 mLayoutAlgorithm.getStackTransform(task, mStackScroller.getStackScroll(), ctx.currentTaskTransform, null);
                 tv.startEnterRecentsAnimation(ctx);
             }
@@ -988,7 +1031,9 @@
 
     @Override
     public void onTaskViewClipStateChanged(TaskView tv) {
-        invalidate();
+        if (!mStackViewsDirty) {
+            invalidate();
+        }
     }
 
     @Override
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 51adc28..1750804 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -20,12 +20,9 @@
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.content.Context;
-import android.graphics.Color;
-import android.graphics.Outline;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
-import android.graphics.Rect;
+import android.graphics.*;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewOutlineProvider;
@@ -72,6 +69,7 @@
     AnimateableViewBounds mViewBounds;
     Paint mLayerPaint = new Paint();
 
+    View mContent;
     TaskViewThumbnail mThumbnailView;
     TaskViewHeader mHeaderView;
     TaskViewFooter mFooterView;
@@ -106,9 +104,12 @@
         mMaxDimScale = mConfig.taskStackMaxDim / 255f;
         mClipViewInStack = true;
         mViewBounds = new AnimateableViewBounds(this, mConfig.taskViewRoundedCornerRadiusPx);
-        setOutlineProvider(mViewBounds);
         setTaskProgress(getTaskProgress());
         setDim(getDim());
+        if (mConfig.fakeShadows) {
+            setBackground(new FakeShadowDrawable(context.getResources(), mConfig));
+        }
+        setOutlineProvider(mViewBounds);
     }
 
     /** Set callback */
@@ -129,15 +130,16 @@
     @Override
     protected void onFinishInflate() {
         // Bind the views
+        mContent = findViewById(R.id.task_view_content);
         mHeaderView = (TaskViewHeader) findViewById(R.id.task_view_bar);
         mThumbnailView = (TaskViewThumbnail) findViewById(R.id.task_view_thumbnail);
+        mThumbnailView.enableTaskBarClip(mHeaderView);
         mActionButtonView = findViewById(R.id.lock_to_app_fab);
         mActionButtonView.setOutlineProvider(new ViewOutlineProvider() {
             @Override
             public void getOutline(View view, Outline outline) {
                 // Set the outline to match the FAB background
-                outline.setOval(0, 0, mActionButtonView.getWidth(),
-                        mActionButtonView.getHeight());
+                outline.setOval(0, 0, mActionButtonView.getWidth(), mActionButtonView.getHeight());
             }
         });
         if (mFooterView != null) {
@@ -150,24 +152,35 @@
         int width = MeasureSpec.getSize(widthMeasureSpec);
         int height = MeasureSpec.getSize(heightMeasureSpec);
 
+        int widthWithoutPadding = width - mPaddingLeft - mPaddingRight;
+        int heightWithoutPadding = height - mPaddingTop - mPaddingBottom;
+
+        // Measure the content
+        mContent.measure(MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY));
+
         // Measure the bar view, thumbnail, and footer
-        mHeaderView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+        mHeaderView.measure(MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY),
                 MeasureSpec.makeMeasureSpec(mConfig.taskBarHeight, MeasureSpec.EXACTLY));
         if (mFooterView != null) {
-            mFooterView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+            mFooterView.measure(
+                    MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY),
                     MeasureSpec.makeMeasureSpec(mConfig.taskViewLockToAppButtonHeight,
                             MeasureSpec.EXACTLY));
         }
-        mActionButtonView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
-                MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
+        mActionButtonView.measure(
+                MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.AT_MOST),
+                MeasureSpec.makeMeasureSpec(heightWithoutPadding, MeasureSpec.AT_MOST));
         if (mIsFullScreenView) {
             // Measure the thumbnail height to be the full dimensions
-            mThumbnailView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
-                    MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
+            mThumbnailView.measure(
+                    MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY),
+                    MeasureSpec.makeMeasureSpec(heightWithoutPadding, MeasureSpec.EXACTLY));
         } else {
             // Measure the thumbnail to be square
-            mThumbnailView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
-                    MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY));
+            mThumbnailView.measure(
+                    MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY),
+                    MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY));
         }
         setMeasuredDimension(width, height);
         invalidateOutline();
@@ -175,10 +188,15 @@
 
     /** Synchronizes this view's properties with the task's transform */
     void updateViewPropertiesToTaskTransform(TaskViewTransform toTransform, int duration) {
+        updateViewPropertiesToTaskTransform(toTransform, duration, null);
+    }
+
+    void updateViewPropertiesToTaskTransform(TaskViewTransform toTransform, int duration,
+                                             ValueAnimator.AnimatorUpdateListener updateCallback) {
         // If we are a full screen view, then only update the Z to keep it in order
         // XXX: Also update/animate the dim as well
         if (mIsFullScreenView) {
-            if (Constants.DebugFlags.App.EnableShadows &&
+            if (!mConfig.fakeShadows &&
                     toTransform.hasTranslationZChangedFrom(getTranslationZ())) {
                 setTranslationZ(toTransform.translationZ);
             }
@@ -186,7 +204,8 @@
         }
 
         // Apply the transform
-        toTransform.applyToTaskView(this, duration, mConfig.fastOutSlowInInterpolator, false);
+        toTransform.applyToTaskView(this, duration, mConfig.fastOutSlowInInterpolator, false,
+                !mConfig.fakeShadows, updateCallback);
 
         // Update the task progress
         if (mTaskProgressAnimator != null) {
@@ -258,9 +277,7 @@
         } else if (mConfig.launchedFromHome) {
             // Move the task view off screen (below) so we can animate it in
             setTranslationY(offscreenY);
-            if (Constants.DebugFlags.App.EnableShadows) {
-                setTranslationZ(0);
-            }
+            setTranslationZ(0);
             setScaleX(1f);
             setScaleY(1f);
         }
@@ -321,8 +338,6 @@
                                 mViewBounds.setClipRight(0);
                                 // Reset the bar translation
                                 mHeaderView.setTranslationY(0);
-                                // Enable the thumbnail clip
-                                mThumbnailView.enableTaskBarClip(mHeaderView);
                                 // Animate the footer into view (if it is the front most task)
                                 animateFooterVisibility(true, mConfig.taskBarEnterAnimDuration);
 
@@ -339,9 +354,6 @@
                         })
                         .start();
             } else {
-                // Otherwise, just enable the thumbnail clip
-                mThumbnailView.enableTaskBarClip(mHeaderView);
-
                 // Animate the footer into view
                 animateFooterVisibility(true, 0);
             }
@@ -349,8 +361,6 @@
 
         } else if (mConfig.launchedFromAppWithThumbnail) {
             if (mTask.isLaunchTarget) {
-                // Enable the task bar clip
-                mThumbnailView.enableTaskBarClip(mHeaderView);
                 // Animate the dim/overlay
                 if (Constants.DebugFlags.App.EnableThumbnailAlphaOnFrontmost) {
                     // Animate the thumbnail alpha before the dim animation (to prevent updating the
@@ -382,8 +392,6 @@
                         .withLayer()
                         .start();
             } else {
-                // Enable the task bar clip
-                mThumbnailView.enableTaskBarClip(mHeaderView);
                 // Animate the task up if it was occluding the launch target
                 if (ctx.currentTaskOccludesLaunchTarget) {
                     setTranslationY(transform.translationY + mConfig.taskViewAffiliateGroupEnterOffsetPx);
@@ -397,7 +405,6 @@
                             .withEndAction(new Runnable() {
                                 @Override
                                 public void run() {
-                                    mThumbnailView.enableTaskBarClip(mHeaderView);
                                     // Decrement the post animation trigger
                                     ctx.postAnimationTrigger.decrement();
                                 }
@@ -411,9 +418,12 @@
         } else if (mConfig.launchedFromHome) {
             // Animate the tasks up
             int frontIndex = (ctx.currentStackViewCount - ctx.currentStackViewIndex - 1);
-            int delay = mConfig.taskViewEnterFromHomeDelay +
-                    frontIndex * mConfig.taskViewEnterFromHomeStaggerDelay;
-            if (Constants.DebugFlags.App.EnableShadows) {
+            float fraction = (float) frontIndex / (ctx.currentStackViewCount - 1);
+            fraction = (float) Math.pow(fraction, 0.85f);
+            int delay = (int) (mConfig.taskViewEnterFromHomeDelay +
+                                fraction * mConfig.taskViewEnterFromHomeStaggerDelay);
+            long delayIncrease = (long) (fraction * mConfig.taskViewEnterFromHomeStaggerDuration);
+            if (!mConfig.fakeShadows) {
                 animate().translationZ(transform.translationZ);
             }
             animate()
@@ -421,13 +431,12 @@
                     .scaleY(transform.scale)
                     .translationY(transform.translationY)
                     .setStartDelay(delay)
-                    .setUpdateListener(null)
+                    .setUpdateListener(ctx.updateListener)
                     .setInterpolator(mConfig.quintOutInterpolator)
-                    .setDuration(mConfig.taskViewEnterFromHomeDuration)
+                    .setDuration(mConfig.taskViewEnterFromHomeDuration + delayIncrease)
                     .withEndAction(new Runnable() {
                         @Override
                         public void run() {
-                            mThumbnailView.enableTaskBarClip(mHeaderView);
                             // Decrement the post animation trigger
                             ctx.postAnimationTrigger.decrement();
                         }
@@ -440,9 +449,6 @@
             startDelay = delay;
 
         } else {
-            // Otherwise, just enable the thumbnail clip
-            mThumbnailView.enableTaskBarClip(mHeaderView);
-
             // Animate the footer into view
             animateFooterVisibility(true, 0);
         }
@@ -474,8 +480,6 @@
     void startLaunchTaskAnimation(final Runnable postAnimRunnable, boolean isLaunchingTask,
             boolean occludesLaunchTarget, boolean lockToTask) {
         if (isLaunchingTask) {
-            // Disable the thumbnail clip
-            mThumbnailView.disableTaskBarClip();
             // Animate the thumbnail alpha back into full opacity for the window animation out
             mThumbnailView.startLaunchTaskAnimation(postAnimRunnable);
 
@@ -637,17 +641,31 @@
     /** Returns the current dim. */
     public void setDim(int dim) {
         mDim = dim;
-        // Defer setting hardware layers if we have not yet measured, or there is no dim to draw
-        if (getMeasuredWidth() > 0 && getMeasuredHeight() > 0) {
-            if (mDimAnimator != null) {
-                mDimAnimator.removeAllListeners();
-                mDimAnimator.cancel();
-            }
+        if (mDimAnimator != null) {
+            mDimAnimator.removeAllListeners();
+            mDimAnimator.cancel();
+        }
+        if (mConfig.useHardwareLayers) {
+            // Defer setting hardware layers if we have not yet measured, or there is no dim to draw
+            if (getMeasuredWidth() > 0 && getMeasuredHeight() > 0) {
+                if (mDimAnimator != null) {
+                    mDimAnimator.removeAllListeners();
+                    mDimAnimator.cancel();
+                }
 
-            int inverse = 255 - mDim;
-            mDimColorFilter.setColor(Color.argb(0xFF, inverse, inverse, inverse));
-            mLayerPaint.setColorFilter(mDimColorFilter);
-            setLayerType(LAYER_TYPE_HARDWARE, mLayerPaint);
+                int inverse = 255 - mDim;
+                mDimColorFilter.setColor(Color.argb(0xFF, inverse, inverse, inverse));
+                mLayerPaint.setColorFilter(mDimColorFilter);
+                mContent.setLayerType(LAYER_TYPE_HARDWARE, mLayerPaint);
+            }
+        } else {
+            float dimAlpha = mDim / 255.0f;
+            if (mThumbnailView != null) {
+                mThumbnailView.setDimAlpha(dimAlpha);
+            }
+            if (mHeaderView != null) {
+                mHeaderView.setDimAlpha(dim);
+            }
         }
     }
 
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 1743433..396d441 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -30,10 +30,13 @@
 import android.graphics.Outline;
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
 import android.graphics.PorterDuffXfermode;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
 import android.graphics.drawable.RippleDrawable;
+import android.graphics.drawable.ShapeDrawable;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
@@ -58,17 +61,20 @@
     TextView mActivityDescription;
 
     RippleDrawable mBackground;
-    ColorDrawable mBackgroundColor;
+    GradientDrawable mBackgroundColorDrawable;
+    int mBackgroundColor;
     Drawable mLightDismissDrawable;
     Drawable mDarkDismissDrawable;
     AnimatorSet mFocusAnimator;
     ValueAnimator backgroundColorAnimator;
+    PorterDuffColorFilter mDimFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_ATOP);
 
     boolean mIsFullscreen;
     boolean mCurrentPrimaryColorIsDark;
     int mCurrentPrimaryColor;
 
     static Paint sHighlightPaint;
+    private Paint mDimPaint = new Paint();
 
     public TaskViewHeader(Context context) {
         this(context, null);
@@ -140,13 +146,14 @@
             }
         }
 
-        mBackgroundColor = new ColorDrawable(0);
+        mBackgroundColorDrawable = (GradientDrawable) getContext().getDrawable(R.drawable
+                .recents_task_view_header_bg_color);
         // Copy the ripple drawable since we are going to be manipulating it
         mBackground = (RippleDrawable)
                 getContext().getDrawable(R.drawable.recents_task_view_header_bg);
         mBackground = (RippleDrawable) mBackground.mutate().getConstantState().newDrawable();
         mBackground.setColor(ColorStateList.valueOf(0));
-        mBackground.setDrawableByLayerId(mBackground.getId(0), mBackgroundColor);
+        mBackground.setDrawableByLayerId(mBackground.getId(0), mBackgroundColorDrawable);
         setBackground(mBackground);
     }
 
@@ -197,7 +204,8 @@
         int existingBgColor = (getBackground() instanceof ColorDrawable) ?
                 ((ColorDrawable) getBackground()).getColor() : 0;
         if (existingBgColor != t.colorPrimary) {
-            mBackgroundColor.setColor(t.colorPrimary);
+            mBackgroundColorDrawable.setColor(t.colorPrimary);
+            mBackgroundColor = t.colorPrimary;
         }
         mCurrentPrimaryColor = t.colorPrimary;
         mCurrentPrimaryColorIsDark = t.useLightOnPrimaryColor;
@@ -251,6 +259,14 @@
         }
     }
 
+    @Override
+    protected int[] onCreateDrawableState(int extraSpace) {
+
+        // Don't forward our state to the drawable - we do it manually in onTaskViewFocusChanged.
+        // This is to prevent layer trashing when the view is pressed.
+        return new int[] {};
+    }
+
     /** Notifies the associated TaskView has been focused. */
     void onTaskViewFocusChanged(boolean focused) {
         boolean isRunning = false;
@@ -276,7 +292,7 @@
             mBackground.setColor(new ColorStateList(states, colors));
             mBackground.setState(newStates);
             // Pulse the background color
-            int currentColor = mBackgroundColor.getColor();
+            int currentColor = mBackgroundColor;
             int lightPrimaryColor = getSecondaryColor(mCurrentPrimaryColor, mCurrentPrimaryColorIsDark);
             ValueAnimator backgroundColor = ValueAnimator.ofObject(new ArgbEvaluator(),
                     lightPrimaryColor, currentColor);
@@ -289,7 +305,9 @@
             backgroundColor.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                 @Override
                 public void onAnimationUpdate(ValueAnimator animation) {
-                    mBackgroundColor.setColor((Integer) animation.getAnimatedValue());
+                    int color = (int) animation.getAnimatedValue();
+                    mBackgroundColorDrawable.setColor(color);
+                    mBackgroundColor = color;
                 }
             });
             backgroundColor.setRepeatCount(ValueAnimator.INFINITE);
@@ -307,13 +325,15 @@
         } else {
             if (isRunning) {
                 // Restore the background color
-                int currentColor = mBackgroundColor.getColor();
+                int currentColor = mBackgroundColor;
                 ValueAnimator backgroundColor = ValueAnimator.ofObject(new ArgbEvaluator(),
                         currentColor, mCurrentPrimaryColor);
                 backgroundColor.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                     @Override
                     public void onAnimationUpdate(ValueAnimator animation) {
-                        mBackgroundColor.setColor((Integer) animation.getAnimatedValue());
+                        int color = (int) animation.getAnimatedValue();
+                        mBackgroundColorDrawable.setColor(color);
+                        mBackgroundColor = color;
                     }
                 });
                 // Restore the translation
@@ -329,4 +349,11 @@
             }
         }
     }
+
+    public void setDimAlpha(int alpha) {
+        int color = Color.argb(alpha, 0, 0, 0);
+        mDimFilter.setColor(color);
+        mDimPaint.setColorFilter(mDimFilter);
+        setLayerType(LAYER_TYPE_HARDWARE, mDimPaint);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
index fe36987..a946a84 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
@@ -16,9 +16,20 @@
 
 package com.android.systemui.recents.views;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.LightingColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
 import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Shader;
 import android.util.AttributeSet;
 import android.view.View;
 import com.android.systemui.recents.RecentsConfiguration;
@@ -26,12 +37,32 @@
 
 
 /** The task thumbnail view */
-public class TaskViewThumbnail extends FixedSizeImageView {
+public class TaskViewThumbnail extends View {
 
+    private final int mCornerRadius;
+    private final Matrix mScaleMatrix = new Matrix();
     RecentsConfiguration mConfig;
 
     // Task bar clipping
     Rect mClipRect = new Rect();
+    Paint mDrawPaint = new Paint();
+    LightingColorFilter mLightingColorFilter = new LightingColorFilter(0xffffffff, 0);
+    private final RectF mBitmapRect = new RectF();
+    private final RectF mLayoutRect = new RectF();
+    private BitmapShader mBitmapShader;
+    private float mBitmapAlpha;
+    private float mDimAlpha;
+    private View mTaskBar;
+    private boolean mInvisible;
+    private ValueAnimator mAlphaAnimator;
+    private ValueAnimator.AnimatorUpdateListener mAlphaUpdateListener
+            = new ValueAnimator.AnimatorUpdateListener() {
+        @Override
+        public void onAnimationUpdate(ValueAnimator animation) {
+            mBitmapAlpha = (float) animation.getAnimatedValue();
+            updateFilter();
+        }
+    };
 
     public TaskViewThumbnail(Context context) {
         this(context, null);
@@ -48,35 +79,75 @@
     public TaskViewThumbnail(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
         mConfig = RecentsConfiguration.getInstance();
-        setScaleType(ScaleType.FIT_XY);
+        mCornerRadius = mConfig.taskViewRoundedCornerRadiusPx;
+        mDrawPaint.setColorFilter(mLightingColorFilter);
+        mDrawPaint.setFilterBitmap(true);
+        mDrawPaint.setAntiAlias(true);
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        if (mInvisible) {
+            return;
+        }
+        canvas.drawRoundRect(0,
+                0,
+                getWidth(),
+                getHeight(),
+                mCornerRadius,
+                mCornerRadius,
+                mDrawPaint);
     }
 
     @Override
     protected void onFinishInflate() {
-        setAlpha(0.9f);
+        mBitmapAlpha = 0.9f;
+        updateFilter();
+    }
+
+    private void updateFilter() {
+        if (mInvisible) {
+            return;
+        }
+        int mul = (int) ((1.0f - mDimAlpha) * mBitmapAlpha * 255);
+        int add = (int) ((1.0f - mDimAlpha) * (1 - mBitmapAlpha) * 255);
+        if (mBitmapShader != null) {
+            mLightingColorFilter.setColorMultiply(Color.argb(255, mul, mul, mul));
+            mLightingColorFilter.setColorAdd(Color.argb(0, add, add, add));
+            mDrawPaint.setColorFilter(mLightingColorFilter);
+            mDrawPaint.setColor(0xffffffff);
+        } else {
+            mDrawPaint.setColorFilter(null);
+            int grey = mul + add;
+            mDrawPaint.setColor(Color.argb(255, grey, grey, grey));
+        }
+        invalidate();
     }
 
     /** Updates the clip rect based on the given task bar. */
     void enableTaskBarClip(View taskBar) {
+        mTaskBar = taskBar;
         int top = (int) Math.max(0, taskBar.getTranslationY() +
                 taskBar.getMeasuredHeight() - 1);
         mClipRect.set(0, top, getMeasuredWidth(), getMeasuredHeight());
         setClipBounds(mClipRect);
     }
 
-    /** Disables the task bar clipping. */
-    void disableTaskBarClip() {
-        mClipRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
-        setClipBounds(mClipRect);
+    void updateVisibility(int clipBottom) {
+        boolean invisible = mTaskBar != null && getHeight() - clipBottom < mTaskBar.getHeight();
+        if (invisible != mInvisible) {
+            mInvisible = invisible;
+            if (!mInvisible) {
+                updateFilter();
+            }
+            invalidate();
+        }
     }
 
     /** Binds the thumbnail view to the screenshot. */
     boolean bindToScreenshot(Bitmap ss) {
-        if (ss != null) {
-            setImageBitmap(ss);
-            return true;
-        }
-        return false;
+        setImageBitmap(ss);
+        return ss != null;
     }
 
     /** Unbinds the thumbnail view from the screenshot. */
@@ -88,12 +159,49 @@
     void rebindToTask(Task t) {
         if (t.thumbnail != null) {
             setImageBitmap(t.thumbnail);
+        } else {
+            setImageBitmap(null);
         }
     }
 
+    public void setImageBitmap(Bitmap bm) {
+        if (bm != null) {
+            mBitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP,
+                    Shader.TileMode.CLAMP);
+            mDrawPaint.setShader(mBitmapShader);
+            mBitmapRect.set(0, 0, bm.getWidth(), bm.getHeight());
+            updateBitmapScale();
+        } else {
+            mBitmapShader = null;
+            mDrawPaint.setShader(null);
+        }
+        updateFilter();
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        if (changed) {
+            mLayoutRect.set(0, 0, getWidth(), getHeight());
+            updateBitmapScale();
+        }
+    }
+
+    private void updateBitmapScale() {
+        if (mBitmapShader != null) {
+            mScaleMatrix.setRectToRect(mBitmapRect, mLayoutRect, Matrix.ScaleToFit.FILL);
+            mBitmapShader.setLocalMatrix(mScaleMatrix);
+        }
+    }
+
+    public void setDimAlpha(float dimAlpha) {
+        mDimAlpha = dimAlpha;
+        updateFilter();
+    }
+
     /** Unbinds the thumbnail view from the task */
     void unbindFromTask() {
-        setImageDrawable(null);
+        setImageBitmap(null);
     }
 
     /** Handles focus changes. */
@@ -112,10 +220,11 @@
     /** Prepares for the enter recents animation. */
     void prepareEnterRecentsAnimation(boolean isTaskViewLaunchTargetTask) {
         if (isTaskViewLaunchTargetTask) {
-            setAlpha(1f);
+            mBitmapAlpha = 1f;
         } else {
-            setAlpha(mConfig.taskViewThumbnailAlpha);
+            mBitmapAlpha = mConfig.taskViewThumbnailAlpha;
         }
+        updateFilter();
     }
 
     /** Animates this task thumbnail as it enters recents */
@@ -130,16 +239,32 @@
     }
 
     /** Animates the thumbnail alpha. */
-    void startFadeAnimation(float finalAlpha, int delay, int duration, Runnable postAnimRunnable) {
-        if (postAnimRunnable != null) {
-            animate().withEndAction(postAnimRunnable);
+    void startFadeAnimation(float finalAlpha, int delay, int duration, final Runnable postAnimRunnable) {
+        if (mAlphaAnimator != null) {
+            mAlphaAnimator.cancel();
         }
-        animate()
-                .alpha(finalAlpha)
-                .setStartDelay(delay)
-                .setInterpolator(mConfig.fastOutSlowInInterpolator)
-                .setDuration(duration)
-                .withLayer()
-                .start();
+        mAlphaAnimator = ValueAnimator.ofFloat(mBitmapAlpha, finalAlpha);
+        mAlphaAnimator.addUpdateListener(mAlphaUpdateListener);
+        mAlphaAnimator.setStartDelay(delay);
+        mAlphaAnimator.setInterpolator(mConfig.fastOutSlowInInterpolator);
+        mAlphaAnimator.setDuration(duration);
+        mAlphaAnimator.start();
+        if (postAnimRunnable != null) {
+            mAlphaAnimator.addListener(new AnimatorListenerAdapter() {
+                public boolean mCancelled;
+
+                @Override
+                public void onAnimationCancel(Animator animation) {
+                    mCancelled = true;
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    if (!mCancelled) {
+                        postAnimRunnable.run();
+                    }
+                }
+            });
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
index ce2e80b..42c0f9f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
@@ -77,7 +77,8 @@
     }
 
     /** Applies this transform to a view. */
-    public void applyToTaskView(View v, int duration, Interpolator interp, boolean allowLayers) {
+    public void applyToTaskView(View v, int duration, Interpolator interp, boolean allowLayers,
+            boolean allowShadows, ValueAnimator.AnimatorUpdateListener updateCallback) {
         // Check to see if any properties have changed, and update the task view
         if (duration > 0) {
             ViewPropertyAnimator anim = v.animate();
@@ -87,8 +88,7 @@
             if (hasTranslationYChangedFrom(v.getTranslationY())) {
                 anim.translationY(translationY);
             }
-            if (Constants.DebugFlags.App.EnableShadows &&
-                    hasTranslationZChangedFrom(v.getTranslationZ())) {
+            if (allowShadows && hasTranslationZChangedFrom(v.getTranslationZ())) {
                 anim.translationZ(translationZ);
             }
             if (hasScaleChangedFrom(v.getScaleX())) {
@@ -104,6 +104,11 @@
             if (requiresLayers && allowLayers) {
                 anim.withLayer();
             }
+            if (updateCallback != null) {
+                anim.setUpdateListener(updateCallback);
+            } else {
+                anim.setUpdateListener(null);
+            }
             anim.setStartDelay(startDelay)
                     .setDuration(duration)
                     .setInterpolator(interp)
@@ -113,8 +118,7 @@
             if (hasTranslationYChangedFrom(v.getTranslationY())) {
                 v.setTranslationY(translationY);
             }
-            if (Constants.DebugFlags.App.EnableShadows &&
-                    hasTranslationZChangedFrom(v.getTranslationZ())) {
+            if (allowShadows && hasTranslationZChangedFrom(v.getTranslationZ())) {
                 v.setTranslationZ(translationZ);
             }
             if (hasScaleChangedFrom(v.getScaleX())) {
@@ -131,9 +135,7 @@
     public static void reset(View v) {
         v.setTranslationX(0f);
         v.setTranslationY(0f);
-        if (Constants.DebugFlags.App.EnableShadows) {
-            v.setTranslationZ(0f);
-        }
+        v.setTranslationZ(0f);
         v.setScaleX(1f);
         v.setScaleY(1f);
         v.setAlpha(1f);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java b/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java
index a1fc40f..4586f12 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.recents.views;
 
+import android.animation.ValueAnimator;
 import android.graphics.Rect;
 import com.android.systemui.recents.misc.ReferenceCountedTrigger;
 
@@ -27,6 +28,8 @@
         // A trigger to run some logic when all the animations complete.  This works around the fact
         // that it is difficult to coordinate ViewPropertyAnimators
         ReferenceCountedTrigger postAnimationTrigger;
+        // An update listener to notify as the enter animation progresses (used for the home transition)
+        ValueAnimator.AnimatorUpdateListener updateListener;
 
         // These following properties are updated for each task view we start the enter animation on
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index e323dd6..754fade 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -25,6 +25,8 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.RemoteException;
@@ -91,6 +93,8 @@
 
     private final TrustDrawable mTrustDrawable;
 
+    private int mLastUnlockIconRes = 0;
+
     public KeyguardBottomAreaView(Context context) {
         this(context, null);
     }
@@ -380,7 +384,17 @@
                 ? com.android.internal.R.drawable.ic_account_circle
                 : mUnlockMethodCache.isMethodInsecure() ? R.drawable.ic_lock_open_24dp
                 : R.drawable.ic_lock_24dp;
-        mLockIcon.setImageResource(iconRes);
+        if (mLastUnlockIconRes != iconRes) {
+            Drawable icon = mContext.getDrawable(iconRes);
+            int iconHeight = getResources().getDimensionPixelSize(
+                    R.dimen.keyguard_affordance_icon_height);
+            int iconWidth = getResources().getDimensionPixelSize(
+                    R.dimen.keyguard_affordance_icon_width);
+            if (icon.getIntrinsicHeight() != iconHeight || icon.getIntrinsicWidth() != iconWidth) {
+                icon = new IntrinsicSizeDrawable(icon, iconWidth, iconHeight);
+            }
+            mLockIcon.setImageDrawable(icon);
+        }
         boolean trustManaged = mUnlockMethodCache.isTrustManaged();
         mTrustDrawable.setTrustManaged(trustManaged);
         updateLockIconClickability();
@@ -469,4 +483,30 @@
             KeyguardIndicationController keyguardIndicationController) {
         mIndicationController = keyguardIndicationController;
     }
+
+
+    /**
+     * A wrapper around another Drawable that overrides the intrinsic size.
+     */
+    private static class IntrinsicSizeDrawable extends InsetDrawable {
+
+        private final int mIntrinsicWidth;
+        private final int mIntrinsicHeight;
+
+        public IntrinsicSizeDrawable(Drawable drawable, int intrinsicWidth, int intrinsicHeight) {
+            super(drawable, 0);
+            mIntrinsicWidth = intrinsicWidth;
+            mIntrinsicHeight = intrinsicHeight;
+        }
+
+        @Override
+        public int getIntrinsicWidth() {
+            return mIntrinsicWidth;
+        }
+
+        @Override
+        public int getIntrinsicHeight() {
+            return mIntrinsicHeight;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
index 685c184..4715d0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -67,8 +67,7 @@
 
     @Override
     public void onClick(View v) {
-        final UserManager um = UserManager.get(getContext());
-        if (um.isUserSwitcherEnabled()) {
+        if (opensUserSwitcherWhenClicked()) {
             if (mKeyguardMode) {
                 if (mKeyguardUserSwitcher != null) {
                     mKeyguardUserSwitcher.show(true /* animate */);
@@ -92,9 +91,8 @@
         super.onPopulateAccessibilityEvent(event);
 
         if (isClickable()) {
-            final UserManager um = UserManager.get(getContext());
             String text;
-            if (um.isUserSwitcherEnabled()) {
+            if (opensUserSwitcherWhenClicked()) {
                 String currentUser = null;
                 if (mQsPanel != null) {
                     UserSwitcherController controller = mQsPanel.getHost()
@@ -122,4 +120,9 @@
     public boolean hasOverlappingRendering() {
         return false;
     }
+
+    private boolean opensUserSwitcherWhenClicked() {
+        UserManager um = UserManager.get(getContext());
+        return UserManager.supportsMultipleUsers() && um.isUserSwitcherEnabled();
+    }
 }
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 1b4254c..353c887 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1485,7 +1485,11 @@
         updateClearAll();
         updateEmptyShadeView();
 
-        mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned());
+        // Disable QS if device not provisioned.
+        // If the user switcher is simple then disable QS during setup because
+        // the user intends to use the lock screen user switcher, QS in not needed.
+        mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned()
+                && (!mUserSwitcherController.isSimpleUserSwitcher() || mUserSetup));
         mShadeUpdates.check();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index 15a7229..cb9abfd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -207,6 +207,8 @@
         FontSizeUtils.updateFontSize(mAmPm, R.dimen.qs_time_collapsed_size);
         FontSizeUtils.updateFontSize(this, R.id.empty_time_view, R.dimen.qs_time_expanded_size);
 
+        mEmergencyCallsOnly.setText(com.android.internal.R.string.emergency_calls_only);
+
         mClockCollapsedSize = getResources().getDimensionPixelSize(R.dimen.qs_time_collapsed_size);
         mClockExpandedSize = getResources().getDimensionPixelSize(R.dimen.qs_time_expanded_size);
         mClockCollapsedScaleFactor = (float) mClockCollapsedSize / (float) mClockExpandedSize;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
new file mode 100644
index 0000000..a3765aa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.CanvasProperty;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
+import android.view.HardwareCanvas;
+import android.view.RenderNodeAnimator;
+import android.view.View;
+import android.view.animation.Interpolator;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+public class KeyButtonRipple extends Drawable {
+
+    private static final float GLOW_MAX_SCALE_FACTOR = 1.35f;
+    private static final float GLOW_MAX_ALPHA = 0.2f;
+    private static final int ANIMATION_DURATION_SCALE = 350;
+    private static final int ANIMATION_DURATION_FADE = 450;
+
+    private Paint mRipplePaint;
+    private CanvasProperty<Float> mLeftProp;
+    private CanvasProperty<Float> mTopProp;
+    private CanvasProperty<Float> mRightProp;
+    private CanvasProperty<Float> mBottomProp;
+    private CanvasProperty<Float> mRxProp;
+    private CanvasProperty<Float> mRyProp;
+    private CanvasProperty<Paint> mPaintProp;
+    private float mGlowAlpha = 0f;
+    private float mGlowScale = 1f;
+    private boolean mPressed;
+    private boolean mDrawingHardwareGlow;
+    private int mMaxWidth;
+
+    private final Interpolator mInterpolator = new LogInterpolator();
+    private final Interpolator mAlphaExitInterpolator = PhoneStatusBar.ALPHA_OUT;
+    private boolean mSupportHardware;
+    private final View mTargetView;
+
+    private final HashSet<Animator> mRunningAnimations = new HashSet<>();
+    private final ArrayList<Animator> mTmpArray = new ArrayList<>();
+
+    public KeyButtonRipple(Context ctx, View targetView) {
+        mMaxWidth =  ctx.getResources().getDimensionPixelSize(R.dimen.key_button_ripple_max_width);
+        mTargetView = targetView;
+    }
+
+    private Paint getRipplePaint() {
+        if (mRipplePaint == null) {
+            mRipplePaint = new Paint();
+            mRipplePaint.setAntiAlias(true);
+            mRipplePaint.setColor(0xffffffff);
+        }
+        return mRipplePaint;
+    }
+
+    private void drawSoftware(Canvas canvas) {
+        if (mGlowAlpha > 0f) {
+            final Paint p = getRipplePaint();
+            p.setAlpha((int)(mGlowAlpha * 255f));
+
+            final float w = getBounds().width();
+            final float h = getBounds().height();
+            final boolean horizontal = w > h;
+            final float diameter = getRippleSize() * mGlowScale;
+            final float radius = diameter * .5f;
+            final float cx = w * .5f;
+            final float cy = h * .5f;
+            final float rx = horizontal ? radius : cx;
+            final float ry = horizontal ? cy : radius;
+            final float corner = horizontal ? cy : cx;
+
+            canvas.drawRoundRect(cx - rx, cy - ry,
+                    cx + rx, cy + ry,
+                    corner, corner, p);
+        }
+    }
+
+
+    @Override
+    public void draw(Canvas canvas) {
+        mSupportHardware = canvas.isHardwareAccelerated();
+        if (mSupportHardware) {
+            drawHardware((HardwareCanvas) canvas);
+        } else {
+            drawSoftware(canvas);
+        }
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        // Not supported.
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter cf) {
+        // Not supported.
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.TRANSLUCENT;
+    }
+
+    private boolean isHorizontal() {
+        return getBounds().width() > getBounds().height();
+    }
+
+    private void drawHardware(HardwareCanvas c) {
+        if (mDrawingHardwareGlow) {
+            c.drawRoundRect(mLeftProp, mTopProp, mRightProp, mBottomProp, mRxProp, mRyProp,
+                    mPaintProp);
+        }
+    }
+
+    public float getGlowAlpha() {
+        return mGlowAlpha;
+    }
+
+    public void setGlowAlpha(float x) {
+        mGlowAlpha = x;
+        invalidateSelf();
+    }
+
+    public float getGlowScale() {
+        return mGlowScale;
+    }
+
+    public void setGlowScale(float x) {
+        mGlowScale = x;
+        invalidateSelf();
+    }
+
+    @Override
+    protected boolean onStateChange(int[] state) {
+        boolean pressed = false;
+        for (int i = 0; i < state.length; i++) {
+            if (state[i] == android.R.attr.state_pressed) {
+                pressed = true;
+                break;
+            }
+        }
+        if (pressed != mPressed) {
+            setPressed(pressed);
+            mPressed = pressed;
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public boolean isStateful() {
+        return true;
+    }
+
+    public void setPressed(boolean pressed) {
+        if (mSupportHardware) {
+            setPressedHardware(pressed);
+        } else {
+            setPressedSoftware(pressed);
+        }
+    }
+
+    private void cancelAnimations() {
+        mTmpArray.addAll(mRunningAnimations);
+        int size = mTmpArray.size();
+        for (int i = 0; i < size; i++) {
+            Animator a = mTmpArray.get(i);
+            a.cancel();
+        }
+        mTmpArray.clear();
+        mRunningAnimations.clear();
+    }
+
+    private void setPressedSoftware(boolean pressed) {
+        if (pressed) {
+            enterSoftware();
+        } else {
+            exitSoftware();
+        }
+    }
+
+    private void enterSoftware() {
+        cancelAnimations();
+        mGlowAlpha = GLOW_MAX_ALPHA;
+        ObjectAnimator scaleAnimator = ObjectAnimator.ofFloat(this, "glowScale",
+                0f, GLOW_MAX_SCALE_FACTOR);
+        scaleAnimator.setInterpolator(mInterpolator);
+        scaleAnimator.setDuration(ANIMATION_DURATION_SCALE);
+        scaleAnimator.addListener(mAnimatorListener);
+        scaleAnimator.start();
+        mRunningAnimations.add(scaleAnimator);
+    }
+
+    private void exitSoftware() {
+        ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(this, "glowAlpha", mGlowAlpha, 0f);
+        alphaAnimator.setInterpolator(mAlphaExitInterpolator);
+        alphaAnimator.setDuration(ANIMATION_DURATION_FADE);
+        alphaAnimator.addListener(mAnimatorListener);
+        alphaAnimator.start();
+        mRunningAnimations.add(alphaAnimator);
+    }
+
+    private void setPressedHardware(boolean pressed) {
+        if (pressed) {
+            enterHardware();
+        } else {
+            exitHardware();
+        }
+    }
+
+    /**
+     * Sets the left/top property for the round rect to {@code prop} depending on whether we are
+     * horizontal or vertical mode.
+     */
+    private void setExtendStart(CanvasProperty<Float> prop) {
+        if (isHorizontal()) {
+            mLeftProp = prop;
+        } else {
+            mTopProp = prop;
+        }
+    }
+
+    private CanvasProperty<Float> getExtendStart() {
+        return isHorizontal() ? mLeftProp : mTopProp;
+    }
+
+    /**
+     * Sets the right/bottom property for the round rect to {@code prop} depending on whether we are
+     * horizontal or vertical mode.
+     */
+    private void setExtendEnd(CanvasProperty<Float> prop) {
+        if (isHorizontal()) {
+            mRightProp = prop;
+        } else {
+            mBottomProp = prop;
+        }
+    }
+
+    private CanvasProperty<Float> getExtendEnd() {
+        return isHorizontal() ? mRightProp : mBottomProp;
+    }
+
+    private int getExtendSize() {
+        return isHorizontal() ? getBounds().width() : getBounds().height();
+    }
+
+    private int getRippleSize() {
+        int size = isHorizontal() ? getBounds().width() : getBounds().height();
+        return Math.min(size, mMaxWidth);
+    }
+
+    private void enterHardware() {
+        cancelAnimations();
+        mDrawingHardwareGlow = true;
+        setExtendStart(CanvasProperty.createFloat(getExtendSize() / 2));
+        final RenderNodeAnimator startAnim = new RenderNodeAnimator(getExtendStart(),
+                getExtendSize()/2 - GLOW_MAX_SCALE_FACTOR * getRippleSize()/2);
+        startAnim.setDuration(ANIMATION_DURATION_SCALE);
+        startAnim.setInterpolator(mInterpolator);
+        startAnim.addListener(mAnimatorListener);
+        startAnim.setTarget(mTargetView);
+
+        setExtendEnd(CanvasProperty.createFloat(getExtendSize() / 2));
+        final RenderNodeAnimator endAnim = new RenderNodeAnimator(getExtendEnd(),
+                getExtendSize()/2 + GLOW_MAX_SCALE_FACTOR * getRippleSize()/2);
+        endAnim.setDuration(ANIMATION_DURATION_SCALE);
+        endAnim.setInterpolator(mInterpolator);
+        endAnim.addListener(mAnimatorListener);
+        endAnim.setTarget(mTargetView);
+
+        if (isHorizontal()) {
+            mTopProp = CanvasProperty.createFloat(0f);
+            mBottomProp = CanvasProperty.createFloat(getBounds().height());
+            mRxProp = CanvasProperty.createFloat(getBounds().height()/2);
+            mRyProp = CanvasProperty.createFloat(getBounds().height()/2);
+        } else {
+            mLeftProp = CanvasProperty.createFloat(0f);
+            mRightProp = CanvasProperty.createFloat(getBounds().width());
+            mRxProp = CanvasProperty.createFloat(getBounds().width()/2);
+            mRyProp = CanvasProperty.createFloat(getBounds().width()/2);
+        }
+
+        mGlowScale = GLOW_MAX_SCALE_FACTOR;
+        mGlowAlpha = GLOW_MAX_ALPHA;
+        mRipplePaint = getRipplePaint();
+        mRipplePaint.setAlpha((int) (mGlowAlpha * 255));
+        mPaintProp = CanvasProperty.createPaint(mRipplePaint);
+
+        startAnim.start();
+        endAnim.start();
+        mRunningAnimations.add(startAnim);
+        mRunningAnimations.add(endAnim);
+
+        invalidateSelf();
+    }
+
+    private void exitHardware() {
+        mPaintProp = CanvasProperty.createPaint(getRipplePaint());
+        final RenderNodeAnimator opacityAnim = new RenderNodeAnimator(mPaintProp,
+                RenderNodeAnimator.PAINT_ALPHA, 0);
+        opacityAnim.setDuration(ANIMATION_DURATION_FADE);
+        opacityAnim.setInterpolator(mAlphaExitInterpolator);
+        opacityAnim.addListener(mAnimatorListener);
+        opacityAnim.setTarget(mTargetView);
+
+        opacityAnim.start();
+        mRunningAnimations.add(opacityAnim);
+
+        invalidateSelf();
+    }
+
+    private final AnimatorListenerAdapter mAnimatorListener =
+            new AnimatorListenerAdapter() {
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            mRunningAnimations.remove(animation);
+            if (mRunningAnimations.isEmpty() && !mPressed) {
+                mDrawingHardwareGlow = false;
+                invalidateSelf();
+            }
+        }
+    };
+
+    /**
+     * Interpolator with a smooth log deceleration
+     */
+    private static final class LogInterpolator implements Interpolator {
+        @Override
+        public float getInterpolation(float input) {
+            return 1 - (float) Math.pow(400, -input * 1.4);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index b814b61..7cc75da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
+import android.graphics.CanvasProperty;
 import android.graphics.Paint;
 import android.graphics.RectF;
 import android.hardware.input.InputManager;
@@ -32,11 +33,14 @@
 import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.MathUtils;
 import android.view.HapticFeedbackConstants;
+import android.view.HardwareCanvas;
 import android.view.InputDevice;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
+import android.view.RenderNodeAnimator;
 import android.view.SoundEffectConstants;
 import android.view.View;
 import android.view.ViewConfiguration;
@@ -44,6 +48,7 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.ImageView;
 import java.lang.Math;
+import java.util.ArrayList;
 
 import com.android.systemui.R;
 
@@ -56,22 +61,15 @@
 
     // TODO: Get rid of this
     public static final float DEFAULT_QUIESCENT_ALPHA = 1f;
-    public static final float MAX_ALPHA = 0.15f;
-    public static final float GLOW_MAX_SCALE_FACTOR = 1.5f;
 
     private long mDownTime;
     private int mCode;
     private int mTouchSlop;
-    private float mGlowAlpha = 0f;
-    private float mGlowScale = 1f;
     private float mDrawingAlpha = 1f;
     private float mQuiescentAlpha = DEFAULT_QUIESCENT_ALPHA;
     private boolean mSupportsLongpress = true;
-    private AnimatorSet mPressedAnim;
-    private Animator mAnimateToQuiescent = new ObjectAnimator();
-    private Paint mRipplePaint;
-    private final TimeInterpolator mInterpolator = (TimeInterpolator) new LogInterpolator();
     private AudioManager mAudioManager;
+    private Animator mAnimateToQuiescent = new ObjectAnimator();
 
     private final Runnable mCheckLongPress = new Runnable() {
         public void run() {
@@ -110,6 +108,7 @@
         setClickable(true);
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        setBackground(new KeyButtonRipple(context, this));
     }
 
     @Override
@@ -141,38 +140,6 @@
         return super.performAccessibilityAction(action, arguments);
     }
 
-    private Paint getRipplePaint() {
-        if (mRipplePaint == null) {
-            mRipplePaint = new Paint();
-            mRipplePaint.setAntiAlias(true);
-            mRipplePaint.setColor(0xffffffff);
-        }
-        return mRipplePaint;
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        final Paint p = getRipplePaint();
-        p.setAlpha((int)(MAX_ALPHA * mDrawingAlpha * mGlowAlpha * 255));
-
-        final float w = getWidth();
-        final float h = getHeight();
-        final boolean horizontal = w > h;
-        final float diameter = (horizontal ? w : h) * mGlowScale;
-        final float radius = diameter * .5f;
-        final float cx = w * .5f;
-        final float cy = h * .5f;
-        final float rx = horizontal ? radius : cx;
-        final float ry = horizontal ? cy : radius;
-        final float corner = horizontal ? cy : cx;
-
-        canvas.drawRoundRect(cx - rx, cy - ry,
-                             cx + rx, cy + ry,
-                             corner, corner, p);
-
-        super.onDraw(canvas);
-    }
-
     public void setQuiescentAlpha(float alpha, boolean animate) {
         mAnimateToQuiescent.cancel();
         alpha = Math.min(Math.max(alpha, 0), 1);
@@ -204,76 +171,6 @@
         mDrawingAlpha = x;
     }
 
-    public float getGlowAlpha() {
-        return mGlowAlpha;
-    }
-
-    public void setGlowAlpha(float x) {
-        mGlowAlpha = x;
-        invalidate();
-    }
-
-    public float getGlowScale() {
-        return mGlowScale;
-    }
-
-    public void setGlowScale(float x) {
-        mGlowScale = x;
-        final float w = getWidth();
-        final float h = getHeight();
-        if (GLOW_MAX_SCALE_FACTOR <= 1.0f) {
-            // this only works if we know the glow will never leave our bounds
-            invalidate();
-        } else {
-            final float rx = (w * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f;
-            final float ry = (h * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f;
-            com.android.systemui.SwipeHelper.invalidateGlobalRegion(
-                    this,
-                    new RectF(getLeft() - rx,
-                              getTop() - ry,
-                              getRight() + rx,
-                              getBottom() + ry));
-
-            // also invalidate our immediate parent to help avoid situations where nearby glows
-            // interfere
-            ((View)getParent()).invalidate();
-        }
-    }
-
-    public void setPressed(boolean pressed) {
-        if (pressed != isPressed()) {
-            if (mPressedAnim != null && mPressedAnim.isRunning()) {
-                mPressedAnim.cancel();
-            }
-            final AnimatorSet as = mPressedAnim = new AnimatorSet();
-            final ObjectAnimator scaleAnimator = ObjectAnimator.ofFloat(this,
-                    "glowScale", GLOW_MAX_SCALE_FACTOR);
-            scaleAnimator.setInterpolator(mInterpolator);
-            if (pressed) {
-                mGlowScale = 0f;
-                if (mGlowAlpha < mQuiescentAlpha)
-                    mGlowAlpha = mQuiescentAlpha;
-                setDrawingAlpha(1f);
-                as.playTogether(
-                    ObjectAnimator.ofFloat(this, "glowAlpha", 1f),
-                    scaleAnimator
-                );
-                as.setDuration(500);
-            } else {
-                mAnimateToQuiescent.cancel();
-                mAnimateToQuiescent = animateToQuiescent();
-                as.playTogether(
-                    ObjectAnimator.ofFloat(this, "glowAlpha", mGlowAlpha, mGlowAlpha * .2f, 0f),
-                    scaleAnimator,
-                    mAnimateToQuiescent
-                );
-                as.setDuration(500);
-            }
-            as.start();
-        }
-        super.setPressed(pressed);
-    }
-
     public boolean onTouchEvent(MotionEvent ev) {
         final int action = ev.getAction();
         int x, y;
@@ -354,17 +251,6 @@
         InputManager.getInstance().injectInputEvent(ev,
                 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
     }
-
-    /**
-    * Interpolator with a smooth log deceleration
-    */
-    private static final class LogInterpolator implements TimeInterpolator {
-        @Override
-        public float getInterpolation(float input) {
-            return 1 - (float) Math.pow(400, -input * 1.4);
-        }
-    }
-
 }
 
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index e8f35fd..bbe6622 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -227,7 +227,14 @@
         int id;
         if (record.isGuest && record.info == null) {
             // No guest user. Create one.
-            id = mUserManager.createGuest(mContext, mContext.getString(R.string.guest_nickname)).id;
+            UserInfo guest = mUserManager.createGuest(
+                    mContext, mContext.getString(R.string.guest_nickname));
+            if (guest == null) {
+                // Couldn't create guest, most likely because there already exists one, we just
+                // haven't reloaded the user list yet.
+                return;
+            }
+            id = guest.id;
         } else if (record.isAddUser) {
             showAddUserDialog();
             return;
@@ -564,8 +571,14 @@
                 cancel();
             } else {
                 dismiss();
-                int id = mUserManager.createUser(
-                        mContext.getString(R.string.user_new_user_name), 0 /* flags */).id;
+                UserInfo user = mUserManager.createUser(
+                        mContext.getString(R.string.user_new_user_name), 0 /* flags */);
+                if (user == null) {
+                    // Couldn't create user, most likely because there are too many, but we haven't
+                    // been able to reload the list yet.
+                    return;
+                }
+                int id = user.id;
                 Bitmap icon = UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon(
                         id, /* light= */ false));
                 mUserManager.setUserIcon(id, icon);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
index 6d30bce..66e1e15 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
@@ -32,6 +32,7 @@
 public class SegmentedButtons extends LinearLayout {
     private static final Typeface MEDIUM = Typeface.create("sans-serif-medium", Typeface.NORMAL);
     private static final Typeface BOLD = Typeface.create("sans-serif", Typeface.BOLD);
+    private static final int LABEL_RES_KEY = R.id.label;
 
     private final Context mContext;
     private final LayoutInflater mInflater;
@@ -69,6 +70,7 @@
 
     public void addButton(int labelResId, Object value) {
         final Button b = (Button) mInflater.inflate(R.layout.segmented_button, this, false);
+        b.setTag(LABEL_RES_KEY, labelResId);
         b.setText(labelResId);
         final LayoutParams lp = (LayoutParams) b.getLayoutParams();
         if (getChildCount() == 0) {
@@ -80,6 +82,14 @@
         b.setOnClickListener(mClick);
     }
 
+    public void updateLocale() {
+        for (int i = 0; i < getChildCount(); i++) {
+            final Button b = (Button) getChildAt(i);
+            final int labelResId = (Integer) b.getTag(LABEL_RES_KEY);
+            b.setText(labelResId);
+        }
+    }
+
     private void fireOnSelected() {
         if (mCallback != null) {
             mCallback.onSelected(mSelectedValue);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index f829994..2b541d3 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -120,7 +120,10 @@
         super.onFinishInflate();
 
         mZenButtons = (SegmentedButtons) findViewById(R.id.zen_buttons);
-        addZenButtons();
+        mZenButtons.addButton(R.string.interruption_level_none, Global.ZEN_MODE_NO_INTERRUPTIONS);
+        mZenButtons.addButton(R.string.interruption_level_priority,
+                Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+        mZenButtons.addButton(R.string.interruption_level_all, Global.ZEN_MODE_OFF);
         mZenButtons.setCallback(mZenButtonsCallback);
 
         mZenSubhead = findViewById(R.id.zen_subhead);
@@ -170,13 +173,6 @@
         setExpanded(false);
     }
 
-    private void addZenButtons() {
-        mZenButtons.addButton(R.string.interruption_level_none, Global.ZEN_MODE_NO_INTERRUPTIONS);
-        mZenButtons.addButton(R.string.interruption_level_priority,
-                Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
-        mZenButtons.addButton(R.string.interruption_level_all, Global.ZEN_MODE_OFF);
-    }
-
     public void setHidden(boolean hidden) {
         if (mHidden == hidden) return;
         mHidden = hidden;
@@ -238,8 +234,7 @@
     }
 
     public void updateLocale() {
-        mZenButtons.removeAllViews();
-        addZenButtons();
+        mZenButtons.updateLocale();
     }
 
     private void setExitCondition(Condition exitCondition) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 6f7f1fb..94c1676 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -2125,8 +2125,7 @@
         }
     }
 
-    private final class DecorView extends FrameLayout implements RootViewSurfaceTaker,
-            View.OnSystemUiVisibilityChangeListener {
+    private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {
         /* package */int mDefaultOpacity = PixelFormat.OPAQUE;
 
         /** The feature ID of the panel, or -1 if this is the application's DecorView */
@@ -2163,7 +2162,6 @@
         private int mLastTopInset = 0;
         private int mLastBottomInset = 0;
         private int mLastRightInset = 0;
-        private int mLastSystemUiVisibility = 0;
 
 
         public DecorView(Context context, int featureId) {
@@ -2642,19 +2640,35 @@
             } else {
                 if (mActionModeView == null) {
                     if (isFloating()) {
-                        mActionModeView = new ActionBarContextView(mContext);
-                        mActionModePopup = new PopupWindow(mContext, null,
+                        // Use the action bar theme.
+                        final TypedValue outValue = new TypedValue();
+                        final Theme baseTheme = mContext.getTheme();
+                        baseTheme.resolveAttribute(R.attr.actionBarTheme, outValue, true);
+
+                        final Context actionBarContext;
+                        if (outValue.resourceId != 0) {
+                            final Theme actionBarTheme = mContext.getResources().newTheme();
+                            actionBarTheme.setTo(baseTheme);
+                            actionBarTheme.applyStyle(outValue.resourceId, true);
+
+                            actionBarContext = new ContextThemeWrapper(mContext, 0);
+                            actionBarContext.getTheme().setTo(actionBarTheme);
+                        } else {
+                            actionBarContext = mContext;
+                        }
+
+                        mActionModeView = new ActionBarContextView(actionBarContext);
+                        mActionModePopup = new PopupWindow(actionBarContext, null,
                                 R.attr.actionModePopupWindowStyle);
                         mActionModePopup.setWindowLayoutType(
                                 WindowManager.LayoutParams.TYPE_APPLICATION);
                         mActionModePopup.setContentView(mActionModeView);
                         mActionModePopup.setWidth(MATCH_PARENT);
 
-                        TypedValue heightValue = new TypedValue();
-                        mContext.getTheme().resolveAttribute(
-                                R.attr.actionBarSize, heightValue, true);
-                        final int height = TypedValue.complexToDimensionPixelSize(heightValue.data,
-                                mContext.getResources().getDisplayMetrics());
+                        actionBarContext.getTheme().resolveAttribute(
+                                R.attr.actionBarSize, outValue, true);
+                        final int height = TypedValue.complexToDimensionPixelSize(outValue.data,
+                                actionBarContext.getResources().getDisplayMetrics());
                         mActionModeView.setContentHeight(height);
                         mActionModePopup.setHeight(WRAP_CONTENT);
                         mShowActionModePopup = new Runnable() {
@@ -2675,8 +2689,8 @@
 
                 if (mActionModeView != null) {
                     mActionModeView.killMode();
-                    mode = new StandaloneActionMode(getContext(), mActionModeView, wrappedCallback,
-                            mActionModePopup == null);
+                    mode = new StandaloneActionMode(mActionModeView.getContext(), mActionModeView,
+                            wrappedCallback, mActionModePopup == null);
                     if (callback.onCreateActionMode(mode, mode.getMenu())) {
                         mode.invalidate();
                         mActionModeView.initForMode(mode);
@@ -2744,8 +2758,7 @@
         }
 
         @Override
-        public void onSystemUiVisibilityChange(int visible) {
-            mLastSystemUiVisibility = visible;
+        public void onWindowSystemUiVisibilityChanged(int visible) {
             updateColorViews(null /* insets */);
         }
 
@@ -2767,6 +2780,9 @@
         }
 
         private WindowInsets updateColorViews(WindowInsets insets) {
+            WindowManager.LayoutParams attrs = getAttributes();
+            int sysUiVisibility = attrs.systemUiVisibility | getWindowSystemUiVisibility();
+
             if (!mIsFloating && ActivityManager.isHighEndGfx()) {
                 if (insets != null) {
                     mLastTopInset = Math.min(insets.getStableInsetTop(),
@@ -2776,13 +2792,13 @@
                     mLastRightInset = Math.min(insets.getStableInsetRight(),
                             insets.getSystemWindowInsetRight());
                 }
-                mStatusColorView = updateColorViewInt(mStatusColorView,
+                mStatusColorView = updateColorViewInt(mStatusColorView, sysUiVisibility,
                         SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS,
                         mStatusBarColor, mLastTopInset, Gravity.TOP,
                         STATUS_BAR_BACKGROUND_TRANSITION_NAME,
                         com.android.internal.R.id.statusBarBackground,
                         (getAttributes().flags & FLAG_FULLSCREEN) != 0);
-                mNavigationColorView = updateColorViewInt(mNavigationColorView,
+                mNavigationColorView = updateColorViewInt(mNavigationColorView, sysUiVisibility,
                         SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION,
                         mNavigationBarColor, mLastBottomInset, Gravity.BOTTOM,
                         NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME,
@@ -2790,9 +2806,6 @@
                         false /* hiddenByWindowFlag */);
             }
 
-            WindowManager.LayoutParams attrs = getAttributes();
-            int sysUiVisibility = attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility;
-
             // When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, we still need
             // to ensure that the rest of the view hierarchy doesn't notice it, unless they've
             // explicitly asked for it.
@@ -2800,7 +2813,7 @@
             boolean consumingNavBar =
                     (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
                             && (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
-                            && (mLastSystemUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
+                            && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
 
             int consumedRight = consumingNavBar ? mLastRightInset : 0;
             int consumedBottom = consumingNavBar ? mLastBottomInset : 0;
@@ -2812,24 +2825,32 @@
                     lp.rightMargin = consumedRight;
                     lp.bottomMargin = consumedBottom;
                     mContentRoot.setLayoutParams(lp);
+
+                    if (insets == null) {
+                        // The insets have changed, but we're not currently in the process
+                        // of dispatching them.
+                        requestApplyInsets();
+                    }
+                }
+                if (insets != null) {
+                    insets = insets.replaceSystemWindowInsets(
+                            insets.getSystemWindowInsetLeft(),
+                            insets.getSystemWindowInsetTop(),
+                            insets.getSystemWindowInsetRight() - consumedRight,
+                            insets.getSystemWindowInsetBottom() - consumedBottom);
                 }
             }
 
             if (insets != null) {
-                insets = insets.consumeStableInsets().replaceSystemWindowInsets(
-                        insets.getSystemWindowInsetLeft(),
-                        insets.getSystemWindowInsetTop(),
-                        insets.getSystemWindowInsetRight() - consumedRight,
-                        insets.getSystemWindowInsetBottom() - consumedBottom
-                );
+                insets = insets.consumeStableInsets();
             }
             return insets;
         }
 
-        private View updateColorViewInt(View view, int systemUiHideFlag, int translucentFlag,
-                int color, int height, int verticalGravity, String transitionName, int id,
-                boolean hiddenByWindowFlag) {
-            boolean show = height > 0 && (mLastSystemUiVisibility & systemUiHideFlag) == 0
+        private View updateColorViewInt(View view, int sysUiVis, int systemUiHideFlag,
+                int translucentFlag, int color, int height, int verticalGravity,
+                String transitionName, int id, boolean hiddenByWindowFlag) {
+            boolean show = height > 0 && (sysUiVis & systemUiHideFlag) == 0
                     && !hiddenByWindowFlag
                     && (getAttributes().flags & translucentFlag) == 0
                     && (color & Color.BLACK) != 0
@@ -2866,32 +2887,35 @@
                 if (mActionModeView.getLayoutParams() instanceof MarginLayoutParams) {
                     MarginLayoutParams mlp = (MarginLayoutParams) mActionModeView.getLayoutParams();
                     boolean mlpChanged = false;
-                    final boolean nonOverlayShown =
-                            (getLocalFeatures() & (1 << FEATURE_ACTION_MODE_OVERLAY)) == 0
-                            && mActionModeView.isShown();
-                    if (nonOverlayShown) {
-                        // set top margin to top insets, show status guard
+                    if (mActionModeView.isShown()) {
+                        final boolean nonOverlay = (getLocalFeatures()
+                                & (1 << FEATURE_ACTION_MODE_OVERLAY)) == 0;
                         if (mlp.topMargin != insets.getSystemWindowInsetTop()) {
                             mlpChanged = true;
                             mlp.topMargin = insets.getSystemWindowInsetTop();
-                            if (mStatusGuard == null) {
-                                mStatusGuard = new View(mContext);
-                                mStatusGuard.setBackgroundColor(mContext.getResources()
-                                        .getColor(R.color.input_method_navigation_guard));
-                                addView(mStatusGuard, indexOfChild(mStatusColorView),
-                                        new LayoutParams(LayoutParams.MATCH_PARENT, mlp.topMargin,
-                                                Gravity.START | Gravity.TOP));
-                            } else {
-                                LayoutParams lp = (LayoutParams) mStatusGuard.getLayoutParams();
-                                if (lp.height != mlp.topMargin) {
-                                    lp.height = mlp.topMargin;
-                                    mStatusGuard.setLayoutParams(lp);
+
+                            // Only show status guard for non-overlay modes.
+                            if (nonOverlay) {
+                                if (mStatusGuard == null) {
+                                    mStatusGuard = new View(mContext);
+                                    mStatusGuard.setBackgroundColor(mContext.getResources()
+                                            .getColor(R.color.input_method_navigation_guard));
+                                    addView(mStatusGuard, indexOfChild(mStatusColorView),
+                                            new LayoutParams(LayoutParams.MATCH_PARENT,
+                                                    mlp.topMargin,
+                                                    Gravity.START | Gravity.TOP));
+                                } else {
+                                    LayoutParams lp = (LayoutParams) mStatusGuard.getLayoutParams();
+                                    if (lp.height != mlp.topMargin) {
+                                        lp.height = mlp.topMargin;
+                                        mStatusGuard.setLayoutParams(lp);
+                                    }
                                 }
                             }
                         }
                         insets = insets.consumeSystemWindowInsets(
-                                false, true /* top */, false, false);
-                        showStatusGuard = true;
+                                false, nonOverlay /* top */, false, false);
+                        showStatusGuard = nonOverlay;
                     } else {
                         // reset top margin
                         if (mlp.topMargin != 0) {
@@ -3305,7 +3329,6 @@
                 setFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
                         FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS & ~getForcedWindowFlags());
             }
-            decor.setOnSystemUiVisibilityChangeListener(decor);
         }
         if (!mForcedStatusBarColor) {
             mStatusBarColor = a.getColor(R.styleable.Window_statusBarColor, 0xFF000000);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 02adef4..fbaaf74 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1827,6 +1827,8 @@
             params.packageName = packageName;
             params.windowAnimations = win.getWindowStyle().getResourceId(
                     com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
+            params.privateFlags |=
+                    WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED;
             params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
 
             if (!compatInfo.supportsScreen()) {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index ebe21ff..24bfba6 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -3277,7 +3277,7 @@
                         // But we still have not gotten the window state from the
                         // window manager, so delay the notification until then.
                         AccessibilityWindowInfo window = findWindowById(event.getWindowId());
-                        if (window == null || !window.isFocused()) {
+                        if (window == null) {
                             mShowingFocusedWindowEvent = AccessibilityEvent.obtain(event);
                             return false;
                         }
@@ -3377,7 +3377,7 @@
             if (mShowingFocusedWindowEvent != null) {
                 final int windowId = mShowingFocusedWindowEvent.getWindowId();
                 AccessibilityWindowInfo window = findWindowById(windowId);
-                if (window != null && window.isFocused()) {
+                if (window != null) {
                     // Sending does the recycle.
                     sendAccessibilityEvent(mShowingFocusedWindowEvent, mCurrentUserId);
                 }
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 7716385..47396bd 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -1537,7 +1537,9 @@
         for (int i=0; i<triggerList.size(); i++) {
             Alarm alarm = triggerList.get(i);
             try {
-                Slog.v(TAG, "sending alarm " + alarm);
+                if (localLOGV) {
+                    Slog.v(TAG, "sending alarm " + alarm);
+                }
                 alarm.operation.send(getContext(), 0,
                         mBackgroundIntent.putExtra(
                                 Intent.EXTRA_ALARM_COUNT, alarm.count),
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 55d8c09..967681b 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1357,13 +1357,6 @@
                 "ConnectivityService");
     }
 
-    // TODO Make this a special check when it goes public
-    private void enforceTetherChangePermission() {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.CHANGE_NETWORK_STATE,
-                "ConnectivityService");
-    }
-
     private void enforceTetherAccessPermission() {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE,
@@ -1925,6 +1918,15 @@
                     }
                     break;
                 }
+                case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
+                    NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
+                    if (nai == null) {
+                        loge("EVENT_SET_EXPLICITLY_SELECTED from unknown NetworkAgent");
+                        break;
+                    }
+                    nai.networkMisc.explicitlySelected = true;
+                    break;
+                }
                 case NetworkMonitor.EVENT_NETWORK_TESTED: {
                     NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj;
                     if (isLiveNetworkAgent(nai, "EVENT_NETWORK_VALIDATED")) {
@@ -1935,6 +1937,11 @@
                             rematchNetworkAndRequests(nai);
                         }
                         updateInetCondition(nai, valid);
+                        // Let the NetworkAgent know the state of its network
+                        nai.asyncChannel.sendMessage(
+                                android.net.NetworkAgent.CMD_REPORT_NETWORK_STATUS,
+                                (valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK),
+                                0, null);
                     }
                     break;
                 }
@@ -2375,8 +2382,7 @@
 
     // javadoc from interface
     public int tether(String iface) {
-        enforceTetherChangePermission();
-
+        ConnectivityManager.enforceTetherChangePermission(mContext);
         if (isTetheringSupported()) {
             return mTethering.tether(iface);
         } else {
@@ -2386,7 +2392,7 @@
 
     // javadoc from interface
     public int untether(String iface) {
-        enforceTetherChangePermission();
+        ConnectivityManager.enforceTetherChangePermission(mContext);
 
         if (isTetheringSupported()) {
             return mTethering.untether(iface);
@@ -2435,7 +2441,7 @@
     }
 
     public int setUsbTethering(boolean enable) {
-        enforceTetherChangePermission();
+        ConnectivityManager.enforceTetherChangePermission(mContext);
         if (isTetheringSupported()) {
             return mTethering.setUsbTethering(enable);
         } else {
@@ -2517,6 +2523,7 @@
             nai = mNetworkForNetId.get(network.netId);
         }
         if (nai == null) return;
+        if (DBG) log("reportBadNetwork(" + nai.name() + ") by " + uid);
         synchronized (nai) {
             if (isNetworkBlocked(nai, uid)) return;
 
@@ -4244,7 +4251,7 @@
         NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
             new NetworkInfo(networkInfo), new LinkProperties(linkProperties),
             new NetworkCapabilities(networkCapabilities), currentScore, mContext, mTrackerHandler,
-            networkMisc);
+            new NetworkMisc(networkMisc));
         synchronized (this) {
             nai.networkMonitor.systemReady = mSystemReady;
         }
@@ -4546,8 +4553,10 @@
         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
             NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(nri.request.requestId);
             if (newNetwork == currentNetwork) {
-                if (DBG) log("Network " + newNetwork.name() + " was already satisfying" +
-                              " request " + nri.request.requestId + ". No change.");
+                if (DBG) {
+                    log("Network " + newNetwork.name() + " was already satisfying" +
+                            " request " + nri.request.requestId + ". No change.");
+                }
                 keep = true;
                 continue;
             }
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index fdcb3b9..cf2a49f 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -50,19 +50,16 @@
 
     // These are the built-in uid -> permission mappings that were read from the
     // system configuration files.
-    final SparseArray<HashSet<String>> mSystemPermissions =
-            new SparseArray<HashSet<String>>();
+    final SparseArray<HashSet<String>> mSystemPermissions = new SparseArray<>();
 
     // These are the built-in shared libraries that were read from the
     // system configuration files.  Keys are the library names; strings are the
     // paths to the libraries.
-    final ArrayMap<String, String> mSharedLibraries
-            = new ArrayMap<String, String>();
+    final ArrayMap<String, String> mSharedLibraries  = new ArrayMap<>();
 
     // These are the features this devices supports that were read from the
     // system configuration files.
-    final HashMap<String, FeatureInfo> mAvailableFeatures =
-            new HashMap<String, FeatureInfo>();
+    final HashMap<String, FeatureInfo> mAvailableFeatures = new HashMap<>();
 
     public static final class PermissionEntry {
         public final String name;
@@ -75,12 +72,14 @@
 
     // These are the permission -> gid mappings that were read from the
     // system configuration files.
-    final ArrayMap<String, PermissionEntry> mPermissions =
-            new ArrayMap<String, PermissionEntry>();
+    final ArrayMap<String, PermissionEntry> mPermissions = new ArrayMap<>();
 
     // These are the packages that are white-listed to be able to run in the
     // background while in power save mode, as read from the configuration files.
-    final ArraySet<String> mAllowInPowerSave = new ArraySet<String>();
+    final ArraySet<String> mAllowInPowerSave = new ArraySet<>();
+
+    // These are the app package names that should not allow IME switching.
+    final ArraySet<String> mFixedImeApps = new ArraySet<>();
 
     public static SystemConfig getInstance() {
         synchronized (SystemConfig.class) {
@@ -115,6 +114,10 @@
         return mAllowInPowerSave;
     }
 
+    public ArraySet<String> getFixedImeApps() {
+        return mFixedImeApps;
+    }
+
     SystemConfig() {
         // Read configuration from system
         readPermissions(Environment.buildPath(
@@ -298,6 +301,17 @@
                     XmlUtils.skipCurrentTag(parser);
                     continue;
 
+                } else if ("fixed-ime-app".equals(name)) {
+                    String pkgname = parser.getAttributeValue(null, "package");
+                    if (pkgname == null) {
+                        Slog.w(TAG, "<fixed-ime-app> without package at "
+                                + parser.getPositionDescription());
+                    } else {
+                        mFixedImeApps.add(pkgname);
+                    }
+                    XmlUtils.skipCurrentTag(parser);
+                    continue;
+
                 } else {
                     XmlUtils.skipCurrentTag(parser);
                     continue;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 95d33e7..741cffe 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3360,7 +3360,7 @@
                     intent.setComponent(new ComponentName(
                             ri.activityInfo.packageName, ri.activityInfo.name));
                     mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
-                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
+                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
                             null);
                 }
             }
@@ -3759,8 +3759,8 @@
             final long origId = Binder.clearCallingIdentity();
             int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
                     r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
-                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
-                    options, false, null, null, null);
+                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
+                    -1, r.launchedFromUid, 0, options, false, null, null, null);
             Binder.restoreCallingIdentity(origId);
 
             r.finishing = wasFinishing;
@@ -8375,12 +8375,17 @@
         synchronized (this) {
             ActivityRecord r = ActivityRecord.isInStackLocked(token);
             if (r != null) {
-                r.taskDescription = td;
+                r.setTaskDescription(td);
                 r.task.updateTaskDescription();
             }
         }
     }
 
+    @Override
+    public Bitmap getTaskDescriptionIcon(String filename) {
+        return mTaskPersister.getTaskDescriptionIcon(filename);
+    }
+
     private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
         mRecentTasks.remove(tr);
         tr.removedFromRecents(mTaskPersister);
@@ -8482,7 +8487,7 @@
 
     void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
-                Binder.getCallingUid(), "Task to front")) {
+                Binder.getCallingUid(), -1, -1, "Task to front")) {
             ActivityOptions.abort(options);
             return;
         }
@@ -8524,7 +8529,7 @@
                 ActivityStack stack = tr.stack;
                 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
                     if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
-                            Binder.getCallingUid(), "Task to back")) {
+                            Binder.getCallingUid(), -1, -1, "Task to back")) {
                         return;
                     }
                 }
@@ -8576,7 +8581,7 @@
 
         synchronized(this) {
             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
-                    Binder.getCallingUid(), "Task backwards")) {
+                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
                 return;
             }
             final long origId = Binder.clearCallingIdentity();
@@ -10120,20 +10125,31 @@
         }
     }
     
-    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
-            String name) {
+    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
+            int callingPid, int callingUid, String name) {
         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
             return true;
         }
 
-        final int perm = checkComponentPermission(
-                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
-                callingUid, -1, true);
+        int perm = checkComponentPermission(
+                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
+                sourceUid, -1, true);
         if (perm == PackageManager.PERMISSION_GRANTED) {
             return true;
         }
-        
-        Slog.w(TAG, name + " request from " + callingUid + " stopped");
+
+        // If the actual IPC caller is different from the logical source, then
+        // also see if they are allowed to control app switches.
+        if (callingUid != -1 && callingUid != sourceUid) {
+            perm = checkComponentPermission(
+                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
+                    callingUid, -1, true);
+            if (perm == PackageManager.PERMISSION_GRANTED) {
+                return true;
+            }
+        }
+
+        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
         return false;
     }
     
@@ -18944,13 +18960,7 @@
                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
                 }
                 if (tr.getRootActivity() != null) {
-                    long origId = Binder.clearCallingIdentity();
-                    try {
-                        moveTaskToFrontLocked(tr.taskId, 0, null);
-                        return;
-                    } finally {
-                        Binder.restoreCallingIdentity(origId);
-                    }
+                    moveTaskToFrontLocked(tr.taskId, 0, null);
                 }
             }
 
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index e043f03..2db7cec 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -205,14 +205,18 @@
                     pw.print(" resultWho="); pw.print(resultWho);
                     pw.print(" resultCode="); pw.println(requestCode);
         }
-        if (taskDescription.getIcon() != null || taskDescription.getLabel() != null ||
+        final String iconFilename = taskDescription.getIconFilename();
+        if (iconFilename != null || taskDescription.getLabel() != null ||
                 taskDescription.getPrimaryColor() != 0) {
             pw.print(prefix); pw.print("taskDescription:");
-                    pw.print(" icon="); pw.print(taskDescription.getIcon());
+                    pw.print(" iconFilename="); pw.print(taskDescription.getIconFilename());
                     pw.print(" label=\""); pw.print(taskDescription.getLabel()); pw.print("\"");
                     pw.print(" color=");
                     pw.println(Integer.toHexString(taskDescription.getPrimaryColor()));
         }
+        if (iconFilename == null && taskDescription.getIcon() != null) {
+            pw.print(prefix); pw.println("taskDescription contains Bitmap");
+        }
         if (results != null) {
             pw.print(prefix); pw.print("results="); pw.println(results);
         }
@@ -917,6 +921,7 @@
             if (displayStartTime != 0) {
                 reportLaunchTimeLocked(SystemClock.uptimeMillis());
             }
+            mStackSupervisor.sendWaitingVisibleReportLocked(this);
             startTime = 0;
             finishLaunchTickingLocked();
             if (task != null) {
@@ -1092,6 +1097,17 @@
                 TaskPersister.IMAGE_EXTENSION;
     }
 
+    void setTaskDescription(TaskDescription _taskDescription) {
+        Bitmap icon;
+        if (_taskDescription.getIconFilename() == null &&
+                (icon = _taskDescription.getIcon()) != null) {
+            final String iconFilename = createImageFilename(createTime, task.taskId);
+            mStackSupervisor.mService.mTaskPersister.saveImage(icon, iconFilename);
+            _taskDescription.setIconFilename(iconFilename);
+        }
+        taskDescription = _taskDescription;
+    }
+
     void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
         out.attribute(null, ATTR_ID, String.valueOf(createTime));
         out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid));
@@ -1105,8 +1121,7 @@
         out.attribute(null, ATTR_USERID, String.valueOf(userId));
 
         if (taskDescription != null) {
-            task.saveTaskDescription(taskDescription, createImageFilename(createTime, task.taskId),
-                    out);
+            taskDescription.saveToXml(out);
         }
 
         out.startTag(null, TAG_INTENT);
@@ -1150,9 +1165,8 @@
                 componentSpecified = Boolean.valueOf(attrValue);
             } else if (ATTR_USERID.equals(attrName)) {
                 userId = Integer.valueOf(attrValue);
-            } else if (TaskRecord.readTaskDescriptionAttribute(taskDescription, attrName,
-                    attrValue)) {
-                // Completed in TaskRecord.readTaskDescriptionAttribute()
+            } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
+                taskDescription.restoreFromXml(attrName, attrValue);
             } else {
                 Log.d(TAG, "Unknown ActivityRecord attribute=" + attrName);
             }
@@ -1196,11 +1210,6 @@
                 null, null, 0, componentSpecified, stackSupervisor, null, null);
 
         r.persistentState = persistentState;
-
-        if (createTime >= 0) {
-            taskDescription.setIcon(TaskPersister.restoreImage(createImageFilename(createTime,
-                    taskId)));
-        }
         r.taskDescription = taskDescription;
         r.createTime = createTime;
 
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index e224ac0..a75fc5a 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -550,10 +550,10 @@
 
             if (DEBUG_TASKS) Slog.d(TAG, "Comparing existing cls="
                     + taskIntent.getComponent().flattenToShortString()
-                    + "/aff=" + r.task.affinity + " to new cls="
+                    + "/aff=" + r.task.rootAffinity + " to new cls="
                     + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
-            if (!isDocument && !taskIsDocument && task.affinity != null) {
-                if (task.affinity.equals(target.taskAffinity)) {
+            if (!isDocument && !taskIsDocument && task.rootAffinity != null) {
+                if (task.rootAffinity.equals(target.taskAffinity)) {
                     if (DEBUG_TASKS) Slog.d(TAG, "Found matching affinity!");
                     return r;
                 }
@@ -2949,7 +2949,7 @@
                     int res = mStackSupervisor.startActivityLocked(srec.app.thread, destIntent,
                             null, aInfo, null, null, parent.appToken, null,
                             0, -1, parent.launchedFromUid, parent.launchedFromPackage,
-                            0, null, true, null, null, null);
+                            -1, parent.launchedFromUid, 0, null, true, null, null, null);
                     foundParentInTask = res == ActivityManager.START_SUCCESS;
                 } catch (RemoteException e) {
                     foundParentInTask = false;
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 7b6a202..482a582 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -650,31 +650,47 @@
     }
 
     void reportActivityVisibleLocked(ActivityRecord r) {
+        sendWaitingVisibleReportLocked(r);
+        notifyActivityDrawnForKeyguard();
+    }
+
+    void sendWaitingVisibleReportLocked(ActivityRecord r) {
+        boolean changed = false;
         for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
             WaitResult w = mWaitingActivityVisible.get(i);
-            w.timeout = false;
-            if (r != null) {
-                w.who = new ComponentName(r.info.packageName, r.info.name);
+            if (w.who == null) {
+                changed = true;
+                w.timeout = false;
+                if (r != null) {
+                    w.who = new ComponentName(r.info.packageName, r.info.name);
+                }
+                w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
+                w.thisTime = w.totalTime;
             }
-            w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
-            w.thisTime = w.totalTime;
         }
-        mService.notifyAll();
-        notifyActivityDrawnForKeyguard();
+        if (changed) {
+            mService.notifyAll();
+        }
     }
 
     void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
             long thisTime, long totalTime) {
+        boolean changed = false;
         for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
             WaitResult w = mWaitingActivityLaunched.remove(i);
-            w.timeout = timeout;
-            if (r != null) {
-                w.who = new ComponentName(r.info.packageName, r.info.name);
+            if (w.who == null) {
+                changed = true;
+                w.timeout = timeout;
+                if (r != null) {
+                    w.who = new ComponentName(r.info.packageName, r.info.name);
+                }
+                w.thisTime = thisTime;
+                w.totalTime = totalTime;
             }
-            w.thisTime = thisTime;
-            w.totalTime = totalTime;
         }
-        mService.notifyAll();
+        if (changed) {
+            mService.notifyAll();
+        }
     }
 
     ActivityRecord topRunningActivityLocked() {
@@ -785,8 +801,8 @@
 
     void startHomeActivity(Intent intent, ActivityInfo aInfo) {
         moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE);
-        startActivityLocked(null, intent, null, aInfo, null, null, null, null, 0, 0, 0, null, 0,
-                null, false, null, null, null);
+        startActivityLocked(null, intent, null, aInfo, null, null, null, null, 0, 0, 0, null,
+                0, 0, 0, null, false, null, null, null);
     }
 
     final int startActivityMayWait(IApplicationThread caller, int callingUid,
@@ -810,12 +826,14 @@
 
         ActivityContainer container = (ActivityContainer)iContainer;
         synchronized (mService) {
+            final int realCallingPid = Binder.getCallingPid();
+            final int realCallingUid = Binder.getCallingUid();
             int callingPid;
             if (callingUid >= 0) {
                 callingPid = -1;
             } else if (caller == null) {
-                callingPid = Binder.getCallingPid();
-                callingUid = Binder.getCallingUid();
+                callingPid = realCallingPid;
+                callingUid = realCallingUid;
             } else {
                 callingPid = callingUid = -1;
             }
@@ -841,11 +859,11 @@
                     if (mService.mHeavyWeightProcess != null &&
                             (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
                             !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
-                        int realCallingUid = callingUid;
+                        int appCallingUid = callingUid;
                         if (caller != null) {
                             ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
                             if (callerApp != null) {
-                                realCallingUid = callerApp.info.uid;
+                                appCallingUid = callerApp.info.uid;
                             } else {
                                 Slog.w(TAG, "Unable to find app for caller " + caller
                                       + " (pid=" + callingPid + ") when starting: "
@@ -857,7 +875,7 @@
 
                         IIntentSender target = mService.getIntentSenderLocked(
                                 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
-                                realCallingUid, userId, null, null, 0, new Intent[] { intent },
+                                appCallingUid, userId, null, null, 0, new Intent[] { intent },
                                 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
                                 | PendingIntent.FLAG_ONE_SHOT, null);
 
@@ -903,7 +921,8 @@
 
             int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                     voiceSession, voiceInteractor, resultTo, resultWho,
-                    requestCode, callingPid, callingUid, callingPackage, startFlags, options,
+                    requestCode, callingPid, callingUid, callingPackage,
+                    realCallingPid, realCallingUid, startFlags, options,
                     componentSpecified, null, container, inTask);
 
             Binder.restoreCallingIdentity(origId);
@@ -933,7 +952,7 @@
                     } while (!outResult.timeout && outResult.who == null);
                 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
                     ActivityRecord r = stack.topRunningActivityLocked(null);
-                    if (r.nowVisible) {
+                    if (r.nowVisible && r.state == ActivityState.RESUMED) {
                         outResult.timeout = false;
                         outResult.who = new ComponentName(r.info.packageName, r.info.name);
                         outResult.totalTime = 0;
@@ -1017,7 +1036,8 @@
                         theseOptions = null;
                     }
                     int res = startActivityLocked(caller, intent, resolvedTypes[i],
-                            aInfo, null, null, resultTo, null, -1, callingPid, callingUid, callingPackage,
+                            aInfo, null, null, resultTo, null, -1, callingPid, callingUid,
+                            callingPackage, callingPid, callingUid,
                             0, theseOptions, componentSpecified, outActivity, null, null);
                     if (res < 0) {
                         return res;
@@ -1248,7 +1268,8 @@
             Intent intent, String resolvedType, ActivityInfo aInfo,
             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
             IBinder resultTo, String resultWho, int requestCode,
-            int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
+            int callingPid, int callingUid, String callingPackage,
+            int realCallingPid, int realCallingUid, int startFlags, Bundle options,
             boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container,
             TaskRecord inTask) {
         int err = ActivityManager.START_SUCCESS;
@@ -1293,8 +1314,7 @@
 
         final int launchFlags = intent.getFlags();
 
-        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
-                && sourceRecord != null) {
+        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
             // Transfer the result target from the source activity to the new
             // one being started, including any failures.
             if (requestCode >= 0) {
@@ -1344,8 +1364,8 @@
             if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
                     && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
                 try {
-                    if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(),
-                            intent, resolvedType)) {
+                    if (!AppGlobals.getPackageManager().activitySupportsIntent(
+                            intent.getComponent(), intent, resolvedType)) {
                         err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
                     }
                 } catch (RemoteException e) {
@@ -1439,7 +1459,8 @@
         final ActivityStack stack = getFocusedStack();
         if (voiceSession == null && (stack.mResumedActivity == null
                 || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
-            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
+            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
+                    realCallingPid, realCallingUid, "Activity start")) {
                 PendingActivityLaunch pal =
                         new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
                 mPendingActivityLaunches.add(pal);
@@ -3668,7 +3689,7 @@
             }
         }
 
-        private void detachLocked() {
+        protected void detachLocked() {
             if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
                     + mActivityDisplay + " Callers=" + Debug.getCallers(2));
             if (mActivityDisplay != null) {
@@ -3792,12 +3813,6 @@
         }
 
         void onTaskListEmptyLocked() {
-            mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
-            if (!mStack.isHomeStack()) {
-                detachLocked();
-                deleteActivityContainer(this);
-            }
-            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
         }
 
         @Override
@@ -3886,6 +3901,13 @@
             return false;
         }
 
+        void onTaskListEmptyLocked() {
+            mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
+            detachLocked();
+            deleteActivityContainer(this);
+            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
+        }
+
         private void setSurfaceIfReadyLocked() {
             if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
                     " mContainerState=" + mContainerState + " mSurface=" + mSurface);
diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index b21af48..1c0564f 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -51,6 +51,12 @@
      * task being launched a chance to load its resources without this occupying IO bandwidth. */
     private static final long PRE_TASK_DELAY_MS = 3000;
 
+    /** The maximum number of entries to keep in the queue before draining it automatically. */
+    private static final int MAX_WRITE_QUEUE_LENGTH = 6;
+
+    /** Special value for mWriteTime to mean don't wait, just write */
+    private static final long FLUSH_QUEUE = -1;
+
     private static final String RECENTS_FILENAME = "_task";
     private static final String TASKS_DIRNAME = "recent_tasks";
     private static final String TASK_EXTENSION = ".xml";
@@ -120,6 +126,31 @@
         mLazyTaskWriterThread.start();
     }
 
+    private void removeThumbnails(TaskRecord task) {
+        final String taskString = Integer.toString(task.taskId);
+        for (int queueNdx = mWriteQueue.size() - 1; queueNdx >= 0; --queueNdx) {
+            final WriteQueueItem item = mWriteQueue.get(queueNdx);
+            if (item instanceof ImageWriteQueueItem &&
+                    ((ImageWriteQueueItem) item).mFilename.startsWith(taskString)) {
+                if (DEBUG) Slog.d(TAG, "Removing " + ((ImageWriteQueueItem) item).mFilename +
+                        " from write queue");
+                mWriteQueue.remove(queueNdx);
+            }
+        }
+    }
+
+    private void yieldIfQueueTooDeep() {
+        boolean stall = false;
+        synchronized (this) {
+            if (mNextWriteTime == FLUSH_QUEUE) {
+                stall = true;
+            }
+        }
+        if (stall) {
+            Thread.yield();
+        }
+    }
+
     void wakeup(TaskRecord task, boolean flush) {
         synchronized (this) {
             if (task != null) {
@@ -128,6 +159,10 @@
                     final WriteQueueItem item = mWriteQueue.get(queueNdx);
                     if (item instanceof TaskWriteQueueItem &&
                             ((TaskWriteQueueItem) item).mTask == task) {
+                        if (!task.inRecents) {
+                            // This task is being removed.
+                            removeThumbnails(task);
+                        }
                         break;
                     }
                 }
@@ -138,15 +173,18 @@
                 // Dummy.
                 mWriteQueue.add(new WriteQueueItem());
             }
-            if (flush) {
-                mNextWriteTime = -1;
+            if (flush || mWriteQueue.size() > MAX_WRITE_QUEUE_LENGTH) {
+                mNextWriteTime = FLUSH_QUEUE;
             } else if (mNextWriteTime == 0) {
                 mNextWriteTime = SystemClock.uptimeMillis() + PRE_TASK_DELAY_MS;
             }
             if (DEBUG) Slog.d(TAG, "wakeup: task=" + task + " flush=" + flush + " mNextWriteTime="
-                    + mNextWriteTime + " Callers=" + Debug.getCallers(4));
+                    + mNextWriteTime + " mWriteQueue.size=" + mWriteQueue.size()
+                    + " Callers=" + Debug.getCallers(4));
             notifyAll();
         }
+
+        yieldIfQueueTooDeep();
     }
 
     void saveImage(Bitmap image, String filename) {
@@ -166,7 +204,9 @@
             if (queueNdx < 0) {
                 mWriteQueue.add(new ImageWriteQueueItem(filename, image));
             }
-            if (mNextWriteTime == 0) {
+            if (mWriteQueue.size() > MAX_WRITE_QUEUE_LENGTH) {
+                mNextWriteTime = FLUSH_QUEUE;
+            } else if (mNextWriteTime == 0) {
                 mNextWriteTime = SystemClock.uptimeMillis() + PRE_TASK_DELAY_MS;
             }
             if (DEBUG) Slog.d(TAG, "saveImage: filename=" + filename + " now=" +
@@ -174,9 +214,20 @@
                     mNextWriteTime + " Callers=" + Debug.getCallers(4));
             notifyAll();
         }
+
+        yieldIfQueueTooDeep();
     }
 
-    Bitmap getThumbnail(String filename) {
+    Bitmap getTaskDescriptionIcon(String filename) {
+        // See if it is in the write queue
+        final Bitmap icon = getImageFromWriteQueue(filename);
+        if (icon != null) {
+            return icon;
+        }
+        return restoreImage(filename);
+    }
+
+    Bitmap getImageFromWriteQueue(String filename) {
         synchronized (this) {
             for (int queueNdx = mWriteQueue.size() - 1; queueNdx >= 0; --queueNdx) {
                 final WriteQueueItem item = mWriteQueue.get(queueNdx);
@@ -425,7 +476,7 @@
                 // If mNextWriteTime, then don't delay between each call to saveToXml().
                 final WriteQueueItem item;
                 synchronized (TaskPersister.this) {
-                    if (mNextWriteTime >= 0) {
+                    if (mNextWriteTime != FLUSH_QUEUE) {
                         // The next write we don't have to wait so long.
                         mNextWriteTime = SystemClock.uptimeMillis() + INTER_WRITE_DELAY_MS;
                         if (DEBUG) Slog.d(TAG, "Next write time may be in " +
@@ -439,13 +490,14 @@
                             TaskPersister.this.wait();
                         } catch (InterruptedException e) {
                         }
-                        // Invariant: mNextWriteTime is either -1 or PRE_WRITE_DELAY_MS from now.
+                        // Invariant: mNextWriteTime is either FLUSH_QUEUE or PRE_WRITE_DELAY_MS
+                        // from now.
                     }
                     item = mWriteQueue.remove(0);
 
                     long now = SystemClock.uptimeMillis();
                     if (DEBUG) Slog.d(TAG, "LazyTaskWriter: now=" + now + " mNextWriteTime=" +
-                            mNextWriteTime);
+                            mNextWriteTime + " mWriteQueue.size=" + mWriteQueue.size());
                     while (now < mNextWriteTime) {
                         try {
                             if (DEBUG) Slog.d(TAG, "LazyTaskWriter: waiting " +
@@ -484,7 +536,7 @@
                     TaskRecord task = ((TaskWriteQueueItem) item).mTask;
                     if (DEBUG) Slog.d(TAG, "Writing task=" + task);
                     synchronized (mService) {
-                        if (mService.mRecentTasks.contains(task)) {
+                        if (task.inRecents) {
                             // Still there.
                             try {
                                 if (DEBUG) Slog.d(TAG, "Saving task=" + task);
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 071db97..73c9783 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -25,6 +25,7 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManager.TaskThumbnail;
+import android.app.ActivityManager.TaskDescription;
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
 import android.content.ComponentName;
@@ -58,6 +59,7 @@
     private static final String ATTR_ORIGACTIVITY = "orig_activity";
     private static final String TAG_ACTIVITY = "activity";
     private static final String ATTR_AFFINITY = "affinity";
+    private static final String ATTR_ROOT_AFFINITY = "root_affinity";
     private static final String ATTR_ROOTHASRESET = "root_has_reset";
     private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
     private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
@@ -69,22 +71,20 @@
     private static final String ATTR_LASTDESCRIPTION = "last_description";
     private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
     private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
-    private static final String ATTR_TASKDESCRIPTIONLABEL = "task_description_label";
-    private static final String ATTR_TASKDESCRIPTIONCOLOR = "task_description_color";
     private static final String ATTR_TASK_AFFILIATION = "task_affiliation";
     private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
     private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
     private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
     private static final String ATTR_CALLING_UID = "calling_uid";
     private static final String ATTR_CALLING_PACKAGE = "calling_package";
-    private static final String LAST_ACTIVITY_ICON_SUFFIX = "_last_activity_icon_";
 
     private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
 
     static final boolean IGNORE_RETURN_TO_RECENTS = true;
 
     final int taskId;       // Unique identifier for this task.
-    String affinity;        // The affinity name for this task, or null.
+    String affinity;        // The affinity name for this task, or null; may change identity.
+    String rootAffinity;    // Initial base affinity, or null; does not change from initial root.
     final IVoiceInteractionSession voiceSession;    // Voice interaction session driving task
     final IVoiceInteractor voiceInteractor;         // Associated interactor to provide to app
     Intent intent;          // The original intent that started the task.
@@ -111,8 +111,7 @@
 
     // This represents the last resolved activity values for this task
     // NOTE: This value needs to be persisted with each task
-    ActivityManager.TaskDescription lastTaskDescription =
-            new ActivityManager.TaskDescription();
+    TaskDescription lastTaskDescription = new TaskDescription();
 
     /** List of all activities in the task arranged in history order */
     final ArrayList<ActivityRecord> mActivities;
@@ -178,7 +177,7 @@
     }
 
     TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
-            ActivityManager.TaskDescription _taskDescription) {
+            TaskDescription _taskDescription) {
         mService = service;
         mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
                 TaskPersister.IMAGE_EXTENSION;
@@ -208,12 +207,12 @@
     }
 
     TaskRecord(ActivityManagerService service, int _taskId, Intent _intent, Intent _affinityIntent,
-            String _affinity, ComponentName _realActivity, ComponentName _origActivity,
-            boolean _rootWasReset, boolean _autoRemoveRecents, boolean _askedCompatMode,
-            int _taskType, int _userId, int _effectiveUid,
+            String _affinity, String _rootAffinity, ComponentName _realActivity,
+            ComponentName _origActivity, boolean _rootWasReset, boolean _autoRemoveRecents,
+            boolean _askedCompatMode, int _taskType, int _userId, int _effectiveUid,
             String _lastDescription, ArrayList<ActivityRecord> activities, long _firstActiveTime,
             long _lastActiveTime, long lastTimeMoved, boolean neverRelinquishIdentity,
-            ActivityManager.TaskDescription _lastTaskDescription, int taskAffiliation,
+            TaskDescription _lastTaskDescription, int taskAffiliation,
             int prevTaskId, int nextTaskId, int taskAffiliationColor, int callingUid,
             String callingPackage) {
         mService = service;
@@ -224,6 +223,7 @@
         intent = _intent;
         affinityIntent = _affinityIntent;
         affinity = _affinity;
+        rootAffinity = _affinity;
         voiceSession = null;
         voiceInteractor = null;
         realActivity = _realActivity;
@@ -279,6 +279,12 @@
         }
 
         affinity = info.taskAffinity;
+        if (intent == null) {
+            // If this task already has an intent associated with it, don't set the root
+            // affinity -- we don't want it changing after initially set, but the initially
+            // set value may be null.
+            rootAffinity = affinity;
+        }
         effectiveUid = info.applicationInfo.uid;
         stringName = null;
 
@@ -318,8 +324,8 @@
             }
         }
 
-        if (intent != null &&
-                (intent.getFlags()&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
+        final int intentFlags = intent == null ? 0 : intent.getFlags();
+        if ((intentFlags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
             // Once we are set to an Intent with this flag, we count this
             // task as having a true root activity.
             rootWasReset = true;
@@ -329,8 +335,8 @@
         if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
             // If the activity itself has requested auto-remove, then just always do it.
             autoRemoveRecents = true;
-        } else if ((intent.getFlags()&(Intent.FLAG_ACTIVITY_NEW_DOCUMENT
-                |Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS)) == Intent.FLAG_ACTIVITY_NEW_DOCUMENT) {
+        } else if ((intentFlags & (Intent.FLAG_ACTIVITY_NEW_DOCUMENT
+                | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS)) == Intent.FLAG_ACTIVITY_NEW_DOCUMENT) {
             // If the caller has not asked for the document to be retained, then we may
             // want to turn on auto-remove, depending on whether the target has set its
             // own document launch mode.
@@ -432,7 +438,7 @@
         thumbs.mainThumbnail = mLastThumbnail;
         thumbs.thumbnailFileDescriptor = null;
         if (mLastThumbnail == null) {
-            thumbs.mainThumbnail = mService.mTaskPersister.getThumbnail(mFilename);
+            thumbs.mainThumbnail = mService.mTaskPersister.getImageFromWriteQueue(mFilename);
         }
         // Only load the thumbnail file if we don't have a thumbnail
         if (thumbs.mainThumbnail == null && mLastThumbnailFile.exists()) {
@@ -750,7 +756,7 @@
             // recent activity values, then we do not fall back to the last set
             // values in the TaskRecord.
             String label = null;
-            Bitmap icon = null;
+            String iconFilename = null;
             int colorPrimary = 0;
             for (--activityNdx; activityNdx >= 0; --activityNdx) {
                 final ActivityRecord r = mActivities.get(activityNdx);
@@ -758,15 +764,15 @@
                     if (label == null) {
                         label = r.taskDescription.getLabel();
                     }
-                    if (icon == null) {
-                        icon = r.taskDescription.getIcon();
+                    if (iconFilename == null) {
+                        iconFilename = r.taskDescription.getIconFilename();
                     }
                     if (colorPrimary == 0) {
                         colorPrimary = r.taskDescription.getPrimaryColor();
                     }
                 }
             }
-            lastTaskDescription = new ActivityManager.TaskDescription(label, icon, colorPrimary);
+            lastTaskDescription = new TaskDescription(label, colorPrimary, iconFilename);
             // Update the task affiliation color if we are the parent of the group
             if (taskId == mAffiliatedTaskId) {
                 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
@@ -775,18 +781,19 @@
     }
 
     int findEffectiveRootIndex() {
-        int activityNdx;
+        int effectiveNdx = 0;
         final int topActivityNdx = mActivities.size() - 1;
-        for (activityNdx = 0; activityNdx < topActivityNdx; ++activityNdx) {
+        for (int activityNdx = 0; activityNdx < topActivityNdx; ++activityNdx) {
             final ActivityRecord r = mActivities.get(activityNdx);
             if (r.finishing) {
                 continue;
             }
+            effectiveNdx = activityNdx;
             if ((r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
                 break;
             }
         }
-        return activityNdx;
+        return effectiveNdx;
     }
 
     void updateEffectiveIntent() {
@@ -795,41 +802,6 @@
         setIntent(r);
     }
 
-    void saveTaskDescription(ActivityManager.TaskDescription taskDescription,
-            String iconFilename, XmlSerializer out) throws IOException {
-        if (taskDescription != null) {
-            final String label = taskDescription.getLabel();
-            if (label != null) {
-                out.attribute(null, ATTR_TASKDESCRIPTIONLABEL, label);
-            }
-            final int colorPrimary = taskDescription.getPrimaryColor();
-            if (colorPrimary != 0) {
-                out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR, Integer.toHexString(colorPrimary));
-            }
-            final Bitmap icon = taskDescription.getIcon();
-            if (icon != null) {
-                mService.mTaskPersister.saveImage(icon, iconFilename);
-            }
-        }
-    }
-
-    static boolean readTaskDescriptionAttribute(ActivityManager.TaskDescription taskDescription,
-            String attrName, String attrValue) {
-        if (ATTR_TASKDESCRIPTIONLABEL.equals(attrName)) {
-            taskDescription.setLabel(attrValue);
-        } else if (ATTR_TASKDESCRIPTIONCOLOR.equals(attrName)) {
-            taskDescription.setPrimaryColor((int) Long.parseLong(attrValue, 16));
-        } else {
-            return false;
-        }
-        return true;
-    }
-
-    private static String createLastTaskDescriptionIconFilename(int taskId, long lastActiveTime) {
-        return String.valueOf(taskId) + LAST_ACTIVITY_ICON_SUFFIX + lastActiveTime +
-                TaskPersister.IMAGE_EXTENSION;
-    }
-
     void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
         if (ActivityManagerService.DEBUG_RECENTS) Slog.i(TAG, "Saving task=" + this);
 
@@ -840,8 +812,17 @@
         if (origActivity != null) {
             out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
         }
+        // Write affinity, and root affinity if it is different from affinity.
+        // We use the special string "@" for a null root affinity, so we can identify
+        // later whether we were given a root affinity or should just make it the
+        // same as the affinity.
         if (affinity != null) {
             out.attribute(null, ATTR_AFFINITY, affinity);
+            if (!affinity.equals(rootAffinity)) {
+                out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
+            }
+        } else if (rootAffinity != null) {
+            out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
         }
         out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
         out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
@@ -857,8 +838,7 @@
             out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
         }
         if (lastTaskDescription != null) {
-            saveTaskDescription(lastTaskDescription, createLastTaskDescriptionIconFilename(taskId,
-                    lastActiveTime), out);
+            lastTaskDescription.saveToXml(out);
         }
         out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
         out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
@@ -901,6 +881,8 @@
         ComponentName realActivity = null;
         ComponentName origActivity = null;
         String affinity = null;
+        String rootAffinity = null;
+        boolean hasRootAffinity = false;
         boolean rootHasReset = false;
         boolean autoRemoveRecents = false;
         boolean askedCompatMode = false;
@@ -914,7 +896,7 @@
         boolean neverRelinquishIdentity = true;
         int taskId = -1;
         final int outerDepth = in.getDepth();
-        ActivityManager.TaskDescription taskDescription = new ActivityManager.TaskDescription();
+        TaskDescription taskDescription = new TaskDescription();
         int taskAffiliation = -1;
         int taskAffiliationColor = 0;
         int prevTaskId = -1;
@@ -935,6 +917,9 @@
                 origActivity = ComponentName.unflattenFromString(attrValue);
             } else if (ATTR_AFFINITY.equals(attrName)) {
                 affinity = attrValue;
+            } else if (ATTR_ROOT_AFFINITY.equals(attrName)) {
+                rootAffinity = attrValue;
+                hasRootAffinity = true;
             } else if (ATTR_ROOTHASRESET.equals(attrName)) {
                 rootHasReset = Boolean.valueOf(attrValue);
             } else if (ATTR_AUTOREMOVERECENTS.equals(attrName)) {
@@ -957,8 +942,8 @@
                 lastTimeOnTop = Long.valueOf(attrValue);
             } else if (ATTR_NEVERRELINQUISH.equals(attrName)) {
                 neverRelinquishIdentity = Boolean.valueOf(attrValue);
-            } else if (readTaskDescriptionAttribute(taskDescription, attrName, attrValue)) {
-                // Completed in TaskPersister.readTaskDescriptionAttribute()
+            } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
+                taskDescription.restoreFromXml(attrName, attrValue);
             } else if (ATTR_TASK_AFFILIATION.equals(attrName)) {
                 taskAffiliation = Integer.valueOf(attrValue);
             } else if (ATTR_PREV_AFFILIATION.equals(attrName)) {
@@ -1002,9 +987,10 @@
             }
         }
 
-        if (lastActiveTime >= 0) {
-            taskDescription.setIcon(TaskPersister.restoreImage(
-                    createLastTaskDescriptionIconFilename(taskId, lastActiveTime)));
+        if (!hasRootAffinity) {
+            rootAffinity = affinity;
+        } else if ("@".equals(rootAffinity)) {
+            rootAffinity = null;
         }
 
         if (effectiveUid <= 0) {
@@ -1028,7 +1014,7 @@
         }
 
         final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
-                affinityIntent, affinity, realActivity, origActivity, rootHasReset,
+                affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
                 autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
                 activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
                 taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
@@ -1047,8 +1033,13 @@
                 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
                 pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
                 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
-        if (affinity != null) {
-            pw.print(prefix); pw.print("affinity="); pw.println(affinity);
+        if (affinity != null || rootAffinity != null) {
+            pw.print(prefix); pw.print("affinity="); pw.print(affinity);
+            if (affinity == null || !affinity.equals(rootAffinity)) {
+                pw.print(" root="); pw.println(rootAffinity);
+            } else {
+                pw.println();
+            }
         }
         if (voiceSession != null || voiceInteractor != null) {
             pw.print(prefix); pw.print("VOICE: session=0x");
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 957d705..15ffc0d 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -53,6 +53,9 @@
     // Penalty applied to scores of Networks that have not been validated.
     private static final int UNVALIDATED_SCORE_PENALTY = 40;
 
+    // Score for explicitly connected network.
+    private static final int EXPLICITLY_SELECTED_NETWORK_SCORE = 100;
+
     // The list of NetworkRequests being satisfied by this Network.
     public final SparseArray<NetworkRequest> networkRequests = new SparseArray<NetworkRequest>();
     public final ArrayList<NetworkRequest> networkLingered = new ArrayList<NetworkRequest>();
@@ -95,9 +98,10 @@
         int score = currentScore;
 
         if (!validated) score -= UNVALIDATED_SCORE_PENALTY;
-
         if (score < 0) score = 0;
 
+        if (networkMisc.explicitlySelected) score = EXPLICITLY_SELECTED_NETWORK_SCORE;
+
         return score;
     }
 
@@ -110,7 +114,8 @@
                 network + "}  lp{" +
                 linkProperties + "}  nc{" +
                 networkCapabilities + "}  Score{" + getCurrentScore() + "} " +
-                "validated{" + validated + "} created{" + created + "} }";
+                "validated{" + validated + "} created{" + created + "} " +
+                "explicitlySelected{" + networkMisc.explicitlySelected + "} }";
     }
 
     public String name() {
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index 9e33205..fb98236 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -82,10 +82,6 @@
     private static final String PERMISSION_ACCESS_NETWORK_CONDITIONS =
             "android.permission.ACCESS_NETWORK_CONDITIONS";
 
-    // Intent broadcast when user selects sign-in notification.
-    private static final String ACTION_SIGN_IN_REQUESTED =
-            "android.net.netmon.sign_in_requested";
-
     // Keep these in sync with CaptivePortalLoginActivity.java.
     // Intent broadcast from CaptivePortalLogin indicating sign-in is complete.
     // Extras:
@@ -260,7 +256,7 @@
         addState(mUserPromptedState, mDefaultState);
         addState(mCaptivePortalState, mDefaultState);
         addState(mLingeringState, mDefaultState);
-        setInitialState(mOfflineState);
+        setInitialState(mDefaultState);
 
         mServer = Settings.Global.getString(mContext.getContentResolver(),
                 Settings.Global.CAPTIVE_PORTAL_SERVER);
@@ -404,38 +400,42 @@
         }
     }
 
-    private class UserPromptedState extends State {
-        private class UserRespondedBroadcastReceiver extends BroadcastReceiver {
-            private final int mToken;
-            UserRespondedBroadcastReceiver(int token) {
-                mToken = token;
-            }
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                if (Integer.parseInt(intent.getStringExtra(Intent.EXTRA_TEXT)) ==
-                        mNetworkAgentInfo.network.netId) {
-                    sendMessage(obtainMessage(CMD_USER_WANTS_SIGN_IN, mToken));
-                }
-            }
+    // BroadcastReceiver that waits for a particular Intent and then posts a message.
+    private class CustomIntentReceiver extends BroadcastReceiver {
+        private final Message mMessage;
+        private final String mAction;
+        CustomIntentReceiver(String action, int token, int message) {
+            mMessage = obtainMessage(message, token);
+            mAction = action + "_" + mNetworkAgentInfo.network.netId + "_" + token;
+            mContext.registerReceiver(this, new IntentFilter(mAction));
         }
+        public PendingIntent getPendingIntent() {
+            return PendingIntent.getBroadcast(mContext, 0, new Intent(mAction), 0);
+        }
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(mAction)) sendMessage(mMessage);
+        }
+    }
 
-        private UserRespondedBroadcastReceiver mUserRespondedBroadcastReceiver;
+    private class UserPromptedState extends State {
+        // Intent broadcast when user selects sign-in notification.
+        private static final String ACTION_SIGN_IN_REQUESTED =
+                "android.net.netmon.sign_in_requested";
+
+        private CustomIntentReceiver mUserRespondedBroadcastReceiver;
 
         @Override
         public void enter() {
             mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED,
                     NETWORK_TEST_RESULT_INVALID, 0, mNetworkAgentInfo));
             // Wait for user to select sign-in notifcation.
-            mUserRespondedBroadcastReceiver = new UserRespondedBroadcastReceiver(
-                    ++mUserPromptedToken);
-            IntentFilter filter = new IntentFilter(ACTION_SIGN_IN_REQUESTED);
-            mContext.registerReceiver(mUserRespondedBroadcastReceiver, filter);
+            mUserRespondedBroadcastReceiver = new CustomIntentReceiver(ACTION_SIGN_IN_REQUESTED,
+                    ++mUserPromptedToken, CMD_USER_WANTS_SIGN_IN);
             // Initiate notification to sign-in.
-            Intent intent = new Intent(ACTION_SIGN_IN_REQUESTED);
-            intent.putExtra(Intent.EXTRA_TEXT, String.valueOf(mNetworkAgentInfo.network.netId));
             Message message = obtainMessage(EVENT_PROVISIONING_NOTIFICATION, 1,
                     mNetworkAgentInfo.network.netId,
-                    PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
+                    mUserRespondedBroadcastReceiver.getPendingIntent());
             mConnectivityServiceHandler.sendMessage(message);
         }
 
@@ -530,33 +530,15 @@
 
     private class LingeringState extends State {
         private static final String ACTION_LINGER_EXPIRED = "android.net.netmon.lingerExpired";
-        private static final String EXTRA_NETID = "lingerExpiredNetId";
-        private static final String EXTRA_TOKEN = "lingerExpiredToken";
 
-        private class LingerExpiredBroadcastReceiver extends BroadcastReceiver {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                if (intent.getAction().equals(ACTION_LINGER_EXPIRED) &&
-                        Integer.parseInt(intent.getStringExtra(EXTRA_NETID)) ==
-                        mNetworkAgentInfo.network.netId) {
-                    sendMessage(CMD_LINGER_EXPIRED,
-                            Integer.parseInt(intent.getStringExtra(EXTRA_TOKEN)));
-                }
-            }
-        }
-
-        private BroadcastReceiver mBroadcastReceiver;
+        private CustomIntentReceiver mBroadcastReceiver;
         private PendingIntent mIntent;
 
         @Override
         public void enter() {
-            mBroadcastReceiver = new LingerExpiredBroadcastReceiver();
-            mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(ACTION_LINGER_EXPIRED));
-
-            Intent intent = new Intent(ACTION_LINGER_EXPIRED, null);
-            intent.putExtra(EXTRA_NETID, String.valueOf(mNetworkAgentInfo.network.netId));
-            intent.putExtra(EXTRA_TOKEN, String.valueOf(++mLingerToken));
-            mIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
+            mBroadcastReceiver = new CustomIntentReceiver(ACTION_LINGER_EXPIRED, ++mLingerToken,
+                    CMD_LINGER_EXPIRED);
+            mIntent = mBroadcastReceiver.getPendingIntent();
             long wakeupTime = SystemClock.elapsedRealtime() + mLingerDelayMs;
             mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, wakeupTime,
                     // Give a specific window so we aren't subject to unknown inexactitude.
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 9a34047..4d9b4e9 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -798,7 +798,7 @@
             // FLAG_HDMI_SYSTEM_AUDIO_VOLUME prevents audio manager from announcing
             // volume change notification back to hdmi control service.
             audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume,
-                    AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME);
+                    AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME);
         }
     }
 
diff --git a/services/core/java/com/android/server/hdmi/MhlConstants.java b/services/core/java/com/android/server/hdmi/MhlConstants.java
deleted file mode 100644
index fe479f3..0000000
--- a/services/core/java/com/android/server/hdmi/MhlConstants.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.android.server.hdmi;
-
-/**
- * Defines constants related to MHL protocol internal implementation.
- */
-final class MhlConstants {
-    // --------------------------------------------------
-    // MHL sub command message types.
-    static final int MSG_MSGE  = 0x02;
-    static final int MSG_RCP   = 0x10;
-    static final int MSG_RCPK  = 0x11;
-    static final int MSG_RCPE  = 0x12;
-    static final int MSG_RAP   = 0x20;
-    static final int MSG_RAPK  = 0x21;
-
-    // MHL RAP messages.
-    static final int RAP_ACTION_POLL = 0x00;
-    static final int RAP_ACTION_CONTENT_ON = 0x10;
-    static final int RAP_ACTION_CONTENT_OFF = 0x11;
-
-    // MHL RAPK messages.
-    static final int RAPK_NO_ERROR = 0x00;
-    static final int RAPK_UNRECOGNIZED_ACTION = 0x01;
-    static final int RAPK_UNSUPPORTED_ACTION = 0x02;
-    static final int RAPK_RESPONDER_BUSY = 0x03;
-
-    static final int INVALID_ADOPTER_ID = -1;
-    static final int INVALID_DEVICE_ID = -1;
-
-    static final int CBUS_MODE_OCBUS = 1;
-    static final int CBUS_MODE_ECBUS_S = 2;
-    static final int CBUS_MODE_ECBUS_D = 3;
-
-    // MHL RCPE messages
-    static final int RCPE_NO_ERROR = 0x00;
-    static final int RCPE_INEFFECTIVE_KEYCODE = 0x01;
-    static final int RCPE_RESPONDER_BUSY = 0x02;
-
-    private MhlConstants() { /* cannot be instantiated */ }
-}
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index df846a8..f1c5a6c 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -162,6 +162,10 @@
     private static final int GPS_CAPABILITY_SINGLE_SHOT = 0x0000008;
     private static final int GPS_CAPABILITY_ON_DEMAND_TIME = 0x0000010;
 
+    // The AGPS SUPL mode
+    private static final int AGPS_SUPL_MODE_MSA = 0x02;
+    private static final int AGPS_SUPL_MODE_MSB = 0x01;
+
     // these need to match AGpsType enum in gps.h
     private static final int AGPS_TYPE_SUPL = 1;
     private static final int AGPS_TYPE_C2K = 2;
@@ -486,12 +490,9 @@
             } else if (action.equals(SIM_STATE_CHANGED)) {
                 TelephonyManager phone = (TelephonyManager)
                         mContext.getSystemService(Context.TELEPHONY_SERVICE);
-                int simState = phone.getSimState();
-                Log.d(TAG, "SIM STATE CHANGED to " + simState);
                 String mccMnc = phone.getSimOperator();
-                if (simState == TelephonyManager.SIM_STATE_READY &&
-                    !TextUtils.isEmpty(mccMnc)) {
-                    Log.d(TAG, "SIM STATE is ready, SIM MCC/MNC is " + mccMnc);
+                if (!TextUtils.isEmpty(mccMnc)) {
+                    Log.d(TAG, "SIM MCC/MNC is available: " + mccMnc);
                     synchronized (mLock) {
                         reloadGpsProperties(context, mProperties);
                         mNIHandler.setSuplEsEnabled(mSuplEsEnabled);
@@ -922,6 +923,39 @@
         }
     }
 
+    /**
+     * Checks what SUPL mode to use, according to the AGPS mode as well as the
+     * allowed mode from properties.
+     *
+     * @param properties GPS properties
+     * @param agpsEnabled whether AGPS is enabled by settings value
+     * @param singleShot whether "singleshot" is needed
+     * @return SUPL mode (MSA vs MSB vs STANDALONE)
+     */
+    private int getSuplMode(Properties properties, boolean agpsEnabled, boolean singleShot) {
+        if (agpsEnabled) {
+            String modeString = properties.getProperty("SUPL_MODE");
+            int suplMode = 0;
+            if (!TextUtils.isEmpty(modeString)) {
+                try {
+                    suplMode = Integer.parseInt(modeString);
+                } catch (NumberFormatException e) {
+                    Log.e(TAG, "unable to parse SUPL_MODE: " + modeString);
+                    return GPS_POSITION_MODE_STANDALONE;
+                }
+            }
+            if (singleShot
+                    && hasCapability(GPS_CAPABILITY_MSA)
+                    && (suplMode & AGPS_SUPL_MODE_MSA) != 0) {
+                return GPS_POSITION_MODE_MS_ASSISTED;
+            } else if (hasCapability(GPS_CAPABILITY_MSB)
+                    && (suplMode & AGPS_SUPL_MODE_MSB) != 0) {
+                return GPS_POSITION_MODE_MS_BASED;
+            }
+        }
+        return GPS_POSITION_MODE_STANDALONE;
+    }
+
     private void handleEnable() {
         if (DEBUG) Log.d(TAG, "handleEnable");
 
@@ -1199,14 +1233,10 @@
             mSingleShot = singleShot;
             mPositionMode = GPS_POSITION_MODE_STANDALONE;
 
-             if (Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.ASSISTED_GPS_ENABLED, 1) != 0) {
-                if (singleShot && hasCapability(GPS_CAPABILITY_MSA)) {
-                    mPositionMode = GPS_POSITION_MODE_MS_ASSISTED;
-                } else if (hasCapability(GPS_CAPABILITY_MSB)) {
-                    mPositionMode = GPS_POSITION_MODE_MS_BASED;
-                }
-            }
+            boolean agpsEnabled =
+                    (Settings.Global.getInt(mContext.getContentResolver(),
+                                            Settings.Global.ASSISTED_GPS_ENABLED, 1) != 0);
+            mPositionMode = getSuplMode(mProperties, agpsEnabled, singleShot);
 
             if (DEBUG) {
                 String mode;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d87fc2e..75fef27 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2161,7 +2161,8 @@
                         userId);
             }
             if (mResolveComponentName.equals(component)) {
-                return mResolveActivity;
+                return PackageParser.generateActivityInfo(mResolveActivity, flags,
+                        new PackageUserState(), userId);
             }
         }
         return null;
@@ -4311,7 +4312,7 @@
                  * grantPermissions will assume the package update is trying to
                  * expand its permissions.
                  */
-                grantPermissionsLPw(pkg, true);
+                grantPermissionsLPw(pkg, true, pkg.packageName);
                 mSettings.disableSystemPackageLPw(pkg.packageName);
             }
         }
@@ -6696,17 +6697,19 @@
         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
             for (PackageParser.Package pkg : mPackages.values()) {
                 if (pkg != pkgInfo) {
-                    grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
+                    grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0,
+                            changingPkg);
                 }
             }
         }
         
         if (pkgInfo != null) {
-            grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0);
+            grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg);
         }
     }
 
-    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace) {
+    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
+            String packageOfInterest) {
         final PackageSetting ps = (PackageSetting) pkg.mExtras;
         if (ps == null) {
             return;
@@ -6740,8 +6743,10 @@
             }
 
             if (bp == null || bp.packageSetting == null) {
-                Slog.w(TAG, "Unknown permission " + name
-                        + " in package " + pkg.packageName);
+                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
+                    Slog.w(TAG, "Unknown permission " + name
+                            + " in package " + pkg.packageName);
+                }
                 continue;
             }
 
@@ -6806,9 +6811,11 @@
                         gp.gids = appendInts(gp.gids, bp.gids);
                     }
                 } else {
-                    Slog.w(TAG, "Not granting permission " + perm
-                            + " to package " + pkg.packageName
-                            + " because it was previously installed without");
+                    if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
+                        Slog.w(TAG, "Not granting permission " + perm
+                                + " to package " + pkg.packageName
+                                + " because it was previously installed without");
+                    }
                 }
             } else {
                 if (gp.grantedPermissions.remove(perm)) {
@@ -6822,11 +6829,13 @@
                 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
                     // Don't print warning for app op permissions, since it is fine for them
                     // not to be granted, there is a UI for the user to decide.
-                    Slog.w(TAG, "Not granting permission " + perm
-                            + " to package " + pkg.packageName
-                            + " (protectionLevel=" + bp.protectionLevel
-                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
-                            + ")");
+                    if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
+                        Slog.w(TAG, "Not granting permission " + perm
+                                + " to package " + pkg.packageName
+                                + " (protectionLevel=" + bp.protectionLevel
+                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
+                                + ")");
+                    }
                 }
             }
         }
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 5bfc834..dc355c4 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -323,9 +323,10 @@
                 notifyInputAddedLocked(userState, inputId);
             } else if (updatedPackages != null) {
                 // Notify the package updates
-                TvInputState inputState = inputMap.get(inputId);
+                ComponentName component = inputMap.get(inputId).info.getComponent();
                 for (String updatedPackage : updatedPackages) {
-                    if (inputState.info.getComponent().getPackageName().equals(updatedPackage)) {
+                    if (component.getPackageName().equals(updatedPackage)) {
+                        updateServiceConnectionLocked(component, userId);
                         notifyInputUpdatedLocked(userState, inputId);
                         break;
                     }
@@ -553,18 +554,6 @@
         updateServiceConnectionLocked(serviceState.component, userId);
     }
 
-    private ClientState createClientStateLocked(IBinder clientToken, int userId) {
-        UserState userState = getUserStateLocked(userId);
-        ClientState clientState = new ClientState(clientToken, userId);
-        try {
-            clientToken.linkToDeath(clientState, 0);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "client process has already died", e);
-        }
-        userState.clientStateMap.put(clientToken, clientState);
-        return clientState;
-    }
-
     private void createSessionInternalLocked(ITvInputService service, IBinder sessionToken,
             int userId) {
         UserState userState = getUserStateLocked(userId);
@@ -1926,56 +1915,67 @@
     }
 
     private final class SessionCallback extends ITvInputSessionCallback.Stub {
-        private final SessionState sessionState;
+        private final SessionState mSessionState;
         private final InputChannel[] mChannels;
 
         SessionCallback(SessionState sessionState, InputChannel[] channels) {
-            this.sessionState = sessionState;
+            mSessionState = sessionState;
             mChannels = channels;
         }
 
         @Override
         public void onSessionCreated(ITvInputSession session, IBinder harewareSessionToken) {
             if (DEBUG) {
-                Slog.d(TAG, "onSessionCreated(inputId=" + sessionState.info.getId() + ")");
+                Slog.d(TAG, "onSessionCreated(inputId=" + mSessionState.info.getId() + ")");
             }
             synchronized (mLock) {
-                sessionState.session = session;
-                sessionState.hardwareSessionToken = harewareSessionToken;
-                if (session == null) {
-                    removeSessionStateLocked(sessionState.sessionToken, sessionState.userId);
-                    sendSessionTokenToClientLocked(sessionState.client,
-                            sessionState.info.getId(), null, null, sessionState.seq);
+                mSessionState.session = session;
+                mSessionState.hardwareSessionToken = harewareSessionToken;
+                if (session != null && addSessionTokenToClientStateLocked(session)) {
+                    sendSessionTokenToClientLocked(mSessionState.client,
+                            mSessionState.info.getId(), mSessionState.sessionToken, mChannels[0],
+                            mSessionState.seq);
                 } else {
-                    try {
-                        session.asBinder().linkToDeath(sessionState, 0);
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "session process has already died", e);
-                    }
-
-                    IBinder clientToken = sessionState.client.asBinder();
-                    UserState userState = getUserStateLocked(sessionState.userId);
-                    ClientState clientState = userState.clientStateMap.get(clientToken);
-                    if (clientState == null) {
-                        clientState = createClientStateLocked(clientToken, sessionState.userId);
-                    }
-                    clientState.sessionTokens.add(sessionState.sessionToken);
-
-                    sendSessionTokenToClientLocked(sessionState.client,
-                            sessionState.info.getId(), sessionState.sessionToken, mChannels[0],
-                            sessionState.seq);
+                    removeSessionStateLocked(mSessionState.sessionToken, mSessionState.userId);
+                    sendSessionTokenToClientLocked(mSessionState.client,
+                            mSessionState.info.getId(), null, null, mSessionState.seq);
                 }
                 mChannels[0].dispose();
             }
         }
 
+        private boolean addSessionTokenToClientStateLocked(ITvInputSession session) {
+            try {
+                session.asBinder().linkToDeath(mSessionState, 0);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "session process has already died", e);
+                return false;
+            }
+
+            IBinder clientToken = mSessionState.client.asBinder();
+            UserState userState = getUserStateLocked(mSessionState.userId);
+            ClientState clientState = userState.clientStateMap.get(clientToken);
+            if (clientState == null) {
+                clientState = new ClientState(clientToken, mSessionState.userId);
+                try {
+                    clientToken.linkToDeath(clientState, 0);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "client process has already died", e);
+                    return false;
+                }
+                userState.clientStateMap.put(clientToken, clientState);
+            }
+            clientState.sessionTokens.add(mSessionState.sessionToken);
+            return true;
+        }
+
         @Override
         public void onChannelRetuned(Uri channelUri) {
             synchronized (mLock) {
                 if (DEBUG) {
                     Slog.d(TAG, "onChannelRetuned(" + channelUri + ")");
                 }
-                if (sessionState.session == null || sessionState.client == null) {
+                if (mSessionState.session == null || mSessionState.client == null) {
                     return;
                 }
                 try {
@@ -1983,7 +1983,7 @@
                     // that, how we can protect the watch log from malicious tv inputs should
                     // be addressed. e.g. add a field which represents where the channel change
                     // originated from.
-                    sessionState.client.onChannelRetuned(channelUri, sessionState.seq);
+                    mSessionState.client.onChannelRetuned(channelUri, mSessionState.seq);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "error in onChannelRetuned", e);
                 }
@@ -1996,11 +1996,11 @@
                 if (DEBUG) {
                     Slog.d(TAG, "onTracksChanged(" + tracks + ")");
                 }
-                if (sessionState.session == null || sessionState.client == null) {
+                if (mSessionState.session == null || mSessionState.client == null) {
                     return;
                 }
                 try {
-                    sessionState.client.onTracksChanged(tracks, sessionState.seq);
+                    mSessionState.client.onTracksChanged(tracks, mSessionState.seq);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "error in onTracksChanged", e);
                 }
@@ -2013,11 +2013,11 @@
                 if (DEBUG) {
                     Slog.d(TAG, "onTrackSelected(type=" + type + ", trackId=" + trackId + ")");
                 }
-                if (sessionState.session == null || sessionState.client == null) {
+                if (mSessionState.session == null || mSessionState.client == null) {
                     return;
                 }
                 try {
-                    sessionState.client.onTrackSelected(type, trackId, sessionState.seq);
+                    mSessionState.client.onTrackSelected(type, trackId, mSessionState.seq);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "error in onTrackSelected", e);
                 }
@@ -2030,11 +2030,11 @@
                 if (DEBUG) {
                     Slog.d(TAG, "onVideoAvailable()");
                 }
-                if (sessionState.session == null || sessionState.client == null) {
+                if (mSessionState.session == null || mSessionState.client == null) {
                     return;
                 }
                 try {
-                    sessionState.client.onVideoAvailable(sessionState.seq);
+                    mSessionState.client.onVideoAvailable(mSessionState.seq);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "error in onVideoAvailable", e);
                 }
@@ -2047,11 +2047,11 @@
                 if (DEBUG) {
                     Slog.d(TAG, "onVideoUnavailable(" + reason + ")");
                 }
-                if (sessionState.session == null || sessionState.client == null) {
+                if (mSessionState.session == null || mSessionState.client == null) {
                     return;
                 }
                 try {
-                    sessionState.client.onVideoUnavailable(reason, sessionState.seq);
+                    mSessionState.client.onVideoUnavailable(reason, mSessionState.seq);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "error in onVideoUnavailable", e);
                 }
@@ -2064,11 +2064,11 @@
                 if (DEBUG) {
                     Slog.d(TAG, "onContentAllowed()");
                 }
-                if (sessionState.session == null || sessionState.client == null) {
+                if (mSessionState.session == null || mSessionState.client == null) {
                     return;
                 }
                 try {
-                    sessionState.client.onContentAllowed(sessionState.seq);
+                    mSessionState.client.onContentAllowed(mSessionState.seq);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "error in onContentAllowed", e);
                 }
@@ -2081,11 +2081,11 @@
                 if (DEBUG) {
                     Slog.d(TAG, "onContentBlocked()");
                 }
-                if (sessionState.session == null || sessionState.client == null) {
+                if (mSessionState.session == null || mSessionState.client == null) {
                     return;
                 }
                 try {
-                    sessionState.client.onContentBlocked(rating, sessionState.seq);
+                    mSessionState.client.onContentBlocked(rating, mSessionState.seq);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "error in onContentBlocked", e);
                 }
@@ -2099,11 +2099,12 @@
                     Slog.d(TAG, "onLayoutSurface (left=" + left + ", top=" + top
                             + ", right=" + right + ", bottom=" + bottom + ",)");
                 }
-                if (sessionState.session == null || sessionState.client == null) {
+                if (mSessionState.session == null || mSessionState.client == null) {
                     return;
                 }
                 try {
-                    sessionState.client.onLayoutSurface(left, top, right, bottom, sessionState.seq);
+                    mSessionState.client.onLayoutSurface(left, top, right, bottom,
+                            mSessionState.seq);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "error in onLayoutSurface", e);
                 }
@@ -2116,12 +2117,11 @@
                 if (DEBUG) {
                     Slog.d(TAG, "onEvent(what=" + eventType + ", data=" + eventArgs + ")");
                 }
-                if (sessionState.session == null || sessionState.client == null) {
+                if (mSessionState.session == null || mSessionState.client == null) {
                     return;
                 }
                 try {
-                    sessionState.client.onSessionEvent(eventType, eventArgs,
-                            sessionState.seq);
+                    mSessionState.client.onSessionEvent(eventType, eventArgs, mSessionState.seq);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "error in onSessionEvent", e);
                 }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index d4bcd5c..0c51160 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -328,6 +328,7 @@
                     for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
                         AppWindowToken wtoken = tokens.get(tokenNdx);
                         if (wtoken.mDeferRemoval) {
+                            stack.mExitingAppTokens.remove(wtoken);
                             wtoken.mDeferRemoval = false;
                             mService.removeAppFromTaskLocked(wtoken);
                         }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a3da1e6..fdf2fc8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3356,7 +3356,8 @@
                 }
                 isFullScreen =
                         ((win.mSystemUiVisibility & SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN) ==
-                                SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN);
+                                SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN) ||
+                                ((win.mAttrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0);
             }
 
             if (atoken.mLaunchTaskBehind) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index da97876..ff17d78 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
 import static com.android.server.wm.WindowManagerService.DEBUG_LAYERS;
@@ -1271,9 +1272,10 @@
             // not always reporting the correct system decor rect. In such
             // cases, we take into account the specified content insets as well.
             if ((w.mSystemUiVisibility & SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN)
-                    == SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN) {
+                    == SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN
+                    || (w.mAttrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0) {
                 // Don't apply the workaround to apps explicitly requesting
-                // fullscreen layout.
+                // fullscreen layout or when the bars are transparent.
                 clipRect.intersect(mClipRect);
             } else {
                 final int offsetTop = Math.max(clipRect.top, w.mContentInsets.top);
diff --git a/services/core/jni/com_android_server_UsbHostManager.cpp b/services/core/jni/com_android_server_UsbHostManager.cpp
index 65a28c0..32c3f95 100644
--- a/services/core/jni/com_android_server_UsbHostManager.cpp
+++ b/services/core/jni/com_android_server_UsbHostManager.cpp
@@ -74,9 +74,9 @@
     char *serial = usb_device_get_serial(device);
 
     jstring deviceName = env->NewStringUTF(devname);
-    jstring manufacturerName = env->NewStringUTF(manufacturer);
-    jstring productName = env->NewStringUTF(product);
-    jstring serialNumber = env->NewStringUTF(serial);
+    jstring manufacturerName = AndroidRuntime::NewStringLatin1(env, manufacturer);
+    jstring productName = AndroidRuntime::NewStringLatin1(env, product);
+    jstring serialNumber = AndroidRuntime::NewStringLatin1(env, serial);
 
     jboolean result = env->CallBooleanMethod(thiz, method_beginUsbDeviceAdded,
             deviceName, usb_device_get_vendor_id(device), usb_device_get_product_id(device),
@@ -99,7 +99,7 @@
         if (desc->bDescriptorType == USB_DT_CONFIG) {
             struct usb_config_descriptor *config = (struct usb_config_descriptor *)desc;
             char *name = usb_device_get_string(device, config->iConfiguration);
-            jstring configName = env->NewStringUTF(name);
+            jstring configName = AndroidRuntime::NewStringLatin1(env, name);
 
             env->CallVoidMethod(thiz, method_addUsbConfiguration,
                     config->bConfigurationValue, configName, config->bmAttributes,
@@ -110,7 +110,7 @@
         } else if (desc->bDescriptorType == USB_DT_INTERFACE) {
             struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)desc;
             char *name = usb_device_get_string(device, interface->iInterface);
-            jstring interfaceName = env->NewStringUTF(name);
+            jstring interfaceName = AndroidRuntime::NewStringLatin1(env, name);
 
             env->CallVoidMethod(thiz, method_addUsbInterface,
                     interface->bInterfaceNumber, interfaceName, interface->bAlternateSetting,
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 95332bc..60ed93a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -17,6 +17,7 @@
 package com.android.server.devicepolicy;
 
 import static android.Manifest.permission.MANAGE_CA_CERTIFICATES;
+import static android.content.pm.PackageManager.GET_UNINSTALLED_PACKAGES;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.accounts.AccountManager;
@@ -4801,19 +4802,19 @@
             long id = Binder.clearCallingIdentity();
 
             try {
-                UserManager um = UserManager.get(mContext);
-                if (!um.getUserInfo(userId).isManagedProfile()) {
-                    throw new IllegalStateException(
-                            "Only call this method from a managed profile.");
-                }
-
-                UserInfo primaryUser = um.getProfileParent(userId);
-
                 if (DBG) {
                     Slog.v(LOG_TAG, "installing " + packageName + " for "
                             + userId);
                 }
 
+                UserManager um = UserManager.get(mContext);
+                UserInfo primaryUser = um.getProfileParent(userId);
+
+                // Call did not come from a managed profile
+                if (primaryUser == null) {
+                    primaryUser = um.getUserInfo(userId);
+                }
+
                 IPackageManager pm = AppGlobals.getPackageManager();
                 if (!isSystemApp(pm, packageName, primaryUser.id)) {
                     throw new IllegalArgumentException("Only system apps can be enabled this way.");
@@ -4847,13 +4848,13 @@
 
             try {
                 UserManager um = UserManager.get(mContext);
-                if (!um.getUserInfo(userId).isManagedProfile()) {
-                    throw new IllegalStateException(
-                            "Only call this method from a managed profile.");
-                }
-
                 UserInfo primaryUser = um.getProfileParent(userId);
 
+                // Call did not come from a managed profile.
+                if (primaryUser == null) {
+                    primaryUser = um.getUserInfo(userId);
+                }
+
                 IPackageManager pm = AppGlobals.getPackageManager();
                 List<ResolveInfo> activitiesToEnable = pm.queryIntentActivities(intent,
                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
@@ -4890,7 +4891,8 @@
 
     private boolean isSystemApp(IPackageManager pm, String packageName, int userId)
             throws RemoteException {
-        ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0, userId);
+        ApplicationInfo appInfo = pm.getApplicationInfo(packageName, GET_UNINSTALLED_PACKAGES,
+                userId);
         return (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) > 0;
     }
 
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java
index cc0d8df..9c15f2b 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java
@@ -24,10 +24,10 @@
 import android.hardware.soundtrigger.SoundTrigger;
 import android.hardware.soundtrigger.SoundTrigger.Keyphrase;
 import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
-import android.os.UserManager;
 import android.text.TextUtils;
 import android.util.Slog;
 
+import java.util.Locale;
 import java.util.UUID;
 
 /**
@@ -37,8 +37,7 @@
  */
 public class DatabaseHelper extends SQLiteOpenHelper {
     static final String TAG = "SoundModelDBHelper";
-    // TODO: Set to false.
-    static final boolean DBG = true;
+    static final boolean DBG = false;
 
     private static final String NAME = "sound_model.db";
     private static final int VERSION = 4;
@@ -67,11 +66,8 @@
             + SoundModelContract.KEY_HINT_TEXT + " TEXT,"
             + SoundModelContract.KEY_USERS + " TEXT" + ")";
 
-    private final UserManager mUserManager;
-
     public DatabaseHelper(Context context) {
         super(context, NAME, null, VERSION);
-        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
     }
 
     @Override
@@ -122,17 +118,20 @@
     /**
      * Deletes the sound model and associated keyphrases.
      */
-    public boolean deleteKeyphraseSoundModel(UUID modelUuid) {
-        if (modelUuid == null) {
-            Slog.w(TAG, "Model UUID must be specified for deletion");
-            return false;
-        }
-
+    public boolean deleteKeyphraseSoundModel(int keyphraseId, int userHandle, String bcp47Locale) {
+        // Sanitize the locale to guard against SQL injection.
+        bcp47Locale = Locale.forLanguageTag(bcp47Locale).toLanguageTag();
         synchronized(this) {
-            SQLiteDatabase db = getWritableDatabase();
-            String soundModelClause = SoundModelContract.KEY_MODEL_UUID + "='"
-                    + modelUuid.toString() + "'";
+            KeyphraseSoundModel soundModel = getKeyphraseSoundModel(keyphraseId, userHandle,
+                    bcp47Locale);
+            if (soundModel == null) {
+                return false;
+            }
 
+            // Delete all sound models for the given keyphrase and specified user.
+            SQLiteDatabase db = getWritableDatabase();
+            String soundModelClause = SoundModelContract.KEY_MODEL_UUID
+                    + "='" + soundModel.uuid.toString() + "'";
             try {
                 return db.delete(SoundModelContract.TABLE, soundModelClause, null) != 0;
             } finally {
@@ -147,11 +146,15 @@
      *
      * TODO: We only support one keyphrase currently.
      */
-    public KeyphraseSoundModel getKeyphraseSoundModel(int keyphraseId) {
+    public KeyphraseSoundModel getKeyphraseSoundModel(int keyphraseId, int userHandle,
+            String bcp47Locale) {
+        // Sanitize the locale to guard against SQL injection.
+        bcp47Locale = Locale.forLanguageTag(bcp47Locale).toLanguageTag();
         synchronized(this) {
             // Find the corresponding sound model ID for the keyphrase.
             String selectQuery = "SELECT  * FROM " + SoundModelContract.TABLE
-                    + " WHERE " + SoundModelContract.KEY_KEYPHRASE_ID + " = '" + keyphraseId + "'";
+                    + " WHERE " + SoundModelContract.KEY_KEYPHRASE_ID + "= '" + keyphraseId
+                    + "' AND " + SoundModelContract.KEY_LOCALE + "='" + bcp47Locale + "'";
             SQLiteDatabase db = getReadableDatabase();
             Cursor c = db.rawQuery(selectQuery, null);
 
@@ -160,14 +163,16 @@
                     do {
                         int type = c.getInt(c.getColumnIndex(SoundModelContract.KEY_TYPE));
                         if (type != SoundTrigger.SoundModel.TYPE_KEYPHRASE) {
-                            Slog.w(TAG, "Ignoring sound model since it's type is incorrect");
+                            if (DBG) {
+                                Slog.w(TAG, "Ignoring SoundModel since it's type is incorrect");
+                            }
                             continue;
                         }
 
                         String modelUuid = c.getString(
                                 c.getColumnIndex(SoundModelContract.KEY_MODEL_UUID));
                         if (modelUuid == null) {
-                            Slog.w(TAG, "Ignoring sound model since it doesn't specify an ID");
+                            Slog.w(TAG, "Ignoring SoundModel since it doesn't specify an ID");
                             continue;
                         }
 
@@ -176,7 +181,7 @@
                                 c.getColumnIndex(SoundModelContract.KEY_RECOGNITION_MODES));
                         int[] users = getArrayForCommaSeparatedString(
                                 c.getString(c.getColumnIndex(SoundModelContract.KEY_USERS)));
-                        String locale = c.getString(
+                        String modelLocale = c.getString(
                                 c.getColumnIndex(SoundModelContract.KEY_LOCALE));
                         String text = c.getString(
                                 c.getColumnIndex(SoundModelContract.KEY_HINT_TEXT));
@@ -184,28 +189,37 @@
                         // Only add keyphrases meant for the current user.
                         if (users == null) {
                             // No users present in the keyphrase.
-                            Slog.w(TAG, "Ignoring keyphrase since it doesn't specify users");
+                            Slog.w(TAG, "Ignoring SoundModel since it doesn't specify users");
                             continue;
                         }
 
                         boolean isAvailableForCurrentUser = false;
-                        int currentUser = mUserManager.getUserHandle();
                         for (int user : users) {
-                            if (currentUser == user) {
+                            if (userHandle == user) {
                                 isAvailableForCurrentUser = true;
                                 break;
                             }
                         }
                         if (!isAvailableForCurrentUser) {
-                            Slog.w(TAG, "Ignoring keyphrase since it's not for the current user");
+                            if (DBG) {
+                                Slog.w(TAG, "Ignoring SoundModel since user handles don't match");
+                            }
                             continue;
+                        } else {
+                            if (DBG) Slog.d(TAG, "Found a SoundModel for user: " + userHandle);
                         }
 
                         Keyphrase[] keyphrases = new Keyphrase[1];
                         keyphrases[0] = new Keyphrase(
-                                keyphraseId, recognitionModes, locale, text, users);
-                        return new KeyphraseSoundModel(UUID.fromString(modelUuid),
+                                keyphraseId, recognitionModes, modelLocale, text, users);
+                        KeyphraseSoundModel model = new KeyphraseSoundModel(
+                                UUID.fromString(modelUuid),
                                 null /* FIXME use vendor UUID */, data, keyphrases);
+                        if (DBG) {
+                            Slog.d(TAG, "Found SoundModel for the given keyphrase/locale/user: "
+                                    + model);
+                        }
+                        return model;
                     } while (c.moveToNext());
                 }
                 Slog.w(TAG, "No SoundModel available for the given keyphrase");
@@ -218,15 +232,17 @@
     }
 
     private static String getCommaSeparatedString(int[] users) {
-        if (users == null || users.length == 0) {
+        if (users == null) {
             return "";
         }
-        String csv = "";
-        for (int user : users) {
-            csv += String.valueOf(user);
-            csv += ",";
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < users.length; i++) {
+            if (i != 0) {
+                sb.append(',');
+            }
+            sb.append(users[i]);
         }
-        return csv.substring(0, csv.length() - 1);
+        return sb.toString();
     }
 
     private static int[] getArrayForCommaSeparatedString(String text) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
index ad38b22..8ce7f74 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
@@ -50,8 +50,7 @@
  */
 public class SoundTriggerHelper implements SoundTrigger.StatusListener {
     static final String TAG = "SoundTriggerHelper";
-    // TODO: Set to false.
-    static final boolean DBG = true;
+    static final boolean DBG = false;
 
     /**
      * Return codes for {@link #startRecognition(int, KeyphraseSoundModel,
@@ -166,8 +165,14 @@
                 }
             }
 
+            // Unload the previous model if the current one isn't invalid
+            // and, it's not the same as the new one, or we are already started
+            // if we are already started, we can get multiple calls to start
+            // if the underlying sound model changes, in which case we should unload and reload.
+            // The model reuse helps only in cases when we trigger and stop internally
+            // without a start recognition call.
             if (mCurrentSoundModelHandle != INVALID_VALUE
-                    && !soundModel.uuid.equals(mCurrentSoundModelUuid)) {
+                    && (!soundModel.uuid.equals(mCurrentSoundModelUuid) || mStarted)) {
                 Slog.w(TAG, "Unloading previous sound model");
                 int status = mModule.unloadSoundModel(mCurrentSoundModelHandle);
                 if (status != SoundTrigger.STATUS_OK) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 7c7b732..82b7f8b 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -446,7 +446,7 @@
         //----------------- Model management APIs --------------------------------//
 
         @Override
-        public KeyphraseSoundModel getKeyphraseSoundModel(int keyphraseId) {
+        public KeyphraseSoundModel getKeyphraseSoundModel(int keyphraseId, String bcp47Locale) {
             synchronized (this) {
                 if (mContext.checkCallingPermission(Manifest.permission.MANAGE_VOICE_KEYPHRASES)
                         != PackageManager.PERMISSION_GRANTED) {
@@ -455,9 +455,14 @@
                 }
             }
 
+            if (bcp47Locale == null) {
+                throw new IllegalArgumentException("Illegal argument(s) in getKeyphraseSoundModel");
+            }
+
+            final int callingUid = UserHandle.getCallingUserId();
             final long caller = Binder.clearCallingIdentity();
             try {
-                return mDbHelper.getKeyphraseSoundModel(keyphraseId);
+                return mDbHelper.getKeyphraseSoundModel(keyphraseId, callingUid, bcp47Locale);
             } finally {
                 Binder.restoreCallingIdentity(caller);
             }
@@ -495,7 +500,7 @@
         }
 
         @Override
-        public int deleteKeyphraseSoundModel(int keyphraseId) {
+        public int deleteKeyphraseSoundModel(int keyphraseId, String bcp47Locale) {
             synchronized (this) {
                 if (mContext.checkCallingPermission(Manifest.permission.MANAGE_VOICE_KEYPHRASES)
                         != PackageManager.PERMISSION_GRANTED) {
@@ -504,13 +509,16 @@
                 }
             }
 
+            if (bcp47Locale == null) {
+                throw new IllegalArgumentException(
+                        "Illegal argument(s) in deleteKeyphraseSoundModel");
+            }
+
+            final int callingUid = UserHandle.getCallingUserId();
             final long caller = Binder.clearCallingIdentity();
             boolean deleted = false;
             try {
-                KeyphraseSoundModel soundModel = mDbHelper.getKeyphraseSoundModel(keyphraseId);
-                if (soundModel != null) {
-                    deleted = mDbHelper.deleteKeyphraseSoundModel(soundModel.uuid);
-                }
+                deleted = mDbHelper.deleteKeyphraseSoundModel(keyphraseId, callingUid, bcp47Locale);
                 return deleted ? SoundTriggerHelper.STATUS_OK : SoundTriggerHelper.STATUS_ERROR;
             } finally {
                 if (deleted) {
@@ -527,7 +535,8 @@
 
         //----------------- SoundTrigger APIs --------------------------------//
         @Override
-        public boolean isEnrolledForKeyphrase(IVoiceInteractionService service, int keyphraseId) {
+        public boolean isEnrolledForKeyphrase(IVoiceInteractionService service, int keyphraseId,
+                String bcp47Locale) {
             synchronized (this) {
                 if (mImpl == null || mImpl.mService == null
                         || service.asBinder() != mImpl.mService.asBinder()) {
@@ -536,9 +545,15 @@
                 }
             }
 
+            if (bcp47Locale == null) {
+                throw new IllegalArgumentException("Illegal argument(s) in isEnrolledForKeyphrase");
+            }
+
+            final int callingUid = UserHandle.getCallingUserId();
             final long caller = Binder.clearCallingIdentity();
             try {
-                KeyphraseSoundModel model = mDbHelper.getKeyphraseSoundModel(keyphraseId);
+                KeyphraseSoundModel model =
+                        mDbHelper.getKeyphraseSoundModel(keyphraseId, callingUid, bcp47Locale);
                 return model != null;
             } finally {
                 Binder.restoreCallingIdentity(caller);
@@ -566,7 +581,8 @@
 
         @Override
         public int startRecognition(IVoiceInteractionService service, int keyphraseId,
-                IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig) {
+                String bcp47Locale, IRecognitionStatusCallback callback,
+                RecognitionConfig recognitionConfig) {
             // Allow the call if this is the current voice interaction service.
             synchronized (this) {
                 if (mImpl == null || mImpl.mService == null
@@ -575,14 +591,16 @@
                             "Caller is not the current voice interaction service");
                 }
 
-                if (callback == null || recognitionConfig == null) {
+                if (callback == null || recognitionConfig == null || bcp47Locale == null) {
                     throw new IllegalArgumentException("Illegal argument(s) in startRecognition");
                 }
             }
 
+            int callingUid = UserHandle.getCallingUserId();
             final long caller = Binder.clearCallingIdentity();
             try {
-                KeyphraseSoundModel soundModel = mDbHelper.getKeyphraseSoundModel(keyphraseId);
+                KeyphraseSoundModel soundModel =
+                        mDbHelper.getKeyphraseSoundModel(keyphraseId, callingUid, bcp47Locale);
                 if (soundModel == null
                         || soundModel.uuid == null
                         || soundModel.keyphrases == null) {
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 1d33b3b..b0b6fb9 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -19,7 +19,6 @@
 import android.annotation.SystemApi;
 import android.net.Uri;
 import android.os.Bundle;
-import android.telephony.DisconnectCause;
 
 import java.lang.String;
 import java.util.ArrayList;
@@ -81,6 +80,15 @@
      */
     public static final int STATE_CONNECTING = 9;
 
+    /**
+     * The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call
+     * extras. Used to pass the phone accounts to display on the front end to the user in order to
+     * select phone accounts to (for example) place a call.
+     *
+     * @hide
+     */
+    public static final String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts";
+
     public static class Details {
         private final Uri mHandle;
         private final int mHandlePresentation;
@@ -89,8 +97,7 @@
         private final PhoneAccountHandle mAccountHandle;
         private final int mCallCapabilities;
         private final int mCallProperties;
-        private final int mDisconnectCauseCode;
-        private final String mDisconnectCauseMessage;
+        private final DisconnectCause mDisconnectCause;
         private final long mConnectTimeMillis;
         private final GatewayInfo mGatewayInfo;
         private final int mVideoState;
@@ -154,18 +161,10 @@
 
         /**
          * @return For a {@link #STATE_DISCONNECTED} {@code Call}, the disconnect cause expressed
-         * as a code chosen from among those declared in {@link DisconnectCause}.
+         * by {@link android.telecomm.DisconnectCause}.
          */
-        public int getDisconnectCauseCode() {
-            return mDisconnectCauseCode;
-        }
-
-        /**
-         * @return For a {@link #STATE_DISCONNECTED} {@code Call}, an optional reason for
-         * disconnection expressed as a free text message.
-         */
-        public String getDisconnectCauseMessage() {
-            return mDisconnectCauseMessage;
+        public DisconnectCause getDisconnectCause() {
+            return mDisconnectCause;
         }
 
         /**
@@ -219,8 +218,7 @@
                         Objects.equals(mAccountHandle, d.mAccountHandle) &&
                         Objects.equals(mCallCapabilities, d.mCallCapabilities) &&
                         Objects.equals(mCallProperties, d.mCallProperties) &&
-                        Objects.equals(mDisconnectCauseCode, d.mDisconnectCauseCode) &&
-                        Objects.equals(mDisconnectCauseMessage, d.mDisconnectCauseMessage) &&
+                        Objects.equals(mDisconnectCause, d.mDisconnectCause) &&
                         Objects.equals(mConnectTimeMillis, d.mConnectTimeMillis) &&
                         Objects.equals(mGatewayInfo, d.mGatewayInfo) &&
                         Objects.equals(mVideoState, d.mVideoState) &&
@@ -240,8 +238,7 @@
                     Objects.hashCode(mAccountHandle) +
                     Objects.hashCode(mCallCapabilities) +
                     Objects.hashCode(mCallProperties) +
-                    Objects.hashCode(mDisconnectCauseCode) +
-                    Objects.hashCode(mDisconnectCauseMessage) +
+                    Objects.hashCode(mDisconnectCause) +
                     Objects.hashCode(mConnectTimeMillis) +
                     Objects.hashCode(mGatewayInfo) +
                     Objects.hashCode(mVideoState) +
@@ -258,8 +255,7 @@
                 PhoneAccountHandle accountHandle,
                 int capabilities,
                 int properties,
-                int disconnectCauseCode,
-                String disconnectCauseMessage,
+                DisconnectCause disconnectCause,
                 long connectTimeMillis,
                 GatewayInfo gatewayInfo,
                 int videoState,
@@ -272,8 +268,7 @@
             mAccountHandle = accountHandle;
             mCallCapabilities = capabilities;
             mCallProperties = properties;
-            mDisconnectCauseCode = disconnectCauseCode;
-            mDisconnectCauseMessage = disconnectCauseMessage;
+            mDisconnectCause = disconnectCause;
             mConnectTimeMillis = connectTimeMillis;
             mGatewayInfo = gatewayInfo;
             mVideoState = videoState;
@@ -654,8 +649,7 @@
                 parcelableCall.getAccountHandle(),
                 parcelableCall.getCapabilities(),
                 parcelableCall.getProperties(),
-                parcelableCall.getDisconnectCauseCode(),
-                parcelableCall.getDisconnectCauseMsg(),
+                parcelableCall.getDisconnectCause(),
                 parcelableCall.getConnectTimeMillis(),
                 parcelableCall.getGatewayInfo(),
                 parcelableCall.getVideoState(),
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index ca85446..9b350c1 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -16,8 +16,6 @@
 
 package android.telecom;
 
-import android.telephony.DisconnectCause;
-
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
@@ -32,7 +30,7 @@
     /** @hide */
     public abstract static class Listener {
         public void onStateChanged(Conference conference, int oldState, int newState) {}
-        public void onDisconnected(Conference conference, int cause, String message) {}
+        public void onDisconnected(Conference conference, DisconnectCause disconnectCause) {}
         public void onConnectionAdded(Conference conference, Connection connection) {}
         public void onConnectionRemoved(Conference conference, Connection connection) {}
         public void onDestroyed(Conference conference) {}
@@ -45,8 +43,9 @@
             Collections.unmodifiableList(mChildConnections);
 
     private PhoneAccountHandle mPhoneAccount;
+    private AudioState mAudioState;
     private int mState = Connection.STATE_NEW;
-    private int mDisconnectCause = DisconnectCause.NOT_VALID;
+    private DisconnectCause mDisconnectCause;
     private int mCapabilities;
     private String mDisconnectMessage;
 
@@ -96,6 +95,15 @@
     }
 
     /**
+     * @return The audio state of the conference, describing how its audio is currently
+     *         being routed by the system. This is {@code null} if this Conference
+     *         does not directly know about its audio state.
+     */
+    public final AudioState getAudioState() {
+        return mAudioState;
+    }
+
+    /**
      * Invoked when the Conference and all it's {@link Connection}s should be disconnected.
      */
     public void onDisconnect() {}
@@ -130,6 +138,25 @@
     public void onSwap() {}
 
     /**
+     * Notifies this conference of a request to play a DTMF tone.
+     *
+     * @param c A DTMF character.
+     */
+    public void onPlayDtmfTone(char c) {}
+
+    /**
+     * Notifies this conference of a request to stop any currently playing DTMF tones.
+     */
+    public void onStopDtmfTone() {}
+
+    /**
+     * Notifies this conference that the {@link #getAudioState()} property has a new value.
+     *
+     * @param state The new call audio state.
+     */
+    public void onAudioStateChanged(AudioState state) {}
+
+    /**
      * Sets state to be on hold.
      */
     public final void setOnHold() {
@@ -146,16 +173,14 @@
     /**
      * Sets state to disconnected.
      *
-     * @param cause The reason for the disconnection, any of
-     *         {@link android.telephony.DisconnectCause}.
-     * @param message Optional call-service-provided message about the disconnect.
+     * @param disconnectCause The reason for the disconnection, as described by
+     *     {@link android.telecom.DisconnectCause}.
      */
-    public final void setDisconnected(int cause, String message) {
-        mDisconnectCause = cause;
-        mDisconnectMessage = message;
+    public final void setDisconnected(DisconnectCause disconnectCause) {
+        mDisconnectCause = disconnectCause;;
         setState(Connection.STATE_DISCONNECTED);
         for (Listener l : mListeners) {
-            l.onDisconnected(this, mDisconnectCause, mDisconnectMessage);
+            l.onDisconnected(this, mDisconnectCause);
         }
     }
 
@@ -222,7 +247,7 @@
         // If not yet disconnected, set the conference call as disconnected first.
         if (mState != Connection.STATE_DISCONNECTED) {
             Log.d(this, "setting to disconnected");
-            setDisconnected(DisconnectCause.LOCAL, null);
+            setDisconnected(new DisconnectCause(DisconnectCause.LOCAL));
         }
 
         // ...and notify.
@@ -255,6 +280,18 @@
         return this;
     }
 
+    /**
+     * Inform this Conference that the state of its audio output has been changed externally.
+     *
+     * @param state The new audio state.
+     * @hide
+     */
+    final void setAudioState(AudioState state) {
+        Log.d(this, "setAudioState %s", state);
+        mAudioState = state;
+        onAudioStateChanged(state);
+    }
+
     private void setState(int newState) {
         if (newState != Connection.STATE_ACTIVE &&
                 newState != Connection.STATE_HOLDING &&
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 5f63af3..7979e44 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -24,7 +24,6 @@
 import android.os.IBinder;
 import android.os.Message;
 import android.os.RemoteException;
-import android.telephony.DisconnectCause;
 import android.view.Surface;
 
 import java.util.ArrayList;
@@ -71,7 +70,7 @@
         public void onCallerDisplayNameChanged(
                 Connection c, String callerDisplayName, int presentation) {}
         public void onVideoStateChanged(Connection c, int videoState) {}
-        public void onDisconnected(Connection c, int cause, String message) {}
+        public void onDisconnected(Connection c, DisconnectCause disconnectCause) {}
         public void onPostDialWait(Connection c, String remaining) {}
         public void onRingbackRequested(Connection c, boolean ringback) {}
         public void onDestroyed(Connection c) {}
@@ -473,8 +472,7 @@
     private boolean mAudioModeIsVoip;
     private StatusHints mStatusHints;
     private int mVideoState;
-    private int mDisconnectCause;
-    private String mDisconnectMessage;
+    private DisconnectCause mDisconnectCause;
     private Conference mConference;
     private ConnectionService mConnectionService;
 
@@ -604,18 +602,11 @@
     /**
      * @return The {@link DisconnectCause} for this connection.
      */
-    public final int getDisconnectCause() {
+    public final DisconnectCause getDisconnectCause() {
         return mDisconnectCause;
     }
 
     /**
-     * @return The disconnect message for this connection.
-     */
-    public final String getDisconnectMessage() {
-        return mDisconnectMessage;
-    }
-
-    /**
      * Inform this Connection that the state of its audio output has been changed externally.
      *
      * @param state The new audio state.
@@ -774,17 +765,15 @@
     /**
      * Sets state to disconnected.
      *
-     * @param cause The reason for the disconnection, any of
+     * @param disconnectCause The reason for the disconnection, as specified by
      *         {@link DisconnectCause}.
-     * @param message Optional call-service-provided message about the disconnect.
      */
-    public final void setDisconnected(int cause, String message) {
-        mDisconnectCause = cause;
-        mDisconnectMessage = message;
+    public final void setDisconnected(DisconnectCause disconnectCause) {
+        mDisconnectCause = disconnectCause;
         setState(STATE_DISCONNECTED);
-        Log.d(this, "Disconnected with cause %d message %s", cause, message);
+        Log.d(this, "Disconnected with cause %s", disconnectCause);
         for (Listener l : mListeners) {
-            l.onDisconnected(this, cause, message);
+            l.onDisconnected(this, disconnectCause);
         }
     }
 
@@ -1071,26 +1060,24 @@
     }
 
     private static class FailureSignalingConnection extends Connection {
-        public FailureSignalingConnection(int cause, String message) {
-            setDisconnected(cause, message);
+        public FailureSignalingConnection(DisconnectCause disconnectCause) {
+            setDisconnected(disconnectCause);
         }
     }
 
     /**
      * Return a {@code Connection} which represents a failed connection attempt. The returned
-     * {@code Connection} will have a {@link #getDisconnectCause()} and
-     * {@link #getDisconnectMessage()} as specified, and a {@link #getState()} of
-     * {@link #STATE_DISCONNECTED}.
+     * {@code Connection} will have a {@link android.telecom.DisconnectCause} and as specified,
+     * and a {@link #getState()} of {@link #STATE_DISCONNECTED}.
      * <p>
      * The returned {@code Connection} can be assumed to {@link #destroy()} itself when appropriate,
      * so users of this method need not maintain a reference to its return value to destroy it.
      *
-     * @param cause The disconnect cause, ({@see DisconnectCause}).
-     * @param message A reason for why the connection failed (not intended to be shown to the user).
+     * @param disconnectCause The disconnect cause, ({@see android.telecomm.DisconnectCause}).
      * @return A {@code Connection} which indicates failure.
      */
-    public static Connection createFailedConnection(int cause, String message) {
-        return new FailureSignalingConnection(cause, message);
+    public static Connection createFailedConnection(DisconnectCause disconnectCause) {
+        return new FailureSignalingConnection(disconnectCause);
     }
 
     /**
@@ -1105,7 +1092,7 @@
      * @return A {@code Connection} which indicates that the underlying call should be canceled.
      */
     public static Connection createCanceledConnection() {
-        return new FailureSignalingConnection(DisconnectCause.OUTGOING_CANCELED, null);
+        return new FailureSignalingConnection(new DisconnectCause(DisconnectCause.CANCELED));
     }
 
     private final void  fireOnConferenceableConnectionsChanged() {
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index cc80e22..3e18bac 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -25,7 +25,6 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
-import android.telephony.DisconnectCause;
 
 import com.android.internal.os.SomeArgs;
 import com.android.internal.telecom.IConnectionService;
@@ -344,9 +343,9 @@
         }
 
         @Override
-        public void onDisconnected(Conference conference, int cause, String message) {
+        public void onDisconnected(Conference conference, DisconnectCause disconnectCause) {
             String id = mIdByConference.get(conference);
-            mAdapter.setDisconnected(id, cause, message);
+            mAdapter.setDisconnected(id, disconnectCause);
         }
 
         @Override
@@ -399,10 +398,10 @@
         }
 
         @Override
-        public void onDisconnected(Connection c, int cause, String message) {
+        public void onDisconnected(Connection c, DisconnectCause disconnectCause) {
             String id = mIdByConnection.get(c);
-            Log.d(this, "Adapter set disconnected %d %s", cause, message);
-            mAdapter.setDisconnected(id, cause, message);
+            Log.d(this, "Adapter set disconnected %s", disconnectCause);
+            mAdapter.setDisconnected(id, disconnectCause);
         }
 
         @Override
@@ -522,7 +521,8 @@
                 : onCreateOutgoingConnection(callManagerAccount, request);
         Log.d(this, "createConnection, connection: %s", connection);
         if (connection == null) {
-            connection = Connection.createFailedConnection(DisconnectCause.OUTGOING_FAILURE, null);
+            connection = Connection.createFailedConnection(
+                    new DisconnectCause(DisconnectCause.ERROR));
         }
 
         if (connection.getState() != Connection.STATE_DISCONNECTED) {
@@ -555,7 +555,6 @@
                         connection.getAudioModeIsVoip(),
                         connection.getStatusHints(),
                         connection.getDisconnectCause(),
-                        connection.getDisconnectMessage(),
                         createConnectionIdList(connection.getConferenceableConnections())));
     }
 
@@ -608,17 +607,29 @@
 
     private void onAudioStateChanged(String callId, AudioState audioState) {
         Log.d(this, "onAudioStateChanged %s %s", callId, audioState);
-        findConnectionForAction(callId, "onAudioStateChanged").setAudioState(audioState);
+        if (mConnectionById.containsKey(callId)) {
+            findConnectionForAction(callId, "onAudioStateChanged").setAudioState(audioState);
+        } else {
+            findConferenceForAction(callId, "onAudioStateChanged").setAudioState(audioState);
+        }
     }
 
     private void playDtmfTone(String callId, char digit) {
         Log.d(this, "playDtmfTone %s %c", callId, digit);
-        findConnectionForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
+        if (mConnectionById.containsKey(callId)) {
+            findConnectionForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
+        } else {
+            findConferenceForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
+        }
     }
 
     private void stopDtmfTone(String callId) {
         Log.d(this, "stopDtmfTone %s", callId);
-        findConnectionForAction(callId, "stopDtmfTone").onStopDtmfTone();
+        if (mConnectionById.containsKey(callId)) {
+            findConnectionForAction(callId, "stopDtmfTone").onStopDtmfTone();
+        } else {
+            findConferenceForAction(callId, "stopDtmfTone").onStopDtmfTone();
+        }
     }
 
     private void conference(String callId1, String callId2) {
@@ -836,7 +847,7 @@
      *         making the connection.
      * @param request Details about the outgoing call.
      * @return The {@code Connection} object to satisfy this call, or the result of an invocation
-     *         of {@link Connection#createFailedConnection(int, String)} to not handle the call.
+     *         of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
      */
     public Connection onCreateOutgoingConnection(
             PhoneAccountHandle connectionManagerPhoneAccount,
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
index f6bcdc6..c676172 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
@@ -134,14 +134,13 @@
      * Sets a call's state to disconnected.
      *
      * @param callId The unique ID of the call whose state is changing to disconnected.
-     * @param disconnectCause The reason for the disconnection, any of
-     *            {@link android.telephony.DisconnectCause}.
-     * @param disconnectMessage Optional call-service-provided message about the disconnect.
+     * @param disconnectCause The reason for the disconnection, as described by
+     *            {@link android.telecomm.DisconnectCause}.
      */
-    void setDisconnected(String callId, int disconnectCause, String disconnectMessage) {
+    void setDisconnected(String callId, DisconnectCause disconnectCause) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setDisconnected(callId, disconnectCause, disconnectMessage);
+                adapter.setDisconnected(callId, disconnectCause);
             } catch (RemoteException e) {
             }
         }
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
index ffbbc8a..217dbc3 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
@@ -96,8 +96,7 @@
                 case MSG_SET_DISCONNECTED: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.setDisconnected(
-                                (String) args.arg1, args.argi1, (String) args.arg2);
+                        mDelegate.setDisconnected((String) args.arg1, (DisconnectCause) args.arg2);
                     } finally {
                         args.recycle();
                     }
@@ -234,11 +233,10 @@
 
         @Override
         public void setDisconnected(
-                String connectionId, int disconnectCause, String disconnectMessage) {
+                String connectionId, DisconnectCause disconnectCause) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
-            args.arg2 = disconnectMessage;
-            args.argi1 = disconnectCause;
+            args.arg2 = disconnectCause;
             mHandler.obtainMessage(MSG_SET_DISCONNECTED, args).sendToTarget();
         }
 
diff --git a/telecomm/java/android/telecom/DisconnectCause.aidl b/telecomm/java/android/telecom/DisconnectCause.aidl
new file mode 100644
index 0000000..26b8652
--- /dev/null
+++ b/telecomm/java/android/telecom/DisconnectCause.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telecom;
+
+/**
+ * {@hide}
+ */
+parcelable DisconnectCause;
diff --git a/telecomm/java/android/telecom/DisconnectCause.java b/telecomm/java/android/telecom/DisconnectCause.java
new file mode 100644
index 0000000..cae115d
--- /dev/null
+++ b/telecomm/java/android/telecom/DisconnectCause.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telecom;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.media.ToneGenerator;
+import android.text.TextUtils;
+
+import java.util.Objects;
+
+/**
+ * Describes the cause of a disconnected call. This always includes a code describing the generic
+ * cause of the disconnect. Optionally, it may include a localized label and/or localized description
+ * to display to the user which is provided by the {@link ConnectionService}. It also may contain a
+ * reason for the the disconnect, which is intended for logging and not for display to the user.
+ */
+public final class DisconnectCause implements Parcelable {
+
+    /** Disconnected because of an unknown or unspecified reason. */
+    public static final int UNKNOWN = 0;
+    /** Disconnected because there was an error, such as a problem with the network. */
+    public static final int ERROR = 1;
+    /** Disconnected because of a local user-initiated action, such as hanging up. */
+    public static final int LOCAL = 2;
+    /**
+     * Disconnected because of a remote user-initiated action, such as the other party hanging up
+     * up.
+     */
+    public static final int REMOTE = 3;
+    /** Disconnected because it has been canceled. */
+    public static final int CANCELED = 4;
+    /** Disconnected because there was no response to an incoming call. */
+    public static final int MISSED = 5;
+    /** Disconnected because the user rejected an incoming call. */
+    public static final int REJECTED = 6;
+    /** Disconnected because the other party was busy. */
+    public static final int BUSY = 7;
+    /**
+     * Disconnected because of a restriction on placing the call, such as dialing in airplane
+     * mode.
+     */
+    public static final int RESTRICTED = 8;
+    /** Disconnected for reason not described by other disconnect codes. */
+    public static final int OTHER = 9;
+
+    private int mDisconnectCode;
+    private CharSequence mDisconnectLabel;
+    private CharSequence mDisconnectDescription;
+    private String mDisconnectReason;
+    private int mToneToPlay;
+
+    /**
+     * Creates a new DisconnectCause.
+     *
+     * @param code The code for the disconnect cause.
+     */
+    public DisconnectCause(int code) {
+        this(code, null, null, null, ToneGenerator.TONE_UNKNOWN);
+    }
+
+    /**
+     * Creates a new DisconnectCause.
+     *
+     * @param code The code for the disconnect cause.
+     * @param reason The reason for the disconnect.
+     */
+    public DisconnectCause(int code, String reason) {
+        this(code, null, null, reason, ToneGenerator.TONE_UNKNOWN);
+    }
+
+    /**
+     * Creates a new DisconnectCause.
+     *
+     * @param code The code for the disconnect cause.
+     * @param label The localized label to show to the user to explain the disconnect.
+     * @param description The localized description to show to the user to explain the disconnect.
+     * @param reason The reason for the disconnect.
+     * @param toneToPlay The tone to play on disconnect, as defined in {@link ToneGenerator}.
+     */
+    public DisconnectCause(int code, CharSequence label, CharSequence description, String reason,
+            int toneToPlay) {
+        mDisconnectCode = code;
+        mDisconnectLabel = label;
+        mDisconnectDescription = description;
+        mDisconnectReason = reason;
+        mToneToPlay = toneToPlay;
+    }
+
+    /**
+     * Returns the code for the reason for this disconnect.
+     *
+     * @return The disconnect code.
+     */
+    public int getCode() {
+        return mDisconnectCode;
+    }
+
+    /**
+     * Returns a short label which explains the reason for the disconnect cause and is for display
+     * in the user interface. The {@link ConnectionService } is responsible for providing and
+     * localizing this label. If there is no string provided, returns null.
+     *
+     * @return The disconnect label.
+     */
+    public CharSequence getLabel() {
+        return mDisconnectLabel;
+    }
+
+    /**
+     * Returns a description which explains the reason for the disconnect cause and is for display
+     * in the user interface. The {@link ConnectionService } is responsible for providing and
+     * localizing this message. If there is no string provided, returns null.
+     *
+     * @return The disconnect description.
+     */
+    public CharSequence getDescription() {
+        return mDisconnectDescription;
+    }
+
+    /**
+     * Returns an explanation of the reason for the disconnect. This is not intended for display to
+     * the user and is used mainly for logging.
+     *
+     * @return The disconnect reason.
+     */
+    public String getReason() {
+        return mDisconnectReason;
+    }
+
+    /**
+     * Returns the tone to play when disconnected.
+     *
+     * @return the tone as defined in {@link ToneGenerator} to play when disconnected.
+     */
+    public int getTone() {
+        return mToneToPlay;
+    }
+
+    public static final Creator<DisconnectCause> CREATOR = new Creator<DisconnectCause>() {
+        @Override
+        public DisconnectCause createFromParcel(Parcel source) {
+            int code = source.readInt();
+            CharSequence label = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+            CharSequence description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+            String reason = source.readString();
+            int tone = source.readInt();
+            return new DisconnectCause(code, label, description, reason, tone);
+        }
+
+        @Override
+        public DisconnectCause[] newArray(int size) {
+            return new DisconnectCause[size];
+        }
+    };
+
+    @Override
+    public void writeToParcel(Parcel destination, int flags) {
+        destination.writeInt(mDisconnectCode);
+        TextUtils.writeToParcel(mDisconnectLabel, destination, flags);
+        TextUtils.writeToParcel(mDisconnectDescription, destination, flags);
+        destination.writeString(mDisconnectReason);
+        destination.writeInt(mToneToPlay);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(mDisconnectCode)
+                + Objects.hashCode(mDisconnectLabel)
+                + Objects.hashCode(mDisconnectDescription)
+                + Objects.hashCode(mDisconnectReason)
+                + Objects.hashCode(mToneToPlay);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof DisconnectCause) {
+            DisconnectCause d = (DisconnectCause) o;
+            return Objects.equals(mDisconnectCode, d.getCode())
+                    && Objects.equals(mDisconnectLabel, d.getLabel())
+                    && Objects.equals(mDisconnectDescription, d.getDescription())
+                    && Objects.equals(mDisconnectReason, d.getReason())
+                    && Objects.equals(mToneToPlay, d.getTone());
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        String code = "";
+        switch (getCode()) {
+            case ERROR:
+                code = "ERROR";
+                break;
+            case LOCAL:
+                code = "LOCAL";
+                break;
+            case REMOTE:
+                code = "REMOTE";
+                break;
+            case MISSED:
+                code = "MISSED";
+                break;
+            case REJECTED:
+                code = "REJECTED";
+                break;
+            case BUSY:
+                code = "BUSY";
+                break;
+            case RESTRICTED:
+                code = "RESTRICTED";
+                break;
+            case OTHER:
+                code = "OTHER";
+                break;
+            case UNKNOWN:
+            default:
+                code = "UNKNOWN";
+        }
+        String label = mDisconnectLabel == null ? "" : mDisconnectLabel.toString();
+        String description = mDisconnectDescription == null
+                ? "" : mDisconnectDescription.toString();
+        String reason = mDisconnectReason == null ? "" : mDisconnectReason;
+        return "DisconnectCause [ Code: (" + code + ")"
+                + " Label: (" + label + ")"
+                + " Description: (" + description + ")"
+                + " Reason: (" + reason + ")"
+                + " Tone: (" + mToneToPlay + ") ]";
+    }
+}
diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java
index 838c7cf..c5c3d11 100644
--- a/telecomm/java/android/telecom/ParcelableCall.java
+++ b/telecomm/java/android/telecom/ParcelableCall.java
@@ -21,7 +21,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
-import android.telephony.DisconnectCause;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -36,8 +35,7 @@
 public final class ParcelableCall implements Parcelable {
     private final String mId;
     private final int mState;
-    private final int mDisconnectCauseCode;
-    private final String mDisconnectCauseMsg;
+    private final DisconnectCause mDisconnectCause;
     private final List<String> mCannedSmsResponses;
     private final int mCapabilities;
     private final int mProperties;
@@ -60,8 +58,7 @@
     public ParcelableCall(
             String id,
             int state,
-            int disconnectCauseCode,
-            String disconnectCauseMsg,
+            DisconnectCause disconnectCause,
             List<String> cannedSmsResponses,
             int capabilities,
             int properties,
@@ -81,8 +78,7 @@
             Bundle extras) {
         mId = id;
         mState = state;
-        mDisconnectCauseCode = disconnectCauseCode;
-        mDisconnectCauseMsg = disconnectCauseMsg;
+        mDisconnectCause = disconnectCause;
         mCannedSmsResponses = cannedSmsResponses;
         mCapabilities = capabilities;
         mProperties = properties;
@@ -113,19 +109,11 @@
     }
 
     /**
-     * Reason for disconnection, values are defined in {@link DisconnectCause}. Valid when call
-     * state is {@link CallState#DISCONNECTED}.
+     * Reason for disconnection, as described by {@link android.telecomm.DisconnectCause}. Valid
+     * when call state is {@link CallState#DISCONNECTED}.
      */
-    public int getDisconnectCauseCode() {
-        return mDisconnectCauseCode;
-    }
-
-    /**
-     * Further optional textual information about the reason for disconnection. Valid when call
-     * state is {@link CallState#DISCONNECTED}.
-     */
-    public String getDisconnectCauseMsg() {
-        return mDisconnectCauseMsg;
+    public DisconnectCause getDisconnectCause() {
+        return mDisconnectCause;
     }
 
     /**
@@ -252,8 +240,7 @@
             ClassLoader classLoader = ParcelableCall.class.getClassLoader();
             String id = source.readString();
             int state = source.readInt();
-            int disconnectCauseCode = source.readInt();
-            String disconnectCauseMsg = source.readString();
+            DisconnectCause disconnectCause = source.readParcelable(classLoader);
             List<String> cannedSmsResponses = new ArrayList<>();
             source.readList(cannedSmsResponses, classLoader);
             int capabilities = source.readInt();
@@ -275,11 +262,27 @@
             List<String> conferenceableCallIds = new ArrayList<>();
             source.readList(conferenceableCallIds, classLoader);
             Bundle extras = source.readParcelable(classLoader);
-            return new ParcelableCall(id, state, disconnectCauseCode, disconnectCauseMsg,
-                    cannedSmsResponses, capabilities, properties, connectTimeMillis, handle,
-                    handlePresentation, callerDisplayName, callerDisplayNamePresentation,
-                    gatewayInfo, accountHandle, videoCallProvider, parentCallId, childCallIds,
-                    statusHints, videoState, conferenceableCallIds, extras);
+            return new ParcelableCall(
+                    id,
+                    state,
+                    disconnectCause,
+                    cannedSmsResponses,
+                    capabilities,
+                    properties,
+                    connectTimeMillis,
+                    handle,
+                    handlePresentation,
+                    callerDisplayName,
+                    callerDisplayNamePresentation,
+                    gatewayInfo,
+                    accountHandle,
+                    videoCallProvider,
+                    parentCallId,
+                    childCallIds,
+                    statusHints,
+                    videoState,
+                    conferenceableCallIds,
+                    extras);
         }
 
         @Override
@@ -299,8 +302,7 @@
     public void writeToParcel(Parcel destination, int flags) {
         destination.writeString(mId);
         destination.writeInt(mState);
-        destination.writeInt(mDisconnectCauseCode);
-        destination.writeString(mDisconnectCauseMsg);
+        destination.writeParcelable(mDisconnectCause, 0);
         destination.writeList(mCannedSmsResponses);
         destination.writeInt(mCapabilities);
         destination.writeInt(mProperties);
diff --git a/telecomm/java/android/telecom/ParcelableConnection.java b/telecomm/java/android/telecom/ParcelableConnection.java
index 63393b2..9004448 100644
--- a/telecomm/java/android/telecom/ParcelableConnection.java
+++ b/telecomm/java/android/telecom/ParcelableConnection.java
@@ -44,8 +44,7 @@
     private final boolean mRingbackRequested;
     private final boolean mIsVoipAudioMode;
     private final StatusHints mStatusHints;
-    private final int mDisconnectCause;
-    private final String mDisconnectMessage;
+    private final DisconnectCause mDisconnectCause;
     private final List<String> mConferenceableConnectionIds;
 
     /** @hide */
@@ -62,8 +61,7 @@
             boolean ringbackRequested,
             boolean isVoipAudioMode,
             StatusHints statusHints,
-            int disconnectCause,
-            String disconnectMessage,
+            DisconnectCause disconnectCause,
             List<String> conferenceableConnectionIds) {
         mPhoneAccount = phoneAccount;
         mState = state;
@@ -78,7 +76,6 @@
         mIsVoipAudioMode = isVoipAudioMode;
         mStatusHints = statusHints;
         mDisconnectCause = disconnectCause;
-        mDisconnectMessage = disconnectMessage;
         this.mConferenceableConnectionIds = conferenceableConnectionIds;
     }
 
@@ -131,14 +128,10 @@
         return mStatusHints;
     }
 
-    public final int getDisconnectCause() {
+    public final DisconnectCause getDisconnectCause() {
         return mDisconnectCause;
     }
 
-    public final String getDisconnectMessage() {
-        return mDisconnectMessage;
-    }
-
     public final List<String> getConferenceableConnectionIds() {
         return mConferenceableConnectionIds;
     }
@@ -174,8 +167,7 @@
             boolean ringbackRequested = source.readByte() == 1;
             boolean audioModeIsVoip = source.readByte() == 1;
             StatusHints statusHints = source.readParcelable(classLoader);
-            int disconnectCauseCode = source.readInt();
-            String disconnectCauseMessage = source.readString();
+            DisconnectCause disconnectCause = source.readParcelable(classLoader);
             List<String> conferenceableConnectionIds = new ArrayList<>();
             source.readStringList(conferenceableConnectionIds);
 
@@ -192,8 +184,7 @@
                     ringbackRequested,
                     audioModeIsVoip,
                     statusHints,
-                    disconnectCauseCode,
-                    disconnectCauseMessage,
+                    disconnectCause,
                     conferenceableConnectionIds);
         }
 
@@ -225,8 +216,7 @@
         destination.writeByte((byte) (mRingbackRequested ? 1 : 0));
         destination.writeByte((byte) (mIsVoipAudioMode ? 1 : 0));
         destination.writeParcelable(mStatusHints, 0);
-        destination.writeInt(mDisconnectCause);
-        destination.writeString(mDisconnectMessage);
+        destination.writeParcelable(mDisconnectCause, 0);
         destination.writeStringList(mConferenceableConnectionIds);
     }
 }
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index 0c233eb..4b059b2 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -91,17 +91,6 @@
     public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 0x10;
 
     /**
-     * Flag indicating that this {@code PhoneAccount} is always enabled and cannot be disabled by
-     * the user.
-     * This capability is reserved for important {@code PhoneAccount}s such as the emergency calling
-     * only {@code PhoneAccount}.
-     * <p>
-     * See {@link #getCapabilities}
-     * @hide
-     */
-    public static final int CAPABILITY_ALWAYS_ENABLED = 0x20;
-
-    /**
      * URI scheme for telephone number URIs.
      */
     public static final String SCHEME_TEL = "tel";
@@ -124,7 +113,6 @@
     private final CharSequence mLabel;
     private final CharSequence mShortDescription;
     private final List<String> mSupportedUriSchemes;
-    private final boolean mIsEnabled;
 
     public static class Builder {
         private PhoneAccountHandle mAccountHandle;
@@ -135,7 +123,6 @@
         private CharSequence mLabel;
         private CharSequence mShortDescription;
         private List<String> mSupportedUriSchemes = new ArrayList<String>();
-        private boolean mIsEnabled = false;
 
         public Builder(PhoneAccountHandle accountHandle, CharSequence label) {
             this.mAccountHandle = accountHandle;
@@ -157,7 +144,6 @@
             mLabel = phoneAccount.getLabel();
             mShortDescription = phoneAccount.getShortDescription();
             mSupportedUriSchemes.addAll(phoneAccount.getSupportedUriSchemes());
-            mIsEnabled = phoneAccount.isEnabled();
         }
 
         public Builder setAddress(Uri value) {
@@ -217,19 +203,6 @@
         }
 
         /**
-         * Specifies whether the {@link PhoneAccount} is enabled or not.  {@link PhoneAccount}s are
-         * by default not enabled.
-         *
-         * @param value {@code True} if the {@link PhoneAccount} is enabled.
-         * @return The Builder.
-         * @hide
-         */
-        public Builder setEnabled(boolean value) {
-            this.mIsEnabled = value;
-            return this;
-        }
-
-        /**
          * Creates an instance of a {@link PhoneAccount} based on the current builder settings.
          *
          * @return The {@link PhoneAccount}.
@@ -248,8 +221,7 @@
                     mIconResId,
                     mLabel,
                     mShortDescription,
-                    mSupportedUriSchemes,
-                    mIsEnabled);
+                    mSupportedUriSchemes);
         }
     }
 
@@ -261,8 +233,7 @@
             int iconResId,
             CharSequence label,
             CharSequence shortDescription,
-            List<String> supportedUriSchemes,
-            boolean enabled) {
+            List<String> supportedUriSchemes) {
         mAccountHandle = account;
         mAddress = address;
         mSubscriptionAddress = subscriptionAddress;
@@ -271,7 +242,6 @@
         mLabel = label;
         mShortDescription = shortDescription;
         mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes);
-        mIsEnabled = enabled;
     }
 
     public static Builder builder(
@@ -392,15 +362,6 @@
     }
 
     /**
-     * Determines whether this {@code PhoneAccount} is enabled.
-     *
-     * @return {@code True} if this {@code PhoneAccount} is enabled..
-     */
-    public boolean isEnabled() {
-        return mIsEnabled;
-    }
-
-    /**
      * The icon resource ID for the icon of this {@code PhoneAccount}.
      *
      * @return A resource ID.
@@ -455,7 +416,6 @@
         out.writeCharSequence(mLabel);
         out.writeCharSequence(mShortDescription);
         out.writeList(mSupportedUriSchemes);
-        out.writeInt(mIsEnabled ? 1 : 0);
     }
 
     public static final Creator<PhoneAccount> CREATOR
@@ -485,6 +445,5 @@
         List<String> supportedUriSchemes = new ArrayList<>();
         in.readList(supportedUriSchemes, classLoader);
         mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes);
-        mIsEnabled = in.readInt() == 1;
     }
 }
diff --git a/telecomm/java/android/telecom/RemoteConference.java b/telecomm/java/android/telecom/RemoteConference.java
index 996e091..f931bc5 100644
--- a/telecomm/java/android/telecom/RemoteConference.java
+++ b/telecomm/java/android/telecom/RemoteConference.java
@@ -19,7 +19,6 @@
 import com.android.internal.telecom.IConnectionService;
 
 import android.os.RemoteException;
-import android.telephony.DisconnectCause;
 
 import java.util.Collections;
 import java.util.List;
@@ -34,7 +33,7 @@
 
     public abstract static class Callback {
         public void onStateChanged(RemoteConference conference, int oldState, int newState) {}
-        public void onDisconnected(RemoteConference conference, int cause, String message) {}
+        public void onDisconnected(RemoteConference conference, DisconnectCause disconnectCause) {}
         public void onConnectionAdded(RemoteConference conference, RemoteConnection connection) {}
         public void onConnectionRemoved(RemoteConference conference, RemoteConnection connection) {}
         public void onCapabilitiesChanged(RemoteConference conference, int capabilities) {}
@@ -50,9 +49,8 @@
             Collections.unmodifiableList(mChildConnections);
 
     private int mState = Connection.STATE_NEW;
-    private int mDisconnectCause = DisconnectCause.NOT_VALID;
+    private DisconnectCause mDisconnectCause;
     private int mCallCapabilities;
-    private String mDisconnectMessage;
 
     /** {@hide} */
     RemoteConference(String id, IConnectionService connectionService) {
@@ -127,13 +125,12 @@
     }
 
     /** {@hide} */
-    void setDisconnected(int cause, String message) {
+    void setDisconnected(DisconnectCause disconnectCause) {
         if (mState != Connection.STATE_DISCONNECTED) {
-            mDisconnectCause = cause;
-            mDisconnectMessage = message;
+            mDisconnectCause = disconnectCause;
             setState(Connection.STATE_DISCONNECTED);
             for (Callback c : mCallbacks) {
-                c.onDisconnected(this, cause, message);
+                c.onDisconnected(this, disconnectCause);
             }
         }
     }
@@ -180,12 +177,29 @@
         }
     }
 
-    public int getDisconnectCause() {
+    public DisconnectCause getDisconnectCause() {
         return mDisconnectCause;
     }
 
-    public String getDisconnectMessage() {
-        return mDisconnectMessage;
+    public void playDtmfTone(char digit) {
+        try {
+            mConnectionService.playDtmfTone(mId, digit);
+        } catch (RemoteException e) {
+        }
+    }
+
+    public void stopDtmfTone() {
+        try {
+            mConnectionService.stopDtmfTone(mId);
+        } catch (RemoteException e) {
+        }
+    }
+
+    public void setAudioState(AudioState state) {
+        try {
+            mConnectionService.onAudioStateChanged(mId, state);
+        } catch (RemoteException e) {
+        }
     }
 
     public final void registerCallback(Callback callback) {
diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java
index bf699b3..9a094df 100644
--- a/telecomm/java/android/telecom/RemoteConnection.java
+++ b/telecomm/java/android/telecom/RemoteConnection.java
@@ -23,7 +23,6 @@
 import android.net.Uri;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.telephony.DisconnectCause;
 import android.view.Surface;
 
 import java.util.ArrayList;
@@ -55,15 +54,12 @@
          * Invoked when this {@code RemoteConnection} is disconnected.
          *
          * @param connection The {@code RemoteConnection} invoking this method.
-         * @param disconnectCauseCode The failure code ({@see DisconnectCause}) associated with this
-         *         failed connection.
-         * @param disconnectCauseMessage The reason for the connection failure. This will not be
-         *         displayed to the user.
+         * @param disconnectCause The ({@see DisconnectCause}) associated with this failed
+         *     connection.
          */
         public void onDisconnected(
                 RemoteConnection connection,
-                int disconnectCauseCode,
-                String disconnectCauseMessage) {}
+                DisconnectCause disconnectCause) {}
 
         /**
          * Invoked when this {@code RemoteConnection} is requesting ringback. See
@@ -383,8 +379,7 @@
             Collections.unmodifiableList(mConferenceableConnections);
 
     private int mState = Connection.STATE_NEW;
-    private int mDisconnectCauseCode = DisconnectCause.NOT_VALID;
-    private String mDisconnectCauseMessage;
+    private DisconnectCause mDisconnectCause;
     private boolean mRingbackRequested;
     private boolean mConnected;
     private int mCallCapabilities;
@@ -396,8 +391,6 @@
     private int mAddressPresentation;
     private String mCallerDisplayName;
     private int mCallerDisplayNamePresentation;
-    private int mFailureCode;
-    private String mFailureMessage;
     private RemoteConference mConference;
 
     /**
@@ -418,15 +411,14 @@
      * "real" purpose will almost certainly fail. Callers should note the failure and act
      * accordingly (moving on to another RemoteConnection, for example)
      *
-     * @param failureCode
-     * @param failureMessage
+     * @param disconnectCause The reason for the failed connection.
+     * @hide
      */
-    RemoteConnection(int failureCode, String failureMessage) {
+    RemoteConnection(DisconnectCause disconnectCause) {
         this("NULL", null, null);
         mConnected = false;
         mState = Connection.STATE_DISCONNECTED;
-        mFailureCode = DisconnectCause.OUTGOING_FAILURE;
-        mFailureMessage = failureMessage + " original code = " + failureCode;
+        mDisconnectCause = disconnectCause;
     }
 
     /**
@@ -463,16 +455,8 @@
      * disconnect cause expressed as a code chosen from among those declared in
      * {@link DisconnectCause}.
      */
-    public int getDisconnectCauseCode() {
-        return mDisconnectCauseCode;
-    }
-
-    /**
-     * @return For a {@link Connection#STATE_DISCONNECTED} {@code RemoteConnection}, an optional
-     * reason for disconnection expressed as a free text message.
-     */
-    public String getDisconnectCauseMessage() {
-        return mDisconnectCauseMessage;
+    public DisconnectCause getDisconnectCause() {
+        return mDisconnectCause;
     }
 
     /**
@@ -547,21 +531,6 @@
     }
 
     /**
-     * @return The failure code ({@see DisconnectCause}) associated with this failed
-     * {@code RemoteConnection}.
-     */
-    public int getFailureCode() {
-        return mFailureCode;
-    }
-
-    /**
-     * @return The reason for the connection failure. This will not be displayed to the user.
-     */
-    public String getFailureMessage() {
-        return mFailureMessage;
-    }
-
-    /**
      * @return Whether the {@code RemoteConnection} is requesting that the framework play a
      * ringback tone on its behalf.
      */
@@ -779,14 +748,13 @@
     /**
      * @hide
      */
-    void setDisconnected(int cause, String message) {
+    void setDisconnected(DisconnectCause disconnectCause) {
         if (mState != Connection.STATE_DISCONNECTED) {
             mState = Connection.STATE_DISCONNECTED;
-            mDisconnectCauseCode = cause;
-            mDisconnectCauseMessage = message;
+            mDisconnectCause = disconnectCause;
 
             for (Callback c : mCallbacks) {
-                c.onDisconnected(this, cause, message);
+                c.onDisconnected(this, mDisconnectCause);
             }
         }
     }
@@ -820,7 +788,8 @@
         if (!mCallbacks.isEmpty()) {
             // Make sure that the callbacks are notified that the call is destroyed first.
             if (mState != Connection.STATE_DISCONNECTED) {
-                setDisconnected(DisconnectCause.ERROR_UNSPECIFIED, "Connection destroyed.");
+                setDisconnected(
+                        new DisconnectCause(DisconnectCause.ERROR, "Connection destroyed."));
             }
 
             for (Callback c : mCallbacks) {
@@ -923,7 +892,7 @@
      *
      * @hide
      */
-    public static RemoteConnection failure(int failureCode, String failureMessage) {
-        return new RemoteConnection(failureCode, failureMessage);
+    public static RemoteConnection failure(DisconnectCause disconnectCause) {
+        return new RemoteConnection(disconnectCause);
     }
 }
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index bfd7c51..03b38c2 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -20,7 +20,6 @@
 import android.os.IBinder;
 import android.os.IBinder.DeathRecipient;
 import android.os.RemoteException;
-import android.telephony.DisconnectCause;
 
 import com.android.internal.telecom.IConnectionService;
 import com.android.internal.telecom.IConnectionServiceAdapter;
@@ -107,14 +106,13 @@
         }
 
         @Override
-        public void setDisconnected(String callId, int disconnectCause,
-                String disconnectMessage) {
+        public void setDisconnected(String callId, DisconnectCause disconnectCause) {
             if (mConnectionById.containsKey(callId)) {
                 findConnectionForAction(callId, "setDisconnected")
-                        .setDisconnected(disconnectCause, disconnectMessage);
+                        .setDisconnected(disconnectCause);
             } else {
                 findConferenceForAction(callId, "setDisconnected")
-                        .setDisconnected(disconnectCause, disconnectMessage);
+                        .setDisconnected(disconnectCause);
             }
         }
 
@@ -351,8 +349,8 @@
             });
             return connection;
         } catch (RemoteException e) {
-            return RemoteConnection
-                    .failure(DisconnectCause.ERROR_UNSPECIFIED, e.toString());
+            return RemoteConnection.failure(
+                    new DisconnectCause(DisconnectCause.ERROR, e.toString()));
         }
     }
 
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 4d438ed..481e483 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -71,24 +71,6 @@
             "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
 
     /**
-     * The {@link android.content.Intent} action used to inform a
-     * {@link android.telecom.ConnectionService} that one of its {@link PhoneAccount}s has been
-     * enabled.  The {@link TelecomManager#EXTRA_PHONE_ACCOUNT_HANDLE} extra is used to indicate
-     * which {@link PhoneAccount} has been enabled.
-     */
-    public static final String ACTION_PHONE_ACCOUNT_ENABLED =
-            "android.telecom.action.PHONE_ACCOUNT_ENABLED";
-
-    /**
-     * The {@link android.content.Intent} action used to inform a
-     * {@link android.telecom.ConnectionService} that one of its {@link PhoneAccount}s has been
-     * disabled.  The {@link TelecomManager#EXTRA_PHONE_ACCOUNT_HANDLE} extra is used to indicate
-     * which {@link PhoneAccount} has been disabled.
-     */
-    public static final String ACTION_PHONE_ACCOUNT_DISABLED =
-            "android.telecom.action.PHONE_ACCOUNT_DISABLED";
-
-    /**
      * Optional extra for {@link android.content.Intent#ACTION_CALL} containing a boolean that
      * determines whether the speakerphone should be automatically turned on for an outgoing call.
      */
@@ -324,22 +306,16 @@
 
     /**
      * Return the {@link PhoneAccount} which is the user-chosen default for making outgoing phone
-     * calls with a specified URI scheme. This {@code PhoneAccount} will always be a member of the
-     * list which is returned from calling {@link #getEnabledPhoneAccounts()}.
+     * calls with a specified URI scheme.
      * <p>
      * Apps must be prepared for this method to return {@code null}, indicating that there currently
-     * exists no user-chosen default {@code PhoneAccount}. In this case, apps wishing to initiate a
-     * phone call must either create their {@link android.content.Intent#ACTION_CALL} or
-     * {@link android.content.Intent#ACTION_DIAL} {@code Intent} with no
-     * {@link TelecomManager#EXTRA_PHONE_ACCOUNT_HANDLE}, or present the user with an affordance to
-     * select one of the elements of {@link #getEnabledPhoneAccounts()}.
+     * exists no user-chosen default {@code PhoneAccount}.
      * <p>
-     * An {@link android.content.Intent#ACTION_CALL} or {@link android.content.Intent#ACTION_DIAL}
-     * {@code Intent} with no {@link TelecomManager#EXTRA_PHONE_ACCOUNT_HANDLE} is valid, and
-     * subsequent steps in the phone call flow are responsible for presenting the user with an
-     * affordance, if necessary, to choose a {@code PhoneAccount}.
-     *
      * @param uriScheme The URI scheme.
+     * @return The {@link PhoneAccountHandle} corresponding to the user-chosen default for outgoing
+     * phone calls for a specified URI scheme.
+     *
+     * @hide
      */
     public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme) {
         try {
@@ -355,7 +331,7 @@
     /**
      * Return the {@link PhoneAccount} which is the user-chosen default for making outgoing phone
      * calls. This {@code PhoneAccount} will always be a member of the list which is returned from
-     * calling {@link #getEnabledPhoneAccounts()}
+     * calling {@link #getCallCapablePhoneAccounts()}
      *
      * Apps must be prepared for this method to return {@code null}, indicating that there currently
      * exists no user-chosen default {@code PhoneAccount}.
@@ -389,24 +365,6 @@
     }
 
     /**
-     * Return a list of enabled {@link PhoneAccountHandle}s which can be used to make and receive
-     * phone calls.
-     *
-     * @see #EXTRA_PHONE_ACCOUNT_HANDLE
-     * @return A list of {@code PhoneAccountHandle} objects.
-     */
-    public List<PhoneAccountHandle> getEnabledPhoneAccounts() {
-        try {
-            if (isServiceConnected()) {
-                return getTelecomService().getEnabledPhoneAccounts();
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelecomService#getEnabledPhoneAccounts", e);
-        }
-        return new ArrayList<>();
-    }
-
-    /**
      * Returns the current SIM call manager. Apps must be prepared for this method to return
      * {@code null}, indicating that there currently exists no user-chosen default
      * {@code PhoneAccount}.
@@ -467,8 +425,8 @@
     }
 
     /**
-     * Returns a list of the enabled {@link PhoneAccountHandle}s which can be used to make and
-     * receive phone calls which support the specified URI scheme.
+     * Returns a list of the {@link PhoneAccountHandle}s which can be used to make and receive phone
+     * calls which support the specified URI scheme.
      * <P>
      * For example, invoking with {@code "tel"} will find all {@link PhoneAccountHandle}s which
      * support telephone calls (e.g. URIs such as {@code tel:555-555-1212}).  Invoking with
@@ -477,6 +435,8 @@
      *
      * @param uriScheme The URI scheme.
      * @return A list of {@code PhoneAccountHandle} objects supporting the URI scheme.
+     *
+     * @hide
      */
     public List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(String uriScheme) {
         try {
@@ -489,14 +449,52 @@
         return new ArrayList<>();
     }
 
+
     /**
-     * Determine whether the device has more than one account registered and enabled.
+     * Return a list of {@link PhoneAccountHandle}s which can be used to make and receive phone
+     * calls.
      *
-     * @return {@code true} if the device has more than one account registered and enabled and
-     * {@code false} otherwise.
+     * @see #EXTRA_PHONE_ACCOUNT_HANDLE
+     * @return A list of {@code PhoneAccountHandle} objects.
+     *
+     * @hide
      */
-    public boolean hasMultipleEnabledAccounts() {
-        return getEnabledPhoneAccounts().size() > 1;
+    public List<PhoneAccountHandle> getCallCapablePhoneAccounts() {
+        try {
+            if (isServiceConnected()) {
+                return getTelecomService().getCallCapablePhoneAccounts();
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelecomService#getCallCapablePhoneAccounts", e);
+        }
+        return new ArrayList<>();
+    }
+
+    /**
+     * Determine whether the device has more than one account registered that can make and receive
+     * phone calls.
+     *
+     * @return {@code true} if the device has more than one account registered and {@code false}
+     * otherwise.
+     */
+    public boolean hasMultipleCallCapableAccounts() {
+        return getCallCapablePhoneAccounts().size() > 1;
+    }
+
+    /**
+     *  Returns a list of all {@link PhoneAccount}s registered for the calling package.
+     *
+     * @return A list of {@code PhoneAccountHandle} objects.
+     */
+    public List<PhoneAccountHandle> getPhoneAccountsForPackage() {
+        try {
+            if (isServiceConnected()) {
+                return getTelecomService().getPhoneAccountsForPackage(mContext.getPackageName());
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelecomService#getPhoneAccountsForPackage", e);
+        }
+        return null;
     }
 
     /**
@@ -518,9 +516,9 @@
     }
 
     /**
-     * Returns a count of enabled and disabled {@link PhoneAccount}s.
+     * Returns a count of all {@link PhoneAccount}s.
      *
-     * @return The count of enabled and disabled {@link PhoneAccount}s.
+     * @return The count of {@link PhoneAccount}s.
      * @hide
      */
     @SystemApi
@@ -572,24 +570,6 @@
     }
 
     /**
-     * Enables or disables a {@link PhoneAccount}.
-     *
-     * @param account The {@link PhoneAccountHandle} to enable or disable.
-     * @param isEnabled {@code True} if the phone account should be enabled.
-     * @hide
-     */
-    @SystemApi
-    public void setPhoneAccountEnabled(PhoneAccountHandle account, boolean isEnabled) {
-        try {
-            if (isServiceConnected()) {
-                getTelecomService().setPhoneAccountEnabled(account, isEnabled);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelecomService#setPhoneAccountEnabled", e);
-        }
-    }
-
-    /**
      * Register a {@link PhoneAccount} for use by the system.
      *
      * @param account The complete {@link PhoneAccount}.
@@ -797,9 +777,8 @@
     /**
      * Registers a new incoming call. A {@link ConnectionService} should invoke this method when it
      * has an incoming call. The specified {@link PhoneAccountHandle} must have been registered
-     * with {@link #registerPhoneAccount} and subsequently enabled by the user within the phone's
-     * settings. Once invoked, this method will cause the system to bind to the
-     * {@link ConnectionService} associated with the {@link PhoneAccountHandle} and request
+     * with {@link #registerPhoneAccount}. Once invoked, this method will cause the system to bind
+     * to the {@link ConnectionService} associated with the {@link PhoneAccountHandle} and request
      * additional information about the call (See
      * {@link ConnectionService#onCreateIncomingConnection}) before starting the incoming call UI.
      *
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
index 8f3506d..5daa568 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
@@ -19,6 +19,7 @@
 import android.app.PendingIntent;
 import android.net.Uri;
 import android.telecom.ConnectionRequest;
+import android.telecom.DisconnectCause;
 import android.telecom.ParcelableConnection;
 import android.telecom.ParcelableConference;
 import android.telecom.StatusHints;
@@ -45,7 +46,7 @@
 
     void setDialing(String callId);
 
-    void setDisconnected(String callId, int disconnectCause, String disconnectMessage);
+    void setDisconnected(String callId, in DisconnectCause disconnectCause);
 
     void setOnHold(String callId);
 
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 4875cc3..feb09d5 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -50,9 +50,9 @@
     void setUserSelectedOutgoingPhoneAccount(in PhoneAccountHandle account);
 
     /**
-     * @see TelecomServiceImpl#getEnabledPhoneAccounts
+     * @see TelecomServiceImpl#getCallCapablePhoneAccounts
      */
-    List<PhoneAccountHandle> getEnabledPhoneAccounts();
+    List<PhoneAccountHandle> getCallCapablePhoneAccounts();
 
     /**
      * @see TelecomManager#getPhoneAccountsSupportingScheme
@@ -60,6 +60,11 @@
     List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(in String uriScheme);
 
     /**
+     * @see TelecomManager#getPhoneAccountsForPackage
+     */
+    List<PhoneAccountHandle> getPhoneAccountsForPackage(in String packageName);
+
+    /**
      * @see TelecomManager#getPhoneAccount
      */
     PhoneAccount getPhoneAccount(in PhoneAccountHandle account);
@@ -95,11 +100,6 @@
     List<PhoneAccountHandle> getSimCallManagers();
 
     /**
-     * @see TelecomServiceImpl#setPhoneAccountEnabled
-     */
-    void setPhoneAccountEnabled(in PhoneAccountHandle account, in boolean isEnabled);
-
-    /**
      * @see TelecomServiceImpl#registerPhoneAccount
      */
     void registerPhoneAccount(in PhoneAccount metadata);
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index 6366c91..6fe10dc 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -18,6 +18,7 @@
 
 /**
  * Contains disconnect call causes generated by the framework and the RIL.
+ * @hide
  */
 public class DisconnectCause {
 
@@ -262,7 +263,7 @@
         case OUTGOING_CANCELED:
             return "OUTGOING_CANCELED";
         default:
-            return "INVALID";
+            return "INVALID: " + cause;
         }
     }
 }
diff --git a/tests/Compatibility/Android.mk b/tests/Compatibility/Android.mk
index 5385413..0ec4d9d 100644
--- a/tests/Compatibility/Android.mk
+++ b/tests/Compatibility/Android.mk
@@ -18,12 +18,12 @@
 # We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
+LOCAL_JAVA_LIBRARIES := android.test.runner
 # Include all test java files.
 LOCAL_SRC_FILES := \
 	$(call all-java-files-under, src)
 
 
-LOCAL_SDK_VERSION := 8
 LOCAL_PACKAGE_NAME := AppCompatibilityTest
 
 include $(BUILD_PACKAGE)
diff --git a/tests/Compatibility/AndroidManifest.xml b/tests/Compatibility/AndroidManifest.xml
index 103ef4c..2884532 100644
--- a/tests/Compatibility/AndroidManifest.xml
+++ b/tests/Compatibility/AndroidManifest.xml
@@ -24,6 +24,4 @@
         android:name=".AppCompatibilityRunner"
         android:targetPackage="com.android.compatibilitytest"
         android:label="App Compability Test Runner" />
-
-    <uses-sdk android:minSdkVersion="8"></uses-sdk>
 </manifest>
diff --git a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
index a2e9117..5794b2b 100644
--- a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
+++ b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
@@ -147,11 +147,19 @@
      *         during the app launch.
      */
     private ProcessErrorStateInfo launchActivity(String packageName) {
+        // the recommended way to see if this is a tv or not.
+        boolean isleanback = !mPackageManager.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
+            && !mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
         Intent homeIntent = new Intent(Intent.ACTION_MAIN);
         homeIntent.addCategory(Intent.CATEGORY_HOME);
         homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        Intent intent = mPackageManager.getLaunchIntentForPackage(packageName);
+        Intent intent;
+        if (isleanback) {
+            Log.d(TAG, "Leanback and relax!");
+            intent = mPackageManager.getLeanbackLaunchIntentForPackage(packageName);
+        } else {
+            intent = mPackageManager.getLaunchIntentForPackage(packageName);
+        }
         // Skip if the apk does not have a launch intent.
         if (intent == null) {
             Log.d(TAG, "Skipping " + packageName + "; missing launch intent");
diff --git a/tools/layoutlib/bridge/tests/Android.mk b/tools/layoutlib/bridge/tests/Android.mk
index 5e47c8c..11390c3 100644
--- a/tools/layoutlib/bridge/tests/Android.mk
+++ b/tools/layoutlib/bridge/tests/Android.mk
@@ -18,8 +18,8 @@
 
 # Only compile source java files in this lib.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
 LOCAL_JAVA_RESOURCE_DIRS := res
+LOCAL_JAVACFLAGS := -source 6 -target 6
 
 LOCAL_MODULE := layoutlib-tests
 LOCAL_MODULE_TAGS := optional