Merge "Add error checking to aapt for split generation" into lmp-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index 6851bbf..a8c2ddc 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4798,7 +4798,9 @@
     method public int getCustomSizePreset();
     method public android.app.PendingIntent getDisplayIntent();
     method public int getGravity();
+    method public boolean getHintAvoidBackgroundClipping();
     method public boolean getHintHideIcon();
+    method public int getHintScreenTimeout();
     method public boolean getHintShowBackgroundOnly();
     method public java.util.List<android.app.Notification> getPages();
     method public boolean getStartScrollBottom();
@@ -4811,9 +4813,13 @@
     method public android.app.Notification.WearableExtender setCustomSizePreset(int);
     method public android.app.Notification.WearableExtender setDisplayIntent(android.app.PendingIntent);
     method public android.app.Notification.WearableExtender setGravity(int);
+    method public android.app.Notification.WearableExtender setHintAvoidBackgroundClipping(boolean);
     method public android.app.Notification.WearableExtender setHintHideIcon(boolean);
+    method public android.app.Notification.WearableExtender setHintScreenTimeout(int);
     method public android.app.Notification.WearableExtender setHintShowBackgroundOnly(boolean);
     method public android.app.Notification.WearableExtender setStartScrollBottom(boolean);
+    field public static final int SCREEN_TIMEOUT_LONG = -1; // 0xffffffff
+    field public static final int SCREEN_TIMEOUT_SHORT = 0; // 0x0
     field public static final int SIZE_DEFAULT = 0; // 0x0
     field public static final int SIZE_FULL_SCREEN = 5; // 0x5
     field public static final int SIZE_LARGE = 4; // 0x4
@@ -16304,6 +16310,7 @@
     method public void setPlaybackToRemote(android.media.VolumeProvider);
     method public void setQueue(java.util.List<android.media.session.MediaSession.QueueItem>);
     method public void setQueueTitle(java.lang.CharSequence);
+    method public void setRatingType(int);
     method public void setSessionActivity(android.app.PendingIntent);
     field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
     field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
@@ -16362,6 +16369,7 @@
     method public long getBufferedPosition();
     method public java.util.List<android.media.session.PlaybackState.CustomAction> getCustomActions();
     method public java.lang.CharSequence getErrorMessage();
+    method public android.os.Bundle getExtras();
     method public long getLastPositionUpdateTime();
     method public float getPlaybackSpeed();
     method public long getPosition();
@@ -16406,6 +16414,7 @@
     method public android.media.session.PlaybackState.Builder setActiveQueueItemId(long);
     method public android.media.session.PlaybackState.Builder setBufferedPosition(long);
     method public android.media.session.PlaybackState.Builder setErrorMessage(java.lang.CharSequence);
+    method public android.media.session.PlaybackState.Builder setExtras(android.os.Bundle);
     method public android.media.session.PlaybackState.Builder setState(int, long, float, long);
     method public android.media.session.PlaybackState.Builder setState(int, long, float);
   }
@@ -28391,6 +28400,7 @@
     method public void addNewIncomingCall(android.telecom.PhoneAccountHandle, android.os.Bundle);
     method public void cancelMissedCallsNotification();
     method public void clearAccounts();
+    method public android.net.Uri getAdnUriForPhoneAccount(android.telecom.PhoneAccountHandle);
     method public android.telecom.PhoneAccountHandle getConnectionManager();
     method public android.telecom.PhoneAccount getPhoneAccount(android.telecom.PhoneAccountHandle);
     method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsForPackage();
@@ -28849,26 +28859,20 @@
   }
 
   public class SubInfoRecord implements android.os.Parcelable {
-    ctor public SubInfoRecord();
-    ctor public SubInfoRecord(int, java.lang.String, int, java.lang.String, int, int, java.lang.String, int, int, int[], int, int);
     method public int describeContents();
     method public int getColor();
-    method public android.graphics.drawable.BitmapDrawable getIconDrawable();
-    method public java.lang.String getLabel();
+    method public int getDataRoaming();
+    method public java.lang.CharSequence getDisplayName();
+    method public java.lang.String getIccId();
+    method public android.graphics.drawable.BitmapDrawable getIcon();
+    method public int getMcc();
+    method public int getMnc();
+    method public int getNameSource();
+    method public java.lang.String getNumber();
+    method public int getSimSlotIndex();
+    method public int getSubscriptionId();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.SubInfoRecord> CREATOR;
-    field public int color;
-    field public int dataRoaming;
-    field public java.lang.String displayName;
-    field public int displayNumberFormat;
-    field public java.lang.String iccId;
-    field public int mcc;
-    field public int mnc;
-    field public int nameSource;
-    field public java.lang.String number;
-    field public int[] simIconRes;
-    field public int slotId;
-    field public int subId;
   }
 
   public class SubscriptionManager implements android.provider.BaseColumns {
@@ -30278,19 +30282,6 @@
     method public static java.text.DateFormat getMediumDateFormat(android.content.Context);
     method public static java.text.DateFormat getTimeFormat(android.content.Context);
     method public static boolean is24HourFormat(android.content.Context);
-    field public static final deprecated char AM_PM = 97; // 0x0061 'a'
-    field public static final deprecated char CAPITAL_AM_PM = 65; // 0x0041 'A'
-    field public static final deprecated char DATE = 100; // 0x0064 'd'
-    field public static final deprecated char DAY = 69; // 0x0045 'E'
-    field public static final deprecated char HOUR = 104; // 0x0068 'h'
-    field public static final deprecated char HOUR_OF_DAY = 107; // 0x006b 'k'
-    field public static final deprecated char MINUTE = 109; // 0x006d 'm'
-    field public static final deprecated char MONTH = 77; // 0x004d 'M'
-    field public static final deprecated char QUOTE = 39; // 0x0027 '\''
-    field public static final deprecated char SECONDS = 115; // 0x0073 's'
-    field public static final deprecated char STANDALONE_MONTH = 76; // 0x004c 'L'
-    field public static final deprecated char TIME_ZONE = 122; // 0x007a 'z'
-    field public static final deprecated char YEAR = 121; // 0x0079 'y'
   }
 
   public class DateUtils {
diff --git a/api/removed.txt b/api/removed.txt
index 8972679..1b69ee8 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -22,6 +22,26 @@
 
 }
 
+package android.text.format {
+
+  public class DateFormat {
+    field public static final deprecated char AM_PM = 97; // 0x0061 'a'
+    field public static final deprecated char CAPITAL_AM_PM = 65; // 0x0041 'A'
+    field public static final deprecated char DATE = 100; // 0x0064 'd'
+    field public static final deprecated char DAY = 69; // 0x0045 'E'
+    field public static final deprecated char HOUR = 104; // 0x0068 'h'
+    field public static final deprecated char HOUR_OF_DAY = 107; // 0x006b 'k'
+    field public static final deprecated char MINUTE = 109; // 0x006d 'm'
+    field public static final deprecated char MONTH = 77; // 0x004d 'M'
+    field public static final deprecated char QUOTE = 39; // 0x0027 '\''
+    field public static final deprecated char SECONDS = 115; // 0x0073 's'
+    field public static final deprecated char STANDALONE_MONTH = 76; // 0x004c 'L'
+    field public static final deprecated char TIME_ZONE = 122; // 0x007a 'z'
+    field public static final deprecated char YEAR = 121; // 0x0079 'y'
+  }
+
+}
+
 package android.view {
 
   public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index ba11a81..bc57030 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -417,7 +417,7 @@
             } else if (opt.equals("--ei")) {
                 String key = nextArgRequired();
                 String value = nextArgRequired();
-                intent.putExtra(key, Integer.valueOf(value));
+                intent.putExtra(key, Integer.decode(value));
             } else if (opt.equals("--eu")) {
                 String key = nextArgRequired();
                 String value = nextArgRequired();
@@ -434,7 +434,7 @@
                 String[] strings = value.split(",");
                 int[] list = new int[strings.length];
                 for (int i = 0; i < strings.length; i++) {
-                    list[i] = Integer.valueOf(strings[i]);
+                    list[i] = Integer.decode(strings[i]);
                 }
                 intent.putExtra(key, list);
             } else if (opt.equals("--el")) {
@@ -477,8 +477,23 @@
                 hasIntentInfo = true;
             } else if (opt.equals("--ez")) {
                 String key = nextArgRequired();
-                String value = nextArgRequired();
-                intent.putExtra(key, Boolean.valueOf(value));
+                String value = nextArgRequired().toLowerCase();
+                // Boolean.valueOf() results in false for anything that is not "true", which is
+                // error-prone in shell commands
+                boolean arg;
+                if ("true".equals(value) || "t".equals(value)) {
+                    arg = true;
+                } else if ("false".equals(value) || "f".equals(value)) {
+                    arg = false;
+                } else {
+                    try {
+                        arg = Integer.decode(value) != 0;
+                    } catch (NumberFormatException ex) {
+                        throw new IllegalArgumentException("Invalid boolean value: " + value);
+                    }
+                }
+
+                intent.putExtra(key, arg);
             } else if (opt.equals("-n")) {
                 String str = nextArgRequired();
                 ComponentName cn = ComponentName.unflattenFromString(str);
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 1e1b33f..a9eaf29 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -24,11 +24,9 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.util.Log;
-import android.view.Display;
 import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
 import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -620,18 +618,6 @@
         }
     }
 
-    @Override
-    public Object getSystemService(String name) {
-        if (Context.WINDOW_SERVICE.equals(name)) {
-            if (mWindowManager == null) {
-                WindowManager wrapped = (WindowManager) super.getSystemService(name);
-                mWindowManager = new LocalWindowManager(wrapped);
-            }
-            return mWindowManager;
-        }
-        return super.getSystemService(name);
-    }
-
     /**
      * Implement to return the implementation of the internal accessibility
      * service interface.
@@ -658,6 +644,9 @@
             public void init(int connectionId, IBinder windowToken) {
                 mConnectionId = connectionId;
                 mWindowToken = windowToken;
+
+                // Let the window manager know about our shiny new token.
+                WindowManagerGlobal.getInstance().setDefaultToken(mWindowToken);
             }
 
             @Override
@@ -812,53 +801,4 @@
             }
         }
     }
-
-    private class LocalWindowManager implements WindowManager {
-        private final WindowManager mImpl;
-
-        private LocalWindowManager(WindowManager impl) {
-            mImpl = impl;
-        }
-
-        @Override
-        public Display getDefaultDisplay() {
-            return mImpl.getDefaultDisplay();
-        }
-
-        @Override
-        public void addView(View view, ViewGroup.LayoutParams params) {
-            if (!(params instanceof WindowManager.LayoutParams)) {
-                throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
-            }
-            WindowManager.LayoutParams windowParams = (WindowManager.LayoutParams) params;
-            if (windowParams.type == LayoutParams.TYPE_ACCESSIBILITY_OVERLAY
-                    && windowParams.token == null) {
-                windowParams.token = mWindowToken;
-            }
-            mImpl.addView(view, params);
-        }
-
-        @Override
-        public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
-            if (!(params instanceof WindowManager.LayoutParams)) {
-                throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
-            }
-            WindowManager.LayoutParams windowParams = (WindowManager.LayoutParams) params;
-            if (windowParams.type == LayoutParams.TYPE_ACCESSIBILITY_OVERLAY
-                    && windowParams.token == null) {
-                windowParams.token = mWindowToken;
-            }
-            mImpl.updateViewLayout(view, params);
-        }
-
-        @Override
-        public void removeViewImmediate(View view) {
-            mImpl.removeViewImmediate(view);
-        }
-
-        @Override
-        public void removeView(View view) {
-            mImpl.removeView(view);
-        }
-    }
 }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 37e8aa4..a285932 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1243,26 +1243,16 @@
     }
 
     /**
-     * If set, the process of the root activity of the task will be killed
-     * as part of removing the task.
-     * @hide
-     */
-    public static final int REMOVE_TASK_KILL_PROCESS = 0x0001;
-
-    /**
      * Completely remove the given task.
      *
      * @param taskId Identifier of the task to be removed.
-     * @param flags Additional operational flags.  May be 0 or
-     * {@link #REMOVE_TASK_KILL_PROCESS}.
      * @return Returns true if the given task was found and removed.
      *
      * @hide
      */
-    public boolean removeTask(int taskId, int flags)
-            throws SecurityException {
+    public boolean removeTask(int taskId) throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault().removeTask(taskId, flags);
+            return ActivityManagerNative.getDefault().removeTask(taskId);
         } catch (RemoteException e) {
             // System dead, we will be dead too soon!
             return false;
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 4e2ff0b..bc7114b 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1884,8 +1884,7 @@
         {
             data.enforceInterface(IActivityManager.descriptor);
             int taskId = data.readInt();
-            int fl = data.readInt();
-            boolean result = removeTask(taskId, fl);
+            boolean result = removeTask(taskId);
             reply.writeNoException();
             reply.writeInt(result ? 1 : 0);
             return true;
@@ -4778,12 +4777,11 @@
         return result;
     }
 
-    public boolean removeTask(int taskId, int flags) throws RemoteException {
+    public boolean removeTask(int taskId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeInt(taskId);
-        data.writeInt(flags);
         mRemote.transact(REMOVE_TASK_TRANSACTION, data, reply, 0);
         reply.readException();
         boolean result = reply.readInt() != 0;
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index be26f30..efcb197 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -373,7 +373,7 @@
     public boolean isUserRunning(int userid, boolean orStopping) throws RemoteException;
     public int[] getRunningUserIds() throws RemoteException;
 
-    public boolean removeTask(int taskId, int flags) throws RemoteException;
+    public boolean removeTask(int taskId) throws RemoteException;
 
     public void registerProcessObserver(IProcessObserver observer) throws RemoteException;
     public void unregisterProcessObserver(IProcessObserver observer) throws RemoteException;
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 9849c51..c65f017 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -4340,6 +4340,19 @@
          */
         public static final int SIZE_FULL_SCREEN = 5;
 
+        /**
+         * Sentinel value for use with {@link #setHintScreenTimeout} to keep the screen on for a
+         * short amount of time when this notification is displayed on the screen. This
+         * is the default value.
+         */
+        public static final int SCREEN_TIMEOUT_SHORT = 0;
+
+        /**
+         * Sentinel value for use with {@link #setHintScreenTimeout} to keep the screen on
+         * for a longer amount of time when this notification is displayed on the screen.
+         */
+        public static final int SCREEN_TIMEOUT_LONG = -1;
+
         /** Notification extra which contains wearable extensions */
         private static final String EXTRA_WEARABLE_EXTENSIONS = "android.wearable.EXTENSIONS";
 
@@ -4355,12 +4368,14 @@
         private static final String KEY_CUSTOM_SIZE_PRESET = "customSizePreset";
         private static final String KEY_CUSTOM_CONTENT_HEIGHT = "customContentHeight";
         private static final String KEY_GRAVITY = "gravity";
+        private static final String KEY_HINT_SCREEN_TIMEOUT = "hintScreenTimeout";
 
         // Flags bitwise-ored to mFlags
         private static final int FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE = 0x1;
         private static final int FLAG_HINT_HIDE_ICON = 1 << 1;
         private static final int FLAG_HINT_SHOW_BACKGROUND_ONLY = 1 << 2;
         private static final int FLAG_START_SCROLL_BOTTOM = 1 << 3;
+        private static final int FLAG_HINT_AVOID_BACKGROUND_CLIPPING = 1 << 4;
 
         // Default value for flags integer
         private static final int DEFAULT_FLAGS = FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE;
@@ -4379,6 +4394,7 @@
         private int mCustomSizePreset = SIZE_DEFAULT;
         private int mCustomContentHeight;
         private int mGravity = DEFAULT_GRAVITY;
+        private int mHintScreenTimeout;
 
         /**
          * Create a {@link android.app.Notification.WearableExtender} with default
@@ -4414,6 +4430,7 @@
                         SIZE_DEFAULT);
                 mCustomContentHeight = wearableBundle.getInt(KEY_CUSTOM_CONTENT_HEIGHT);
                 mGravity = wearableBundle.getInt(KEY_GRAVITY, DEFAULT_GRAVITY);
+                mHintScreenTimeout = wearableBundle.getInt(KEY_HINT_SCREEN_TIMEOUT);
             }
         }
 
@@ -4461,6 +4478,9 @@
             if (mGravity != DEFAULT_GRAVITY) {
                 wearableBundle.putInt(KEY_GRAVITY, mGravity);
             }
+            if (mHintScreenTimeout != 0) {
+                wearableBundle.putInt(KEY_HINT_SCREEN_TIMEOUT, mHintScreenTimeout);
+            }
 
             builder.getExtras().putBundle(EXTRA_WEARABLE_EXTENSIONS, wearableBundle);
             return builder;
@@ -4480,6 +4500,7 @@
             that.mCustomSizePreset = this.mCustomSizePreset;
             that.mCustomContentHeight = this.mCustomContentHeight;
             that.mGravity = this.mGravity;
+            that.mHintScreenTimeout = this.mHintScreenTimeout;
             return that;
         }
 
@@ -4875,6 +4896,48 @@
             return (mFlags & FLAG_HINT_SHOW_BACKGROUND_ONLY) != 0;
         }
 
+        /**
+         * Set a hint that this notification's background should not be clipped if possible.
+         * @param hintAvoidBackgroundClipping {@code true} to avoid clipping if possible.
+         * @return this object for method chaining
+         */
+        public WearableExtender setHintAvoidBackgroundClipping(
+                boolean hintAvoidBackgroundClipping) {
+            setFlag(FLAG_HINT_AVOID_BACKGROUND_CLIPPING, hintAvoidBackgroundClipping);
+            return this;
+        }
+
+        /**
+         * Get a hint that this notification's background should not be clipped if possible.
+         * @return {@code true} if it's ok if the background is clipped on the screen, false
+         * otherwise. The default value is {@code false} if this was never set.
+         */
+        public boolean getHintAvoidBackgroundClipping() {
+            return (mFlags & FLAG_HINT_AVOID_BACKGROUND_CLIPPING) != 0;
+        }
+
+        /**
+         * Set a hint that the screen should remain on for at least this duration when
+         * this notification is displayed on the screen.
+         * @param timeout The requested screen timeout in milliseconds. Can also be either
+         *     {@link #SCREEN_TIMEOUT_SHORT} or {@link #SCREEN_TIMEOUT_LONG}.
+         * @return this object for method chaining
+         */
+        public WearableExtender setHintScreenTimeout(int timeout) {
+            mHintScreenTimeout = timeout;
+            return this;
+        }
+
+        /**
+         * Get the duration, in milliseconds, that the screen should remain on for
+         * when this notification is displayed.
+         * @return the duration in milliseconds if > 0, or either one of the sentinel values
+         *     {@link #SCREEN_TIMEOUT_SHORT} or {@link #SCREEN_TIMEOUT_LONG}.
+         */
+        public int getHintScreenTimeout() {
+            return mHintScreenTimeout;
+        }
+
         private void setFlag(int mask, boolean value) {
             if (value) {
                 mFlags |= mask;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 7676e4b..e06f034 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -41,6 +41,7 @@
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.Process;
 import android.os.StrictMode;
 import android.os.UserHandle;
 import android.provider.DocumentsContract;
@@ -7498,8 +7499,10 @@
      */
     public void prepareToEnterProcess() {
         if (mContentUserHint != UserHandle.USER_CURRENT) {
-            fixUris(mContentUserHint);
-            mContentUserHint = UserHandle.USER_CURRENT;
+            if (UserHandle.getAppId(Process.myUid()) != Process.SYSTEM_UID) {
+                fixUris(mContentUserHint);
+                mContentUserHint = UserHandle.USER_CURRENT;
+            }
         }
     }
 
diff --git a/core/java/android/hardware/hdmi/HdmiRecordListener.java b/core/java/android/hardware/hdmi/HdmiRecordListener.java
index 29f6cfc..90b7768 100644
--- a/core/java/android/hardware/hdmi/HdmiRecordListener.java
+++ b/core/java/android/hardware/hdmi/HdmiRecordListener.java
@@ -39,6 +39,8 @@
     /**
      * Called when one touch record is started or failed during initialization.
      *
+     * @param recorderAddress An address of recorder that reports result of one touch record
+     *            request
      * @param result result code. For more details, please look at all constants starting with
      *            "ONE_TOUCH_RECORD_". Only
      *            {@link HdmiControlManager#ONE_TOUCH_RECORD_RECORDING_CURRENTLY_SELECTED_SOURCE},
@@ -47,15 +49,17 @@
      *            {@link HdmiControlManager#ONE_TOUCH_RECORD_RECORDING_EXTERNAL_INPUT} mean normal
      *            start of recording; otherwise, describes failure.
      */
-    public void onOneTouchRecordResult(int result) {
+    public void onOneTouchRecordResult(int recorderAddress, int result) {
     }
 
     /**
      * Called when timer recording is started or failed during initialization.
      *
+     * @param recorderAddress An address of recorder that reports result of timer recording
+     *            request
      * @param data timer status data. For more details, look at {@link TimerStatusData}.
      */
-    public void onTimerRecordingResult(TimerStatusData data) {
+    public void onTimerRecordingResult(int recorderAddress, TimerStatusData data) {
     }
 
     /**
@@ -230,6 +234,8 @@
     /**
      * Called when receiving result for clear timer recording request.
      *
+     * @param recorderAddress An address of recorder that reports result of clear timer recording
+     *            request
      * @param result result of clear timer. It should be one of
      *            {@link HdmiControlManager#CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_RECORDING}
      *            {@link HdmiControlManager#CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_NO_MATCHING},
@@ -239,6 +245,6 @@
      *            {@link HdmiControlManager#CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE},
      *            {@link HdmiControlManager#CLEAR_TIMER_STATUS_CEC_DISABLE}.
      */
-    public void onClearTimerRecordingResult(int result) {
+    public void onClearTimerRecordingResult(int recorderAddress, int result) {
     }
 }
diff --git a/core/java/android/hardware/hdmi/HdmiTvClient.java b/core/java/android/hardware/hdmi/HdmiTvClient.java
index dbfb4ef..cef17dd 100644
--- a/core/java/android/hardware/hdmi/HdmiTvClient.java
+++ b/core/java/android/hardware/hdmi/HdmiTvClient.java
@@ -226,19 +226,19 @@
             }
 
             @Override
-            public void onOneTouchRecordResult(int result) {
-                callback.onOneTouchRecordResult(result);
+            public void onOneTouchRecordResult(int recorderAddress, int result) {
+                callback.onOneTouchRecordResult(recorderAddress, result);
             }
 
             @Override
-            public void onTimerRecordingResult(int result) {
-                callback.onTimerRecordingResult(
+            public void onTimerRecordingResult(int recorderAddress, int result) {
+                callback.onTimerRecordingResult(recorderAddress,
                         HdmiRecordListener.TimerStatusData.parseFrom(result));
             }
 
             @Override
-            public void onClearTimerRecordingResult(int result) {
-                callback.onClearTimerRecordingResult(result);
+            public void onClearTimerRecordingResult(int recorderAddress, int result) {
+                callback.onClearTimerRecordingResult(recorderAddress, result);
             }
         };
     }
diff --git a/core/java/android/hardware/hdmi/IHdmiRecordListener.aidl b/core/java/android/hardware/hdmi/IHdmiRecordListener.aidl
index 44d9065..d2deb38 100644
--- a/core/java/android/hardware/hdmi/IHdmiRecordListener.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiRecordListener.aidl
@@ -31,19 +31,25 @@
      /**
       * Called when one touch record is started or failed during initialization.
       *
+      * @param recorderAddress An address of recorder that reports result of one touch record
+      *            request
       * @param result result code for one touch record
       */
-     void onOneTouchRecordResult(int result);
+     void onOneTouchRecordResult(int recorderAddress, int result);
      /**
       * Called when timer recording is started or failed during initialization.
-
+      *
+      * @param recorderAddress An address of recorder that reports result of timer recording
+      *            request
       * @param result result code for timer recording
       */
-     void onTimerRecordingResult(int result);
+     void onTimerRecordingResult(int recorderAddress, int result);
      /**
       * Called when receiving result for clear timer recording request.
       *
-      * @param result result of clear timer.
+      * @param recorderAddress An address of recorder that reports result of clear timer recording
+      *            request
+      * @param result result of clear timer
       */
-     void onClearTimerRecordingResult(int result);
+     void onClearTimerRecordingResult(int recorderAddress, int result);
  }
\ No newline at end of file
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index 71df60a..6159e1e 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -200,7 +200,7 @@
         vendorInfo = info;
     }
 
-    public void setDomains(String domains) {
-        domains = domains;
+    public void setDomains(String newDomains) {
+        domains = newDomains;
     }
 }
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index 5a273cf..598a503 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -107,6 +107,7 @@
         for (InetAddress dns : dnsServers) {
             lp.addDnsServer(dns);
         }
+        lp.setDomains(domains);
         return lp;
     }
 
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 084ca30..3f42d25 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -165,7 +165,7 @@
         public int otherSwappedOut;
 
         /** @hide */
-        public static final int NUM_OTHER_STATS = 16;
+        public static final int NUM_OTHER_STATS = 17;
 
         /** @hide */
         public static final int NUM_DVK_STATS = 5;
@@ -296,23 +296,24 @@
                 case 1: return "Stack";
                 case 2: return "Cursor";
                 case 3: return "Ashmem";
-                case 4: return "Other dev";
-                case 5: return ".so mmap";
-                case 6: return ".jar mmap";
-                case 7: return ".apk mmap";
-                case 8: return ".ttf mmap";
-                case 9: return ".dex mmap";
-                case 10: return "code mmap";
-                case 11: return "image mmap";
-                case 12: return "Other mmap";
-                case 13: return "Graphics";
-                case 14: return "GL";
-                case 15: return "Memtrack";
-                case 16: return ".Heap";
-                case 17: return ".LOS";
-                case 18: return ".LinearAlloc";
-                case 19: return ".GC";
-                case 20: return ".JITCache";
+                case 4: return "Gfx driver";
+                case 5: return "Other dev";
+                case 6: return ".so mmap";
+                case 7: return ".jar mmap";
+                case 8: return ".apk mmap";
+                case 9: return ".ttf mmap";
+                case 10: return ".dex mmap";
+                case 11: return ".oat mmap";
+                case 12: return ".art mmap";
+                case 13: return "Other mmap";
+                case 14: return "Graphics";
+                case 15: return "GL";
+                case 16: return "Memtrack";
+                case 17: return ".Heap";
+                case 18: return ".LOS";
+                case 19: return ".LinearAlloc";
+                case 20: return ".GC";
+                case 21: return ".JITCache";
                 default: return "????";
             }
         }
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 9a84a1e..9fb3535 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -498,7 +498,7 @@
     }
 
     // For built-in conditions
-    private static final String SYSTEM_AUTHORITY = "android";
+    public static final String SYSTEM_AUTHORITY = "android";
 
     // Built-in countdown conditions, e.g. condition://android/countdown/1399917958951
     private static final String COUNTDOWN_PATH = "countdown";
diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java
index 9fec9a1..933bcee 100755
--- a/core/java/android/text/format/DateFormat.java
+++ b/core/java/android/text/format/DateFormat.java
@@ -60,27 +60,45 @@
  * {@code SimpleDateFormat}.
  */
 public class DateFormat {
-    /** @deprecated Use a literal {@code '} instead. */
+    /**
+     * @deprecated Use a literal {@code '} instead.
+     * @removed
+     */
     @Deprecated
     public  static final char    QUOTE                  =    '\'';
 
-    /** @deprecated Use a literal {@code 'a'} instead. */
+    /**
+     * @deprecated Use a literal {@code 'a'} instead.
+     * @removed
+     */
     @Deprecated
     public  static final char    AM_PM                  =    'a';
 
-    /** @deprecated Use a literal {@code 'a'} instead; 'A' was always equivalent to 'a'. */
+    /**
+     * @deprecated Use a literal {@code 'a'} instead; 'A' was always equivalent to 'a'.
+     * @removed
+     */
     @Deprecated
     public  static final char    CAPITAL_AM_PM          =    'A';
 
-    /** @deprecated Use a literal {@code 'd'} instead. */
+    /**
+     * @deprecated Use a literal {@code 'd'} instead.
+     * @removed
+     */
     @Deprecated
     public  static final char    DATE                   =    'd';
 
-    /** @deprecated Use a literal {@code 'E'} instead. */
+    /**
+     * @deprecated Use a literal {@code 'E'} instead.
+     * @removed
+     */
     @Deprecated
     public  static final char    DAY                    =    'E';
 
-    /** @deprecated Use a literal {@code 'h'} instead. */
+    /**
+     * @deprecated Use a literal {@code 'h'} instead.
+     * @removed
+     */
     @Deprecated
     public  static final char    HOUR                   =    'h';
 
@@ -88,31 +106,51 @@
      * @deprecated Use a literal {@code 'H'} (for compatibility with {@link SimpleDateFormat}
      * and Unicode) or {@code 'k'} (for compatibility with Android releases up to and including
      * Jelly Bean MR-1) instead. Note that the two are incompatible.
+     *
+     * @removed
      */
     @Deprecated
     public  static final char    HOUR_OF_DAY            =    'k';
 
-    /** @deprecated Use a literal {@code 'm'} instead. */
+    /**
+     * @deprecated Use a literal {@code 'm'} instead.
+     * @removed
+     */
     @Deprecated
     public  static final char    MINUTE                 =    'm';
 
-    /** @deprecated Use a literal {@code 'M'} instead. */
+    /**
+     * @deprecated Use a literal {@code 'M'} instead.
+     * @removed
+     */
     @Deprecated
     public  static final char    MONTH                  =    'M';
 
-    /** @deprecated Use a literal {@code 'L'} instead. */
+    /**
+     * @deprecated Use a literal {@code 'L'} instead.
+     * @removed
+     */
     @Deprecated
     public  static final char    STANDALONE_MONTH       =    'L';
 
-    /** @deprecated Use a literal {@code 's'} instead. */
+    /**
+     * @deprecated Use a literal {@code 's'} instead.
+     * @removed
+     */
     @Deprecated
     public  static final char    SECONDS                =    's';
 
-    /** @deprecated Use a literal {@code 'z'} instead. */
+    /**
+     * @deprecated Use a literal {@code 'z'} instead.
+     * @removed
+     */
     @Deprecated
     public  static final char    TIME_ZONE              =    'z';
 
-    /** @deprecated Use a literal {@code 'y'} instead. */
+    /**
+     * @deprecated Use a literal {@code 'y'} instead.
+     * @removed
+     */
     @Deprecated
     public  static final char    YEAR                   =    'y';
 
@@ -306,9 +344,9 @@
     }
 
     /**
-     * Gets the current date format stored as a char array. The array will contain
-     * 3 elements ({@link #DATE}, {@link #MONTH}, and {@link #YEAR}) in the order
-     * specified by the user's format preference.  Note that this order is
+     * Gets the current date format stored as a char array. Returns a 3 element
+     * array containing the day ({@code 'd'}), month ({@code 'M'}), and year ({@code 'y'}))
+     * in the order specified by the user's format preference.  Note that this order is
      * <i>only</i> appropriate for all-numeric dates; spelled-out (MEDIUM and LONG)
      * dates will generally contain other punctuation, spaces, or words,
      * not just the day, month, and year, and not necessarily in the same
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index e99c2cf..2705bcf 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -84,8 +84,8 @@
  *
  * <p>Custom transition classes may be instantiated with a <code>transition</code> tag:</p>
  * <pre>&lt;transition class="my.app.transition.CustomTransition"/></pre>
- * <p>Custom transition classes loaded from XML must have a public nullary (no argument)
- * constructor.</p>
+ * <p>Custom transition classes loaded from XML should have a public constructor taking
+ * a {@link android.content.Context} and {@link android.util.AttributeSet}.</p>
  *
  * <p>Note that attributes for the transition are not required, just as they are
  * optional when declared in code; Transitions created from XML resources will use
@@ -955,7 +955,7 @@
      * Views with different IDs, or no IDs whatsoever, will be ignored.
      *
      * <p>Note that using ids to specify targets implies that ids should be unique
-     * within the view hierarchy underneat the scene root.</p>
+     * within the view hierarchy underneath the scene root.</p>
      *
      * @see View#getId()
      * @param targetId The id of a target view, must be a positive number.
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 1cadf69..5e05683 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -1109,15 +1109,17 @@
                         || accessibilityViewId == providerHost.getAccessibilityViewId()) {
                     final AccessibilityNodeInfo parent;
                     if (virtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
-                        parent = provider.createAccessibilityNodeInfo(
-                                virtualDescendantId);
+                        parent = provider.createAccessibilityNodeInfo(virtualDescendantId);
                     } else {
-                        parent= provider.createAccessibilityNodeInfo(
+                        parent = provider.createAccessibilityNodeInfo(
                                 AccessibilityNodeProvider.HOST_VIEW_ID);
                     }
-                    if (parent != null) {
-                        outInfos.add(parent);
+                    if (parent == null) {
+                        // Couldn't obtain the parent, which means we have a
+                        // disconnected sub-tree. Abort prefetch immediately.
+                        return;
                     }
+                    outInfos.add(parent);
                     parentNodeId = parent.getParentNodeId();
                     accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(
                             parentNodeId);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 6450146..ea0a077 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -728,8 +728,8 @@
                 }
 
                 final Rect insets = attrs.surfaceInsets;
-                final boolean hasSurfaceInsets = insets.left == 0 || insets.right == 0
-                        || insets.top == 0 || insets.bottom == 0;
+                final boolean hasSurfaceInsets = insets.left != 0 || insets.right != 0
+                        || insets.top != 0 || insets.bottom != 0;
                 final boolean translucent = attrs.format != PixelFormat.OPAQUE || hasSurfaceInsets;
                 mAttachInfo.mHardwareRenderer = HardwareRenderer.create(mContext, translucent);
                 if (mAttachInfo.mHardwareRenderer != null) {
@@ -1746,8 +1746,8 @@
                 if (hwInitialized ||
                         mWidth != mAttachInfo.mHardwareRenderer.getWidth() ||
                         mHeight != mAttachInfo.mHardwareRenderer.getHeight()) {
-                    final Rect surfaceInsets = params != null ? params.surfaceInsets : null;
-                    mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight, surfaceInsets);
+                    mAttachInfo.mHardwareRenderer.setup(
+                            mWidth, mHeight, mWindowAttributes.surfaceInsets);
                     if (!hwInitialized) {
                         mAttachInfo.mHardwareRenderer.invalidate(mSurface);
                         mFullRedrawNeeded = true;
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 5926d5f..82b1073 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -118,6 +118,9 @@
 
     private Runnable mSystemPropertyUpdater;
 
+    /** Default token to apply to added views. */
+    private IBinder mDefaultToken;
+
     private WindowManagerGlobal() {
     }
 
@@ -169,6 +172,17 @@
         }
     }
 
+    /**
+     * Sets the default token to use in {@link #addView} when no parent window
+     * token is available and no token has been explicitly set in the view's
+     * layout params.
+     *
+     * @param token Default window token to apply to added views.
+     */
+    public void setDefaultToken(IBinder token) {
+        mDefaultToken = token;
+    }
+
     public String[] getViewRootNames() {
         synchronized (mLock) {
             final int numRoots = mRoots.size();
@@ -216,6 +230,10 @@
             }
         }
 
+        if (wparams.token == null && mDefaultToken != null) {
+            wparams.token = mDefaultToken;
+        }
+
         ViewRootImpl root;
         View panelParentView = null;
 
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index fcf66f6..f9544d0 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -107,9 +107,9 @@
 
         mAdapter.setRange(mMinDate, mMaxDate);
 
-        if (constrainCalendar(mSelectedDay, mMinDate, mMaxDate)) {
-            goTo(mSelectedDay, false, true, true);
-        }
+        // Changing the min/max date changes the selection position since we
+        // don't really have stable IDs.
+        goTo(mSelectedDay, false, true, true);
     }
 
     /**
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index d4d186c..f90d64a 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -1752,6 +1752,17 @@
     }
 
     /**
+     * Accessor to enable LayoutLib to get ActionMenuPresenter directly.
+     */
+    ActionMenuPresenter getOuterActionMenuPresenter() {
+        return mOuterActionMenuPresenter;
+    }
+
+    Context getPopupContext() {
+        return mPopupContext;
+    }
+
+    /**
      * Interface responsible for receiving menu item click events if the items themselves
      * do not have individual item click listeners.
      */
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 0bc1a8d..64bd6b6 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -20,6 +20,7 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentSender;
+import android.content.pm.ActivityInfo;
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.util.Log;
@@ -75,16 +76,21 @@
     }
 
     @Override
-    public Intent getReplacementIntent(String packageName, Intent defIntent) {
+    public Intent getReplacementIntent(ActivityInfo aInfo, Intent defIntent) {
+        Intent result = defIntent;
         if (mReplacementExtras != null) {
-            final Bundle replExtras = mReplacementExtras.getBundle(packageName);
+            final Bundle replExtras = mReplacementExtras.getBundle(aInfo.packageName);
             if (replExtras != null) {
-                final Intent result = new Intent(defIntent);
+                result = new Intent(defIntent);
                 result.putExtras(replExtras);
-                return result;
             }
         }
-        return defIntent;
+        if (aInfo.name.equals(IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER)
+                || aInfo.name.equals(IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE)) {
+            result = Intent.createChooser(result,
+                    getIntent().getCharSequenceExtra(Intent.EXTRA_TITLE));
+        }
+        return result;
     }
 
     @Override
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 6e2f84a..9656a21 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -58,21 +58,22 @@
         Intent intentReceived = getIntent();
 
         String className = intentReceived.getComponent().getClassName();
-        final UserHandle userDest;
+        final int targetUserId;
         final int userMessageId;
 
         if (className.equals(FORWARD_INTENT_TO_USER_OWNER)) {
             userMessageId = com.android.internal.R.string.forward_intent_to_owner;
-            userDest = UserHandle.OWNER;
+            targetUserId = UserHandle.USER_OWNER;
         } else if (className.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) {
             userMessageId = com.android.internal.R.string.forward_intent_to_work;
-            userDest = getManagedProfile();
+            targetUserId = getManagedProfile();
         } else {
             Slog.wtf(TAG, IntentForwarderActivity.class.getName() + " cannot be called directly");
             userMessageId = -1;
-            userDest = null;
+            targetUserId = UserHandle.USER_NULL;
         }
-        if (userDest == null) { // This covers the case where there is no managed profile.
+        if (targetUserId == UserHandle.USER_NULL) {
+            // This covers the case where there is no managed profile.
             finish();
             return;
         }
@@ -83,31 +84,24 @@
         newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
                 |Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
         int callingUserId = getUserId();
-        IPackageManager ipm = AppGlobals.getPackageManager();
-        String resolvedType = newIntent.resolveTypeIfNeeded(getContentResolver());
-        boolean canForward = false;
-        Intent selector = newIntent.getSelector();
-        if (selector == null) {
-            selector = newIntent;
-        }
-        try {
-            canForward = ipm.canForwardTo(selector, resolvedType, callingUserId,
-                    userDest.getIdentifier());
-        } catch (RemoteException e) {
-            Slog.e(TAG, "PackageManagerService is dead?");
-        }
-        if (canForward) {
-            newIntent.setContentUserHint(callingUserId);
+
+        if (canForward(newIntent, targetUserId)) {
+            if (newIntent.getAction().equals(Intent.ACTION_CHOOSER)) {
+                Intent innerIntent = (Intent) newIntent.getParcelableExtra(Intent.EXTRA_INTENT);
+                innerIntent.setContentUserHint(callingUserId);
+            } else {
+                newIntent.setContentUserHint(callingUserId);
+            }
 
             final android.content.pm.ResolveInfo ri = getPackageManager().resolveActivityAsUser(
-                        newIntent, MATCH_DEFAULT_ONLY, userDest.getIdentifier());
+                        newIntent, MATCH_DEFAULT_ONLY, targetUserId);
 
             // Only show a disclosure if this is a normal (non-OS) app
             final boolean shouldShowDisclosure =
                     !UserHandle.isSameApp(ri.activityInfo.applicationInfo.uid, Process.SYSTEM_UID);
 
             try {
-                startActivityAsCaller(newIntent, null, userDest.getIdentifier());
+                startActivityAsCaller(newIntent, null, targetUserId);
             } catch (RuntimeException e) {
                 int launchedFromUid = -1;
                 String launchedFromPackage = "?";
@@ -129,26 +123,55 @@
             }
         } else {
             Slog.wtf(TAG, "the intent: " + newIntent + "cannot be forwarded from user "
-                    + callingUserId + " to user " + userDest.getIdentifier());
+                    + callingUserId + " to user " + targetUserId);
         }
         finish();
     }
 
+    boolean canForward(Intent intent, int targetUserId)  {
+        IPackageManager ipm = AppGlobals.getPackageManager();
+        if (intent.getAction().equals(Intent.ACTION_CHOOSER)) {
+            // The EXTRA_INITIAL_INTENTS may not be allowed to be forwarded.
+            if (intent.hasExtra(Intent.EXTRA_INITIAL_INTENTS)) {
+                Slog.wtf(TAG, "An chooser intent with extra initial intents cannot be forwarded to"
+                        + " a different user");
+                return false;
+            }
+            if (intent.hasExtra(Intent.EXTRA_REPLACEMENT_EXTRAS)) {
+                Slog.wtf(TAG, "A chooser intent with replacement extras cannot be forwarded to a"
+                        + " different user");
+                return false;
+            }
+            intent = (Intent) intent.getParcelableExtra(Intent.EXTRA_INTENT);
+        }
+        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+        if (intent.getSelector() != null) {
+            intent = intent.getSelector();
+        }
+        try {
+            return ipm.canForwardTo(intent, resolvedType, getUserId(),
+                    targetUserId);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "PackageManagerService is dead?");
+            return false;
+        }
+    }
+
     /**
-     * Returns the managed profile for this device or null if there is no managed
-     * profile.
+     * Returns the userId of the managed profile for this device or UserHandle.USER_NULL if there is
+     * no managed profile.
      *
      * TODO: Remove the assumption that there is only one managed profile
      * on the device.
      */
-    private UserHandle getManagedProfile() {
+    private int getManagedProfile() {
         UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
         List<UserInfo> relatedUsers = userManager.getProfiles(UserHandle.USER_OWNER);
         for (UserInfo userInfo : relatedUsers) {
-            if (userInfo.isManagedProfile()) return new UserHandle(userInfo.id);
+            if (userInfo.isManagedProfile()) return userInfo.id;
         }
         Slog.wtf(TAG, FORWARD_INTENT_TO_MANAGED_PROFILE
                 + " has been called, but there is no managed profile");
-        return null;
+        return UserHandle.USER_NULL;
     }
 }
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 7df76e5..376db6e 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -100,6 +100,7 @@
     private int mMaxColumns;
     private int mLastSelected = ListView.INVALID_POSITION;
     private boolean mResolvingHome = false;
+    private int mProfileSwitchMessageId = -1;
 
     private UsageStatsManager mUsm;
     private Map<String, UsageStats> mStats;
@@ -200,6 +201,11 @@
             List<ResolveInfo> rList, boolean alwaysUseOption) {
         setTheme(R.style.Theme_DeviceDefault_Resolver);
         super.onCreate(savedInstanceState);
+
+        // Determine whether we should show that intent is forwarded
+        // from managed profile to owner or other way around.
+        setProfileSwitchMessageId(intent.getContentUserHint());
+
         try {
             mLaunchedFromUid = ActivityManagerNative.getDefault().getLaunchedFromUid(
                     getActivityToken());
@@ -320,6 +326,22 @@
         }
     }
 
+    private void setProfileSwitchMessageId(int contentUserHint) {
+        if (contentUserHint != UserHandle.USER_CURRENT &&
+                contentUserHint != UserHandle.myUserId()) {
+            UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
+            UserInfo originUserInfo = userManager.getUserInfo(contentUserHint);
+            boolean originIsManaged = originUserInfo != null ? originUserInfo.isManagedProfile()
+                    : false;
+            boolean targetIsManaged = userManager.isManagedProfile();
+            if (originIsManaged && !targetIsManaged) {
+                mProfileSwitchMessageId = com.android.internal.R.string.forward_intent_to_owner;
+            } else if (!originIsManaged && targetIsManaged) {
+                mProfileSwitchMessageId = com.android.internal.R.string.forward_intent_to_work;
+            }
+        }
+    }
+
     /**
      * Turn on launch mode that is safe to use when forwarding intents received from
      * applications and running in system processes.  This mode uses Activity.startActivityAsCaller
@@ -529,7 +551,7 @@
     /**
      * Replace me in subclasses!
      */
-    public Intent getReplacementIntent(String packageName, Intent defIntent) {
+    public Intent getReplacementIntent(ActivityInfo aInfo, Intent defIntent) {
         return defIntent;
     }
 
@@ -642,6 +664,11 @@
     }
 
     public void safelyStartActivity(Intent intent) {
+        // If needed, show that intent is forwarded
+        // from managed profile to owner or other way around.
+        if (mProfileSwitchMessageId != -1) {
+            Toast.makeText(this, getString(mProfileSwitchMessageId), Toast.LENGTH_LONG).show();
+        }
         if (!mSafeForwardingMode) {
             startActivity(intent);
             onActivityStarted(intent);
@@ -943,7 +970,7 @@
             DisplayResolveInfo dri = filtered ? getItem(position) : mList.get(position);
 
             Intent intent = new Intent(dri.origIntent != null ? dri.origIntent :
-                    getReplacementIntent(dri.ri.activityInfo.packageName, mIntent));
+                    getReplacementIntent(dri.ri.activityInfo, mIntent));
             intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
                     |Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
             ActivityInfo ai = dri.ri.activityInfo;
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 9ec9993..178bab6 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -46,10 +46,12 @@
     HEAP_UNKNOWN,
     HEAP_DALVIK,
     HEAP_NATIVE,
+
     HEAP_DALVIK_OTHER,
     HEAP_STACK,
     HEAP_CURSOR,
     HEAP_ASHMEM,
+    HEAP_GL_DEV,
     HEAP_UNKNOWN_DEV,
     HEAP_SO,
     HEAP_JAR,
@@ -297,7 +299,11 @@
             } else if (strncmp(name, "[stack", 6) == 0) {
                 whichHeap = HEAP_STACK;
             } else if (strncmp(name, "/dev/", 5) == 0) {
-                whichHeap = HEAP_UNKNOWN_DEV;
+                if (strncmp(name, "/dev/kgsl-3d0", 13) == 0) {
+                    whichHeap = HEAP_GL_DEV;
+                } else {
+                    whichHeap = HEAP_UNKNOWN_DEV;
+                }
             } else if (nameLen > 3 && strcmp(name+nameLen-3, ".so") == 0) {
                 whichHeap = HEAP_SO;
                 is_swappable = true;
diff --git a/core/res/res/drawable-hdpi/sym_def_app_icon.png b/core/res/res/drawable-hdpi/sym_def_app_icon.png
index 96a442e..cde69bc 100644
--- a/core/res/res/drawable-hdpi/sym_def_app_icon.png
+++ b/core/res/res/drawable-hdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_def_app_icon.png b/core/res/res/drawable-mdpi/sym_def_app_icon.png
index 359047d..c133a0c 100644
--- a/core/res/res/drawable-mdpi/sym_def_app_icon.png
+++ b/core/res/res/drawable-mdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/sym_def_app_icon.png b/core/res/res/drawable-xhdpi/sym_def_app_icon.png
index 71c6d76..bfa42f0 100644
--- a/core/res/res/drawable-xhdpi/sym_def_app_icon.png
+++ b/core/res/res/drawable-xhdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/sym_def_app_icon.png b/core/res/res/drawable-xxhdpi/sym_def_app_icon.png
index 20a47a0..324e72c 100644
--- a/core/res/res/drawable-xxhdpi/sym_def_app_icon.png
+++ b/core/res/res/drawable-xxhdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/sym_def_app_icon.png b/core/res/res/drawable-xxxhdpi/sym_def_app_icon.png
new file mode 100644
index 0000000..aee44e1
--- /dev/null
+++ b/core/res/res/drawable-xxxhdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/mipmap-hdpi/sym_def_app_icon.png b/core/res/res/mipmap-hdpi/sym_def_app_icon.png
index c8a38ed..cde69bc 100644
--- a/core/res/res/mipmap-hdpi/sym_def_app_icon.png
+++ b/core/res/res/mipmap-hdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/mipmap-mdpi/sym_def_app_icon.png b/core/res/res/mipmap-mdpi/sym_def_app_icon.png
index b3e10f6..c133a0c 100644
--- a/core/res/res/mipmap-mdpi/sym_def_app_icon.png
+++ b/core/res/res/mipmap-mdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/mipmap-xhdpi/sym_def_app_icon.png b/core/res/res/mipmap-xhdpi/sym_def_app_icon.png
index f381f86..bfa42f0 100644
--- a/core/res/res/mipmap-xhdpi/sym_def_app_icon.png
+++ b/core/res/res/mipmap-xhdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/mipmap-xxhdpi/sym_def_app_icon.png b/core/res/res/mipmap-xxhdpi/sym_def_app_icon.png
index e3f3144..324e72c 100644
--- a/core/res/res/mipmap-xxhdpi/sym_def_app_icon.png
+++ b/core/res/res/mipmap-xxhdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/mipmap-xxxhdpi/sym_def_app_icon.png b/core/res/res/mipmap-xxxhdpi/sym_def_app_icon.png
new file mode 100644
index 0000000..aee44e1
--- /dev/null
+++ b/core/res/res/mipmap-xxxhdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 1534b49..52ef4f9 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -473,6 +473,8 @@
     <bool name="config_allowTheaterModeWakeFromDock">false</bool>
     <!-- If this is true, allow wake from theater mode from window layout flag. -->
     <bool name="config_allowTheaterModeWakeFromWindowLayout">false</bool>
+    <!-- If this is true, go to sleep when theater mode is enabled from button press -->
+    <bool name="config_goToSleepOnButtonPressTheaterMode">true</bool>
 
     <!-- Auto-rotation behavior -->
 
@@ -801,6 +803,13 @@
          that can be set by the user. -->
     <integer name="config_screenBrightnessDoze">1</integer>
 
+    <!-- Allow automatic adjusting of the screen brightness while dozing in low power state. -->
+    <bool name="config_allowAutoBrightnessWhileDozing">false</bool>
+
+    <!-- If we allow automatic adjustment of screen brightness while dozing, how many times we want
+         to reduce it to preserve the battery. Value of 100% means no scaling. -->
+    <fraction name="config_screenAutoBrightnessDozeScaleFactor">100%</fraction>
+
     <!-- Screen brightness used to dim the screen when the user activity
          timeout expires.  May be less than the minimum allowed brightness setting
          that can be set by the user. -->
@@ -1907,4 +1916,7 @@
            1. Lenient threshold
     -->
     <integer name="config_LTE_RSRP_threshold_type">1</integer>
+
+    <!-- Show the next-alarm as a zen exit condition if it occurs in the next n hours. -->
+    <integer name="config_next_alarm_condition_lookahead_threshold_hrs">12</integer>
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 61fc161..3051234 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4879,7 +4879,10 @@
     <string name="battery_saver_description">To help improve battery life, battery saver reduces your device’s performance and limits vibration and most background data. Email, messaging, and other apps that rely on syncing may not update unless you open them.\n\nBattery saver turns off automatically when your device is charging.</string>
 
     <!-- [CHAR_LIMIT=NONE] Zen mode: Condition summary for built-in downtime condition, if active -->
-    <string name="downtime_condition_summary">Until your downtime ends at <xliff:g id="formattedTime" example="10.00 PM">%1$s</xliff:g></string>
+    <string name="downtime_condition_summary">Until your downtime ends at <xliff:g id="formattedTime" example="10:00 PM">%1$s</xliff:g></string>
+
+    <!-- [CHAR_LIMIT=NONE] Zen mode: Condition line one for built-in downtime condition, if active -->
+    <string name="downtime_condition_line_one">Until your downtime ends</string>
 
     <!-- Zen mode condition - summary: time duration in minutes. [CHAR LIMIT=NONE] -->
     <plurals name="zen_mode_duration_minutes_summary">
@@ -4913,4 +4916,10 @@
 
     <!-- Content description for the Toolbar icon used to collapse an expanded action mode. [CHAR LIMIT=NONE] -->
     <string name="toolbar_collapse_description">Collapse</string>
+
+    <!-- Zen mode condition - summary: until next alarm. [CHAR LIMIT=NONE] -->
+    <string name="zen_mode_next_alarm_summary">Until next alarm at <xliff:g id="formattedTime" example="7:30 AM">%1$s</xliff:g></string>
+
+    <!-- Zen mode condition - line one: until next alarm. [CHAR LIMIT=NONE] -->
+    <string name="zen_mode_next_alarm_line_one">Until next alarm</string>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3835d8b..db3ced1 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1574,6 +1574,7 @@
   <java-symbol type="bool" name="config_enableNetworkLocationOverlay" />
   <java-symbol type="bool" name="config_sf_limitedAlpha" />
   <java-symbol type="bool" name="config_unplugTurnsOnScreen" />
+  <java-symbol type="bool" name="config_allowAutoBrightnessWhileDozing" />
   <java-symbol type="bool" name="config_allowTheaterModeWakeFromUnplug" />
   <java-symbol type="bool" name="config_allowTheaterModeWakeFromGesture" />
   <java-symbol type="bool" name="config_allowTheaterModeWakeFromCameraLens" />
@@ -1583,6 +1584,7 @@
   <java-symbol type="bool" name="config_allowTheaterModeWakeFromLidSwitch" />
   <java-symbol type="bool" name="config_allowTheaterModeWakeFromDock" />
   <java-symbol type="bool" name="config_allowTheaterModeWakeFromWindowLayout" />
+  <java-symbol type="bool" name="config_goToSleepOnButtonPressTheaterMode" />
   <java-symbol type="bool" name="config_wifi_background_scan_support" />
   <java-symbol type="bool" name="config_wifi_dual_band_support" />
   <java-symbol type="bool" name="config_wimaxEnabled" />
@@ -1615,6 +1617,7 @@
   <java-symbol type="id" name="replace_app_icon" />
   <java-symbol type="id" name="replace_message" />
   <java-symbol type="fraction" name="config_dimBehindFadeDuration" />
+  <java-symbol type="fraction" name="config_screenAutoBrightnessDozeScaleFactor" />
   <java-symbol type="integer" name="config_carDockKeepsScreenOn" />
   <java-symbol type="integer" name="config_criticalBatteryWarningLevel" />
   <java-symbol type="integer" name="config_datause_notification_type" />
@@ -1984,12 +1987,16 @@
   <java-symbol type="string" name="timepicker_transition_end_radius_multiplier" />
   <java-symbol type="string" name="battery_saver_description" />
   <java-symbol type="string" name="downtime_condition_summary" />
+  <java-symbol type="string" name="downtime_condition_line_one" />
   <java-symbol type="string" name="zen_mode_forever" />
   <java-symbol type="plurals" name="zen_mode_duration_minutes" />
   <java-symbol type="plurals" name="zen_mode_duration_hours" />
   <java-symbol type="plurals" name="zen_mode_duration_minutes_summary" />
   <java-symbol type="plurals" name="zen_mode_duration_hours_summary" />
   <java-symbol type="string" name="zen_mode_until" />
+  <java-symbol type="string" name="zen_mode_next_alarm_summary" />
+  <java-symbol type="string" name="zen_mode_next_alarm_line_one" />
+  <java-symbol type="integer" name="config_next_alarm_condition_lookahead_threshold_hrs" />
 
   <java-symbol type="string" name="item_is_selected" />
   <java-symbol type="string" name="day_of_week_label_typeface" />
diff --git a/docs/html/design/tv/index.jd b/docs/html/design/tv/index.jd
index 483c24f..d79e279 100644
--- a/docs/html/design/tv/index.jd
+++ b/docs/html/design/tv/index.jd
@@ -1,4 +1,7 @@
-page.title=Android TV
+page.title=Designing for Android TV
+page.tags="tv", "leanback","designguidelines"
+page.metaDescription=Guidelines to help you create a great leanback experience on Android TV.
+page.image=design/tv/images/apps-games-rows.jpg
 @jd:body
 
 
@@ -6,12 +9,15 @@
   experience. It's important to understand how your app is presented in the main user interface and
   how your app can help users get to the content they want quickly.</p>
 
-<p class="note">
+<p class="caution">
   <strong>Important:</strong> There are specific design requirements your app must meet to qualify
   as an Android TV app on Google Play. For more information, see the requirements listed in
   <a href="{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a>.
 </p>
 
+<p class="note"><strong>Note:</strong> For information about how to publish your TV apps in Google Play,
+see <a href="/distribute/googleplay/tv.html">Distributing to Android TV</a>.</p>
+
 <h2>Home Screen</h2>
 
 <p>The Home Screen is the start of the user experience, providing search, content
diff --git a/docs/html/distribute/essentials/quality/tv.jd b/docs/html/distribute/essentials/quality/tv.jd
index b13307e..20018c3 100644
--- a/docs/html/distribute/essentials/quality/tv.jd
+++ b/docs/html/distribute/essentials/quality/tv.jd
@@ -47,11 +47,9 @@
   qualify as an Android TV app on Google Play.
 </p>
 
-<p class="note">
-  <strong>Note:</strong> You will be able to submit TV apps to Google Play with the public release
-  of Android 5.0 on November 3. Stay tuned for more information about how to submit your TV apps
-  through the Google Play Developer Console.
-</p>
+<p class="note"><strong>Note:</strong> For information about how to publish your TV apps in Google Play,
+see <a href="{@docRoot}distribute/googleplay/tv.html">Distributing to Android TV</a>.</p>
+
 
 
 <div class="headerLine">
diff --git a/docs/html/distribute/googleplay/edu/start.jd b/docs/html/distribute/googleplay/edu/start.jd
index 3c3a175..f4c9717 100644
--- a/docs/html/distribute/googleplay/edu/start.jd
+++ b/docs/html/distribute/googleplay/edu/start.jd
@@ -1,4 +1,4 @@
-page.title=Publish Apps
+page.title=Publish Education Apps
 page.image=/distribute/images/play-education.jpg
 meta.tags="education", "guidelines", "quality"
 page.tags="education", "addendum"
diff --git a/docs/html/distribute/googleplay/googleplay_toc.cs b/docs/html/distribute/googleplay/googleplay_toc.cs
index 45464c7..fc7cd11 100644
--- a/docs/html/distribute/googleplay/googleplay_toc.cs
+++ b/docs/html/distribute/googleplay/googleplay_toc.cs
@@ -18,6 +18,12 @@
     </div>
   </li>
   <li class="nav-section">
+    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/tv.html">
+          <span class="en">Distributing to <span style="white-space:nowrap">Android TV</span></span>
+        </a>
+    </div>
+  </li>
+  <li class="nav-section">
     <div class="nav-section-header" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/edu/about.html">
           <span class="en">Google Play for Education</span>
         </a>
diff --git a/docs/html/distribute/googleplay/index.jd b/docs/html/distribute/googleplay/index.jd
index a215930..20f07fa 100644
--- a/docs/html/distribute/googleplay/index.jd
+++ b/docs/html/distribute/googleplay/index.jd
@@ -21,7 +21,7 @@
     data-maxResults="3">
   </div>
 
-  <h3>Google Play for Education</h3>
+  <h3>Distribute Your Apps</h3>
 
   <div class="resource-widget resource-flow-layout landing col-16"
     data-query="collection:distribute/gp/gpfelanding"
diff --git a/docs/html/distribute/googleplay/tv.jd b/docs/html/distribute/googleplay/tv.jd
new file mode 100644
index 0000000..37cbe26
--- /dev/null
+++ b/docs/html/distribute/googleplay/tv.jd
@@ -0,0 +1,320 @@
+page.title=Distributing to Android TV
+page.image=/design/tv/images/atv-home.jpg
+meta.tags="tv", "publish", "quality"
+page.tags="tv", "publish", "googleplay"
+page.metaDescription=Distribute your apps, games, and content to Android TV.
+
+@jd:body
+
+<div id="qv-wrapper"><div id="qv">
+<h2>How to Participate</h2>
+<ol>
+<li><a href="#understand_guidelines">Understand the guidelines</a></li>
+<li><a href="#develop_app">Develop a great app for TV</a></li>
+<li><a href="#test_app">Test for TV App Quality</a></li>
+<li><a href="#opt_in">Opt-in</a></li>
+<li><a href="#track_review">Track your review</a></li>
+</ol>
+
+<h2>You Should Also Read</h2>
+<ol>
+<li><a href="{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a></li>
+<li><a href="{@docRoot}distribute/essentials/quality/core.html">Core App Quality</a></li>
+</ol>
+
+</div></div>
+
+<p>
+  If you've got a great app or game, Android TV and Google Play can help you
+  bring it to users right in their living rooms. You'll be able to offer your
+  apps and games in a storefront experience that’s optimized for TV. You can
+  extend your new or existing apps for TV and then publish them using familiar
+  tools and processes in Google Play.
+</p>
+
+<p>
+  To get started, review the sections in this document to learn how to
+  distribute your TV apps to users through Google Play. Be sure to read
+  <a href="{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a>
+  for information on the usability and quality standards that your apps should
+  meet. When your app is ready, you can opt-in to publishing in the Android TV
+  storefront from the Developer Console.
+</p>
+
+<h2 id="how_to_participate">
+  How to Participate
+</h2>
+
+<p>
+  Google Play lets you put your TV apps in front of a new audience of users in
+  their living rooms. You can develop and publish using your existing Developer
+  Console account and your current distribution and pricing settings. It's easy
+  to participate — the sections below outline the process.
+</p>
+
+<div style="float:right;margin:1em 0 1.5em 2em;">
+  <img src="{@docRoot}images/gp-tv-process.png">
+</div>
+
+<h3 id="understand_guidelines">
+  1. Understand guidelines and requirements
+</h3>
+
+<p>
+  To prepare for a successful launch on Android TV, start by reviewing the
+  guidelines for creating great app experiences on TV. See the <a href=
+  "{@docRoot}design/tv/index.html">Android TV design guidelines</a> for ideas
+  on extending your app for TV and details on design and usability.
+</p>
+
+<p>
+  As you get started designing your TV experience, make sure to read and
+  understand the quality criteria for TV apps. The Google Play experience for
+  Android TV <strong>showcases only apps that are usable on the TV</strong>
+  &mdash; your apps can participate if they meet a set of basic quality
+  criteria. See <a href="{@docRoot}distribute/essentials/quality/tv.html">TV
+  App Quality</a> for details.
+</p>
+
+<h3 id="develop_app">2. Develop a great app for TV</h3>
+
+<p>
+  A great app for TV is designed for living room use and takes advantage of the
+  capabilities of Android TV and related input accessories such as game
+  controllers, D-pads, and remotes. The app is refined to offer a polished,
+  high-quality experience on large screens and delivers a compelling feature
+  set for users.
+</p>
+
+<p>
+  As you consider your TV app, review the <a href=
+  "{@docRoot}training/tv/start/index.html">developer documentation</a> and
+  usability guidelines and plan on supporting them to the greatest extent
+  possible. Make sure to design a great leanback experience for users and build
+  it with the leanback library included in the SDK. You’ll want to optimize
+  other parts of your app for the TV use case and it's a good idea to identify
+  those early in your development process.
+</p>
+
+<p>
+  In most cases, we recommend delivering your TV experience as part of your
+  existing app for phones, tablets, and other devices, using the same package
+  name and store listing. This approach lets users upgrade to your TV experience
+  seamlessly and also lets you take advantage of the reviews and ratings you’ve
+  earned in your app for phones and tablets.
+</p>
+
+<p>
+  You can bundle your TV intents, leanback library, and TV-specific code and
+  resources as part of a single APK solution for all supported devices. If
+  necessary, you can use <a href=
+  "{@docRoot}google/play/publishing/multiple-apks.html">Multiple APK
+  Support</a> to deliver a custom binary to Android TV devices under the same
+  package name and store listing that you use for phones and tablets.
+</p>
+
+<p>
+  Throughout design and development, it's important to have a suitable device
+  on which to prototype and test your user experience. You should acquire one
+  or more Android TV devices or emulators and set up your testing environment
+  as early as possible. The recommended hardware device for testing in the
+  Android TV environment is Nexus Player, which is <a href=
+  "http://www.google.com/intl/all/nexus/player/">available from Google Play</a>
+  and other stores, and you should also acquire a game controller and other TV
+  input devices.
+</p>
+
+<h3 id="test_app">3. Test for TV App Quality</h3>
+
+<p>
+  Your TV apps should be designed to perform well, look great on Android TV,
+  and offer the best user experience possible. Google Play showcases
+  high-quality apps for easy discovery by users in Google Play. Here’s how you
+  can participate and deliver an Android TV app that users will enjoy.
+</p>
+
+<ul>
+  <li>Meet Core App Quality guidelines
+    <ul>
+      <li>Follow <a href="{@docRoot}design/index.html">Android Design
+      guidelines</a>. Pay special attention to using <a href=
+      "http://www.google.com/design/spec/material-design/introduction.html">material
+      design</a> in your app.
+      </li>
+
+      <li>Test your apps against the <a href=
+      "{@docRoot}distribute/essentials/quality/core.html">Core App Quality
+      guidelines</a>.
+      </li>
+    </ul>
+  </li>
+  <li>Meet <a href="{@docRoot}distribute/essentials/quality/tv.html">TV App
+  Quality</a> guidelines
+    <ul>
+      <li>Follow our best practices for <a href="{@docRoot}training/tv/index.html">
+      TV app development</a></li>
+      <li>Make sure your app meets all of the <a href=
+      "{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a> criteria</li>
+    </ul>
+  </li>
+  <li>Strive for simplicity and highest usability</li>
+</ul>
+
+<h3 id="opt_in">4. Opt-in to Android TV and publish</h3>
+
+<p>
+  When you've built your release-ready APK and tested to ensure that it meets
+  all of the <a href="{@docRoot}distribute/essentials/quality/tv.html">TV App
+  Quality</a> guidelines, upload it to the Developer Console. Update your store
+  listing with TV screenshots and TV banner, and set distribution options as
+  needed. If you aren't familiar with how to prepare for launch on Google Play,
+  see the <a href=
+  "{@docRoot}distribute/googleplay/publish/preparing.html">Launch
+  Checklist.</a>
+</p>
+
+<p>
+  Before you can publish to Android TV users, you need to opt-in to Android
+  TV from the <strong>Pricing and Distribution</strong> section of the
+  Developer Console. Opt-in means that you want your app to be made available
+  to Android TV users through Google Play, and that
+  your app meets <a href="{@docRoot}distribute/essentials/quality/tv.html">TV
+  App Quality</a> guidelines.
+</p>
+
+<p>
+  You can opt-in only if your app meets two preliminary quality
+  criteria that are automatically checked on APK upload:
+</p>
+
+<ul>
+  <li>Your app manifest must include an intent type of <a href=
+  "{@docRoot}reference/android/content/Intent.html#ACTION_MAIN"><code>ACTION_MAIN</code></a>
+  with category <a href=
+  "{@docRoot}reference/android/content/Intent.html#CATEGORY_LEANBACK_LAUNCHER">
+    <code>CATEGORY_LEANBACK_LAUNCHER</code></a>. Learn more <a href=
+    "{@docRoot}training/tv/start/start.html#tv-activity">here</a>.
+  </li>
+
+  <li>Your app must declare that it does not require a touchscreen. The
+  manifest must declare the <code>android.hardware.touchscreen</code> hardware
+  with <code>android:required="false”</code>. Learn more <a href=
+  "{@docRoot}training/tv/start/hardware.html#declare-hardware-requirements">here</a>.
+  </li>
+</ul>
+
+<p>
+  If your app meets the preliminary criteria, you’ll see an opt-in checkbox for
+  Android TV, as shown below. If the opt-in checkbox is not enabled, review
+  your APK to ensure it meets the preliminary criteria.
+</p>
+
+<p>
+  After you opt-in and save the changes, you can publish your app as usual.
+  Before making the app available to Android TV users, Google Play submits
+  your app for review against the <a href=
+  "{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a> criteria
+  and notifies you of the result. See the next section for details on how to
+  track the approval status of your app.
+</p>
+
+<p>
+  If your app meet <a href="{@docRoot}distribute/essentials/quality/tv.html">TV
+  App Quality</a> criteria, Google Play makes that app available to Android TV
+  users. Your app is alsoeligible for higher-visibility featuring in app
+  collections and promotions. To let users everywhere know that your app is
+  designed for Android TV, Google Play decorates the app’s store listing with a
+  TV badge.
+</p>
+
+<p>
+  Note that opt-in and review do not affect the availability of your app to
+  other devices in Google Play Store &mdash; on phones and tablets, for
+  example, your app is available as soon as you publish.
+</p>
+
+<p>
+  Here are the steps to opt-in to Android TV in the Developer Console:
+</p>
+
+<ol>
+  <li>Make sure your app meets all <a href=
+  "{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a> criteria
+  </li>
+
+  <li>Add TV screenshots and banner graphic to the app’s store listing
+  </li>
+
+  <li>In the <strong>All Applications</strong> page, click the app you want to opt-in.
+  </li>
+
+  <li>Under <strong>Pricing and Distribution</strong>, scroll down to find <em>Android TV</em> and the
+  opt-in checkbox.
+  </li>
+
+  <li>Click the checkbox next to <em>Distribute your app to Android TV</em>.
+  </li>
+
+  <li>Click <strong>Save</strong> to save your changes.
+  </li>
+</ol>
+
+<div style="padding-top:1em">
+  <img style="border:2px solid #ddd;" src="{@docRoot}images/gp-tv-opt-in.png">
+  <p class="caption">
+    <strong>Opt-in for TV:</strong> Include your app in Android TV by opting-in from the
+    Developer Console.
+  </p>
+</div>
+
+<h3 id="track_review">5. Track your review and approval</h3>
+
+<p>
+  If your app meets the technical and quality criteria for Android TV, as described above,
+  your app will be available for users to enjoy on Android TV. If your app doesn’t meet
+  the criteria, you’ll receive a <strong>notification email sent to your developer account
+  address</strong>, with a summary of the areas that you need to address. When you’ve made
+  the necessary adjustments, you can upload a new version of your app to the Developer
+  Console. 
+</p>
+
+<p>
+  At any time, you can check the review and approval status of your app in the
+  Developer Console, under <em>Android TV</em> in the app's <strong>Pricing and Distribution</strong>
+  page.
+</p>
+
+<p>
+  There are three approval states:
+</p>
+
+<ul>
+  <li>
+    <em>Pending</em> — Your app was sent for review and the review is not yet
+    complete.
+  </li>
+
+  <li>
+    <em>Approved</em> — Your app was reviewed and approved. The app will be
+    made available directly to Android TV users. 
+  </li>
+
+  <li>
+    <em>Not approved</em> — Your app was reviewed and not approved. Check the
+    notification email for information about why the app was not approved. You
+    can address any issues and opt-in and publish again to initiate another
+    review.
+  </li>
+</ul>
+
+<p>To understand how your apps are evaluated, please see the <a href=
+"{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a> document. </p>
+
+
+  <h3>Related resources</h3>
+
+  <div class="resource-widget resource-flow-layout col-16"
+    data-query="collection:tvlanding"
+    data-cardSizes="9x6, 6x3x2"
+    data-maxResults="6">
+  </div>
diff --git a/docs/html/images/emulator-wvga800l.png b/docs/html/images/emulator-wvga800l.png
deleted file mode 100644
index c92c1b9..0000000
--- a/docs/html/images/emulator-wvga800l.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/emulator.png b/docs/html/images/emulator.png
new file mode 100644
index 0000000..96a2507
--- /dev/null
+++ b/docs/html/images/emulator.png
Binary files differ
diff --git a/docs/html/images/emulator@2x.png b/docs/html/images/emulator@2x.png
new file mode 100644
index 0000000..9b825a7
--- /dev/null
+++ b/docs/html/images/emulator@2x.png
Binary files differ
diff --git a/docs/html/images/games/game-controller-buttons_2x_crop.png b/docs/html/images/games/game-controller-buttons_2x_crop.png
new file mode 100644
index 0000000..54dc2fa
--- /dev/null
+++ b/docs/html/images/games/game-controller-buttons_2x_crop.png
Binary files differ
diff --git a/docs/html/images/gp-tv-opt-in.png b/docs/html/images/gp-tv-opt-in.png
new file mode 100644
index 0000000..a815818
--- /dev/null
+++ b/docs/html/images/gp-tv-opt-in.png
Binary files differ
diff --git a/docs/html/images/gp-tv-process.png b/docs/html/images/gp-tv-process.png
new file mode 100644
index 0000000..a530777
--- /dev/null
+++ b/docs/html/images/gp-tv-process.png
Binary files differ
diff --git a/docs/html/images/tools/as-attach.png b/docs/html/images/tools/as-attach.png
new file mode 100644
index 0000000..c572b1e
--- /dev/null
+++ b/docs/html/images/tools/as-attach.png
Binary files differ
diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js
index 08c0090..d63580e 100644
--- a/docs/html/jd_collections.js
+++ b/docs/html/jd_collections.js
@@ -57,8 +57,8 @@
   },
   "distribute/gp/gpfelanding": {
     "resources": [
+      "distribute/googleplay/tv.html",
       "distribute/googleplay/edu/about.html",
-      "distribute/googleplay/edu/start.html",
       "distribute/googleplay/edu/videos.html"
     ]
   },
@@ -773,6 +773,14 @@
       "https://support.google.com/googleplay/answer/2651410"
     ]
   },
+  "tvlanding": {
+    "title": "",
+    "resources": [
+      "tv/index.html",
+      "design/tv/index.html",
+      "training/tv/index.html"
+    ]
+  },
   "distribute/stories/games": {
     "title": "",
     "resources": [
diff --git a/docs/html/sdk/installing/studio-debug.jd b/docs/html/sdk/installing/studio-debug.jd
index 2e3e137..b048400 100644
--- a/docs/html/sdk/installing/studio-debug.jd
+++ b/docs/html/sdk/installing/studio-debug.jd
@@ -6,7 +6,11 @@
 <div id="qv">
 <h2>In this document</h2>
 <ol>
-  <li><a href="#runDebug">Run your App in Debug Mode</a></li>
+  <li><a href="#runDebug">Run your App in Debug Mode</a>
+    <ol>
+      <li><a href="#attachDebug">Attach the debugger to a running process</a></li>
+    </ol>
+  </li>
   <li><a href="#systemLog">Use the System Log</a>
     <ol>
       <li><a href="#systemLogWrite">Write log messages in your code</a></li>
@@ -94,6 +98,22 @@
 <p class="img-caption"><strong>Figure 2.</strong> The Debug tool window in Android Studio showing
 the current thread and the object tree for a variable.</p>
 
+<h3 id="attachDebug">Attach the debugger to a running process</h3>
+
+<p>You don't always have to restart your app to debug it. To debug an app that you're already
+running:</p>
+
+<ol>
+<li>Click <strong>Attach debugger to Android proccess</strong>
+<img src="{@docRoot}images/tools/as-attach.png" alt=""
+style="vertical-align:bottom;margin:0;height:20px"/>.</li>
+<li>In the <em>Choose Process</em> window, select the device and app you want to attach the
+debugger to.</li>
+<li>To open the <em>Debug</em> tool window, click <strong>Debug</strong>
+<img src="{@docRoot}images/tools/as-debugwindowbutton.png"
+alt="" style="vertical-align:bottom;margin:0;height:20px"/>.</li>
+</ol>
+
 
 <h2 id="systemLog">Use the System Log</h2>
 
diff --git a/docs/html/tools/devices/emulator.jd b/docs/html/tools/devices/emulator.jd
index ea1549d..d7bb8c7 100644
--- a/docs/html/tools/devices/emulator.jd
+++ b/docs/html/tools/devices/emulator.jd
@@ -80,7 +80,9 @@
 provides a screen in which your application is displayed, together with any other
 active Android applications. </p>
 
-<img src="{@docRoot}images/emulator-wvga800l.png" width="367" height="349" />
+<img src="{@docRoot}images/emulator@2x.png"
+srcset="{@docRoot}images/emulator.png 1x, {@docRoot}images/emulator@2x.png 2x" alt=""
+  width="367" height="330"/>
 
 <p>To let you model and test your application more easily, the emulator utilizes
 Android Virtual Device (AVD) configurations. AVDs let you define certain hardware
diff --git a/docs/html/training/material/animations.jd b/docs/html/training/material/animations.jd
index e8291b8..efc0ee3 100644
--- a/docs/html/training/material/animations.jd
+++ b/docs/html/training/material/animations.jd
@@ -84,12 +84,14 @@
 int cy = (myView.getTop() + myView.getBottom()) / 2;
 
 // get the final radius for the clipping circle
-int finalRadius = myView.getWidth();
+int finalRadius = Math.max(myView.getWidth(), myView.getHeight());
 
-// create and start the animator for this view
-// (the start radius is zero)
+// create the animator for this view (the start radius is zero)
 Animator anim =
     ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
+
+// make the view visible and start the animation
+myView.setVisibility(View.VISIBLE);
 anim.start();
 </pre>
 
diff --git a/docs/html/training/tv/discovery/index.jd b/docs/html/training/tv/discovery/index.jd
index fbc8c9f..5849149 100644
--- a/docs/html/training/tv/discovery/index.jd
+++ b/docs/html/training/tv/discovery/index.jd
@@ -1,4 +1,5 @@
-page.title=Helping Users Find Content on TV
+page.title=Helping Users Find Your Content on TV
+page.tags="tv", "leanback"
 
 startpage=true
 
diff --git a/docs/html/training/tv/games/index.jd b/docs/html/training/tv/games/index.jd
index 8a998e0..5276d7f 100644
--- a/docs/html/training/tv/games/index.jd
+++ b/docs/html/training/tv/games/index.jd
@@ -1,5 +1,7 @@
 page.title=Building TV Games
-page.tags="controller"
+page.tags="tv", "games", "controller"
+page.image=images/games/game-controller-buttons_2x_crop.png
+page.metaDescription=How to bring your games to Android TV, including recommendations and examples.
 page.article=true
 
 @jd:body
@@ -180,7 +182,7 @@
 It includes a white controller on black background and a black controller on white background
 (shown in figure 1), as a PNG file and an Adobe&reg; Illustrator&reg; file.</p>
 
-<img src="{@docRoot}images/games/game-controller-buttons_2x.png" width="700"
+<img itemprop="image" src="{@docRoot}images/games/game-controller-buttons_2x.png" width="700"
      srcset="{@docRoot}images/games/game-controller-buttons_2x.png 2x,
              {@docRoot}images/games/game-controller-buttons.png 1x" />
 <p class="img-caption"><b>Figure 1.</b> Example controller instructions using the
diff --git a/docs/html/training/tv/index.jd b/docs/html/training/tv/index.jd
index 56667a9..d52e1e8 100644
--- a/docs/html/training/tv/index.jd
+++ b/docs/html/training/tv/index.jd
@@ -1,8 +1,11 @@
 page.title=Building Apps for TV
 page.trainingcourse=true
-
+page.metaDescription=Starting point for building apps and games for Android TV, with guidelines, information, and examples.
+page.image=design/tv/images/focus.png
 @jd:body
 
 
 
-<p>These classes teach you how to build apps for TV devices.</p>
\ No newline at end of file
+<p>These classes teach you how to build apps for TV devices.</p>
+
+<p class="note"><strong>Note:</strong> For details on how to publish your TV apps in Google Play,  see <a href="{docRoot}distribute/googleplay/tv.html">Distributing to Android TV</a>.</p>
\ No newline at end of file
diff --git a/docs/html/training/tv/playback/index.jd b/docs/html/training/tv/playback/index.jd
index 118fc6c..09c3f24 100644
--- a/docs/html/training/tv/playback/index.jd
+++ b/docs/html/training/tv/playback/index.jd
@@ -1,5 +1,5 @@
 page.title=Building TV Playback Apps
-page.tags="leanback"
+page.tags="tv","leanback"
 
 startpage=true
 
diff --git a/docs/html/training/tv/start/index.jd b/docs/html/training/tv/start/index.jd
index ceefea1..fb478a8 100644
--- a/docs/html/training/tv/start/index.jd
+++ b/docs/html/training/tv/start/index.jd
@@ -1,4 +1,5 @@
 page.title=Building TV Apps
+page.tags="tv", "leanback"
 startpage=true
 
 @jd:body
diff --git a/docs/html/training/tv/tif/index.jd b/docs/html/training/tv/tif/index.jd
index 4746e42..cde8ba7 100644
--- a/docs/html/training/tv/tif/index.jd
+++ b/docs/html/training/tv/tif/index.jd
@@ -1,5 +1,5 @@
 page.title=Building Live TV Apps
-page.tags=tif
+page.tags="tv", "tif"
 page.article=true
 
 @jd:body
diff --git a/docs/html/training/wearables/apps/bt-debugging.jd b/docs/html/training/wearables/apps/bt-debugging.jd
index 8d09c43..98cf804 100644
--- a/docs/html/training/wearables/apps/bt-debugging.jd
+++ b/docs/html/training/wearables/apps/bt-debugging.jd
@@ -58,7 +58,8 @@
 </li>
 <li>Connect the handheld to your machine over USB and run:
 <pre>
-adb forward tcp:4444 localabstract:/adb-hub; adb connect localhost:4444
+adb forward tcp:4444 localabstract:/adb-hub
+adb connect localhost:4444
 </pre>
 
 <p class="note"><b>Note</b>: You can use any available port that you have access to.</p>
diff --git a/docs/html/training/wearables/data-layer/accessing.jd b/docs/html/training/wearables/data-layer/accessing.jd
index 896a698..36e3daa 100644
--- a/docs/html/training/wearables/data-layer/accessing.jd
+++ b/docs/html/training/wearables/data-layer/accessing.jd
@@ -37,7 +37,7 @@
 implementing its callbacks, and handling error cases.</p>
 
 <pre style="clear:right">
-GoogleApiClient mGoogleAppiClient = new GoogleApiClient.Builder(this)
+GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
         .addConnectionCallbacks(new ConnectionCallbacks() {
                 &#64;Override
                 public void onConnected(Bundle connectionHint) {
@@ -64,4 +64,4 @@
 method, as described in
 <a href="{@docRoot}google/auth/api-client.html#Starting">Accessing Google Play services APIs</a>.
 When the system invokes the <code>onConnected()</code> callback for your client, you're ready
-to use the data layer API.</p>
\ No newline at end of file
+to use the data layer API.</p>
diff --git a/docs/html/tv/index.jd b/docs/html/tv/index.jd
index 71e177b..e4d7f7a 100644
--- a/docs/html/tv/index.jd
+++ b/docs/html/tv/index.jd
@@ -1,5 +1,9 @@
-page.title=Android TV
+page.title=About Android TV
+page.type=about
+page.image=tv/images/hero.jpg
 page.viewport_width=970
+page.tags="tv", "leanback"
+page.metaDescription=Bring your apps, games, and content to the biggest screen in the house.
 fullpage=true
 no_footer_links=true
 page.type=about
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 1458238..94c7026 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -943,7 +943,11 @@
 
                     float radius = st.mGradientRadius;
                     if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION) {
-                        radius *= Math.min(st.mWidth, st.mHeight);
+                        // Fall back to parent width or height if intrinsic
+                        // size is not specified.
+                        final float width = st.mWidth >= 0 ? st.mWidth : r.width();
+                        final float height = st.mHeight >= 0 ? st.mHeight : r.height();
+                        radius *= Math.min(width, height);
                     } else if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION_PARENT) {
                         radius *= Math.min(r.width(), r.height());
                     }
@@ -954,9 +958,9 @@
 
                     mGradientRadius = radius;
 
-                    if (radius == 0) {
-                        // We can't have a shader with zero radius, so let's
-                        // have a very, very small radius.
+                    if (radius <= 0) {
+                        // We can't have a shader with non-positive radius, so
+                        // let's have a very, very small radius.
                         radius = 0.001f;
                     }
 
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
index 281ca02..27ef06f 100644
--- a/libs/hwui/PathTessellator.cpp
+++ b/libs/hwui/PathTessellator.cpp
@@ -812,7 +812,7 @@
     // determine point shape
     SkPath path;
     float radius = paintInfo.halfStrokeWidth;
-    if (radius == 0.0f) radius = 0.25f;
+    if (radius == 0.0f) radius = 0.5f;
 
     if (paintInfo.cap == SkPaint::kRound_Cap) {
         path.addCircle(0, 0, radius);
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 2f68382..29d4930 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -533,6 +533,8 @@
 
     private AudioOrientationEventListener mOrientationListener;
 
+    private static Long mLastDeviceConnectMsgTime = new Long(0);
+
     ///////////////////////////////////////////////////////////////////////////
     // Construction
     ///////////////////////////////////////////////////////////////////////////
@@ -740,15 +742,17 @@
     }
 
     private void checkAllAliasStreamVolumes() {
-        int numStreamTypes = AudioSystem.getNumStreamTypes();
-        for (int streamType = 0; streamType < numStreamTypes; streamType++) {
-            if (streamType != mStreamVolumeAlias[streamType]) {
-                mStreamStates[streamType].
+        synchronized (VolumeStreamState.class) {
+            int numStreamTypes = AudioSystem.getNumStreamTypes();
+            for (int streamType = 0; streamType < numStreamTypes; streamType++) {
+                if (streamType != mStreamVolumeAlias[streamType]) {
+                    mStreamStates[streamType].
                                     setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]]);
-            }
-            // apply stream volume
-            if (!mStreamStates[streamType].isMuted()) {
-                mStreamStates[streamType].applyAllVolumes();
+                }
+                // apply stream volume
+                if (!mStreamStates[streamType].isMuted_syncVSS()) {
+                    mStreamStates[streamType].applyAllVolumes();
+                }
             }
         }
     }
@@ -1520,7 +1524,9 @@
 
     /** get stream mute state. */
     public boolean isStreamMute(int streamType) {
-        return mStreamStates[streamType].isMuted();
+        synchronized (VolumeStreamState.class) {
+            return mStreamStates[streamType].isMuted_syncVSS();
+        }
     }
 
     private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient {
@@ -1658,17 +1664,19 @@
     public int getStreamVolume(int streamType) {
         ensureValidStreamType(streamType);
         int device = getDeviceForStream(streamType);
-        int index = mStreamStates[streamType].getIndex(device);
+        synchronized (VolumeStreamState.class) {
+            int index = mStreamStates[streamType].getIndex(device);
 
-        // by convention getStreamVolume() returns 0 when a stream is muted.
-        if (mStreamStates[streamType].isMuted()) {
-            index = 0;
+            // by convention getStreamVolume() returns 0 when a stream is muted.
+            if (mStreamStates[streamType].isMuted_syncVSS()) {
+                index = 0;
+            }
+            if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
+                    (device & mFixedVolumeDevices) != 0) {
+                index = mStreamStates[streamType].getMaxIndex();
+            }
+            return (index + 5) / 10;
         }
-        if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
-                (device & mFixedVolumeDevices) != 0) {
-            index = mStreamStates[streamType].getMaxIndex();
-        }
-        return (index + 5) / 10;
     }
 
     public int getMasterVolume() {
@@ -1822,7 +1830,7 @@
                     // on voice capable devices
                     if (isPlatformVoice() &&
                             mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) {
-                        synchronized (mStreamStates[streamType]) {
+                        synchronized (VolumeStreamState.class) {
                             Set set = mStreamStates[streamType].mIndex.entrySet();
                             Iterator i = set.iterator();
                             while (i.hasNext()) {
@@ -2321,16 +2329,15 @@
                 continue;
             }
 
-            synchronized (streamState) {
-                streamState.readSettings();
-
+            streamState.readSettings();
+            synchronized (VolumeStreamState.class) {
                 // unmute stream that was muted but is not affect by mute anymore
-                if (streamState.isMuted() && ((!isStreamAffectedByMute(streamType) &&
+                if (streamState.isMuted_syncVSS() && ((!isStreamAffectedByMute(streamType) &&
                         !isStreamMutedByRingerMode(streamType)) || mUseFixedVolume)) {
                     int size = streamState.mDeathHandlers.size();
                     for (int i = 0; i < size; i++) {
                         streamState.mDeathHandlers.get(i).mMuteCount = 1;
-                        streamState.mDeathHandlers.get(i).mute(false);
+                        streamState.mDeathHandlers.get(i).mute_syncVSS(false);
                     }
                 }
             }
@@ -3264,8 +3271,15 @@
         } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
             return;
         }
-
-        handler.sendMessageDelayed(handler.obtainMessage(msg, arg1, arg2, obj), delay);
+        synchronized (mLastDeviceConnectMsgTime) {
+            long time = SystemClock.uptimeMillis() + delay;
+            handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time);
+            if (msg == MSG_SET_WIRED_DEVICE_CONNECTION_STATE ||
+                    msg == MSG_SET_A2DP_SRC_CONNECTION_STATE ||
+                    msg == MSG_SET_A2DP_SINK_CONNECTION_STATE) {
+                mLastDeviceConnectMsgTime = time;
+            }
+        }
     }
 
     boolean checkAudioSettingsPermission(String method) {
@@ -3344,6 +3358,12 @@
     // Inner classes
     ///////////////////////////////////////////////////////////////////////////
 
+    // NOTE: Locking order for synchronized objects related to volume or ringer mode management:
+    //  1 mScoclient OR mSafeMediaVolumeState
+    //  2   mSetModeDeathHandlers
+    //  3     mSettingsLock
+    //  4       VolumeStreamState.class
+    //  5         mCameraSoundForced
     public class VolumeStreamState {
         private final int mStreamType;
 
@@ -3425,9 +3445,10 @@
             }
         }
 
-        public void applyDeviceVolume(int device) {
+        // must be called while synchronized VolumeStreamState.class
+        public void applyDeviceVolume_syncVSS(int device) {
             int index;
-            if (isMuted()) {
+            if (isMuted_syncVSS()) {
                 index = 0;
             } else if (((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 && mAvrcpAbsVolSupported)
                     || ((device & mFullVolumeDevices) != 0)) {
@@ -3443,7 +3464,7 @@
                 // apply default volume first: by convention this will reset all
                 // devices volumes in audio policy manager to the supplied value
                 int index;
-                if (isMuted()) {
+                if (isMuted_syncVSS()) {
                     index = 0;
                 } else {
                     index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10;
@@ -3456,7 +3477,7 @@
                     Map.Entry entry = (Map.Entry)i.next();
                     int device = ((Integer)entry.getKey()).intValue();
                     if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
-                        if (isMuted()) {
+                        if (isMuted_syncVSS()) {
                             index = 0;
                         } else if (((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 &&
                                 mAvrcpAbsVolSupported)
@@ -3568,12 +3589,12 @@
 
         public void mute(IBinder cb, boolean state) {
             synchronized (VolumeStreamState.class) {
-                VolumeDeathHandler handler = getDeathHandler(cb, state);
+                VolumeDeathHandler handler = getDeathHandler_syncVSS(cb, state);
                 if (handler == null) {
                     Log.e(TAG, "Could not get client death handler for stream: "+mStreamType);
                     return;
                 }
-                handler.mute(state);
+                handler.mute_syncVSS(state);
             }
         }
 
@@ -3595,7 +3616,7 @@
                                 || (((device & mFixedVolumeDevices) != 0) && index != 0)) {
                             entry.setValue(mIndexMax);
                         }
-                        applyDeviceVolume(device);
+                        applyDeviceVolume_syncVSS(device);
                     }
                 }
             }
@@ -3619,8 +3640,8 @@
                 mICallback = cb;
             }
 
-            // must be called while synchronized on parent VolumeStreamState
-            public void mute(boolean state) {
+            // must be called while synchronized VolumeStreamState.class
+            public void mute_syncVSS(boolean state) {
                 boolean updateVolume = false;
                 if (state) {
                     if (mMuteCount == 0) {
@@ -3632,7 +3653,7 @@
                             }
                             VolumeStreamState.this.mDeathHandlers.add(this);
                             // If the stream is not yet muted by any client, set level to 0
-                            if (!VolumeStreamState.this.isMuted()) {
+                            if (!VolumeStreamState.this.isMuted_syncVSS()) {
                                 updateVolume = true;
                             }
                         } catch (RemoteException e) {
@@ -3656,7 +3677,7 @@
                             if (mICallback != null) {
                                 mICallback.unlinkToDeath(this, 0);
                             }
-                            if (!VolumeStreamState.this.isMuted()) {
+                            if (!VolumeStreamState.this.isMuted_syncVSS()) {
                                 updateVolume = true;
                             }
                         }
@@ -3674,15 +3695,17 @@
 
             public void binderDied() {
                 Log.w(TAG, "Volume service client died for stream: "+mStreamType);
-                if (mMuteCount != 0) {
-                    // Reset all active mute requests from this client.
-                    mMuteCount = 1;
-                    mute(false);
+                synchronized (VolumeStreamState.class) {
+                    if (mMuteCount != 0) {
+                        // Reset all active mute requests from this client.
+                        mMuteCount = 1;
+                        mute_syncVSS(false);
+                    }
                 }
             }
         }
 
-        private synchronized int muteCount() {
+        private int muteCount() {
             int count = 0;
             int size = mDeathHandlers.size();
             for (int i = 0; i < size; i++) {
@@ -3691,12 +3714,13 @@
             return count;
         }
 
-        private synchronized boolean isMuted() {
+        // must be called while synchronized VolumeStreamState.class
+        private boolean isMuted_syncVSS() {
             return muteCount() != 0;
         }
 
-        // only called by mute() which is already synchronized
-        private VolumeDeathHandler getDeathHandler(IBinder cb, boolean state) {
+        // must be called while synchronized VolumeStreamState.class
+        private VolumeDeathHandler getDeathHandler_syncVSS(IBinder cb, boolean state) {
             VolumeDeathHandler handler;
             int size = mDeathHandlers.size();
             for (int i = 0; i < size; i++) {
@@ -3773,25 +3797,26 @@
 
         private void setDeviceVolume(VolumeStreamState streamState, int device) {
 
-            // Apply volume
-            streamState.applyDeviceVolume(device);
+            synchronized (VolumeStreamState.class) {
+                // Apply volume
+                streamState.applyDeviceVolume_syncVSS(device);
 
-            // Apply change to all streams using this one as alias
-            int numStreamTypes = AudioSystem.getNumStreamTypes();
-            for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
-                if (streamType != streamState.mStreamType &&
-                        mStreamVolumeAlias[streamType] == streamState.mStreamType) {
-                    // Make sure volume is also maxed out on A2DP device for aliased stream
-                    // that may have a different device selected
-                    int streamDevice = getDeviceForStream(streamType);
-                    if ((device != streamDevice) && mAvrcpAbsVolSupported &&
-                            ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0)) {
-                        mStreamStates[streamType].applyDeviceVolume(device);
+                // Apply change to all streams using this one as alias
+                int numStreamTypes = AudioSystem.getNumStreamTypes();
+                for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
+                    if (streamType != streamState.mStreamType &&
+                            mStreamVolumeAlias[streamType] == streamState.mStreamType) {
+                        // Make sure volume is also maxed out on A2DP device for aliased stream
+                        // that may have a different device selected
+                        int streamDevice = getDeviceForStream(streamType);
+                        if ((device != streamDevice) && mAvrcpAbsVolSupported &&
+                                ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0)) {
+                            mStreamStates[streamType].applyDeviceVolume_syncVSS(device);
+                        }
+                        mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice);
                     }
-                    mStreamStates[streamType].applyDeviceVolume(streamDevice);
                 }
             }
-
             // Post a persist volume msg
             sendMsg(mAudioHandler,
                     MSG_PERSIST_VOLUME,
@@ -4571,7 +4596,12 @@
         if (mAudioHandler.hasMessages(MSG_SET_A2DP_SRC_CONNECTION_STATE) ||
                 mAudioHandler.hasMessages(MSG_SET_A2DP_SINK_CONNECTION_STATE) ||
                 mAudioHandler.hasMessages(MSG_SET_WIRED_DEVICE_CONNECTION_STATE)) {
-            delay = 1000;
+            synchronized (mLastDeviceConnectMsgTime) {
+                long time = SystemClock.uptimeMillis();
+                if (mLastDeviceConnectMsgTime > time) {
+                    delay = (int)(mLastDeviceConnectMsgTime - time);
+                }
+            }
         }
         return delay;
     }
@@ -5032,42 +5062,45 @@
             boolean cameraSoundForced = mContext.getResources().getBoolean(
                     com.android.internal.R.bool.config_camera_sound_forced);
             synchronized (mSettingsLock) {
+                boolean cameraSoundForcedChanged = false;
                 synchronized (mCameraSoundForced) {
                     if (cameraSoundForced != mCameraSoundForced) {
                         mCameraSoundForced = cameraSoundForced;
-
-                        if (!isPlatformTelevision()) {
-                            VolumeStreamState s = mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED];
-                            if (cameraSoundForced) {
-                                s.setAllIndexesToMax();
-                                mRingerModeAffectedStreams &=
-                                        ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
-                            } else {
-                                s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM]);
-                                mRingerModeAffectedStreams |=
-                                        (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
-                            }
-                            // take new state into account for streams muted by ringer mode
-                            setRingerModeInt(getRingerMode(), false);
-                        }
-
-                        sendMsg(mAudioHandler,
-                                MSG_SET_FORCE_USE,
-                                SENDMSG_QUEUE,
-                                AudioSystem.FOR_SYSTEM,
-                                cameraSoundForced ?
-                                        AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
-                                null,
-                                0);
-
-                        sendMsg(mAudioHandler,
-                                MSG_SET_ALL_VOLUMES,
-                                SENDMSG_QUEUE,
-                                0,
-                                0,
-                                mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED], 0);
+                        cameraSoundForcedChanged = true;
                     }
                 }
+                if (cameraSoundForcedChanged) {
+                    if (!isPlatformTelevision()) {
+                        VolumeStreamState s = mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED];
+                        if (cameraSoundForced) {
+                            s.setAllIndexesToMax();
+                            mRingerModeAffectedStreams &=
+                                    ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
+                        } else {
+                            s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM]);
+                            mRingerModeAffectedStreams |=
+                                    (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
+                        }
+                        // take new state into account for streams muted by ringer mode
+                        setRingerModeInt(getRingerMode(), false);
+                    }
+
+                    sendMsg(mAudioHandler,
+                            MSG_SET_FORCE_USE,
+                            SENDMSG_QUEUE,
+                            AudioSystem.FOR_SYSTEM,
+                            cameraSoundForced ?
+                                    AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
+                            null,
+                            0);
+
+                    sendMsg(mAudioHandler,
+                            MSG_SET_ALL_VOLUMES,
+                            SENDMSG_QUEUE,
+                            0,
+                            0,
+                            mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED], 0);
+                }
             }
             mVolumeController.setLayoutDirection(config.getLayoutDirection());
         } catch (Exception e) {
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 86da80a..973527f 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -286,7 +286,9 @@
         if (volumeProvider == null) {
             throw new IllegalArgumentException("volumeProvider may not be null!");
         }
-        mVolumeProvider = volumeProvider;
+        synchronized (mLock) {
+            mVolumeProvider = volumeProvider;
+        }
         volumeProvider.setCallback(new VolumeProvider.Callback() {
             @Override
             public void onVolumeChanged(VolumeProvider volumeProvider) {
@@ -449,6 +451,27 @@
     }
 
     /**
+     * Set the style of rating used by this session. Apps trying to set the
+     * rating should use this style. Must be one of the following:
+     * <ul>
+     * <li>{@link Rating#RATING_NONE}</li>
+     * <li>{@link Rating#RATING_3_STARS}</li>
+     * <li>{@link Rating#RATING_4_STARS}</li>
+     * <li>{@link Rating#RATING_5_STARS}</li>
+     * <li>{@link Rating#RATING_HEART}</li>
+     * <li>{@link Rating#RATING_PERCENTAGE}</li>
+     * <li>{@link Rating#RATING_THUMB_UP_DOWN}</li>
+     * </ul>
+     */
+    public void setRatingType(int type) {
+        try {
+            mBinder.setRatingType(type);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error in setRatingType.", e);
+        }
+    }
+
+    /**
      * Set some extras that can be associated with the {@link MediaSession}. No assumptions should
      * be made as to how a {@link MediaController} will handle these extras.
      * Keys should be fully qualified (e.g. com.example.MY_EXTRA) to avoid conflicts.
@@ -470,9 +493,11 @@
      * @hide
      */
     public void notifyRemoteVolumeChanged(VolumeProvider provider) {
-        if (provider == null || provider != mVolumeProvider) {
-            Log.w(TAG, "Received update from stale volume provider");
-            return;
+        synchronized (mLock) {
+            if (provider == null || provider != mVolumeProvider) {
+                Log.w(TAG, "Received update from stale volume provider");
+                return;
+            }
         }
         try {
             mBinder.setCurrentVolume(provider.getCurrentVolume());
@@ -537,6 +562,14 @@
         postToCallback(CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent);
     }
 
+    private void dispatchAdjustVolume(int direction) {
+        postToCallback(CallbackMessageHandler.MSG_ADJUST_VOLUME, direction);
+    }
+
+    private void dispatchSetVolumeTo(int volume) {
+        postToCallback(CallbackMessageHandler.MSG_SET_VOLUME, volume);
+    }
+
     private void postToCallback(int what) {
         postToCallback(what, null);
     }
@@ -988,9 +1021,7 @@
         public void onAdjustVolume(int direction) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
-                if (session.mVolumeProvider != null) {
-                    session.mVolumeProvider.onAdjustVolume(direction);
-                }
+                session.dispatchAdjustVolume(direction);
             }
         }
 
@@ -998,9 +1029,7 @@
         public void onSetVolumeTo(int value) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
-                if (session.mVolumeProvider != null) {
-                    session.mVolumeProvider.onSetVolumeTo(value);
-                }
+                session.dispatchSetVolumeTo(value);
             }
         }
 
@@ -1117,6 +1146,8 @@
         private static final int MSG_CUSTOM_ACTION = 13;
         private static final int MSG_MEDIA_BUTTON = 14;
         private static final int MSG_COMMAND = 15;
+        private static final int MSG_ADJUST_VOLUME = 16;
+        private static final int MSG_SET_VOLUME = 17;
 
         private MediaSession.Callback mCallback;
 
@@ -1145,6 +1176,7 @@
 
         @Override
         public void handleMessage(Message msg) {
+            VolumeProvider vp;
             switch (msg.what) {
                 case MSG_PLAY:
                     mCallback.onPlay();
@@ -1192,6 +1224,22 @@
                     Command cmd = (Command) msg.obj;
                     mCallback.onCommand(cmd.command, cmd.extras, cmd.stub);
                     break;
+                case MSG_ADJUST_VOLUME:
+                    synchronized (mLock) {
+                        vp = mVolumeProvider;
+                    }
+                    if (vp != null) {
+                        vp.onAdjustVolume((int) msg.obj);
+                    }
+                    break;
+                case MSG_SET_VOLUME:
+                    synchronized (mLock) {
+                        vp = mVolumeProvider;
+                    }
+                    if (vp != null) {
+                        vp.onSetVolumeTo((int) msg.obj);
+                    }
+                    break;
             }
         }
     }
diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
index 267d1ff..54d0acd 100644
--- a/media/java/android/media/session/PlaybackState.java
+++ b/media/java/android/media/session/PlaybackState.java
@@ -16,6 +16,7 @@
 package android.media.session;
 
 import android.annotation.DrawableRes;
+import android.annotation.Nullable;
 import android.media.RemoteControlClient;
 import android.os.Bundle;
 import android.os.Parcel;
@@ -232,11 +233,12 @@
     private final CharSequence mErrorMessage;
     private final long mUpdateTime;
     private final long mActiveItemId;
+    private final Bundle mExtras;
 
     private PlaybackState(int state, long position, long updateTime, float speed,
             long bufferedPosition, long transportControls,
             List<PlaybackState.CustomAction> customActions, long activeItemId,
-            CharSequence error) {
+            CharSequence error, Bundle extras) {
         mState = state;
         mPosition = position;
         mSpeed = speed;
@@ -246,6 +248,7 @@
         mCustomActions = new ArrayList<>(customActions);
         mActiveItemId = activeItemId;
         mErrorMessage = error;
+        mExtras = extras;
     }
 
     private PlaybackState(Parcel in) {
@@ -258,7 +261,7 @@
         mCustomActions = in.createTypedArrayList(CustomAction.CREATOR);
         mActiveItemId = in.readLong();
         mErrorMessage = in.readCharSequence();
-
+        mExtras = in.readBundle();
     }
 
     @Override
@@ -293,6 +296,7 @@
         dest.writeTypedList(mCustomActions);
         dest.writeLong(mActiveItemId);
         dest.writeCharSequence(mErrorMessage);
+        dest.writeBundle(mExtras);
     }
 
     /**
@@ -306,6 +310,7 @@
      * <li> {@link PlaybackState#STATE_REWINDING}</li>
      * <li> {@link PlaybackState#STATE_BUFFERING}</li>
      * <li> {@link PlaybackState#STATE_ERROR}</li>
+     * </ul>
      */
     public int getState() {
         return mState;
@@ -394,6 +399,15 @@
     }
 
     /**
+     * Get any custom extras that were set on this playback state.
+     *
+     * @return The extras for this state or null.
+     */
+    public @Nullable Bundle getExtras() {
+        return mExtras;
+    }
+
+    /**
      * Get the {@link PlaybackState} state for the given
      * {@link RemoteControlClient} state.
      *
@@ -737,6 +751,7 @@
         private CharSequence mErrorMessage;
         private long mUpdateTime;
         private long mActiveItemId = MediaSession.QueueItem.UNKNOWN_ID;
+        private Bundle mExtras;
 
         /**
          * Creates an initially empty state builder.
@@ -765,6 +780,7 @@
             mErrorMessage = from.mErrorMessage;
             mUpdateTime = from.mUpdateTime;
             mActiveItemId = from.mActiveItemId;
+            mExtras = from.mExtras;
         }
 
         /**
@@ -947,13 +963,25 @@
         }
 
         /**
-         * Build and return the {@link PlaybackState} instance with these values.
+         * Set any custom extras to be included with the playback state.
+         *
+         * @param extras The extras to include.
+         * @return this
+         */
+        public Builder setExtras(Bundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /**
+         * Build and return the {@link PlaybackState} instance with these
+         * values.
          *
          * @return A new state instance.
          */
         public PlaybackState build() {
             return new PlaybackState(mState, mPosition, mUpdateTime, mSpeed, mBufferedPosition,
-                    mActions, mCustomActions, mActiveItemId, mErrorMessage);
+                    mActions, mCustomActions, mActiveItemId, mErrorMessage, mExtras);
         }
     }
 }
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 0ca5810..93cca2f 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -159,15 +159,6 @@
     }
 
     /**
-     * Get the number of callbacks that are registered.
-     * @hide
-     */
-    @VisibleForTesting
-    public final int getRegisteredCallbackCount() {
-        return mCallbacks.getRegisteredCallbackCount();
-    }
-
-    /**
      * Returns a concrete implementation of {@link Session}.
      * <p>
      * May return {@code null} if this TV input service fails to create a session for some reason.
@@ -550,13 +541,14 @@
          * @param left Left position in pixels, relative to the overlay view.
          * @param top Top position in pixels, relative to the overlay view.
          * @param right Right position in pixels, relative to the overlay view.
-         * @param bottm Bottom position in pixels, relative to the overlay view.
+         * @param bottom Bottom position in pixels, relative to the overlay view.
          * @see #onOverlayViewSizeChanged
          * @hide
          */
         @SystemApi
-        public void layoutSurface(final int left, final int top, final int right, final int bottm) {
-            if (left > right || top > bottm) {
+        public void layoutSurface(final int left, final int top, final int right,
+                final int bottom) {
+            if (left > right || top > bottom) {
                 throw new IllegalArgumentException("Invalid parameter");
             }
             executeOrPostRunnable(new Runnable() {
@@ -564,8 +556,8 @@
                 public void run() {
                     try {
                         if (DEBUG) Log.d(TAG, "layoutSurface (l=" + left + ", t=" + top + ", r="
-                                + right + ", b=" + bottm + ",)");
-                        mSessionCallback.onLayoutSurface(left, top, right, bottm);
+                                + right + ", b=" + bottom + ",)");
+                        mSessionCallback.onLayoutSurface(left, top, right, bottom);
                     } catch (RemoteException e) {
                         Log.w(TAG, "error in layoutSurface");
                     }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 1c6dc2c..aa5819e 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -518,7 +518,7 @@
          * Determine whether the device is plugged in (USB, power, or wireless).
          * @return true if the device is plugged in.
          */
-        boolean isPluggedIn() {
+        public boolean isPluggedIn() {
             return plugged == BatteryManager.BATTERY_PLUGGED_AC
                     || plugged == BatteryManager.BATTERY_PLUGGED_USB
                     || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_cross_1.xml
new file mode 100644
index 0000000..a49ebf8
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_cross_1.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+            android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+            android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_invert_colors_disable_cross_1_pathdata_interpolator" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="0"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="17"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="0"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_icon.xml b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_icon.xml
new file mode 100644
index 0000000..9cc3b8e
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_icon.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="alpha"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="alpha"
+            android:valueFrom="1"
+            android:valueTo="0.5"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_mask.xml
new file mode 100644
index 0000000..605ef90
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_mask.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueTo="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_root.xml b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_root.xml
new file mode 100644
index 0000000..770c401
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_root.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="350"
+        android:propertyName="alpha"
+        android:valueFrom="1.0"
+        android:valueTo="0.3"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_cross_1.xml
new file mode 100644
index 0000000..94f54b6
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_cross_1.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+            android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+            android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_invert_colors_enable_cross_1_pathdata_interpolator" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="533"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="17"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="1"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_icon.xml b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_icon.xml
new file mode 100644
index 0000000..50a1af6
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_icon.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="alpha"
+            android:valueFrom="0.54"
+            android:valueTo="0.54"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="alpha"
+            android:valueFrom="0.54"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_mask.xml
new file mode 100644
index 0000000..9531cd9
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_mask.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueTo="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_invert_colors_enable_mask_pathdata_interpolator" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_root.xml b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_root.xml
new file mode 100644
index 0000000..387ca29
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_root.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="350"
+        android:propertyName="alpha"
+        android:valueFrom="0.3"
+        android:valueTo="1.0"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml
new file mode 100644
index 0000000..9add90c
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="567"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="33"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml
new file mode 100644
index 0000000..9add90c
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="567"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="33"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml
new file mode 100644
index 0000000..6c4e133
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="317"
+            android:propertyName="scaleX"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleX"
+            android:valueFrom="1"
+            android:valueTo="0.9"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="317"
+            android:propertyName="scaleY"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleY"
+            android:valueFrom="1"
+            android:valueTo="0.9"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="rotation"
+            android:valueFrom="0"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="450"
+            android:propertyName="rotation"
+            android:valueFrom="0"
+            android:valueTo="-135"
+            android:interpolator="@interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml
new file mode 100644
index 0000000..a8f5ce0
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="267"
+            android:propertyName="pathData"
+            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="217"
+            android:propertyName="pathData"
+            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
new file mode 100644
index 0000000..b9bb42d
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="rotation"
+            android:valueFrom="0"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="400"
+            android:propertyName="rotation"
+            android:valueFrom="0"
+            android:valueTo="-45"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml
new file mode 100644
index 0000000..b8823a9
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="250"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="33"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml
new file mode 100644
index 0000000..b8823a9
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="250"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="33"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml
new file mode 100644
index 0000000..14c2776
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="scaleX"
+            android:valueFrom="0.9"
+            android:valueTo="0.9"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleX"
+            android:valueFrom="0.9"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="scaleY"
+            android:valueFrom="0.9"
+            android:valueTo="0.9"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleY"
+            android:valueFrom="0.9"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="rotation"
+            android:valueFrom="-135"
+            android:valueTo="-135"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="450"
+            android:propertyName="rotation"
+            android:valueFrom="-135"
+            android:valueTo="0"
+            android:interpolator="@interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml
new file mode 100644
index 0000000..ea8f979
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="267"
+            android:propertyName="pathData"
+            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="217"
+            android:propertyName="pathData"
+            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml
new file mode 100644
index 0000000..4e3a356
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="rotation"
+            android:valueFrom="-45"
+            android:valueTo="-45"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="400"
+            android:propertyName="rotation"
+            android:valueFrom="-45"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml
new file mode 100644
index 0000000..d05c4e1
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="600"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="83"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml
new file mode 100644
index 0000000..d05c4e1
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="600"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="83"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml
new file mode 100644
index 0000000..8bcbf1e
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="317"
+            android:propertyName="scaleX"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleX"
+            android:valueFrom="1"
+            android:valueTo="0.9"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="317"
+            android:propertyName="scaleY"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleY"
+            android:valueFrom="1"
+            android:valueTo="0.9"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="rotation"
+            android:valueFrom="0"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="617"
+            android:propertyName="rotation"
+            android:valueFrom="0"
+            android:valueTo="-221"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml
new file mode 100644
index 0000000..79b1827
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="rotation"
+            android:valueFrom="0"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="400"
+            android:propertyName="rotation"
+            android:valueFrom="0"
+            android:valueTo="-135"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml
new file mode 100644
index 0000000..a8f5ce0
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="267"
+            android:propertyName="pathData"
+            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="217"
+            android:propertyName="pathData"
+            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml
new file mode 100644
index 0000000..c3ae6c1
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="250"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="83"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml
new file mode 100644
index 0000000..c3ae6c1
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="250"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="83"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml
new file mode 100644
index 0000000..fde172a
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleX"
+            android:valueFrom="0.9"
+            android:valueTo="0.9"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleX"
+            android:valueFrom="0.9"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleY"
+            android:valueFrom="0.9"
+            android:valueTo="0.9"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleY"
+            android:valueFrom="0.9"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="rotation"
+            android:valueFrom="-221"
+            android:valueTo="-221"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="617"
+            android:propertyName="rotation"
+            android:valueFrom="-221"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml
new file mode 100644
index 0000000..accf16d
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="250"
+            android:propertyName="rotation"
+            android:valueFrom="-135"
+            android:valueTo="-135"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="400"
+            android:propertyName="rotation"
+            android:valueFrom="-135"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml
new file mode 100644
index 0000000..15c6705
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="250"
+            android:propertyName="pathData"
+            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="500"
+            android:propertyName="pathData"
+            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_cross_1.xml
new file mode 100644
index 0000000..553da1a
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_cross_1.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+            android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+            android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_signal_airplane_disable_cross_1_pathdata_interpolator" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="0"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="17"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="0"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_ic_signal_airplane.xml b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_ic_signal_airplane.xml
new file mode 100644
index 0000000..9cc3b8e
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_ic_signal_airplane.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="alpha"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="alpha"
+            android:valueFrom="1"
+            android:valueTo="0.5"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_mask.xml
new file mode 100644
index 0000000..605ef90
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_mask.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueTo="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_root.xml b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_root.xml
new file mode 100644
index 0000000..770c401
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_root.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="350"
+        android:propertyName="alpha"
+        android:valueFrom="1.0"
+        android:valueTo="0.3"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_cross_1.xml
new file mode 100644
index 0000000..87cbaec8
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_cross_1.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+            android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+            android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_signal_airplane_enable_cross_1_pathdata_interpolator" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="533"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="17"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="1"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_ic_signal_airplane.xml b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_ic_signal_airplane.xml
new file mode 100644
index 0000000..5fdb2a0
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_ic_signal_airplane.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="alpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.5"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="alpha"
+            android:valueFrom="0.5"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_mask.xml
new file mode 100644
index 0000000..56e0d1c
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_mask.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueTo="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_signal_airplane_enable_mask_pathdata_interpolator" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_root.xml b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_root.xml
new file mode 100644
index 0000000..387ca29
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_root.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="350"
+        android:propertyName="alpha"
+        android:valueFrom="0.3"
+        android:valueTo="1.0"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_cross_1.xml
new file mode 100644
index 0000000..aff3567
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_cross_1.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
+            android:valueTo="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
+            android:valueTo="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="0"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="17"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="0"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_ic_signal_flashlight.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_ic_signal_flashlight.xml
new file mode 100644
index 0000000..9cc3b8e
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_ic_signal_flashlight.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="alpha"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="alpha"
+            android:valueFrom="1"
+            android:valueTo="0.5"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_mask.xml
new file mode 100644
index 0000000..31583f2
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_mask.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueTo="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueTo="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_root.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_root.xml
new file mode 100644
index 0000000..770c401
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_root.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="350"
+        android:propertyName="alpha"
+        android:valueFrom="1.0"
+        android:valueTo="0.3"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_cross_1.xml
new file mode 100644
index 0000000..c923015
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_cross_1.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
+            android:valueTo="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
+            android:valueTo="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_signal_flashlight_enable_cross_1_pathdata_interpolator" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="533"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="17"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="1"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_ic_signal_flashlight.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_ic_signal_flashlight.xml
new file mode 100644
index 0000000..5fdb2a0
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_ic_signal_flashlight.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="alpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.5"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="alpha"
+            android:valueFrom="0.5"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_mask.xml
new file mode 100644
index 0000000..650d89f
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_mask.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueTo="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueTo="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_signal_flashlight_enable_mask_pathdata_interpolator" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_root.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_root.xml
new file mode 100644
index 0000000..387ca29
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_root.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="350"
+        android:propertyName="alpha"
+        android:valueFrom="0.3"
+        android:valueTo="1.0"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_cross_1.xml
new file mode 100644
index 0000000..73283a8
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_cross_1.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
+            android:valueTo="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
+            android:valueTo="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="0"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="17"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="0"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_ic_signal_location.xml b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_ic_signal_location.xml
new file mode 100644
index 0000000..9cc3b8e
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_ic_signal_location.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="alpha"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="alpha"
+            android:valueFrom="1"
+            android:valueTo="0.5"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_mask.xml
new file mode 100644
index 0000000..7ef7b5b
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_mask.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueTo="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueTo="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_root.xml b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_root.xml
new file mode 100644
index 0000000..770c401
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_root.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="350"
+        android:propertyName="alpha"
+        android:valueFrom="1.0"
+        android:valueTo="0.3"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_cross_1.xml
new file mode 100644
index 0000000..f4fc20e
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_cross_1.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
+            android:valueTo="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
+            android:valueTo="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_signal_location_enable_cross_1_pathdata_interpolator" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="533"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="17"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="1"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_ic_signal_location.xml b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_ic_signal_location.xml
new file mode 100644
index 0000000..5fdb2a0
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_ic_signal_location.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="alpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.5"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="alpha"
+            android:valueFrom="0.5"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_mask.xml
new file mode 100644
index 0000000..b825eb9
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_mask.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueTo="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueTo="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_signal_location_enable_mask_pathdata_interpolator" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_root.xml b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_root.xml
new file mode 100644
index 0000000..387ca29
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_root.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="350"
+        android:propertyName="alpha"
+        android:valueFrom="0.3"
+        android:valueTo="1.0"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_disable.xml b/packages/SystemUI/res/drawable/ic_invert_colors_disable.xml
new file mode 100644
index 0000000..f901e86
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_invert_colors_disable.xml
@@ -0,0 +1,56 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="root"
+    android:alpha="1.0"
+    android:height="48dp"
+    android:width="48dp"
+    android:viewportHeight="48"
+    android:viewportWidth="48" >
+    <group
+        android:name="icon"
+        android:translateX="21.9995"
+        android:translateY="25.73401" >
+        <group
+            android:name="icon_pivot"
+            android:translateX="-23.21545"
+            android:translateY="-18.86649" >
+            <clip-path
+                android:name="mask"
+                android:pathData="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+            <group
+                android:name="cross" >
+                <path
+                    android:name="cross_1"
+                    android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+                    android:strokeColor="#FFFFFFFF"
+                    android:strokeAlpha="0"
+                    android:strokeWidth="3.5"
+                    android:fillColor="#00000000" />
+            </group>
+            <group
+                android:name="ink_drop"
+                android:translateY="-6.8" >
+                <path
+                    android:name="outer_drop"
+                    android:pathData="M 35.3000030518,15.8999938965 c 0.0,0.0 -11.3000030518,-11.3999938965 -11.3000030518,-11.3999938965 c 0,0.0 -11.3000030518,11.3999938965 -11.3000030518,11.3999938965 c -6.19999694824,6.20001220703 -6.19999694824,16.4000091553 0.0,22.6000061035 c 3.10000610352,3.10000610352 7.19999694824,4.69999694824 11.3000030518,4.69999694824 c 4.10000610352,0.0 8.19999694824,-1.59999084473 11.3000030518,-4.69999694824 c 6.30000305176,-6.30000305176 6.30000305176,-16.3999938965 0.0,-22.6000061035 Z M 24,39.1999969482 c 0,0.0 0,0.0 0,0.0 c -3.19999694824,0.0 -6.19999694824,-1.19999694824 -8.5,-3.5 c -2.30000305176,-2.29998779297 -3.5,-5.30000305176 -3.5,-8.5 c 0,-3.19999694824 1.19999694824,-6.19999694824 3.5,-8.5 c 0.0,0.0 8.5,-8.5 8.5,-8.5 c 0,0.0 0,29.0 0,29.0 Z"
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_disable_animation.xml b/packages/SystemUI/res/drawable/ic_invert_colors_disable_animation.xml
new file mode 100644
index 0000000..2e26d42
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_invert_colors_disable_animation.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_invert_colors_disable" >
+    <target
+        android:name="root"
+        android:animation="@anim/ic_invert_colors_disable_animation_root" />
+    <target
+        android:name="icon"
+        android:animation="@anim/ic_invert_colors_disable_animation_icon" />
+    <target
+        android:name="mask"
+        android:animation="@anim/ic_invert_colors_disable_animation_mask" />
+    <target
+        android:name="cross_1"
+        android:animation="@anim/ic_invert_colors_disable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml b/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml
new file mode 100644
index 0000000..730ecc4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml
@@ -0,0 +1,57 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="root"
+    android:alpha="0.3"
+    android:height="48dp"
+    android:width="48dp"
+    android:viewportHeight="48"
+    android:viewportWidth="48" >
+    <group
+        android:name="icon"
+        android:translateX="21.9995"
+        android:translateY="25.73401"
+        android:alpha="0.54" >
+        <group
+            android:name="icon_pivot"
+            android:translateX="-23.21545"
+            android:translateY="-18.86649" >
+            <clip-path
+                android:name="mask"
+                android:pathData="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+            <group
+                android:name="cross" >
+                <path
+                    android:name="cross_1"
+                    android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+                    android:strokeColor="#FFFFFFFF"
+                    android:strokeAlpha="1"
+                    android:strokeWidth="3.5"
+                    android:fillColor="#00000000" />
+            </group>
+            <group
+                android:name="ink_drop"
+                android:translateY="-6.8" >
+                <path
+                    android:name="outer_drop"
+                    android:pathData="M 35.3000030518,15.8999938965 c 0.0,0.0 -11.3000030518,-11.3999938965 -11.3000030518,-11.3999938965 c 0,0.0 -11.3000030518,11.3999938965 -11.3000030518,11.3999938965 c -6.19999694824,6.20001220703 -6.19999694824,16.4000091553 0.0,22.6000061035 c 3.10000610352,3.10000610352 7.19999694824,4.69999694824 11.3000030518,4.69999694824 c 4.10000610352,0.0 8.19999694824,-1.59999084473 11.3000030518,-4.69999694824 c 6.30000305176,-6.30000305176 6.30000305176,-16.3999938965 0.0,-22.6000061035 Z M 24,39.1999969482 c 0,0.0 0,0.0 0,0.0 c -3.19999694824,0.0 -6.19999694824,-1.19999694824 -8.5,-3.5 c -2.30000305176,-2.29998779297 -3.5,-5.30000305176 -3.5,-8.5 c 0,-3.19999694824 1.19999694824,-6.19999694824 3.5,-8.5 c 0.0,0.0 8.5,-8.5 8.5,-8.5 c 0,0.0 0,29.0 0,29.0 Z"
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_enable_animation.xml b/packages/SystemUI/res/drawable/ic_invert_colors_enable_animation.xml
new file mode 100644
index 0000000..a709efb
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_invert_colors_enable_animation.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_invert_colors_enable" >
+    <target
+        android:name="root"
+        android:animation="@anim/ic_invert_colors_enable_animation_root" />
+    <target
+        android:name="icon"
+        android:animation="@anim/ic_invert_colors_enable_animation_icon" />
+    <target
+        android:name="mask"
+        android:animation="@anim/ic_invert_colors_enable_animation_mask" />
+    <target
+        android:name="cross_1"
+        android:animation="@anim/ic_invert_colors_enable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml
new file mode 100644
index 0000000..bc545ba
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml
@@ -0,0 +1,62 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="48dp"
+    android:width="48dp"
+    android:viewportHeight="48"
+    android:viewportWidth="48" >
+    <group
+        android:name="ic_screen_rotation_48px_outlines"
+        android:translateX="24"
+        android:translateY="24" >
+        <group
+            android:name="ic_screen_rotation_48px_outlines_pivot"
+            android:translateX="-24.15"
+            android:translateY="-24.25" >
+            <group
+                android:name="arrows"
+                android:translateX="24.1"
+                android:translateY="24.1" >
+                <group
+                    android:name="arrows_pivot"
+                    android:translateX="-24.1"
+                    android:translateY="-24.1" >
+                    <path
+                        android:name="arrow_top"
+                        android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
+                        android:fillColor="#FFFFFFFF"
+                        android:fillAlpha="1" />
+                    <path
+                        android:name="arrow_bottom"
+                        android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
+                        android:fillColor="#FFFFFFFF"
+                        android:fillAlpha="1" />
+                </group>
+            </group>
+            <group
+                android:name="device"
+                android:translateX="24.14999"
+                android:translateY="24.25" >
+                <path
+                    android:name="body"
+                    android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml
new file mode 100644
index 0000000..400a28b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml
@@ -0,0 +1,34 @@
+<?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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_landscape_from_auto_rotate" >
+    <target
+        android:name="arrows"
+        android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrows" />
+    <target
+        android:name="arrow_top"
+        android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrow_top" />
+    <target
+        android:name="arrow_bottom"
+        android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrow_bottom" />
+    <target
+        android:name="device"
+        android:animation="@anim/ic_landscape_from_auto_rotate_animation_device" />
+    <target
+        android:name="body"
+        android:animation="@anim/ic_landscape_from_auto_rotate_animation_body" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml
new file mode 100644
index 0000000..0bd75d1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml
@@ -0,0 +1,66 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="48dp"
+    android:width="48dp"
+    android:viewportHeight="48"
+    android:viewportWidth="48" >
+    <group
+        android:name="ic_screen_rotation_48px_outlines"
+        android:translateX="24"
+        android:translateY="24" >
+        <group
+            android:name="ic_screen_rotation_48px_outlines_pivot"
+            android:translateX="-24.15"
+            android:translateY="-24.25" >
+            <group
+                android:name="arrows"
+                android:translateX="24.1"
+                android:translateY="24.1"
+                android:scaleX="0.9"
+                android:scaleY="0.9"
+                android:rotation="-135" >
+                <group
+                    android:name="arrows_pivot"
+                    android:translateX="-24.1"
+                    android:translateY="-24.1" >
+                    <path
+                        android:name="arrow_top"
+                        android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
+                        android:fillColor="#FFFFFFFF"
+                        android:fillAlpha="0" />
+                    <path
+                        android:name="arrow_bottom"
+                        android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
+                        android:fillColor="#FFFFFFFF"
+                        android:fillAlpha="0" />
+                </group>
+            </group>
+            <group
+                android:name="device"
+                android:translateX="24.14999"
+                android:translateY="24.25"
+                android:rotation="-45" >
+                <path
+                    android:name="body"
+                    android:pathData="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml
new file mode 100644
index 0000000..5263eb4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml
@@ -0,0 +1,34 @@
+<?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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_landscape_to_auto_rotate" >
+    <target
+        android:name="arrows"
+        android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrows" />
+    <target
+        android:name="arrow_top"
+        android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrow_top" />
+    <target
+        android:name="arrow_bottom"
+        android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrow_bottom" />
+    <target
+        android:name="device"
+        android:animation="@anim/ic_landscape_to_auto_rotate_animation_device" />
+    <target
+        android:name="body"
+        android:animation="@anim/ic_landscape_to_auto_rotate_animation_body" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml
new file mode 100644
index 0000000..1805a8e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml
@@ -0,0 +1,62 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="48dp"
+    android:width="48dp"
+    android:viewportHeight="48"
+    android:viewportWidth="48" >
+    <group
+        android:name="ic_screen_rotation_48px_outlines"
+        android:translateX="24"
+        android:translateY="24" >
+        <group
+            android:name="ic_screen_rotation_48px_outlines_pivot"
+            android:translateX="-24.15"
+            android:translateY="-24.25" >
+            <group
+                android:name="arrows"
+                android:translateX="24.1"
+                android:translateY="24.1" >
+                <group
+                    android:name="arrows_pivot"
+                    android:translateX="-24.1"
+                    android:translateY="-24.1" >
+                    <path
+                        android:name="arrow_top"
+                        android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
+                        android:fillColor="#FFFFFFFF"
+                        android:fillAlpha="1" />
+                    <path
+                        android:name="arrow_bottom"
+                        android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
+                        android:fillColor="#FFFFFFFF"
+                        android:fillAlpha="1" />
+                </group>
+            </group>
+            <group
+                android:name="device"
+                android:translateX="24.14999"
+                android:translateY="24.25" >
+                <path
+                    android:name="device_1"
+                    android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml
new file mode 100644
index 0000000..565ef26
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml
@@ -0,0 +1,34 @@
+<?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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_portrait_from_auto_rotate" >
+    <target
+        android:name="arrows"
+        android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrows" />
+    <target
+        android:name="arrow_top"
+        android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrow_top" />
+    <target
+        android:name="arrow_bottom"
+        android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrow_bottom" />
+    <target
+        android:name="device"
+        android:animation="@anim/ic_portrait_from_auto_rotate_animation_device" />
+    <target
+        android:name="device_1"
+        android:animation="@anim/ic_portrait_from_auto_rotate_animation_device_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml
new file mode 100644
index 0000000..feb3025
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml
@@ -0,0 +1,66 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="48dp"
+    android:width="48dp"
+    android:viewportHeight="48"
+    android:viewportWidth="48" >
+    <group
+        android:name="ic_screen_rotation_48px_outlines"
+        android:translateX="24"
+        android:translateY="24" >
+        <group
+            android:name="ic_screen_rotation_48px_outlines_pivot"
+            android:translateX="-24.15"
+            android:translateY="-24.25" >
+            <group
+                android:name="arrows"
+                android:translateX="24.1"
+                android:translateY="24.1"
+                android:scaleX="0.9"
+                android:scaleY="0.9"
+                android:rotation="-221" >
+                <group
+                    android:name="arrows_pivot"
+                    android:translateX="-24.1"
+                    android:translateY="-24.1" >
+                    <path
+                        android:name="arrow_top"
+                        android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
+                        android:fillColor="#FFFFFFFF"
+                        android:fillAlpha="0" />
+                    <path
+                        android:name="arrow_bottom"
+                        android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
+                        android:fillColor="#FFFFFFFF"
+                        android:fillAlpha="0" />
+                </group>
+            </group>
+            <group
+                android:name="device"
+                android:translateX="24.14999"
+                android:translateY="24.25"
+                android:rotation="-135" >
+                <path
+                    android:name="device_1"
+                    android:pathData="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml
new file mode 100644
index 0000000..f75617f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml
@@ -0,0 +1,34 @@
+<?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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_portrait_to_auto_rotate" >
+    <target
+        android:name="arrows"
+        android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrows" />
+    <target
+        android:name="arrow_top"
+        android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrow_top" />
+    <target
+        android:name="arrow_bottom"
+        android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrow_bottom" />
+    <target
+        android:name="device"
+        android:animation="@anim/ic_portrait_to_auto_rotate_animation_device" />
+    <target
+        android:name="device_1"
+        android:animation="@anim/ic_portrait_to_auto_rotate_animation_device_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_airplane_off.xml b/packages/SystemUI/res/drawable/ic_qs_airplane_off.xml
deleted file mode 100644
index 79a9d409..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_airplane_off.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-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="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M26.0,18.0L26.0,7.0c0.0,-1.7 -1.3,-3.0 -3.0,-3.0c-1.7,0.0 -3.0,1.3 -3.0,3.0l0.0,7.4L35.7,30.0l6.3,2.0l0.0,-4.0L26.0,18.0zM6.0,10.5l10.0,10.0L4.0,28.0l0.0,4.0l16.0,-5.0l0.0,11.0l-4.0,3.0l0.0,3.0l7.0,-2.0l7.0,2.0l0.0,-3.0l-4.0,-3.0l0.0,-7.5L37.5,42.0l2.5,-2.5L8.5,8.0L6.0,10.5z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_airplane_on.xml b/packages/SystemUI/res/drawable/ic_qs_airplane_on.xml
deleted file mode 100644
index 5d5d257..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_airplane_on.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-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="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M20.4,18.0"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M42.0,32.0l0.0,-4.0L26.0,18.0L26.0,7.0c0.0,-1.7 -1.3,-3.0 -3.0,-3.0c-1.7,0.0 -3.0,1.3 -3.0,3.0l0.0,11.0L4.0,28.0l0.0,4.0l16.0,-5.0l0.0,11.0l-4.0,3.0l0.0,3.0l7.0,-2.0l7.0,2.0l0.0,-3.0l-4.0,-3.0L26.0,27.0L42.0,32.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_flashlight_off.xml b/packages/SystemUI/res/drawable/ic_qs_flashlight_off.xml
deleted file mode 100644
index d4bd76f..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_flashlight_off.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-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="64.0dp"
-        android:height="64.0dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M14.708,11.394l14.899,14.9l0.0,-6.771c4.359,-2.353 3.831,-7.489 3.831,-7.489l0.0,-0.64L14.708,11.393998z"/>
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M14.568,4.0l18.87,0.0l0.0,3.917l-18.87,0.0z"/>
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M38.284,39.427l-29.767,-29.766998 -2.4750004,2.4750004 12.351999,12.351 0.0,19.514 11.213001,0.0 0.0,-8.300999 6.2019978,6.2019997z"/>
-</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_qs_flashlight_on.xml b/packages/SystemUI/res/drawable/ic_qs_flashlight_on.xml
deleted file mode 100644
index 5514b44c..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_flashlight_on.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-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="64.0dp"
-        android:height="64.0dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M33.438,12.034l0.0,-0.64l-18.87,0.0l0.0,0.64c0.0,0.0 -0.581,5.189 3.826,7.523L18.394,44.0l11.213,0.0L29.606998,19.523C33.966,17.17 33.438,12.034 33.438,12.034zM24.0,27.697c-1.523,0.0 -2.757,-1.234 -2.757,-2.757c0.0,-1.523 1.234,-2.757 2.757,-2.757c1.523,0.0 2.757,1.234 2.757,2.757C26.757,26.462 25.523,27.697 24.0,27.697z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M14.568,4.0l18.87,0.0l0.0,3.917l-18.87,0.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml b/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml
deleted file mode 100644
index 4237b63..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-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="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M41.3,41.7L36.6,37.0L24.0,24.5l-7.1,-7.1L14.0,14.5L8.5,9.0L6.0,11.5l5.6,5.6c-5.1,6.3 -4.7,15.5 1.1,21.4c3.1,3.1 7.2,4.7 11.3,4.7c3.6,0.0 7.1,-1.2 10.1,-3.6l5.4,5.4l2.5,-2.5L41.3,41.7zM24.0,39.2c-3.2,0.0 -6.2,-1.2 -8.5,-3.5c-2.3,-2.3 -3.5,-5.3 -3.5,-8.5c0.0,-2.6 0.9,-5.1 2.4,-7.2l9.6,9.6L24.0,39.2zM24.0,10.2l0.0,9.2l14.5,14.5c2.7,-5.9 1.7,-13.1 -3.2,-18.0L24.0,4.5l0.0,0.0l0.0,0.0L16.6,12.0l2.8,2.8L24.0,10.2z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml b/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
deleted file mode 100644
index 860e769..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-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="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M35.3,15.9L24.0,4.5l0.0,0.0l0.0,0.0L12.7,15.9c-6.2,6.2 -6.2,16.4 0.0,22.6c3.1,3.1 7.2,4.7 11.3,4.7s8.2,-1.6 11.3,-4.7C41.6,32.2 41.6,22.1 35.3,15.9zM24.0,39.2L24.0,39.2c-3.2,0.0 -6.2,-1.2 -8.5,-3.5c-2.3,-2.3 -3.5,-5.3 -3.5,-8.5s1.2,-6.2 3.5,-8.5l8.5,-8.5L24.0,39.2z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_off.xml b/packages/SystemUI/res/drawable/ic_qs_location_off.xml
deleted file mode 100644
index e0fe12e..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_off.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-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="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M24.0,13.0c2.8,0.0 5.0,2.2 5.0,5.0c0.0,1.5 -0.7,2.8 -1.7,3.7l7.3,7.3c2.0,-3.7 3.4,-7.6 3.4,-11.0c0.0,-7.7 -6.3,-14.0 -14.0,-14.0c-4.0,0.0 -7.5,1.6 -10.1,4.3l6.4,6.4C21.2,13.6 22.5,13.0 24.0,13.0zM32.7,32.2l-9.3,-9.3l-0.2,-0.2L6.5,6.0L4.0,8.5l6.4,6.4c-0.2,1.0 -0.4,2.0 -0.4,3.1c0.0,10.5 14.0,26.0 14.0,26.0s3.3,-3.7 6.8,-8.7l6.7,6.7l2.5,-2.5L32.7,32.2z"/>
-    <path
-        android:pathData="M23.5,22.9l0.0,0.0 -0.20000076,-0.19999886z"
-        android:fillColor="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_on.xml b/packages/SystemUI/res/drawable/ic_qs_location_on.xml
deleted file mode 100644
index 6a7cd53..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_on.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-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="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M24.0,4.0c-7.7,0.0 -14.0,6.3 -14.0,14.0c0.0,10.5 14.0,26.0 14.0,26.0s14.0,-15.5 14.0,-26.0C38.0,10.3 31.7,4.0 24.0,4.0zM24.0,23.0c-2.8,0.0 -5.0,-2.2 -5.0,-5.0s2.2,-5.0 5.0,-5.0c2.8,0.0 5.0,2.2 5.0,5.0S26.8,23.0 24.0,23.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_rotation_landscape.xml b/packages/SystemUI/res/drawable/ic_qs_rotation_landscape.xml
deleted file mode 100644
index 4bb3668..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_rotation_landscape.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-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="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M2.0,14.0l0.0,20.0c0.0,2.2 1.8,4.0 4.0,4.0l36.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,14.0c0.0,-2.2 -1.8,-4.0 -4.0,-4.0L6.0,10.0C3.8,10.0 2.0,11.8 2.0,14.0zM38.0,14.0l0.0,20.0L10.0,34.0L10.0,14.0L38.0,14.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_rotation_portrait.xml b/packages/SystemUI/res/drawable/ic_qs_rotation_portrait.xml
deleted file mode 100644
index f0878c7..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_rotation_portrait.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-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="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M34.0,2.0L14.0,2.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,36.0c0.0,2.2 1.8,4.0 4.0,4.0l20.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L38.0,6.0C38.0,3.8 36.2,2.0 34.0,2.0zM34.0,38.0L14.0,38.0L14.0,10.0l20.0,0.0L34.0,38.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_rotation_unlocked.xml b/packages/SystemUI/res/drawable/ic_qs_rotation_unlocked.xml
deleted file mode 100644
index 94b3a6b..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_rotation_unlocked.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-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="64dp"
-        android:height="64dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M16.600000,2.500000c3.300000,1.500000 5.600000,4.700000 6.000000,8.500000l1.500000,0.000000c-0.600000,-6.200000 -5.700000,-11.000000 -12.000000,-11.000000c-0.200000,0.000000 -0.400000,0.000000 -0.700000,0.000000l3.800000,3.800000L16.600000,2.500000zM10.300000,1.700000c-0.600000,-0.600000 -1.500000,-0.600000 -2.100000,0.000000L1.800000,8.100000c-0.600000,0.600000 -0.600000,1.500000 0.000000,2.100000l12.000000,12.000000c0.600000,0.600000 1.500000,0.600000 2.100000,0.000000l6.400000,-6.400000c0.600000,-0.600000 0.600000,-1.500000 0.000000,-2.100000L10.300000,1.700000zM13.400000,19.700001l-9.200000,-9.200000l6.400000,-6.400000l9.200000,9.200000L13.400000,19.700001zM7.600000,21.500000C4.300000,20.000000 2.000000,16.799999 1.600000,13.000000L0.200000,13.000000c0.500000,6.200000 5.600000,11.000000 11.900000,11.000000c0.200000,0.000000 0.400000,0.000000 0.700000,0.000000L9.000000,20.200001L7.600000,21.500000z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml
new file mode 100644
index 0000000..09a67e1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml
@@ -0,0 +1,57 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="root"
+    android:alpha="1.0"
+    android:height="48dp"
+    android:width="48dp"
+    android:viewportHeight="48"
+    android:viewportWidth="48" >
+    <group
+        android:name="ic_signal_airplane"
+        android:translateX="21.9995"
+        android:translateY="25.73401" >
+        <group
+            android:name="ic_signal_airplane_pivot"
+            android:translateX="-23.21545"
+            android:translateY="-18.86649" >
+            <clip-path
+                android:name="mask"
+                android:pathData="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+            <group
+                android:name="cross" >
+                <path
+                    android:name="cross_1"
+                    android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+                    android:strokeColor="#FFFFFFFF"
+                    android:strokeAlpha="0"
+                    android:strokeWidth="3.5"
+                    android:fillColor="#00000000" />
+            </group>
+            <group
+                android:name="plane"
+                android:translateX="23.481"
+                android:translateY="18.71151" >
+                <path
+                    android:name="plane_1"
+                    android:pathData="M 18.9439849854,7.98849487305 c 0.0,0.0 0.0,-4.0 0.0,-4.0 c 0.0,0.0 -16.0,-10.0 -16.0,-10.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,-1.70001220703 -1.30000305176,-3.0 -3.0,-3.0 c -1.69999694824,0.0 -3.0,1.29998779297 -3.0,3.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -16.0,10.0 -16.0,10.0 c 0.0,0.0 0.0,4.0 0.0,4.0 c 0.0,0.0 16.0,-5.0 16.0,-5.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -4.0,3.0 -4.0,3.0 c 0.0,0.0 0.0,3.0 0.0,3.0 c 0.0,0.0 7.0,-2.0 7.0,-2.0 c 0.0,0.0 7.0,2.0 7.0,2.0 c 0.0,0.0 0.0,-3.0 0.0,-3.0 c 0.0,0.0 -4.0,-3.0 -4.0,-3.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,0.0 16.0,5.0 16.0,5.0 Z"
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_disable_animation.xml
new file mode 100644
index 0000000..3e838e2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_airplane_disable_animation.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_signal_airplane_disable" >
+    <target
+        android:name="root"
+        android:animation="@anim/ic_signal_airplane_disable_animation_root" />
+    <target
+        android:name="ic_signal_airplane"
+        android:animation="@anim/ic_signal_airplane_disable_animation_ic_signal_airplane" />
+    <target
+        android:name="mask"
+        android:animation="@anim/ic_signal_airplane_disable_animation_mask" />
+    <target
+        android:name="cross_1"
+        android:animation="@anim/ic_signal_airplane_disable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_enable.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_enable.xml
new file mode 100644
index 0000000..ea3a15b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_airplane_enable.xml
@@ -0,0 +1,58 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="root"
+    android:alpha="0.3"
+    android:height="48dp"
+    android:width="48dp"
+    android:viewportHeight="48"
+    android:viewportWidth="48" >
+    <group
+        android:name="ic_signal_airplane"
+        android:translateX="21.9995"
+        android:translateY="25.73401"
+        android:alpha="0.3" >
+        <group
+            android:name="ic_signal_airplane_pivot"
+            android:translateX="-23.21545"
+            android:translateY="-18.86649" >
+            <clip-path
+                android:name="mask"
+                android:pathData="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+            <group
+                android:name="cross" >
+                <path
+                    android:name="cross_1"
+                    android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+                    android:strokeColor="#FFFFFFFF"
+                    android:strokeAlpha="1"
+                    android:strokeWidth="3.5"
+                    android:fillColor="#00000000" />
+            </group>
+            <group
+                android:name="plane"
+                android:translateX="23.481"
+                android:translateY="18.71151" >
+                <path
+                    android:name="plane_1"
+                    android:pathData="M 18.9439849854,7.98849487305 c 0.0,0.0 0.0,-4.0 0.0,-4.0 c 0.0,0.0 -16.0,-10.0 -16.0,-10.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,-1.70001220703 -1.30000305176,-3.0 -3.0,-3.0 c -1.69999694824,0.0 -3.0,1.29998779297 -3.0,3.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -16.0,10.0 -16.0,10.0 c 0.0,0.0 0.0,4.0 0.0,4.0 c 0.0,0.0 16.0,-5.0 16.0,-5.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -4.0,3.0 -4.0,3.0 c 0.0,0.0 0.0,3.0 0.0,3.0 c 0.0,0.0 7.0,-2.0 7.0,-2.0 c 0.0,0.0 7.0,2.0 7.0,2.0 c 0.0,0.0 0.0,-3.0 0.0,-3.0 c 0.0,0.0 -4.0,-3.0 -4.0,-3.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,0.0 16.0,5.0 16.0,5.0 Z"
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_enable_animation.xml
new file mode 100644
index 0000000..d64b199
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_airplane_enable_animation.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_signal_airplane_enable" >
+    <target
+        android:name="root"
+        android:animation="@anim/ic_signal_airplane_enable_animation_root" />
+    <target
+        android:name="ic_signal_airplane"
+        android:animation="@anim/ic_signal_airplane_enable_animation_ic_signal_airplane" />
+    <target
+        android:name="mask"
+        android:animation="@anim/ic_signal_airplane_enable_animation_mask" />
+    <target
+        android:name="cross_1"
+        android:animation="@anim/ic_signal_airplane_enable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_disable.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_disable.xml
new file mode 100644
index 0000000..35844b7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_flashlight_disable.xml
@@ -0,0 +1,57 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="root"
+    android:alpha="1.0"
+    android:height="48dp"
+    android:width="48dp"
+    android:viewportHeight="48"
+    android:viewportWidth="48" >
+    <group
+        android:name="ic_signal_flashlight"
+        android:translateX="21.9995"
+        android:translateY="25.73401" >
+        <group
+            android:name="ic_signal_flashlight_pivot"
+            android:translateX="-23.21545"
+            android:translateY="-18.86649" >
+            <clip-path
+                android:name="mask"
+                android:pathData="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+            <group
+                android:name="cross" >
+                <path
+                    android:name="cross_1"
+                    android:pathData="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
+                    android:strokeColor="#FFFFFFFF"
+                    android:strokeAlpha="0"
+                    android:strokeWidth="3.5"
+                    android:fillColor="#00000000" />
+            </group>
+            <group
+                android:name="flashlight"
+                android:translateX="25.06235"
+                android:translateY="22.48294" >
+                <path
+                    android:name="light"
+                    android:pathData="M -9.40809631348,-23.6970062256 c 0.0,0.0 18.8699951172,0.0 18.8699951172,0.0 c 0.0,0.0 0.0,3.91700744629 0.0,3.91700744629 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,-3.91700744629 0.0,-3.91700744629 Z M 9.4615020752,-15.6629943848 c 0.0,0.0 0.0,-0.639999389648 0.0,-0.639999389649 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,0.639999389648 0.0,0.639999389649 c 0.0,0.0 -0.581008911133,5.18899536133 3.82598876953,7.52299499512 c 0.0,0.0 0.0,24.4429931641 0.0,24.4429931641 c 0.0,0.0 11.2129974365,0.0 11.2129974365,0.0 c 0.0,0.0 0.0,-24.4769897461 0.0,-24.4769897461 c 4.35900878906,-2.35301208496 3.83100891113,-7.48899841309 3.83100891113,-7.48899841309 Z M 0.0234985351562,0 c -1.52299499512,0 -2.75700378418,-1.23399353027 -2.75700378418,-2.75700378418 c 0.0,-1.52299499512 1.23400878906,-2.75700378418 2.75700378418,-2.75700378418 c 1.52299499512,0.0 2.75700378418,1.23400878906 2.75700378418,2.75700378418 c 0.0,1.52200317383 -1.23400878906,2.75700378418 -2.75700378418,2.75700378418 Z"
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_disable_animation.xml
new file mode 100644
index 0000000..6d787ab
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_flashlight_disable_animation.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_signal_flashlight_disable" >
+    <target
+        android:name="root"
+        android:animation="@anim/ic_signal_flashlight_disable_animation_root" />
+    <target
+        android:name="ic_signal_flashlight"
+        android:animation="@anim/ic_signal_flashlight_disable_animation_ic_signal_flashlight" />
+    <target
+        android:name="mask"
+        android:animation="@anim/ic_signal_flashlight_disable_animation_mask" />
+    <target
+        android:name="cross_1"
+        android:animation="@anim/ic_signal_flashlight_disable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_enable.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_enable.xml
new file mode 100644
index 0000000..93e97ee
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_flashlight_enable.xml
@@ -0,0 +1,58 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="root"
+    android:alpha="0.3"
+    android:height="48dp"
+    android:width="48dp"
+    android:viewportHeight="48"
+    android:viewportWidth="48" >
+    <group
+        android:name="ic_signal_flashlight"
+        android:translateX="21.9995"
+        android:translateY="25.73401"
+        android:alpha="0.3" >
+        <group
+            android:name="ic_signal_flashlight_pivot"
+            android:translateX="-23.21545"
+            android:translateY="-18.86649" >
+            <clip-path
+                android:name="mask"
+                android:pathData="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+            <group
+                android:name="cross" >
+                <path
+                    android:name="cross_1"
+                    android:pathData="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
+                    android:strokeColor="#FFFFFFFF"
+                    android:strokeAlpha="1"
+                    android:strokeWidth="3.5"
+                    android:fillColor="#00000000" />
+            </group>
+            <group
+                android:name="flashlight"
+                android:translateX="25.06235"
+                android:translateY="22.48294" >
+                <path
+                    android:name="light"
+                    android:pathData="M -9.40809631348,-23.6970062256 c 0.0,0.0 18.8699951172,0.0 18.8699951172,0.0 c 0.0,0.0 0.0,3.91700744629 0.0,3.91700744629 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,-3.91700744629 0.0,-3.91700744629 Z M 9.4615020752,-15.6629943848 c 0.0,0.0 0.0,-0.639999389648 0.0,-0.639999389649 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,0.639999389648 0.0,0.639999389649 c 0.0,0.0 -0.581008911133,5.18899536133 3.82598876953,7.52299499512 c 0.0,0.0 0.0,24.4429931641 0.0,24.4429931641 c 0.0,0.0 11.2129974365,0.0 11.2129974365,0.0 c 0.0,0.0 0.0,-24.4769897461 0.0,-24.4769897461 c 4.35900878906,-2.35301208496 3.83100891113,-7.48899841309 3.83100891113,-7.48899841309 Z M 0.0234985351562,0 c -1.52299499512,0 -2.75700378418,-1.23399353027 -2.75700378418,-2.75700378418 c 0.0,-1.52299499512 1.23400878906,-2.75700378418 2.75700378418,-2.75700378418 c 1.52299499512,0.0 2.75700378418,1.23400878906 2.75700378418,2.75700378418 c 0.0,1.52200317383 -1.23400878906,2.75700378418 -2.75700378418,2.75700378418 Z"
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_enable_animation.xml
new file mode 100644
index 0000000..dcfba7d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_flashlight_enable_animation.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_signal_flashlight_enable" >
+    <target
+        android:name="root"
+        android:animation="@anim/ic_signal_flashlight_enable_animation_root" />
+    <target
+        android:name="ic_signal_flashlight"
+        android:animation="@anim/ic_signal_flashlight_enable_animation_ic_signal_flashlight" />
+    <target
+        android:name="mask"
+        android:animation="@anim/ic_signal_flashlight_enable_animation_mask" />
+    <target
+        android:name="cross_1"
+        android:animation="@anim/ic_signal_flashlight_enable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_disable.xml b/packages/SystemUI/res/drawable/ic_signal_location_disable.xml
new file mode 100644
index 0000000..439851d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_location_disable.xml
@@ -0,0 +1,57 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="root"
+    android:alpha="1.0"
+    android:height="48dp"
+    android:width="48dp"
+    android:viewportHeight="48"
+    android:viewportWidth="48" >
+    <group
+        android:name="ic_signal_location"
+        android:translateX="21.9995"
+        android:translateY="25.73401" >
+        <group
+            android:name="ic_signal_location_pivot"
+            android:translateX="-23.21545"
+            android:translateY="-18.86649" >
+            <clip-path
+                android:name="mask"
+                android:pathData="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+            <group
+                android:name="cross" >
+                <path
+                    android:name="cross_1"
+                    android:pathData="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
+                    android:strokeColor="#FFFFFFFF"
+                    android:strokeAlpha="0"
+                    android:strokeWidth="3.5"
+                    android:fillColor="#00000000" />
+            </group>
+            <group
+                android:name="location"
+                android:translateX="23.481"
+                android:translateY="18.71151" >
+                <path
+                    android:name="pin"
+                    android:pathData="M 1.76899719238,-20.011505127 c -7.69999694824,0.0 -14.0,6.30000305176 -14.0,14.0 c 0.0,10.5 14.0,26.0 14.0,26.0 c 0.0,0.0 14.0,-15.5 14.0,-26.0 c 0.0,-7.69999694824 -6.30000305176,-14.0 -14.0,-14.0 Z M 1.76899719238,-1.01150512695 c -2.80000305176,0.0 -5.0,-2.19999694824 -5.0,-5.0 c 0.0,-2.80000305176 2.19999694824,-5.0 5.0,-5.0 c 2.80000305176,0.0 5.0,2.19999694824 5.0,5.0 c 0.0,2.80000305176 -2.19999694824,5.0 -5.0,5.0 Z"
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_location_disable_animation.xml
new file mode 100644
index 0000000..a219c54
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_location_disable_animation.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_signal_location_disable" >
+    <target
+        android:name="root"
+        android:animation="@anim/ic_signal_location_disable_animation_root" />
+    <target
+        android:name="ic_signal_location"
+        android:animation="@anim/ic_signal_location_disable_animation_ic_signal_location" />
+    <target
+        android:name="mask"
+        android:animation="@anim/ic_signal_location_disable_animation_mask" />
+    <target
+        android:name="cross_1"
+        android:animation="@anim/ic_signal_location_disable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_enable.xml b/packages/SystemUI/res/drawable/ic_signal_location_enable.xml
new file mode 100644
index 0000000..c800ef4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_location_enable.xml
@@ -0,0 +1,58 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="root"
+    android:alpha="0.3"
+    android:height="48dp"
+    android:width="48dp"
+    android:viewportHeight="48"
+    android:viewportWidth="48" >
+    <group
+        android:name="ic_signal_location"
+        android:translateX="21.9995"
+        android:translateY="25.73401"
+        android:alpha="0.3" >
+        <group
+            android:name="ic_signal_location_pivot"
+            android:translateX="-23.21545"
+            android:translateY="-18.86649" >
+            <clip-path
+                android:name="mask"
+                android:pathData="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+            <group
+                android:name="cross" >
+                <path
+                    android:name="cross_1"
+                    android:pathData="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
+                    android:strokeColor="#FFFFFFFF"
+                    android:strokeAlpha="1"
+                    android:strokeWidth="3.5"
+                    android:fillColor="#00000000" />
+            </group>
+            <group
+                android:name="location"
+                android:translateX="23.481"
+                android:translateY="18.71151" >
+                <path
+                    android:name="pin"
+                    android:pathData="M 1.76899719238,-20.011505127 c -7.69999694824,0.0 -14.0,6.30000305176 -14.0,14.0 c 0.0,10.5 14.0,26.0 14.0,26.0 c 0.0,0.0 14.0,-15.5 14.0,-26.0 c 0.0,-7.69999694824 -6.30000305176,-14.0 -14.0,-14.0 Z M 1.76899719238,-1.01150512695 c -2.80000305176,0.0 -5.0,-2.19999694824 -5.0,-5.0 c 0.0,-2.80000305176 2.19999694824,-5.0 5.0,-5.0 c 2.80000305176,0.0 5.0,2.19999694824 5.0,5.0 c 0.0,2.80000305176 -2.19999694824,5.0 -5.0,5.0 Z"
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_location_enable_animation.xml
new file mode 100644
index 0000000..bbc1d73
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_location_enable_animation.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_signal_location_enable" >
+    <target
+        android:name="root"
+        android:animation="@anim/ic_signal_location_enable_animation_root" />
+    <target
+        android:name="ic_signal_location"
+        android:animation="@anim/ic_signal_location_enable_animation_ic_signal_location" />
+    <target
+        android:name="mask"
+        android:animation="@anim/ic_signal_location_enable_animation_mask" />
+    <target
+        android:name="cross_1"
+        android:animation="@anim/ic_signal_location_enable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/interpolator/ic_invert_colors_disable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_invert_colors_disable_cross_1_pathdata_interpolator.xml
new file mode 100644
index 0000000..bc0442f
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_invert_colors_disable_cross_1_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0,0 c 0.166666667,0 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_invert_colors_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_invert_colors_enable_cross_1_pathdata_interpolator.xml
new file mode 100644
index 0000000..bc90d28
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_invert_colors_enable_cross_1_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0,0 c 0.8,0 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_invert_colors_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_invert_colors_enable_mask_pathdata_interpolator.xml
new file mode 100644
index 0000000..f7072f2
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_invert_colors_enable_mask_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml b/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml
new file mode 100644
index 0000000..76f5667
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0,0 c 0.458031162,0 0.299442342,0.748308635 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml b/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml
new file mode 100644
index 0000000..ac27e4d
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0,0 c 0.4,0.143709151 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_airplane_disable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_airplane_disable_cross_1_pathdata_interpolator.xml
new file mode 100644
index 0000000..bc0442f
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_airplane_disable_cross_1_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0,0 c 0.166666667,0 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_cross_1_pathdata_interpolator.xml
new file mode 100644
index 0000000..bc90d28
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_cross_1_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0,0 c 0.8,0 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_mask_pathdata_interpolator.xml
new file mode 100644
index 0000000..f7072f2
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_mask_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_cross_1_pathdata_interpolator.xml
new file mode 100644
index 0000000..f7072f2
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_cross_1_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_mask_pathdata_interpolator.xml
new file mode 100644
index 0000000..f7072f2
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_mask_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_location_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_location_enable_cross_1_pathdata_interpolator.xml
new file mode 100644
index 0000000..f7072f2
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_location_enable_cross_1_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_location_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_location_enable_mask_pathdata_interpolator.xml
new file mode 100644
index 0000000..f7072f2
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_location_enable_mask_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 4e93cd8..4a9eb55 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -35,5 +35,6 @@
     <item type="id" name="top_inset_animator_start_value_tag"/>
     <item type="id" name="height_animator_start_value_tag"/>
     <item type="id" name="doze_saved_filter_tag"/>
+    <item type="id" name="qs_icon_tag"/>
 </resources>
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 54a8414..1ddd352 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -203,7 +203,7 @@
         }
     }
 
-    private void refreshAllTiles() {
+    public void refreshAllTiles() {
         for (TileRecord r : mRecords) {
             r.tile.refreshState();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 6ef6e9e..2a66484 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -18,11 +18,13 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -299,10 +301,91 @@
         }
     }
 
+    public static abstract class Icon {
+        abstract public Drawable getDrawable(Context context);
+
+        @Override
+        public int hashCode() {
+            return Icon.class.hashCode();
+        }
+    }
+
+    public static class ResourceIcon extends Icon {
+        private static final SparseArray<Icon> ICONS = new SparseArray<Icon>();
+
+        private final int mResId;
+
+        private ResourceIcon(int resId) {
+            mResId = resId;
+        }
+
+        public static Icon get(int resId) {
+            Icon icon = ICONS.get(resId);
+            if (icon == null) {
+                icon = new ResourceIcon(resId);
+                ICONS.put(resId, icon);
+            }
+            return icon;
+        }
+
+        @Override
+        public Drawable getDrawable(Context context) {
+            return context.getDrawable(mResId);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            return o instanceof ResourceIcon && ((ResourceIcon) o).mResId == mResId;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("ResourceIcon[resId=0x%08x]", mResId);
+        }
+    }
+
+    protected class AnimationIcon extends ResourceIcon {
+        private boolean mAllowAnimation;
+
+        public AnimationIcon(int resId) {
+            super(resId);
+        }
+
+        public void setAllowAnimation(boolean allowAnimation) {
+            mAllowAnimation = allowAnimation;
+        }
+
+        @Override
+        public Drawable getDrawable(Context context) {
+            // workaround: get a clean state for every new AVD
+            final AnimatedVectorDrawable d = (AnimatedVectorDrawable) super.getDrawable(context)
+                    .getConstantState().newDrawable();
+            d.start();
+            if (mAllowAnimation) {
+                mAllowAnimation = false;
+            } else {
+                d.stop(); // skip directly to end state
+            }
+            return d;
+        }
+    }
+
+    protected enum UserBoolean {
+        USER_TRUE(true, true),
+        USER_FALSE(true, false),
+        BACKGROUND_TRUE(false, true),
+        BACKGROUND_FALSE(false, false);
+        public final boolean value;
+        public final boolean userInitiated;
+        private UserBoolean(boolean userInitiated, boolean value) {
+            this.value = value;
+            this.userInitiated = userInitiated;
+        }
+    }
+
     public static class State {
         public boolean visible;
-        public int iconId;
-        public Drawable icon;
+        public Icon icon;
         public String label;
         public String contentDescription;
         public String dualLabelContentDescription;
@@ -312,7 +395,6 @@
             if (other == null) throw new IllegalArgumentException();
             if (!other.getClass().equals(getClass())) throw new IllegalArgumentException();
             final boolean changed = other.visible != visible
-                    || other.iconId != iconId
                     || !Objects.equals(other.icon, icon)
                     || !Objects.equals(other.label, label)
                     || !Objects.equals(other.contentDescription, contentDescription)
@@ -320,7 +402,6 @@
                     || !Objects.equals(other.dualLabelContentDescription,
                     dualLabelContentDescription);
             other.visible = visible;
-            other.iconId = iconId;
             other.icon = icon;
             other.label = label;
             other.contentDescription = contentDescription;
@@ -335,9 +416,8 @@
         }
 
         protected StringBuilder toStringBuilder() {
-            final StringBuilder sb = new StringBuilder(  getClass().getSimpleName()).append('[');
+            final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('[');
             sb.append("visible=").append(visible);
-            sb.append(",iconId=").append(iconId);
             sb.append(",icon=").append(icon);
             sb.append(",label=").append(label);
             sb.append(",contentDescription=").append(contentDescription);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index d5c90d0..3d0f47c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -21,6 +21,7 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Typeface;
+import android.graphics.drawable.Animatable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.RippleDrawable;
 import android.os.Handler;
@@ -39,6 +40,8 @@
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile.State;
 
+import java.util.Objects;
+
 /** View that represents a standard quick settings tile. **/
 public class QSTileView extends ViewGroup {
     private static final Typeface CONDENSED = Typeface.create("sans-serif-condensed",
@@ -60,6 +63,7 @@
     private boolean mDual;
     private OnClickListener mClickPrimary;
     private OnClickListener mClickSecondary;
+    private Drawable mTileBackground;
     private RippleDrawable mRipple;
 
     public QSTileView(Context context) {
@@ -72,6 +76,7 @@
         mTilePaddingBelowIconPx =  res.getDimensionPixelSize(R.dimen.qs_tile_padding_below_icon);
         mDualTileVerticalPaddingPx =
                 res.getDimensionPixelSize(R.dimen.qs_dual_tile_padding_vertical);
+        mTileBackground = newTileBackground();
         recreateLabel();
         setClipChildren(false);
 
@@ -172,22 +177,21 @@
         if (changed) {
             recreateLabel();
         }
-        Drawable tileBackground = getTileBackground();
-        if (tileBackground instanceof RippleDrawable) {
-            setRipple((RippleDrawable) tileBackground);
+        if (mTileBackground instanceof RippleDrawable) {
+            setRipple((RippleDrawable) mTileBackground);
         }
         if (dual) {
             mTopBackgroundView.setOnClickListener(mClickPrimary);
             setOnClickListener(null);
             setClickable(false);
             setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
-            mTopBackgroundView.setBackground(tileBackground);
+            mTopBackgroundView.setBackground(mTileBackground);
         } else {
             mTopBackgroundView.setOnClickListener(null);
             mTopBackgroundView.setClickable(false);
             setOnClickListener(mClickPrimary);
             setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
-            setBackground(tileBackground);
+            setBackground(mTileBackground);
         }
         mTopBackgroundView.setFocusable(dual);
         setFocusable(!dual);
@@ -214,7 +218,7 @@
         return icon;
     }
 
-    private Drawable getTileBackground() {
+    private Drawable newTileBackground() {
         final int[] attrs = new int[] { android.R.attr.selectableItemBackgroundBorderless };
         final TypedArray ta = mContext.obtainStyledAttributes(attrs);
         final Drawable d = ta.getDrawable(0);
@@ -285,16 +289,7 @@
 
     protected void handleStateChanged(QSTile.State state) {
         if (mIcon instanceof ImageView) {
-            ImageView iv = (ImageView) mIcon;
-            if (state.icon != null) {
-                iv.setImageDrawable(state.icon);
-            } else if (state.iconId > 0) {
-                iv.setImageResource(state.iconId);
-            }
-            Drawable drawable = iv.getDrawable();
-            if (state.autoMirrorDrawable && drawable != null) {
-                drawable.setAutoMirrored(true);
-            }
+            setIcon((ImageView) mIcon, state);
         }
         if (mDual) {
             mDualLabel.setText(state.label);
@@ -306,6 +301,22 @@
         }
     }
 
+    protected void setIcon(ImageView iv, QSTile.State state) {
+        if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))) {
+            Drawable d = state.icon != null ? state.icon.getDrawable(mContext) : null;
+            if (d != null && state.autoMirrorDrawable) {
+                d.setAutoMirrored(true);
+            }
+            iv.setImageDrawable(d);
+            iv.setTag(R.id.qs_icon_tag, state.icon);
+            if (d instanceof Animatable) {
+                if (!iv.isShown()) {
+                    ((Animatable) d).stop(); // skip directly to end state
+                }
+            }
+        }
+    }
+
     public void onStateChanged(QSTile.State state) {
         mHandler.obtainMessage(H.STATE_CHANGED, state).sendToTarget();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
index cfcd74e..9ac7944 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
@@ -104,7 +104,7 @@
     protected void handleStateChanged(QSTile.State state) {
         super.handleStateChanged(state);
         final SignalState s = (SignalState) state;
-        mSignal.setImageResource(s.iconId);
+        setIcon(mSignal, s);
         if (s.overlayIconId > 0) {
             mOverlay.setVisibility(VISIBLE);
             mOverlay.setImageResource(s.overlayIconId);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index 51401c8..2dd02a5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -29,6 +29,10 @@
 
 /** Quick settings tile: Airplane mode **/
 public class AirplaneModeTile extends QSTile<QSTile.BooleanState> {
+    private final AnimationIcon mEnable =
+            new AnimationIcon(R.drawable.ic_signal_airplane_enable_animation);
+    private final AnimationIcon mDisable =
+            new AnimationIcon(R.drawable.ic_signal_airplane_disable_animation);
     private final GlobalSetting mSetting;
 
     private boolean mListening;
@@ -52,6 +56,8 @@
     @Override
     public void handleClick() {
         setEnabled(!mState.value);
+        mEnable.setAllowAnimation(true);
+        mDisable.setAllowAnimation(true);
     }
 
     private void setEnabled(boolean enabled) {
@@ -68,11 +74,11 @@
         state.visible = true;
         state.label = mContext.getString(R.string.quick_settings_airplane_mode_label);
         if (airplaneMode) {
-            state.iconId =  R.drawable.ic_qs_airplane_on;
+            state.icon = mEnable;
             state.contentDescription =  mContext.getString(
                     R.string.accessibility_quick_settings_airplane_on);
         } else {
-            state.iconId = R.drawable.ic_qs_airplane_off;
+            state.icon = mDisable;
             state.contentDescription =  mContext.getString(
                     R.string.accessibility_quick_settings_airplane_off);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 84bfb8f..4d77348 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -92,17 +92,17 @@
         if (enabled) {
             state.label = null;
             if (connected) {
-                state.iconId = R.drawable.ic_qs_bluetooth_connected;
+                state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_connected);
                 state.contentDescription = mContext.getString(
                         R.string.accessibility_quick_settings_bluetooth_connected);
                 state.label = mController.getLastDeviceName();
             } else if (connecting) {
-                state.iconId = R.drawable.ic_qs_bluetooth_connecting;
+                state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_connecting);
                 state.contentDescription = mContext.getString(
                         R.string.accessibility_quick_settings_bluetooth_connecting);
                 state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
             } else {
-                state.iconId = R.drawable.ic_qs_bluetooth_on;
+                state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_on);
                 state.contentDescription = mContext.getString(
                         R.string.accessibility_quick_settings_bluetooth_on);
             }
@@ -110,7 +110,7 @@
                 state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
             }
         } else {
-            state.iconId = R.drawable.ic_qs_bluetooth_off;
+            state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_off);
             state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_bluetooth_off);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 8304291..5bf6fb5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -107,7 +107,8 @@
         if (!state.value && connecting) {
             state.label = mContext.getString(R.string.quick_settings_connecting);
         }
-        state.iconId = state.value ? R.drawable.ic_qs_cast_on : R.drawable.ic_qs_cast_off;
+        state.icon = ResourceIcon.get(state.value ? R.drawable.ic_qs_cast_on
+                : R.drawable.ic_qs_cast_off);
         mDetailAdapter.updateItems(devices);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 359a259..178590b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -87,16 +87,17 @@
         if (cb == null) return;
 
         final Resources r = mContext.getResources();
-        state.iconId = cb.noSim ? R.drawable.ic_qs_no_sim
+        final int iconId = cb.noSim ? R.drawable.ic_qs_no_sim
                 : !cb.enabled || cb.airplaneModeEnabled ? R.drawable.ic_qs_signal_disabled
                 : cb.mobileSignalIconId > 0 ? cb.mobileSignalIconId
                 : R.drawable.ic_qs_signal_no_signal;
+        state.icon = ResourceIcon.get(iconId);
         state.isOverlayIconWide = cb.isDataTypeIconWide;
         state.autoMirrorDrawable = !cb.noSim;
         state.overlayIconId = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiConnected
                 ? cb.dataTypeIconId
                 : 0;
-        state.filter = state.iconId != R.drawable.ic_qs_no_sim;
+        state.filter = iconId != R.drawable.ic_qs_no_sim;
         state.activityIn = cb.enabled && cb.activityIn;
         state.activityOut = cb.enabled && cb.activityOut;
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 7ba1dc0..a19c29f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -26,6 +26,10 @@
 /** Quick settings tile: Invert colors **/
 public class ColorInversionTile extends QSTile<QSTile.BooleanState> {
 
+    private final AnimationIcon mEnable
+            = new AnimationIcon(R.drawable.ic_invert_colors_enable_animation);
+    private final AnimationIcon mDisable
+            = new AnimationIcon(R.drawable.ic_invert_colors_disable_animation);
     private final SecureSetting mSetting;
     private final UsageTracker mUsageTracker;
 
@@ -79,6 +83,8 @@
     @Override
     protected void handleClick() {
         mSetting.setValue(mState.value ? 0 : 1);
+        mEnable.setAllowAnimation(true);
+        mDisable.setAllowAnimation(true);
     }
 
     @Override
@@ -88,7 +94,7 @@
         state.visible = enabled || mUsageTracker.isRecentlyUsed();
         state.value = enabled;
         state.label = mContext.getString(R.string.quick_settings_inversion_label);
-        state.iconId = enabled ? R.drawable.ic_qs_inversion_on : R.drawable.ic_qs_inversion_off;
+        state.icon = enabled ? mEnable : mDisable;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index e6b7f02..5c1a317 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -31,6 +31,10 @@
      * still available because it was recently on. */
     private static final long RECENTLY_ON_DURATION_MILLIS = 500;
 
+    private final AnimationIcon mEnable
+            = new AnimationIcon(R.drawable.ic_signal_flashlight_enable_animation);
+    private final AnimationIcon mDisable
+            = new AnimationIcon(R.drawable.ic_signal_flashlight_disable_animation);
     private final FlashlightController mFlashlightController;
     private long mWasLastOn;
 
@@ -66,7 +70,7 @@
         }
         boolean newState = !mState.value;
         mFlashlightController.setFlashlight(newState);
-        refreshState(newState);
+        refreshState(newState ? UserBoolean.USER_TRUE : UserBoolean.USER_FALSE);
     }
 
     @Override
@@ -75,8 +79,8 @@
             mWasLastOn = SystemClock.uptimeMillis();
         }
 
-        if (arg instanceof Boolean) {
-            state.value = (Boolean) arg;
+        if (arg instanceof UserBoolean) {
+            state.value = ((UserBoolean) arg).value;
         }
 
         if (!state.value && mWasLastOn != 0) {
@@ -92,8 +96,9 @@
         // the camera is not available while it is being used for the flashlight.
         state.visible = mWasLastOn != 0 || mFlashlightController.isAvailable();
         state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
-        state.iconId = state.value
-                ? R.drawable.ic_qs_flashlight_on : R.drawable.ic_qs_flashlight_off;
+        final AnimationIcon icon = state.value ? mEnable : mDisable;
+        icon.setAllowAnimation(arg instanceof UserBoolean && ((UserBoolean) arg).userInitiated);
+        state.icon = icon;
         int onOrOffId = state.value
                 ? R.string.accessibility_quick_settings_flashlight_on
                 : R.string.accessibility_quick_settings_flashlight_off;
@@ -111,12 +116,12 @@
 
     @Override
     public void onFlashlightOff() {
-        refreshState(false);
+        refreshState(UserBoolean.BACKGROUND_FALSE);
     }
 
     @Override
     public void onFlashlightError() {
-        refreshState(false);
+        refreshState(UserBoolean.BACKGROUND_FALSE);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index b30a1d3..64dab85 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -71,8 +71,8 @@
         state.label = mContext.getString(R.string.quick_settings_hotspot_label);
 
         state.value = mController.isHotspotEnabled();
-        state.iconId = state.visible && state.value ? R.drawable.ic_qs_hotspot_on
-                : R.drawable.ic_qs_hotspot_off;
+        state.icon = ResourceIcon.get(state.visible && state.value ? R.drawable.ic_qs_hotspot_on
+                : R.drawable.ic_qs_hotspot_off);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
index 58587e6..6fb9cd8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
@@ -31,6 +31,9 @@
 
 import com.android.systemui.qs.QSTile;
 
+import java.util.Arrays;
+import java.util.Objects;
+
 public class IntentTile extends QSTile<QSTile.State> {
     public static final String PREFIX = "intent(";
 
@@ -96,13 +99,11 @@
         state.visible = intent.getBooleanExtra("visible", true);
         state.contentDescription = intent.getStringExtra("contentDescription");
         state.label = intent.getStringExtra("label");
-        state.iconId = 0;
         state.icon = null;
         final byte[] iconBitmap = intent.getByteArrayExtra("iconBitmap");
         if (iconBitmap != null) {
             try {
-                final Bitmap b = BitmapFactory.decodeByteArray(iconBitmap, 0, iconBitmap.length);
-                state.icon = new BitmapDrawable(mContext.getResources(), b);
+                state.icon = new BytesIcon(iconBitmap);
             } catch (Throwable t) {
                 Log.w(TAG, "Error loading icon bitmap, length " + iconBitmap.length, t);
             }
@@ -111,9 +112,9 @@
             if (iconId != 0) {
                 final String iconPackage = intent.getStringExtra("iconPackage");
                 if (!TextUtils.isEmpty(iconPackage)) {
-                    state.icon = getPackageDrawable(iconPackage, iconId);
+                    state.icon = new PackageDrawableIcon(iconPackage, iconId);
                 } else {
-                    state.iconId = iconId;
+                    state.icon = ResourceIcon.get(iconId);
                 }
             }
         }
@@ -121,19 +122,66 @@
         mOnClickUri = intent.getStringExtra("onClickUri");
     }
 
-    private Drawable getPackageDrawable(String pkg, int id) {
-        try {
-            return mContext.createPackageContext(pkg, 0).getDrawable(id);
-        } catch (Throwable t) {
-            Log.w(TAG, "Error loading package drawable pkg=" + pkg + " id=" + id, t);
-            return null;
-        }
-    }
-
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             refreshState(intent);
         }
     };
+
+    private static class BytesIcon extends Icon {
+        private final byte[] mBytes;
+
+        public BytesIcon(byte[] bytes) {
+            mBytes = bytes;
+        }
+
+        @Override
+        public Drawable getDrawable(Context context) {
+            final Bitmap b = BitmapFactory.decodeByteArray(mBytes, 0, mBytes.length);
+            return new BitmapDrawable(context.getResources(), b);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            return o instanceof BytesIcon && Arrays.equals(((BytesIcon) o).mBytes, mBytes);
+        }
+
+        @Override
+        public String toString() {
+            return String.format("BytesIcon[len=%s]", mBytes.length);
+        }
+    }
+
+    private class PackageDrawableIcon extends Icon {
+        private final String mPackage;
+        private final int mResId;
+
+        public PackageDrawableIcon(String pkg, int resId) {
+            mPackage = pkg;
+            mResId = resId;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof PackageDrawableIcon)) return false;
+            final PackageDrawableIcon other = (PackageDrawableIcon) o;
+            return Objects.equals(other.mPackage, mPackage) && other.mResId == mResId;
+        }
+
+        @Override
+        public Drawable getDrawable(Context context) {
+            try {
+                return context.createPackageContext(mPackage, 0).getDrawable(mResId);
+            } catch (Throwable t) {
+                Log.w(TAG, "Error loading package drawable pkg=" + mPackage + " id=" + mResId, t);
+                return null;
+            }
+        }
+
+        @Override
+        public String toString() {
+            return String.format("PackageDrawableIcon[pkg=%s,id=0x%08x]", mPackage, mResId);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index d1dc5d2..11ec722 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -25,6 +25,11 @@
 /** Quick settings tile: Location **/
 public class LocationTile extends QSTile<QSTile.BooleanState> {
 
+    private final AnimationIcon mEnable =
+            new AnimationIcon(R.drawable.ic_signal_location_enable_animation);
+    private final AnimationIcon mDisable =
+            new AnimationIcon(R.drawable.ic_signal_location_disable_animation);
+
     private final LocationController mController;
     private final KeyguardMonitor mKeyguard;
     private final Callback mCallback = new Callback();
@@ -55,6 +60,8 @@
     protected void handleClick() {
         final boolean wasEnabled = (Boolean) mState.value;
         mController.setLocationEnabled(!wasEnabled);
+        mEnable.setAllowAnimation(true);
+        mDisable.setAllowAnimation(true);
     }
 
     @Override
@@ -67,12 +74,12 @@
         state.visible = !mKeyguard.isShowing();
         state.value = locationEnabled;
         if (locationEnabled) {
-            state.iconId = R.drawable.ic_qs_location_on;
+            state.icon = mEnable;
             state.label = mContext.getString(R.string.quick_settings_location_label);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_location_on);
         } else {
-            state.iconId = R.drawable.ic_qs_location_off;
+            state.icon = mDisable;
             state.label = mContext.getString(R.string.quick_settings_location_label);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_location_off);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index ae40a4d..f46b9a6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -17,7 +17,6 @@
 package com.android.systemui.qs.tiles;
 
 import android.content.res.Configuration;
-import android.content.res.Resources;
 
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
@@ -26,6 +25,15 @@
 
 /** Quick settings tile: Rotation **/
 public class RotationLockTile extends QSTile<QSTile.BooleanState> {
+    private final AnimationIcon mPortraitToAuto
+            = new AnimationIcon(R.drawable.ic_portrait_to_auto_rotate_animation);
+    private final AnimationIcon mAutoToPortrait
+            = new AnimationIcon(R.drawable.ic_portrait_from_auto_rotate_animation);
+
+    private final AnimationIcon mLandscapeToAuto
+            = new AnimationIcon(R.drawable.ic_landscape_to_auto_rotate_animation);
+    private final AnimationIcon mAutoToLandscape
+            = new AnimationIcon(R.drawable.ic_landscape_from_auto_rotate_animation);
 
     private final RotationLockController mController;
 
@@ -51,30 +59,34 @@
     @Override
     protected void handleClick() {
         if (mController == null) return;
-        mController.setRotationLocked(!mState.value);
+        final boolean newState = !mState.value;
+        mController.setRotationLocked(newState);
+        refreshState(newState ? UserBoolean.USER_TRUE : UserBoolean.USER_FALSE);
     }
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
         if (mController == null) return;
-        final boolean rotationLocked = mController.isRotationLocked();
+        final boolean rotationLocked = arg != null ? ((UserBoolean) arg).value
+                : mController.isRotationLocked();
+        final boolean userInitiated = arg != null ? ((UserBoolean) arg).userInitiated : false;
         state.visible = mController.isRotationLockAffordanceVisible();
-        final Resources res = mContext.getResources();
         state.value = rotationLocked;
+        final boolean portrait = mContext.getResources().getConfiguration().orientation
+                != Configuration.ORIENTATION_LANDSCAPE;
+        final AnimationIcon icon;
         if (rotationLocked) {
-            final boolean portrait = res.getConfiguration().orientation
-                    != Configuration.ORIENTATION_LANDSCAPE;
             final int label = portrait ? R.string.quick_settings_rotation_locked_portrait_label
                     : R.string.quick_settings_rotation_locked_landscape_label;
-            final int icon = portrait ? R.drawable.ic_qs_rotation_portrait
-                    : R.drawable.ic_qs_rotation_landscape;
             state.label = mContext.getString(label);
-            state.icon = mContext.getDrawable(icon);
+            icon = portrait ? mAutoToPortrait : mAutoToLandscape;
         } else {
             state.label = mContext.getString(R.string.quick_settings_rotation_unlocked_label);
-            state.icon = res.getDrawable(R.drawable.ic_qs_rotation_unlocked);
+            icon = portrait ? mPortraitToAuto : mLandscapeToAuto;
         }
-        state.contentDescription = getAccessibilityString(
+        icon.setAllowAnimation(userInitiated);
+        state.icon = icon;
+        state.contentDescription = getAccessibilityString(rotationLocked,
                 R.string.accessibility_rotation_lock_on_portrait,
                 R.string.accessibility_rotation_lock_on_landscape,
                 R.string.accessibility_rotation_lock_off);
@@ -83,14 +95,16 @@
     /**
      * Get the correct accessibility string based on the state
      *
+     * @param locked Whether or not rotation is locked.
      * @param idWhenPortrait The id which should be used when locked in portrait.
      * @param idWhenLandscape The id which should be used when locked in landscape.
      * @param idWhenOff The id which should be used when the rotation lock is off.
      * @return
      */
-    private String getAccessibilityString(int idWhenPortrait, int idWhenLandscape, int idWhenOff) {
+    private String getAccessibilityString(boolean locked, int idWhenPortrait, int idWhenLandscape,
+            int idWhenOff) {
         int stringID;
-        if (mState.value) {
+        if (locked) {
             final boolean portrait = mContext.getResources().getConfiguration().orientation
                     != Configuration.ORIENTATION_LANDSCAPE;
             stringID = portrait ? idWhenPortrait: idWhenLandscape;
@@ -102,7 +116,7 @@
 
     @Override
     protected String composeChangeAnnouncement() {
-        return getAccessibilityString(
+        return getAccessibilityString(mState.value,
                 R.string.accessibility_rotation_lock_on_portrait_changed,
                 R.string.accessibility_rotation_lock_on_landscape_changed,
                 R.string.accessibility_rotation_lock_off_changed);
@@ -111,7 +125,8 @@
     private final RotationLockControllerCallback mCallback = new RotationLockControllerCallback() {
         @Override
         public void onRotationLockStateChanged(boolean rotationLocked, boolean affordanceVisible) {
-            refreshState();
+            refreshState(rotationLocked ? UserBoolean.BACKGROUND_TRUE
+                    : UserBoolean.BACKGROUND_FALSE);
         }
     };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 20c4ee8..7aa884e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -120,19 +120,19 @@
         final String signalContentDescription;
         final Resources r = mContext.getResources();
         if (!state.enabled) {
-            state.iconId = R.drawable.ic_qs_wifi_disabled;
+            state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_disabled);
             state.label = r.getString(R.string.quick_settings_wifi_label);
             signalContentDescription = r.getString(R.string.accessibility_wifi_off);
         } else if (wifiConnected) {
-            state.iconId = cb.wifiSignalIconId;
+            state.icon = ResourceIcon.get(cb.wifiSignalIconId);
             state.label = removeDoubleQuotes(cb.enabledDesc);
             signalContentDescription = cb.wifiSignalContentDescription;
         } else if (wifiNotConnected) {
-            state.iconId = R.drawable.ic_qs_wifi_0;
+            state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_0);
             state.label = r.getString(R.string.quick_settings_wifi_label);
             signalContentDescription = r.getString(R.string.accessibility_no_wifi);
         } else {
-            state.iconId = R.drawable.ic_qs_wifi_no_network;
+            state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_no_network);
             state.label = r.getString(R.string.quick_settings_wifi_label);
             signalContentDescription = r.getString(R.string.accessibility_wifi_off);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 2a782cc..4c3460e 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -728,7 +728,7 @@
         final ActivityManager am = (ActivityManager)
                 getContext().getSystemService(Context.ACTIVITY_SERVICE);
         if (am != null) {
-            am.removeTask(ad.persistentTaskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
+            am.removeTask(ad.persistentTaskId);
 
             // Accessibility feedback
             setContentDescription(
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 71a3ef1..b661385 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -291,18 +291,18 @@
         }
     }
 
-    /** Removes the task and kills the process */
-    public void removeTask(int taskId, boolean isDocument) {
+    /** Removes the task */
+    public void removeTask(int taskId) {
         if (mAm == null) return;
         if (Constants.DebugFlags.App.EnableSystemServicesProxy) return;
 
-        // Remove the task, and only kill the process if it is not a document
-        mAm.removeTask(taskId, isDocument ? 0 : ActivityManager.REMOVE_TASK_KILL_PROCESS);
+        // Remove the task.
+        mAm.removeTask(taskId);
     }
 
     /**
      * Returns the activity info for a given component name.
-     * 
+     *
      * @param cn The component name of the activity.
      * @param userId The userId of the user that this is for.
      */
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 a0dee07..e1179fa 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
@@ -17,7 +17,6 @@
 package com.android.systemui.recents.misc;
 
 import android.animation.Animator;
-import android.content.Intent;
 import android.graphics.Color;
 import android.graphics.Matrix;
 import android.graphics.Rect;
@@ -184,12 +183,6 @@
         sPropertyMethod.invoke(null, property, value);
     }
 
-    /** Returns whether the specified intent is a document. */
-    public static boolean isDocument(Intent intent) {
-        int flags = intent.getFlags();
-        return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
-    }
-
     /**
      * Cancels an animation ensuring that if it has listeners, onCancel and onEnd
      * are not called.
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 6b0d306..ff0330d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -34,7 +34,6 @@
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.RecentsConfiguration;
 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;
@@ -522,8 +521,7 @@
         loader.deleteTaskData(t, false);
 
         // Remove the old task from activity manager
-        RecentsTaskLoader.getInstance().getSystemServicesProxy().removeTask(t.key.id,
-                Utilities.isDocument(t.key.baseIntent));
+        RecentsTaskLoader.getInstance().getSystemServicesProxy().removeTask(t.key.id);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissViewImageButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/DismissViewImageButton.java
index d55b0b3..35fd688 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DismissViewImageButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DismissViewImageButton.java
@@ -61,4 +61,9 @@
         outRect.top += translationY;
         outRect.bottom += translationY;
     }
+
+    @Override
+    public boolean hasOverlappingRendering() {
+        return false;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index ce35e4b..992aa9f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -162,8 +162,9 @@
     KeyguardUpdateMonitorCallback mUpdateMonitor = new KeyguardUpdateMonitorCallback() {
         @Override
         public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) {
-            mPowerPluggedIn = status.status == BatteryManager.BATTERY_STATUS_CHARGING
+            boolean isChargingOrFull = status.status == BatteryManager.BATTERY_STATUS_CHARGING
                     || status.status == BatteryManager.BATTERY_STATUS_FULL;
+            mPowerPluggedIn = status.isPluggedIn() && isChargingOrFull;
             mPowerCharged = status.isCharged();
             updateIndication();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
index 32fb567..e89e15d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
@@ -45,6 +45,7 @@
     public static final int MODE_LIGHTS_OUT = 3;
     public static final int MODE_TRANSPARENT = 4;
     public static final int MODE_WARNING = 5;
+    public static final int MODE_LIGHTS_OUT_TRANSPARENT = 6;
 
     public static final int LIGHTS_IN_DURATION = 250;
     public static final int LIGHTS_OUT_DURATION = 750;
@@ -75,6 +76,9 @@
                 || mode == MODE_TRANSPARENT)) {
             mode = MODE_OPAQUE;
         }
+        if (!HIGH_END && (mode == MODE_LIGHTS_OUT_TRANSPARENT)) {
+            mode = MODE_LIGHTS_OUT;
+        }
         if (mMode == mode) return;
         int oldMode = mMode;
         mMode = mode;
@@ -102,6 +106,7 @@
         if (mode == MODE_LIGHTS_OUT) return "MODE_LIGHTS_OUT";
         if (mode == MODE_TRANSPARENT) return "MODE_TRANSPARENT";
         if (mode == MODE_WARNING) return "MODE_WARNING";
+        if (mode == MODE_LIGHTS_OUT_TRANSPARENT) return "MODE_LIGHTS_OUT_TRANSPARENT";
         throw new IllegalArgumentException("Unknown mode " + mode);
     }
 
@@ -109,6 +114,10 @@
         mBarBackground.finishAnimation();
     }
 
+    protected boolean isLightsOut(int mode) {
+        return mode == MODE_LIGHTS_OUT || mode == MODE_LIGHTS_OUT_TRANSPARENT;
+    }
+
     private static class BarBackgroundDrawable extends Drawable {
         private final int mOpaque;
         private final int mSemiTransparent;
@@ -196,7 +205,7 @@
                 targetColor = mSemiTransparent;
             } else if (mMode == MODE_SEMI_TRANSPARENT) {
                 targetColor = mSemiTransparent;
-            } else if (mMode == MODE_TRANSPARENT) {
+            } else if (mMode == MODE_TRANSPARENT || mMode == MODE_LIGHTS_OUT_TRANSPARENT) {
                 targetColor = mTransparent;
             } else {
                 targetColor = mOpaque;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
index 052b6c6..15f6dc2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
@@ -84,7 +84,7 @@
         applyBackButtonQuiescentAlpha(mode, animate);
 
         // apply to lights out
-        applyLightsOut(mode == MODE_LIGHTS_OUT, animate, force);
+        applyLightsOut(isLightsOut(mode), animate, force);
     }
 
     private float alphaForMode(int mode) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index d9e44c3..bb992b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -291,8 +291,8 @@
         } else {
             setQsExpansion(mQsMinExpansionHeight + mLastOverscroll);
             mNotificationStackScroller.setStackHeight(getExpandedHeight());
-            updateHeader();
         }
+        updateHeader();
         mNotificationStackScroller.updateIsSmallScreen(
                 mHeader.getCollapsedHeight() + mQsPeekHeight);
     }
@@ -1329,6 +1329,16 @@
         float notificationHeight = mNotificationStackScroller.getHeight()
                 - mNotificationStackScroller.getEmptyBottomMargin()
                 - mNotificationStackScroller.getTopPadding();
+
+        // When only empty shade view is visible in QS collapsed state, simulate that we would have
+        // it in expanded QS state as well so we don't run into troubles when fading the view in/out
+        // and expanding/collapsing the whole panel from/to quick settings.
+        if (mNotificationStackScroller.getNotGoneChildCount() == 0
+                && mShadeEmpty) {
+            notificationHeight = mNotificationStackScroller.getEmptyShadeViewHeight()
+                    + mNotificationStackScroller.getBottomStackPeekSize()
+                    + mNotificationStackScroller.getCollapseSecondCardPadding();
+        }
         float totalHeight = Math.max(
                 mQsMaxExpansionHeight + mNotificationStackScroller.getNotificationTopPadding(),
                 mClockPositionResult.stackScrollerPadding - mTopPaddingAdjustment)
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 72dfee6..84ebcdfb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -23,6 +23,7 @@
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
 import static android.app.StatusBarManager.windowStateToString;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
@@ -2600,8 +2601,10 @@
     }
 
     private int barMode(int vis, int transientFlag, int translucentFlag) {
+        int lightsOutTransparent = View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_TRANSPARENT;
         return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
                 : (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT
+                : (vis & lightsOutTransparent) == lightsOutTransparent ? MODE_LIGHTS_OUT_TRANSPARENT
                 : (vis & View.SYSTEM_UI_TRANSPARENT) != 0 ? MODE_TRANSPARENT
                 : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
                 : MODE_OPAQUE;
@@ -3071,8 +3074,6 @@
             }
             else if (Intent.ACTION_SCREEN_ON.equals(action)) {
                 mScreenOn = true;
-                // work around problem where mDisplay.getRotation() is not stable while screen is off (bug 7086018)
-                repositionNavigationBar();
                 notifyNavigationBarScreenOn(true);
             }
             else if (ACTION_DEMO.equals(action)) {
@@ -3597,6 +3598,12 @@
             instantCollapseNotificationPanel();
         }
         updateKeyguardState(staying, false /* fromShadeLocked */);
+
+        // Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
+        // visibilities so next time we open the panel we know the correct height already.
+        if (mQSPanel != null) {
+            mQSPanel.refreshAllTiles();
+        }
         return staying;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
index 8520f40..fb1addf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
@@ -57,19 +57,19 @@
     }
 
     private float getNonBatteryClockAlphaFor(int mode) {
-        return mode == MODE_LIGHTS_OUT ? ICON_ALPHA_WHEN_LIGHTS_OUT_NON_BATTERY_CLOCK
+        return isLightsOut(mode) ? ICON_ALPHA_WHEN_LIGHTS_OUT_NON_BATTERY_CLOCK
                 : !isOpaque(mode) ? ICON_ALPHA_WHEN_NOT_OPAQUE
                 : mIconAlphaWhenOpaque;
     }
 
     private float getBatteryClockAlpha(int mode) {
-        return mode == MODE_LIGHTS_OUT ? ICON_ALPHA_WHEN_LIGHTS_OUT_BATTERY_CLOCK
+        return isLightsOut(mode) ? ICON_ALPHA_WHEN_LIGHTS_OUT_BATTERY_CLOCK
                 : getNonBatteryClockAlphaFor(mode);
     }
 
     private boolean isOpaque(int mode) {
         return !(mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSLUCENT
-                || mode == MODE_TRANSPARENT);
+                || mode == MODE_TRANSPARENT || mode == MODE_LIGHTS_OUT_TRANSPARENT);
     }
 
     @Override
@@ -94,7 +94,7 @@
                     animateTransitionTo(mBattery, newAlphaBC),
                     animateTransitionTo(mClock, newAlphaBC)
                     );
-            if (mode == MODE_LIGHTS_OUT) {
+            if (isLightsOut(mode)) {
                 anims.setDuration(LIGHTS_OUT_DURATION);
             }
             anims.start();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index a4db46a..45a1386 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -21,6 +21,7 @@
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.net.Uri;
+import android.os.Process;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
@@ -108,7 +109,8 @@
         mKeyguard = keyguard;
         mSecurity = security;
 
-        final HandlerThread ht = new HandlerThread(QSTileHost.class.getSimpleName());
+        final HandlerThread ht = new HandlerThread(QSTileHost.class.getSimpleName(),
+                Process.THREAD_PRIORITY_BACKGROUND);
         ht.start();
         mLooper = ht.getLooper();
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 87ce565..d543cff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -2272,6 +2272,10 @@
         return height;
     }
 
+    public int getEmptyShadeViewHeight() {
+        return mEmptyShadeView.getHeight();
+    }
+
     public float getBottomMostNotificationBottom() {
         final int count = getChildCount();
         float max = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index c840f17..28ecbf9 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -69,6 +69,7 @@
     private static final int TIME_CONDITION_INDEX = 1;
     private static final int FIRST_CONDITION_INDEX = 2;
     private static final float SILENT_HINT_PULSE_SCALE = 1.1f;
+    private static final long SELECT_DEFAULT_DELAY = 300;
 
     public static final Intent ZEN_SETTINGS = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
 
@@ -373,8 +374,9 @@
         if (isDowntime(mSessionExitCondition) && !foundDowntime) {
             bind(mSessionExitCondition, null);
         }
-        // ensure something is selected
-        checkForDefault();
+        // ensure something is selected, after waiting for providers to respond
+        mHandler.removeMessages(H.SELECT_DEFAULT);
+        mHandler.sendEmptyMessageDelayed(H.SELECT_DEFAULT, SELECT_DEFAULT_DELAY);
     }
 
     private static boolean isDowntime(Condition c) {
@@ -385,7 +387,8 @@
         return (ConditionTag) mZenConditions.getChildAt(index).getTag();
     }
 
-    private void checkForDefault() {
+    private void handleSelectDefault() {
+        if (!mExpanded) return;
         // are we left without anything selected?  if so, set a default
         for (int i = 0; i < mZenConditions.getChildCount(); i++) {
             if (getConditionTagAt(i).rb.isChecked()) {
@@ -638,6 +641,7 @@
         private static final int UPDATE_CONDITIONS = 1;
         private static final int EXIT_CONDITION_CHANGED = 2;
         private static final int UPDATE_ZEN = 3;
+        private static final int SELECT_DEFAULT = 4;
 
         private H() {
             super(Looper.getMainLooper());
@@ -651,6 +655,8 @@
                 handleExitConditionChanged((Condition) msg.obj);
             } else if (msg.what == UPDATE_ZEN) {
                 handleUpdateZen(msg.arg1);
+            } else if (msg.what == SELECT_DEFAULT) {
+                handleSelectDefault();
             }
         }
     }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index bf5cdff..3c44e87 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -48,6 +48,7 @@
 import android.media.RingtoneManager;
 import android.media.session.MediaSessionLegacyHelper;
 import android.os.Bundle;
+import android.os.Debug;
 import android.os.FactoryTest;
 import android.os.Handler;
 import android.os.IBinder;
@@ -116,6 +117,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.HashSet;
+import java.util.List;
 
 import static android.view.WindowManager.LayoutParams.*;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
@@ -527,6 +529,9 @@
     private boolean mAllowTheaterModeWakeFromLidSwitch;
     private boolean mAllowTheaterModeWakeFromWakeGesture;
 
+    // Whether to go to sleep entering theater mode from power button
+    private boolean mGoToSleepOnButtonPressTheaterMode;
+
     // Screenshot trigger states
     // Time to volume and power must be pressed within this interval of each other.
     private static final long SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS = 150;
@@ -984,7 +989,8 @@
                     Slog.i(TAG, "Toggling theater mode on.");
                     Settings.Global.putInt(mContext.getContentResolver(),
                             Settings.Global.THEATER_MODE_ON, 1);
-                    if (interactive) {
+
+                    if (mGoToSleepOnButtonPressTheaterMode && interactive) {
                         mPowerManager.goToSleep(eventTime,
                                 PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
                     }
@@ -1236,6 +1242,9 @@
         mAllowTheaterModeWakeFromWakeGesture = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_allowTheaterModeWakeFromGesture);
 
+        mGoToSleepOnButtonPressTheaterMode = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_goToSleepOnButtonPressTheaterMode);
+
         mShortPressOnPowerBehavior = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_shortPressOnPowerBehavior);
         mLongPressOnPowerBehavior = mContext.getResources().getInteger(
@@ -2099,11 +2108,8 @@
     /** {@inheritDoc} */
     @Override
     public void removeStartingWindow(IBinder appToken, View window) {
-        if (DEBUG_STARTING_WINDOW) {
-            RuntimeException e = new RuntimeException("here");
-            e.fillInStackTrace();
-            Log.v(TAG, "Removing starting window for " + appToken + ": " + window, e);
-        }
+        if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Removing starting window for " + appToken + ": "
+                + window + " Callers=" + Debug.getCallers(4));
 
         if (window != null) {
             WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
@@ -2299,24 +2305,19 @@
             boolean goingToNotificationShade) {
         if (goingToNotificationShade) {
             return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_behind_enter_fade_in);
-        } else if (onWallpaper) {
-            Animation a = AnimationUtils.loadAnimation(mContext,
-                    R.anim.lock_screen_behind_enter_wallpaper);
-            AnimationSet set = (AnimationSet) a;
-
-            // TODO: Use XML interpolators when we have log interpolators available in XML.
-            set.getAnimations().get(0).setInterpolator(mLogDecelerateInterpolator);
-            set.getAnimations().get(1).setInterpolator(mLogDecelerateInterpolator);
-            return set;
-        } else {
-            Animation a = AnimationUtils.loadAnimation(mContext,
-                    R.anim.lock_screen_behind_enter);
-            AnimationSet set = (AnimationSet) a;
-
-            // TODO: Use XML interpolators when we have log interpolators available in XML.
-            set.getAnimations().get(0).setInterpolator(mLogDecelerateInterpolator);
-            return set;
         }
+
+        AnimationSet set = (AnimationSet) AnimationUtils.loadAnimation(mContext, onWallpaper ?
+                    R.anim.lock_screen_behind_enter_wallpaper :
+                    R.anim.lock_screen_behind_enter);
+
+        // TODO: Use XML interpolators when we have log interpolators available in XML.
+        final List<Animation> animations = set.getAnimations();
+        for (int i = animations.size() - 1; i >= 0; --i) {
+            animations.get(i).setInterpolator(mLogDecelerateInterpolator);
+        }
+
+        return set;
     }
 
 
@@ -4767,18 +4768,39 @@
     @Override
     public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) {
         if ((policyFlags & FLAG_WAKE) != 0) {
-            wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotion);
-            return 0;
+            if (wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotion)) {
+                return 0;
+            }
         }
+
         if (shouldDispatchInputWhenNonInteractive()) {
             return ACTION_PASS_TO_USER;
         }
+
         return 0;
     }
 
     private boolean shouldDispatchInputWhenNonInteractive() {
-        return keyguardIsShowingTq() && mDisplay != null &&
-                mDisplay.getState() != Display.STATE_OFF;
+        // Send events to keyguard while the screen is on.
+        if (keyguardIsShowingTq() && mDisplay != null && mDisplay.getState() != Display.STATE_OFF) {
+            return true;
+        }
+
+        // Send events to a dozing dream even if the screen is off since the dream
+        // is in control of the state of the screen.
+        IDreamManager dreamManager = getDreamManager();
+
+        try {
+            if (dreamManager != null && dreamManager.isDreaming()) {
+                return true;
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "RemoteException when checking if dreaming", e);
+        }
+
+        // Otherwise, consume events since the user can't see what is being
+        // interacted with.
+        return false;
     }
 
     void dispatchMediaKeyWithWakeLock(KeyEvent event) {
@@ -4949,12 +4971,13 @@
         wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey);
     }
 
-    private void wakeUp(long wakeTime, boolean wakeInTheaterMode) {
+    private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode) {
         if (!wakeInTheaterMode && isTheaterModeEnabled()) {
-            return;
+            return false;
         }
 
         mPowerManager.wakeUp(wakeTime);
+        return true;
     }
 
     // Called on the PowerManager's Notifier thread.
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index bf67461..a2d246d 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -3701,12 +3701,11 @@
 
     private void updateCapabilities(NetworkAgentInfo networkAgent,
             NetworkCapabilities networkCapabilities) {
-        //  TODO - turn this on in MR1 when we have more dogfooding time.
-        // rematchAllNetworksAndRequests();
         if (!Objects.equals(networkAgent.networkCapabilities, networkCapabilities)) {
             synchronized (networkAgent) {
                 networkAgent.networkCapabilities = networkCapabilities;
             }
+            rematchAllNetworksAndRequests(networkAgent, networkAgent.getCurrentScore());
             notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_CAP_CHANGED);
         }
     }
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index b708c3f..11ba8e8 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -18,49 +18,38 @@
 
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
-import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 
+import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE;
 import static android.content.Context.USER_SERVICE;
 import static android.Manifest.permission.READ_PROFILE;
-import android.database.Cursor;
+
 import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteStatement;
 import android.os.Binder;
-import android.os.Environment;
 import android.os.IBinder;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.storage.IMountService;
 import android.os.ServiceManager;
-import android.os.storage.StorageManager;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
 import android.provider.Settings.Secure;
 import android.provider.Settings.SettingNotFoundException;
-import android.security.KeyChain;
-import android.security.KeyChain.KeyChainConnection;
 import android.security.KeyStore;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Slog;
 
-import com.android.internal.os.BackgroundThread;
 import com.android.internal.widget.ILockSettings;
 import com.android.internal.widget.ILockSettingsObserver;
 import com.android.internal.widget.LockPatternUtils;
 
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.RandomAccessFile;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -73,27 +62,17 @@
  */
 public class LockSettingsService extends ILockSettings.Stub {
 
-    private static final String PERMISSION = "android.permission.ACCESS_KEYGUARD_SECURE_STORAGE";
+    private static final String PERMISSION = ACCESS_KEYGUARD_SECURE_STORAGE;
 
     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
 
-    private final DatabaseHelper mOpenHelper;
+
     private static final String TAG = "LockSettingsService";
 
-    private static final String TABLE = "locksettings";
-    private static final String COLUMN_KEY = "name";
-    private static final String COLUMN_USERID = "user";
-    private static final String COLUMN_VALUE = "value";
-
-    private static final String[] COLUMNS_FOR_QUERY = {
-        COLUMN_VALUE
-    };
-
-    private static final String SYSTEM_DIRECTORY = "/system/";
-    private static final String LOCK_PATTERN_FILE = "gesture.key";
-    private static final String LOCK_PASSWORD_FILE = "password.key";
-
     private final Context mContext;
+
+    private final LockSettingsStorage mStorage;
+
     private LockPatternUtils mLockPatternUtils;
     private boolean mFirstCallToVold;
 
@@ -102,7 +81,6 @@
     public LockSettingsService(Context context) {
         mContext = context;
         // Open the database
-        mOpenHelper = new DatabaseHelper(mContext);
 
         mLockPatternUtils = new LockPatternUtils(context);
         mFirstCallToVold = true;
@@ -110,6 +88,18 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_ADDED);
         mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
+
+        mStorage = new LockSettingsStorage(context, new LockSettingsStorage.Callback() {
+            @Override
+            public void initialize(SQLiteDatabase db) {
+                // Get the lockscreen default from a system property, if available
+                boolean lockScreenDisable = SystemProperties.getBoolean(
+                        "ro.lockscreen.disable.default", false);
+                if (lockScreenDisable) {
+                    mStorage.writeKeyValue(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0);
+                }
+            }
+        });
     }
 
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -220,29 +210,31 @@
     @Override
     public void setBoolean(String key, boolean value, int userId) throws RemoteException {
         checkWritePermission(userId);
-
-        writeToDb(key, value ? "1" : "0", userId);
+        setStringUnchecked(key, userId, value ? "1" : "0");
     }
 
     @Override
     public void setLong(String key, long value, int userId) throws RemoteException {
         checkWritePermission(userId);
-
-        writeToDb(key, Long.toString(value), userId);
+        setStringUnchecked(key, userId, Long.toString(value));
     }
 
     @Override
     public void setString(String key, String value, int userId) throws RemoteException {
         checkWritePermission(userId);
+        setStringUnchecked(key, userId, value);
+    }
 
-        writeToDb(key, value, userId);
+    private void setStringUnchecked(String key, int userId, String value) {
+        mStorage.writeKeyValue(key, value, userId);
+        notifyObservers(key, userId);
     }
 
     @Override
     public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException {
         checkReadPermission(key, userId);
 
-        String value = readFromDb(key, null, userId);
+        String value = mStorage.readKeyValue(key, null, userId);
         return TextUtils.isEmpty(value) ?
                 defaultValue : (value.equals("1") || value.equals("true"));
     }
@@ -251,7 +243,7 @@
     public long getLong(String key, long defaultValue, int userId) throws RemoteException {
         checkReadPermission(key, userId);
 
-        String value = readFromDb(key, null, userId);
+        String value = mStorage.readKeyValue(key, null, userId);
         return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value);
     }
 
@@ -259,7 +251,7 @@
     public String getString(String key, String defaultValue, int userId) throws RemoteException {
         checkReadPermission(key, userId);
 
-        return readFromDb(key, defaultValue, userId);
+        return mStorage.readKeyValue(key, defaultValue, userId);
     }
 
     @Override
@@ -308,57 +300,18 @@
         }
     }
 
-    private int getUserParentOrSelfId(int userId) {
-        if (userId != 0) {
-            final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
-            final UserInfo pi = um.getProfileParent(userId);
-            if (pi != null) {
-                return pi.id;
-            }
-        }
-        return userId;
-    }
-
-    private String getLockPatternFilename(int userId) {
-        String dataSystemDirectory =
-                android.os.Environment.getDataDirectory().getAbsolutePath() +
-                SYSTEM_DIRECTORY;
-        userId = getUserParentOrSelfId(userId);
-        if (userId == 0) {
-            // Leave it in the same place for user 0
-            return dataSystemDirectory + LOCK_PATTERN_FILE;
-        } else {
-            return  new File(Environment.getUserSystemDirectory(userId), LOCK_PATTERN_FILE)
-                    .getAbsolutePath();
-        }
-    }
-
-    private String getLockPasswordFilename(int userId) {
-        userId = getUserParentOrSelfId(userId);
-        String dataSystemDirectory =
-                android.os.Environment.getDataDirectory().getAbsolutePath() +
-                SYSTEM_DIRECTORY;
-        if (userId == 0) {
-            // Leave it in the same place for user 0
-            return dataSystemDirectory + LOCK_PASSWORD_FILE;
-        } else {
-            return new File(Environment.getUserSystemDirectory(userId), LOCK_PASSWORD_FILE)
-                    .getAbsolutePath();
-        }
-    }
-
     @Override
     public boolean havePassword(int userId) throws RemoteException {
         // Do we need a permissions check here?
 
-        return new File(getLockPasswordFilename(userId)).length() > 0;
+        return mStorage.hasPassword(userId);
     }
 
     @Override
     public boolean havePattern(int userId) throws RemoteException {
         // Do we need a permissions check here?
 
-        return new File(getLockPatternFilename(userId)).length() > 0;
+        return mStorage.hasPattern(userId);
     }
 
     private void maybeUpdateKeystore(String password, int userHandle) {
@@ -394,7 +347,7 @@
 
         final byte[] hash = LockPatternUtils.patternToHash(
                 LockPatternUtils.stringToPattern(pattern));
-        writeFile(getLockPatternFilename(userId), hash);
+        mStorage.writePatternHash(hash, userId);
     }
 
     @Override
@@ -403,68 +356,46 @@
 
         maybeUpdateKeystore(password, userId);
 
-        writeFile(getLockPasswordFilename(userId),
-                mLockPatternUtils.passwordToHash(password, userId));
+        mStorage.writePasswordHash(mLockPatternUtils.passwordToHash(password, userId), userId);
     }
 
     @Override
     public boolean checkPattern(String pattern, int userId) throws RemoteException {
         checkPasswordReadPermission(userId);
-        try {
-            // Read all the bytes from the file
-            RandomAccessFile raf = new RandomAccessFile(getLockPatternFilename(userId), "r");
-            final byte[] stored = new byte[(int) raf.length()];
-            int got = raf.read(stored, 0, stored.length);
-            raf.close();
-            if (got <= 0) {
-                return true;
-            }
-            // Compare the hash from the file with the entered pattern's hash
-            final byte[] hash = LockPatternUtils.patternToHash(
-                    LockPatternUtils.stringToPattern(pattern));
-            final boolean matched = Arrays.equals(stored, hash);
-            if (matched && !TextUtils.isEmpty(pattern)) {
-                maybeUpdateKeystore(pattern, userId);
-            }
-            return matched;
-        } catch (FileNotFoundException fnfe) {
-            Slog.e(TAG, "Cannot read file " + fnfe);
-        } catch (IOException ioe) {
-            Slog.e(TAG, "Cannot read file " + ioe);
+        byte[] hash = LockPatternUtils.patternToHash(LockPatternUtils.stringToPattern(pattern));
+        byte[] storedHash = mStorage.readPatternHash(userId);
+
+        if (storedHash == null) {
+            return true;
         }
-        return true;
+
+        boolean matched = Arrays.equals(hash, storedHash);
+        if (matched && !TextUtils.isEmpty(pattern)) {
+            maybeUpdateKeystore(pattern, userId);
+        }
+        return matched;
     }
 
     @Override
     public boolean checkPassword(String password, int userId) throws RemoteException {
         checkPasswordReadPermission(userId);
 
-        try {
-            // Read all the bytes from the file
-            RandomAccessFile raf = new RandomAccessFile(getLockPasswordFilename(userId), "r");
-            final byte[] stored = new byte[(int) raf.length()];
-            int got = raf.read(stored, 0, stored.length);
-            raf.close();
-            if (got <= 0) {
-                return true;
-            }
-            // Compare the hash from the file with the entered password's hash
-            final byte[] hash = mLockPatternUtils.passwordToHash(password, userId);
-            final boolean matched = Arrays.equals(stored, hash);
-            if (matched && !TextUtils.isEmpty(password)) {
-                maybeUpdateKeystore(password, userId);
-            }
-            return matched;
-        } catch (FileNotFoundException fnfe) {
-            Slog.e(TAG, "Cannot read file " + fnfe);
-        } catch (IOException ioe) {
-            Slog.e(TAG, "Cannot read file " + ioe);
+        byte[] hash = mLockPatternUtils.passwordToHash(password, userId);
+        byte[] storedHash = mStorage.readPasswordHash(userId);
+
+        if (storedHash == null) {
+            return true;
         }
-        return true;
+
+        boolean matched = Arrays.equals(hash, storedHash);
+        if (matched && !TextUtils.isEmpty(password)) {
+            maybeUpdateKeystore(password, userId);
+        }
+        return matched;
     }
 
     @Override
-        public boolean checkVoldPassword(int userId) throws RemoteException {
+    public boolean checkVoldPassword(int userId) throws RemoteException {
         if (!mFirstCallToVold) {
             return false;
         }
@@ -512,166 +443,14 @@
     public void removeUser(int userId) {
         checkWritePermission(userId);
 
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        try {
-            final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
-            final UserInfo parentInfo = um.getProfileParent(userId);
-            if (parentInfo == null) {
-                // This user owns its lock settings files - safe to delete them
-                File file = new File(getLockPasswordFilename(userId));
-                if (file.exists()) {
-                    file.delete();
-                }
-                file = new File(getLockPatternFilename(userId));
-                if (file.exists()) {
-                    file.delete();
-                }
-            }
-
-            db.beginTransaction();
-            db.delete(TABLE, COLUMN_USERID + "='" + userId + "'", null);
-            db.setTransactionSuccessful();
-        } finally {
-            db.endTransaction();
-        }
+        mStorage.removeUser(userId);
+        notifyObservers(null /* key */, userId);
 
         final KeyStore ks = KeyStore.getInstance();
         final int userUid = UserHandle.getUid(userId, Process.SYSTEM_UID);
         ks.resetUid(userUid);
     }
 
-    private void writeFile(String name, byte[] hash) {
-        try {
-            // Write the hash to file
-            RandomAccessFile raf = new RandomAccessFile(name, "rw");
-            // Truncate the file if pattern is null, to clear the lock
-            if (hash == null || hash.length == 0) {
-                raf.setLength(0);
-            } else {
-                raf.write(hash, 0, hash.length);
-            }
-            raf.close();
-        } catch (IOException ioe) {
-            Slog.e(TAG, "Error writing to file " + ioe);
-        }
-    }
-
-    private void writeToDb(String key, String value, int userId) {
-        writeToDb(mOpenHelper.getWritableDatabase(), key, value, userId);
-        notifyObservers(key, userId);
-    }
-
-    private void writeToDb(SQLiteDatabase db, String key, String value, int userId) {
-        ContentValues cv = new ContentValues();
-        cv.put(COLUMN_KEY, key);
-        cv.put(COLUMN_USERID, userId);
-        cv.put(COLUMN_VALUE, value);
-
-        db.beginTransaction();
-        try {
-            db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?",
-                    new String[] {key, Integer.toString(userId)});
-            db.insert(TABLE, null, cv);
-            db.setTransactionSuccessful();
-        } finally {
-            db.endTransaction();
-        }
-    }
-
-    private String readFromDb(String key, String defaultValue, int userId) {
-        Cursor cursor;
-        String result = defaultValue;
-        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-        if ((cursor = db.query(TABLE, COLUMNS_FOR_QUERY,
-                COLUMN_USERID + "=? AND " + COLUMN_KEY + "=?",
-                new String[] { Integer.toString(userId), key },
-                null, null, null)) != null) {
-            if (cursor.moveToFirst()) {
-                result = cursor.getString(0);
-            }
-            cursor.close();
-        }
-        return result;
-    }
-
-    class DatabaseHelper extends SQLiteOpenHelper {
-        private static final String TAG = "LockSettingsDB";
-        private static final String DATABASE_NAME = "locksettings.db";
-
-        private static final int DATABASE_VERSION = 2;
-
-        public DatabaseHelper(Context context) {
-            super(context, DATABASE_NAME, null, DATABASE_VERSION);
-            setWriteAheadLoggingEnabled(true);
-        }
-
-        private void createTable(SQLiteDatabase db) {
-            db.execSQL("CREATE TABLE " + TABLE + " (" +
-                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
-                    COLUMN_KEY + " TEXT," +
-                    COLUMN_USERID + " INTEGER," +
-                    COLUMN_VALUE + " TEXT" +
-                    ");");
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            createTable(db);
-            initializeDefaults(db);
-        }
-
-        private void initializeDefaults(SQLiteDatabase db) {
-            // Get the lockscreen default from a system property, if available
-            boolean lockScreenDisable = SystemProperties.getBoolean("ro.lockscreen.disable.default",
-                    false);
-            if (lockScreenDisable) {
-                writeToDb(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0);
-            }
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
-            int upgradeVersion = oldVersion;
-            if (upgradeVersion == 1) {
-                // Set the initial value for {@link LockPatternUtils#LOCKSCREEN_WIDGETS_ENABLED}
-                // during upgrade based on whether each user previously had widgets in keyguard.
-                maybeEnableWidgetSettingForUsers(db);
-                upgradeVersion = 2;
-            }
-
-            if (upgradeVersion != DATABASE_VERSION) {
-                Log.w(TAG, "Failed to upgrade database!");
-            }
-        }
-
-        private void maybeEnableWidgetSettingForUsers(SQLiteDatabase db) {
-            final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
-            final ContentResolver cr = mContext.getContentResolver();
-            final List<UserInfo> users = um.getUsers();
-            for (int i = 0; i < users.size(); i++) {
-                final int userId = users.get(i).id;
-                final boolean enabled = mLockPatternUtils.hasWidgetsEnabledInKeyguard(userId);
-                Log.v(TAG, "Widget upgrade uid=" + userId + ", enabled="
-                        + enabled + ", w[]=" + mLockPatternUtils.getAppWidgets());
-                loadSetting(db, LockPatternUtils.LOCKSCREEN_WIDGETS_ENABLED, userId, enabled);
-            }
-        }
-
-        private void loadSetting(SQLiteDatabase db, String key, int userId, boolean value) {
-            SQLiteStatement stmt = null;
-            try {
-                stmt = db.compileStatement(
-                        "INSERT OR REPLACE INTO locksettings(name,user,value) VALUES(?,?,?);");
-                stmt.bindString(1, key);
-                stmt.bindLong(2, userId);
-                stmt.bindLong(3, value ? 1 : 0);
-                stmt.execute();
-            } finally {
-                if (stmt != null) stmt.close();
-            }
-        }
-    }
-
     private static final String[] VALID_SETTINGS = new String[] {
         LockPatternUtils.LOCKOUT_PERMANENT_KEY,
         LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
diff --git a/services/core/java/com/android/server/LockSettingsStorage.java b/services/core/java/com/android/server/LockSettingsStorage.java
new file mode 100644
index 0000000..acbf8ef
--- /dev/null
+++ b/services/core/java/com/android/server/LockSettingsStorage.java
@@ -0,0 +1,307 @@
+/*
+ * 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.server;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.os.Environment;
+import android.os.UserManager;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Slog;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import static android.content.Context.USER_SERVICE;
+
+/**
+ * Storage for the lock settings service.
+ */
+class LockSettingsStorage {
+
+    private static final String TAG = "LockSettingsStorage";
+    private static final String TABLE = "locksettings";
+
+    private static final String COLUMN_KEY = "name";
+    private static final String COLUMN_USERID = "user";
+    private static final String COLUMN_VALUE = "value";
+
+    private static final String[] COLUMNS_FOR_QUERY = {
+            COLUMN_VALUE
+    };
+
+    private static final String SYSTEM_DIRECTORY = "/system/";
+    private static final String LOCK_PATTERN_FILE = "gesture.key";
+    private static final String LOCK_PASSWORD_FILE = "password.key";
+
+    private final DatabaseHelper mOpenHelper;
+    private final Context mContext;
+    private final Object mFileWriteLock = new Object();
+
+    LockSettingsStorage(Context context, Callback callback) {
+        mContext = context;
+        mOpenHelper = new DatabaseHelper(context, callback);
+    }
+
+    void writeKeyValue(String key, String value, int userId) {
+        writeKeyValue(mOpenHelper.getWritableDatabase(), key, value, userId);
+    }
+
+    void writeKeyValue(SQLiteDatabase db, String key, String value, int userId) {
+        ContentValues cv = new ContentValues();
+        cv.put(COLUMN_KEY, key);
+        cv.put(COLUMN_USERID, userId);
+        cv.put(COLUMN_VALUE, value);
+
+        db.beginTransaction();
+        try {
+            db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?",
+                    new String[] {key, Integer.toString(userId)});
+            db.insert(TABLE, null, cv);
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+
+    }
+
+    String readKeyValue(String key, String defaultValue, int userId) {
+        Cursor cursor;
+        String result = defaultValue;
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        if ((cursor = db.query(TABLE, COLUMNS_FOR_QUERY,
+                COLUMN_USERID + "=? AND " + COLUMN_KEY + "=?",
+                new String[] { Integer.toString(userId), key },
+                null, null, null)) != null) {
+            if (cursor.moveToFirst()) {
+                result = cursor.getString(0);
+            }
+            cursor.close();
+        }
+        return result;
+    }
+
+    byte[] readPasswordHash(int userId) {
+        final byte[] stored = readFile(getLockPasswordFilename(userId), userId);
+        if (stored != null && stored.length > 0) {
+            return stored;
+        }
+        return null;
+    }
+
+    byte[] readPatternHash(int userId) {
+        final byte[] stored = readFile(getLockPatternFilename(userId), userId);
+        if (stored != null && stored.length > 0) {
+            return stored;
+        }
+        return null;
+    }
+
+    boolean hasPassword(int userId) {
+        return hasFile(getLockPasswordFilename(userId), userId);
+    }
+
+    boolean hasPattern(int userId) {
+        return hasFile(getLockPatternFilename(userId), userId);
+    }
+
+    private boolean hasFile(String name, int userId) {
+        byte[] contents = readFile(name, userId);
+        return contents != null && contents.length > 0;
+    }
+
+    private byte[] readFile(String name, int userId) {
+        RandomAccessFile raf = null;
+        byte[] stored = null;
+        try {
+            raf = new RandomAccessFile(name, "r");
+            stored = new byte[(int) raf.length()];
+            raf.readFully(stored, 0, stored.length);
+            raf.close();
+        } catch (IOException e) {
+            Slog.e(TAG, "Cannot read file " + e);
+        } finally {
+            if (raf != null) {
+                try {
+                    raf.close();
+                } catch (IOException e) {
+                    Slog.e(TAG, "Error closing file " + e);
+                }
+            }
+        }
+        return stored;
+    }
+
+    private void writeFile(String name, byte[] hash, int userId) {
+        synchronized (mFileWriteLock) {
+            RandomAccessFile raf = null;
+            try {
+                // Write the hash to file
+                raf = new RandomAccessFile(name, "rw");
+                // Truncate the file if pattern is null, to clear the lock
+                if (hash == null || hash.length == 0) {
+                    raf.setLength(0);
+                } else {
+                    raf.write(hash, 0, hash.length);
+                }
+                raf.close();
+            } catch (IOException e) {
+                Slog.e(TAG, "Error writing to file " + e);
+            } finally {
+                if (raf != null) {
+                    try {
+                        raf.close();
+                    } catch (IOException e) {
+                        Slog.e(TAG, "Error closing file " + e);
+                    }
+                }
+            }
+        }
+    }
+
+    public void writePatternHash(byte[] hash, int userId) {
+        writeFile(getLockPatternFilename(userId), hash, userId);
+    }
+
+    public void writePasswordHash(byte[] hash, int userId) {
+        writeFile(getLockPasswordFilename(userId), hash, userId);
+    }
+
+
+    private String getLockPatternFilename(int userId) {
+        String dataSystemDirectory =
+                android.os.Environment.getDataDirectory().getAbsolutePath() +
+                        SYSTEM_DIRECTORY;
+        userId = getUserParentOrSelfId(userId);
+        if (userId == 0) {
+            // Leave it in the same place for user 0
+            return dataSystemDirectory + LOCK_PATTERN_FILE;
+        } else {
+            return new File(Environment.getUserSystemDirectory(userId), LOCK_PATTERN_FILE)
+                    .getAbsolutePath();
+        }
+    }
+
+    private String getLockPasswordFilename(int userId) {
+        userId = getUserParentOrSelfId(userId);
+        String dataSystemDirectory =
+                android.os.Environment.getDataDirectory().getAbsolutePath() +
+                        SYSTEM_DIRECTORY;
+        if (userId == 0) {
+            // Leave it in the same place for user 0
+            return dataSystemDirectory + LOCK_PASSWORD_FILE;
+        } else {
+            return new File(Environment.getUserSystemDirectory(userId), LOCK_PASSWORD_FILE)
+                    .getAbsolutePath();
+        }
+    }
+
+    private int getUserParentOrSelfId(int userId) {
+        if (userId != 0) {
+            final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
+            final UserInfo pi = um.getProfileParent(userId);
+            if (pi != null) {
+                return pi.id;
+            }
+        }
+        return userId;
+    }
+
+
+    public void removeUser(int userId) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
+        final UserInfo parentInfo = um.getProfileParent(userId);
+
+        synchronized (mFileWriteLock) {
+            if (parentInfo == null) {
+                // This user owns its lock settings files - safe to delete them
+                File file = new File(getLockPasswordFilename(userId));
+                if (file.exists()) {
+                    file.delete();
+                }
+                file = new File(getLockPatternFilename(userId));
+                if (file.exists()) {
+                    file.delete();
+                }
+            }
+        }
+
+        try {
+            db.beginTransaction();
+            db.delete(TABLE, COLUMN_USERID + "='" + userId + "'", null);
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+
+    interface Callback {
+        void initialize(SQLiteDatabase db);
+    }
+
+    class DatabaseHelper extends SQLiteOpenHelper {
+        private static final String TAG = "LockSettingsDB";
+        private static final String DATABASE_NAME = "locksettings.db";
+
+        private static final int DATABASE_VERSION = 2;
+
+        private final Callback mCallback;
+
+        public DatabaseHelper(Context context, Callback callback) {
+            super(context, DATABASE_NAME, null, DATABASE_VERSION);
+            setWriteAheadLoggingEnabled(true);
+            mCallback = callback;
+        }
+
+        private void createTable(SQLiteDatabase db) {
+            db.execSQL("CREATE TABLE " + TABLE + " (" +
+                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
+                    COLUMN_KEY + " TEXT," +
+                    COLUMN_USERID + " INTEGER," +
+                    COLUMN_VALUE + " TEXT" +
+                    ");");
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            createTable(db);
+            mCallback.initialize(db);
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
+            int upgradeVersion = oldVersion;
+            if (upgradeVersion == 1) {
+                // Previously migrated lock screen widget settings. Now defunct.
+                upgradeVersion = 2;
+            }
+
+            if (upgradeVersion != DATABASE_VERSION) {
+                Log.w(TAG, "Failed to upgrade database!");
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java
index 6f378fd..de90aa2 100644
--- a/services/core/java/com/android/server/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/PersistentDataBlockService.java
@@ -72,7 +72,7 @@
     private final String mDataBlockFile;
     private final Object mLock = new Object();
 
-    private int mAllowedAppId = -1;
+    private int mAllowedUid = -1;
     /*
      * Separate lock for OEM unlock related operations as they can happen in parallel with regular
      * block operations.
@@ -86,11 +86,11 @@
         mContext = context;
         mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP);
         mBlockDeviceSize = -1; // Load lazily
-        mAllowedAppId = getAllowedAppId(UserHandle.USER_OWNER);
+        mAllowedUid = getAllowedUid(UserHandle.USER_OWNER);
     }
 
 
-    private int getAllowedAppId(int userHandle) {
+    private int getAllowedUid(int userHandle) {
         String allowedPackage = mContext.getResources()
                 .getString(R.string.config_persistentDataPackageName);
         PackageManager pm = mContext.getPackageManager();
@@ -101,7 +101,7 @@
             // not expected
             Slog.e(TAG, "not able to find package " + allowedPackage, e);
         }
-        return UserHandle.getAppId(allowedUid);
+        return allowedUid;
     }
 
     @Override
@@ -116,11 +116,17 @@
     }
 
     private void enforceUid(int callingUid) {
-        if (UserHandle.getAppId(callingUid) != mAllowedAppId) {
+        if (callingUid != mAllowedUid) {
             throw new SecurityException("uid " + callingUid + " not allowed to access PST");
         }
     }
 
+    private void enforceIsOwner() {
+        if (!Binder.getCallingUserHandle().isOwner()) {
+            throw new SecurityException("Only the Owner is allowed to change OEM unlock state");
+        }
+    }
+
     private int getTotalDataSizeLocked(DataInputStream inputStream) throws IOException {
         int totalDataSize;
         int blockId = inputStream.readInt();
@@ -249,6 +255,7 @@
                 return;
             }
             enforceOemUnlockPermission();
+            enforceIsOwner();
             FileOutputStream outputStream;
             try {
                 outputStream = new FileOutputStream(new File(mDataBlockFile));
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 9179cc4..91e2df0 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1836,8 +1836,8 @@
 
                     ComponentName cn = tr.intent.getComponent();
                     if (cn != null && cn.getPackageName().equals(packageName)) {
-                        // If the package name matches, remove the task and kill the process
-                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
+                        // If the package name matches, remove the task
+                        removeTaskByIdLocked(tr.taskId, true);
                     }
                 }
             }
@@ -1891,9 +1891,7 @@
             // Prune all the tasks with removed components from the list of recent tasks
             synchronized (ActivityManagerService.this) {
                 for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
-                    // Remove the task but don't kill the process (since other components in that
-                    // package may still be running and in the background)
-                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
+                    removeTaskByIdLocked(tasksToRemove.get(i), false);
                 }
             }
         }
@@ -4313,9 +4311,9 @@
                 boolean res;
                 if (finishTask && r == rootR) {
                     // If requested, remove the task that is associated to this activity only if it
-                    // was the root activity in the task.  The result code and data is ignored because
-                    // we don't support returning them across task boundaries.
-                    res = removeTaskByIdLocked(tr.taskId, 0);
+                    // was the root activity in the task. The result code and data is ignored
+                    // because we don't support returning them across task boundaries.
+                    res = removeTaskByIdLocked(tr.taskId, false);
                 } else {
                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
                             resultData, "app-request", true);
@@ -5142,7 +5140,7 @@
                             tr.getBaseIntent().getComponent().getPackageName();
                     if (tr.userId != userId) continue;
                     if (!taskPackageName.equals(packageName)) continue;
-                    removeTaskByIdLocked(tr.taskId, 0);
+                    removeTaskByIdLocked(tr.taskId, false);
                 }
             }
 
@@ -8287,52 +8285,65 @@
         return mTaskPersister.getTaskDescriptionIcon(filename);
     }
 
-    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
+    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
         mRecentTasks.remove(tr);
         tr.removedFromRecents(mTaskPersister);
-        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
-        Intent baseIntent = new Intent(
-                tr.intent != null ? tr.intent : tr.affinityIntent);
-        ComponentName component = baseIntent.getComponent();
+        ComponentName component = tr.getBaseIntent().getComponent();
         if (component == null) {
-            Slog.w(TAG, "Now component for base intent of task: " + tr);
+            Slog.w(TAG, "No component for base intent of task: " + tr);
             return;
         }
 
-        // Find any running services associated with this app.
-        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
+        if (!killProcess) {
+            return;
+        }
 
-        if (killProcesses) {
-            // Find any running processes associated with this app.
-            final String pkg = component.getPackageName();
-            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
-            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
-            for (int i=0; i<pmap.size(); i++) {
-                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
-                for (int j=0; j<uids.size(); j++) {
-                    ProcessRecord proc = uids.valueAt(j);
-                    if (proc.userId != tr.userId) {
-                        continue;
-                    }
-                    if (!proc.pkgList.containsKey(pkg)) {
-                        continue;
-                    }
-                    procs.add(proc);
+        // Determine if the process(es) for this task should be killed.
+        final String pkg = component.getPackageName();
+        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
+        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
+        for (int i = 0; i < pmap.size(); i++) {
+
+            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
+            for (int j = 0; j < uids.size(); j++) {
+                ProcessRecord proc = uids.valueAt(j);
+                if (proc.userId != tr.userId) {
+                    // Don't kill process for a different user.
+                    continue;
                 }
-            }
-
-            // Kill the running processes.
-            for (int i=0; i<procs.size(); i++) {
-                ProcessRecord pr = procs.get(i);
-                if (pr == mHomeProcess) {
+                if (proc == mHomeProcess) {
                     // Don't kill the home process along with tasks from the same package.
                     continue;
                 }
-                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
-                    pr.kill("remove task", true);
-                } else {
-                    pr.waitingToKill = "remove task";
+                if (!proc.pkgList.containsKey(pkg)) {
+                    // Don't kill process that is not associated with this task.
+                    continue;
                 }
+
+                for (int k = 0; k < proc.activities.size(); k++) {
+                    TaskRecord otherTask = proc.activities.get(k).task;
+                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
+                        // Don't kill process(es) that has an activity in a different task that is
+                        // also in recents.
+                        return;
+                    }
+                }
+
+                // Add process to kill list.
+                procsToKill.add(proc);
+            }
+        }
+
+        // Find any running services associated with this app and stop if needed.
+        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
+
+        // Kill the running processes.
+        for (int i = 0; i < procsToKill.size(); i++) {
+            ProcessRecord pr = procsToKill.get(i);
+            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
+                pr.kill("remove task", true);
+            } else {
+                pr.waitingToKill = "remove task";
             }
         }
     }
@@ -8341,15 +8352,14 @@
      * Removes the task with the specified task id.
      *
      * @param taskId Identifier of the task to be removed.
-     * @param flags Additional operational flags.  May be 0 or
-     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
+     * @param killProcess Kill any process associated with the task if possible.
      * @return Returns true if the given task was found and removed.
      */
-    private boolean removeTaskByIdLocked(int taskId, int flags) {
+    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
         TaskRecord tr = recentTaskForIdLocked(taskId);
         if (tr != null) {
             tr.removeTaskActivitiesLocked();
-            cleanUpRemovedTaskLocked(tr, flags);
+            cleanUpRemovedTaskLocked(tr, killProcess);
             if (tr.isPersistable) {
                 notifyTaskPersisterLocked(null, true);
             }
@@ -8359,19 +8369,19 @@
     }
 
     @Override
-    public boolean removeTask(int taskId, int flags) {
+    public boolean removeTask(int taskId) {
         synchronized (this) {
             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
                     "removeTask()");
             long ident = Binder.clearCallingIdentity();
             try {
-                return removeTaskByIdLocked(taskId, flags);
+                return removeTaskByIdLocked(taskId, true);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
         }
     }
-    
+
     /**
      * TODO: Add mController hook
      */
@@ -19167,16 +19177,9 @@
             synchronized (ActivityManagerService.this) {
                 long origId = Binder.clearCallingIdentity();
                 try {
-                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
-                    if (tr == null) {
+                    if (!removeTaskByIdLocked(mTaskId, false)) {
                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
                     }
-                    // Only kill the process if we are not a new document
-                    int flags = tr.getBaseIntent().getFlags();
-                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
-                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
-                    removeTaskByIdLocked(mTaskId,
-                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
                 } finally {
                     Binder.restoreCallingIdentity(origId);
                 }
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index e1b8278..b61bd8a 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -835,7 +835,7 @@
         prev.task.touchActiveTime();
         clearLaunchTime(prev);
         final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
-        if (mService.mHasRecents && (next == null || next.noDisplay || next.task != prev.task)) {
+        if (mService.mHasRecents && (next == null || next.noDisplay || next.task != prev.task || uiSleeping)) {
             prev.updateThumbnail(screenshotActivities(prev), null);
         }
         stopFullyDrawnTraceIfNeeded();
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 5b22255..843a0cb 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -235,22 +235,16 @@
             Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
         }
 
-        // We've now baked in the increase to the basic oom values above, since
-        // they seem to be useful more generally for devices that are tight on
-        // memory than just for 64 bit.  This should probably have some more
-        // tuning done, so not deleting it quite yet...
-        final boolean is64bit = false; //Build.SUPPORTED_64_BIT_ABIS.length > 0;
+        if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
+            // Increase the high min-free levels for cached processes for 64-bit
+            mOomMinFreeHigh[4] = 225000;
+            mOomMinFreeHigh[5] = 325000;
+        }
 
         for (int i=0; i<mOomAdj.length; i++) {
             int low = mOomMinFreeLow[i];
             int high = mOomMinFreeHigh[i];
             mOomMinFree[i] = (int)(low + ((high-low)*scale));
-            if (is64bit) {
-                // On 64 bit devices, we consume more baseline RAM, because 64 bit is cool!
-                // To avoid being all pagey and stuff, scale up the memory levels to
-                // give us some breathing room.
-                mOomMinFree[i] = (3*mOomMinFree[i])/2;
-            }
         }
 
         if (minfree_abs >= 0) {
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 238402f..debda14 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -191,8 +191,8 @@
         }
         try {
             if (add) {
-                mNetd.setPermission(CHANGE_NETWORK_STATE, toIntArray(network));
-                mNetd.setPermission(CONNECTIVITY_INTERNAL, toIntArray(system));
+                mNetd.setPermission("NETWORK", toIntArray(network));
+                mNetd.setPermission("SYSTEM", toIntArray(system));
             } else {
                 mNetd.clearPermission(toIntArray(network));
                 mNetd.clearPermission(toIntArray(system));
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 45d3771..d919bf6 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -21,7 +21,6 @@
 import com.android.server.twilight.TwilightManager;
 import com.android.server.twilight.TwilightState;
 
-import android.content.res.Resources;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
@@ -120,6 +119,7 @@
     // The minimum and maximum screen brightnesses.
     private final int mScreenBrightnessRangeMinimum;
     private final int mScreenBrightnessRangeMaximum;
+    private final float mDozeScaleFactor;
 
     // Amount of time to delay auto-brightness after screen on while waiting for
     // the light sensor to warm-up in milliseconds.
@@ -171,9 +171,12 @@
     // The last screen auto-brightness gamma.  (For printing in dump() only.)
     private float mLastScreenAutoBrightnessGamma = 1.0f;
 
+    // Are we going to adjust brightness while dozing.
+    private boolean mDozing;
+
     public AutomaticBrightnessController(Callbacks callbacks, Looper looper,
-            SensorManager sensorManager, Spline autoBrightnessSpline,
-            int lightSensorWarmUpTime, int brightnessMin, int brightnessMax) {
+            SensorManager sensorManager, Spline autoBrightnessSpline, int lightSensorWarmUpTime,
+            int brightnessMin, int brightnessMax, float dozeScaleFactor) {
         mCallbacks = callbacks;
         mTwilight = LocalServices.getService(TwilightManager.class);
         mSensorManager = sensorManager;
@@ -181,6 +184,7 @@
         mScreenBrightnessRangeMinimum = brightnessMin;
         mScreenBrightnessRangeMaximum = brightnessMax;
         mLightSensorWarmUpTimeConfig = lightSensorWarmUpTime;
+        mDozeScaleFactor = dozeScaleFactor;
 
         mHandler = new AutomaticBrightnessHandler(looper);
         mAmbientLightRingBuffer = new AmbientLightRingBuffer();
@@ -195,11 +199,20 @@
     }
 
     public int getAutomaticScreenBrightness() {
+        if (mDozing) {
+            return (int) (mScreenAutoBrightness * mDozeScaleFactor);
+        }
         return mScreenAutoBrightness;
     }
 
-    public void configure(boolean enable, float adjustment) {
-        boolean changed = setLightSensorEnabled(enable);
+    public void configure(boolean enable, float adjustment, boolean dozing) {
+        // While dozing, the application processor may be suspended which will prevent us from
+        // receiving new information from the light sensor. On some devices, we may be able to
+        // switch to a wake-up light sensor instead but for now we will simply disable the sensor
+        // and hold onto the last computed screen auto brightness.  We save the dozing flag for
+        // debugging purposes.
+        mDozing = dozing;
+        boolean changed = setLightSensorEnabled(enable && !dozing);
         changed |= setScreenAutoBrightnessAdjustment(adjustment);
         if (changed) {
             updateAutoBrightness(false /*sendUpdate*/);
@@ -230,6 +243,7 @@
         pw.println("  mScreenAutoBrightness=" + mScreenAutoBrightness);
         pw.println("  mScreenAutoBrightnessAdjustment=" + mScreenAutoBrightnessAdjustment);
         pw.println("  mLastScreenAutoBrightnessGamma=" + mLastScreenAutoBrightnessGamma);
+        pw.println("  mDozing=" + mDozing);
     }
 
     private boolean setLightSensorEnabled(boolean enable) {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 1d8003b..81cd94b 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -155,6 +155,9 @@
     // True if auto-brightness should be used.
     private boolean mUseSoftwareAutoBrightnessConfig;
 
+    // True if should use light sensor to automatically determine doze screen brightness.
+    private final boolean mAllowAutoBrightnessWhileDozingConfig;
+
     // True if we should fade the screen while turning it off, false if we should play
     // a stylish color fade animation instead.
     private boolean mColorFadeFadesConfig;
@@ -295,6 +298,10 @@
 
         mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
                 com.android.internal.R.bool.config_automatic_brightness_available);
+
+        mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
+                com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
+
         if (mUseSoftwareAutoBrightnessConfig) {
             int[] lux = resources.getIntArray(
                     com.android.internal.R.array.config_autoBrightnessLevels);
@@ -302,6 +309,9 @@
                     com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
             int lightSensorWarmUpTimeConfig = resources.getInteger(
                     com.android.internal.R.integer.config_lightSensorWarmupTime);
+            final float dozeScaleFactor = resources.getFraction(
+                    com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
+                    1, 1);
 
             Spline screenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
             if (screenAutoBrightnessSpline == null) {
@@ -326,7 +336,7 @@
                 mAutomaticBrightnessController = new AutomaticBrightnessController(this,
                         handler.getLooper(), sensorManager, screenAutoBrightnessSpline,
                         lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum,
-                        mScreenBrightnessRangeMaximum);
+                        mScreenBrightnessRangeMaximum, dozeScaleFactor);
             }
         }
 
@@ -523,7 +533,9 @@
                 } else {
                     state = Display.STATE_DOZE;
                 }
-                brightness = mPowerRequest.dozeScreenBrightness;
+                if (!mAllowAutoBrightnessWhileDozingConfig) {
+                    brightness = mPowerRequest.dozeScreenBrightness;
+                }
                 break;
             case DisplayPowerRequest.POLICY_DIM:
             case DisplayPowerRequest.POLICY_BRIGHT:
@@ -577,19 +589,16 @@
             brightness = PowerManager.BRIGHTNESS_ON;
         }
 
-        // Use default brightness when dozing unless overridden.
-        if (brightness < 0 && (state == Display.STATE_DOZE
-                || state == Display.STATE_DOZE_SUSPEND)) {
-            brightness = mScreenBrightnessDozeConfig;
-        }
-
         // Configure auto-brightness.
         boolean autoBrightnessEnabled = false;
         if (mAutomaticBrightnessController != null) {
+            final boolean autoBrightnessEnabledInDoze = mAllowAutoBrightnessWhileDozingConfig
+                    && (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND);
             autoBrightnessEnabled = mPowerRequest.useAutoBrightness
-                    && state == Display.STATE_ON && brightness < 0;
+                    && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
+                    && brightness < 0;
             mAutomaticBrightnessController.configure(autoBrightnessEnabled,
-                    mPowerRequest.screenAutoBrightnessAdjustment);
+                    mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON);
         }
 
         // Apply auto-brightness.
@@ -612,6 +621,12 @@
             mAppliedAutoBrightness = false;
         }
 
+        // Use default brightness when dozing unless overridden.
+        if (brightness < 0 && (state == Display.STATE_DOZE
+                || state == Display.STATE_DOZE_SUSPEND)) {
+            brightness = mScreenBrightnessDozeConfig;
+        }
+
         // Apply manual brightness.
         // Use the current brightness setting from the request, which is expected
         // provide a nominal default value for the case where auto-brightness
@@ -1024,6 +1039,8 @@
         pw.println("  mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
         pw.println("  mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
         pw.println("  mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig);
+        pw.println("  mAllowAutoBrightnessWhileDozingConfig=" +
+                mAllowAutoBrightnessWhileDozingConfig);
         pw.println("  mColorFadeFadesConfig=" + mColorFadeFadesConfig);
 
         mHandler.runWithScissors(new Runnable() {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 6bae761..f0f7973 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -1029,6 +1029,7 @@
             OneTouchRecordAction action = actions.get(0);
             if (action.getRecorderAddress() != message.getSource()) {
                 announceOneTouchRecordResult(
+                        message.getSource(),
                         HdmiControlManager.ONE_TOUCH_RECORD_PREVIOUS_RECORDING_IN_PROGRESS);
             }
             return super.handleRecordTvScreen(message);
@@ -1047,20 +1048,20 @@
     protected boolean handleTimerClearedStatus(HdmiCecMessage message) {
         byte[] params = message.getParams();
         int timerClearedStatusData = params[0] & 0xFF;
-        announceTimerRecordingResult(timerClearedStatusData);
+        announceTimerRecordingResult(message.getSource(), timerClearedStatusData);
         return true;
     }
 
-    void announceOneTouchRecordResult(int result) {
-        mService.invokeOneTouchRecordResult(result);
+    void announceOneTouchRecordResult(int recorderAddress, int result) {
+        mService.invokeOneTouchRecordResult(recorderAddress, result);
     }
 
-    void announceTimerRecordingResult(int result) {
-        mService.invokeTimerRecordingResult(result);
+    void announceTimerRecordingResult(int recorderAddress, int result) {
+        mService.invokeTimerRecordingResult(recorderAddress, result);
     }
 
-    void announceClearTimerRecordingResult(int result) {
-        mService.invokeClearTimerRecordingResult(result);
+    void announceClearTimerRecordingResult(int recorderAddress, int result) {
+        mService.invokeClearTimerRecordingResult(recorderAddress, result);
     }
 
     private boolean isMessageForSystemAudio(HdmiCecMessage message) {
@@ -1528,19 +1529,21 @@
         assertRunOnServiceThread();
         if (!mService.isControlEnabled()) {
             Slog.w(TAG, "Can not start one touch record. CEC control is disabled.");
-            announceOneTouchRecordResult(ONE_TOUCH_RECORD_CEC_DISABLED);
+            announceOneTouchRecordResult(recorderAddress, ONE_TOUCH_RECORD_CEC_DISABLED);
             return Constants.ABORT_NOT_IN_CORRECT_MODE;
         }
 
         if (!checkRecorder(recorderAddress)) {
             Slog.w(TAG, "Invalid recorder address:" + recorderAddress);
-            announceOneTouchRecordResult(ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
+            announceOneTouchRecordResult(recorderAddress,
+                    ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
             return Constants.ABORT_NOT_IN_CORRECT_MODE;
         }
 
         if (!checkRecordSource(recordSource)) {
             Slog.w(TAG, "Invalid record source." + Arrays.toString(recordSource));
-            announceOneTouchRecordResult(ONE_TOUCH_RECORD_FAIL_TO_RECORD_DISPLAYED_SCREEN);
+            announceOneTouchRecordResult(recorderAddress,
+                    ONE_TOUCH_RECORD_FAIL_TO_RECORD_DISPLAYED_SCREEN);
             return Constants.ABORT_UNABLE_TO_DETERMINE;
         }
 
@@ -1555,13 +1558,14 @@
         assertRunOnServiceThread();
         if (!mService.isControlEnabled()) {
             Slog.w(TAG, "Can not stop one touch record. CEC control is disabled.");
-            announceOneTouchRecordResult(ONE_TOUCH_RECORD_CEC_DISABLED);
+            announceOneTouchRecordResult(recorderAddress, ONE_TOUCH_RECORD_CEC_DISABLED);
             return;
         }
 
         if (!checkRecorder(recorderAddress)) {
             Slog.w(TAG, "Invalid recorder address:" + recorderAddress);
-            announceOneTouchRecordResult(ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
+            announceOneTouchRecordResult(recorderAddress,
+                    ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
             return;
         }
 
@@ -1587,13 +1591,14 @@
         assertRunOnServiceThread();
         if (!mService.isControlEnabled()) {
             Slog.w(TAG, "Can not start one touch record. CEC control is disabled.");
-            announceTimerRecordingResult(TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED);
+            announceTimerRecordingResult(recorderAddress,
+                    TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED);
             return;
         }
 
         if (!checkRecorder(recorderAddress)) {
             Slog.w(TAG, "Invalid recorder address:" + recorderAddress);
-            announceTimerRecordingResult(
+            announceTimerRecordingResult(recorderAddress,
                     TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
             return;
         }
@@ -1601,6 +1606,7 @@
         if (!checkTimerRecordingSource(sourceType, recordSource)) {
             Slog.w(TAG, "Invalid record source." + Arrays.toString(recordSource));
             announceTimerRecordingResult(
+                    recorderAddress,
                     TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE);
             return;
         }
@@ -1621,26 +1627,29 @@
         assertRunOnServiceThread();
         if (!mService.isControlEnabled()) {
             Slog.w(TAG, "Can not start one touch record. CEC control is disabled.");
-            announceClearTimerRecordingResult(CLEAR_TIMER_STATUS_CEC_DISABLE);
+            announceClearTimerRecordingResult(recorderAddress, CLEAR_TIMER_STATUS_CEC_DISABLE);
             return;
         }
 
         if (!checkRecorder(recorderAddress)) {
             Slog.w(TAG, "Invalid recorder address:" + recorderAddress);
-            announceClearTimerRecordingResult(CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION);
+            announceClearTimerRecordingResult(recorderAddress,
+                    CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION);
             return;
         }
 
         if (!checkTimerRecordingSource(sourceType, recordSource)) {
             Slog.w(TAG, "Invalid record source." + Arrays.toString(recordSource));
-            announceClearTimerRecordingResult(CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
+            announceClearTimerRecordingResult(recorderAddress,
+                    CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
             return;
         }
 
         sendClearTimerMessage(recorderAddress, sourceType, recordSource);
     }
 
-    private void sendClearTimerMessage(int recorderAddress, int sourceType, byte[] recordSource) {
+    private void sendClearTimerMessage(final int recorderAddress, int sourceType,
+            byte[] recordSource) {
         HdmiCecMessage message = null;
         switch (sourceType) {
             case TIMER_RECORDING_TYPE_DIGITAL:
@@ -1657,7 +1666,8 @@
                 break;
             default:
                 Slog.w(TAG, "Invalid source type:" + recorderAddress);
-                announceClearTimerRecordingResult(CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
+                announceClearTimerRecordingResult(recorderAddress,
+                        CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
                 return;
 
         }
@@ -1665,7 +1675,7 @@
             @Override
             public void onSendCompleted(int error) {
                 if (error != Constants.SEND_RESULT_SUCCESS) {
-                    announceClearTimerRecordingResult(
+                    announceClearTimerRecordingResult(recorderAddress,
                             CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
                 }
             }
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index aeb21db..d8d513e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -1661,11 +1661,11 @@
         }
     }
 
-    void invokeOneTouchRecordResult(int result) {
+    void invokeOneTouchRecordResult(int recorderAddress, int result) {
         synchronized (mLock) {
             if (mRecordListenerRecord != null) {
                 try {
-                    mRecordListenerRecord.mListener.onOneTouchRecordResult(result);
+                    mRecordListenerRecord.mListener.onOneTouchRecordResult(recorderAddress, result);
                 } catch (RemoteException e) {
                     Slog.w(TAG, "Failed to call onOneTouchRecordResult.", e);
                 }
@@ -1673,11 +1673,11 @@
         }
     }
 
-    void invokeTimerRecordingResult(int result) {
+    void invokeTimerRecordingResult(int recorderAddress, int result) {
         synchronized (mLock) {
             if (mRecordListenerRecord != null) {
                 try {
-                    mRecordListenerRecord.mListener.onTimerRecordingResult(result);
+                    mRecordListenerRecord.mListener.onTimerRecordingResult(recorderAddress, result);
                 } catch (RemoteException e) {
                     Slog.w(TAG, "Failed to call onTimerRecordingResult.", e);
                 }
@@ -1685,11 +1685,12 @@
         }
     }
 
-    void invokeClearTimerRecordingResult(int result) {
+    void invokeClearTimerRecordingResult(int recorderAddress, int result) {
         synchronized (mLock) {
             if (mRecordListenerRecord != null) {
                 try {
-                    mRecordListenerRecord.mListener.onClearTimerRecordingResult(result);
+                    mRecordListenerRecord.mListener.onClearTimerRecordingResult(recorderAddress,
+                            result);
                 } catch (RemoteException e) {
                     Slog.w(TAG, "Failed to call onClearTimerRecordingResult.", e);
                 }
diff --git a/services/core/java/com/android/server/hdmi/OneTouchRecordAction.java b/services/core/java/com/android/server/hdmi/OneTouchRecordAction.java
index 906944b..d80b81f6 100644
--- a/services/core/java/com/android/server/hdmi/OneTouchRecordAction.java
+++ b/services/core/java/com/android/server/hdmi/OneTouchRecordAction.java
@@ -64,6 +64,7 @@
                         // if failed to send <Record On>, display error message and finish action.
                         if (error != Constants.SEND_RESULT_SUCCESS) {
                             tv().announceOneTouchRecordResult(
+                                    mRecorderAddress,
                                     ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
                             finish();
                             return;
@@ -94,7 +95,7 @@
         }
 
         int recordStatus = cmd.getParams()[0];
-        tv().announceOneTouchRecordResult(recordStatus);
+        tv().announceOneTouchRecordResult(mRecorderAddress, recordStatus);
         Slog.i(TAG, "Got record status:" + recordStatus + " from " + cmd.getSource());
 
         // If recording started successfully, change state and keep this action until <Record Off>
@@ -121,7 +122,8 @@
             return;
         }
 
-        tv().announceOneTouchRecordResult(ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
+        tv().announceOneTouchRecordResult(mRecorderAddress,
+                ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
         finish();
     }
 
diff --git a/services/core/java/com/android/server/hdmi/TimerRecordingAction.java b/services/core/java/com/android/server/hdmi/TimerRecordingAction.java
index 5fcbc91..16fc25f 100644
--- a/services/core/java/com/android/server/hdmi/TimerRecordingAction.java
+++ b/services/core/java/com/android/server/hdmi/TimerRecordingAction.java
@@ -74,7 +74,7 @@
                         mRecorderAddress, mRecordSource);
                 break;
             default:
-                tv().announceTimerRecordingResult(
+                tv().announceTimerRecordingResult(mRecorderAddress,
                         TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE);
                 finish();
                 return;
@@ -83,7 +83,7 @@
             @Override
             public void onSendCompleted(int error) {
                 if (error != Constants.SEND_RESULT_SUCCESS) {
-                    tv().announceTimerRecordingResult(
+                    tv().announceTimerRecordingResult(mRecorderAddress,
                             TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
                     finish();
                     return;
@@ -114,7 +114,7 @@
         byte[] timerStatusData = cmd.getParams();
         // [Timer Status Data] should be one or three bytes.
         if (timerStatusData.length == 1 || timerStatusData.length == 3) {
-            tv().announceTimerRecordingResult(bytesToInt(timerStatusData));
+            tv().announceTimerRecordingResult(mRecorderAddress, bytesToInt(timerStatusData));
             Slog.i(TAG, "Received [Timer Status Data]:" + Arrays.toString(timerStatusData));
         } else {
             Slog.w(TAG, "Invalid [Timer Status Data]:" + Arrays.toString(timerStatusData));
@@ -138,7 +138,8 @@
         }
         int reason = params[1] & 0xFF;
         Slog.i(TAG, "[Feature Abort] for " + messageType + " reason:" + reason);
-        tv().announceTimerRecordingResult(TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
+        tv().announceTimerRecordingResult(mRecorderAddress,
+                TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
         finish();
         return true;
     }
@@ -163,7 +164,8 @@
             return;
         }
 
-        tv().announceTimerRecordingResult(TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
+        tv().announceTimerRecordingResult(mRecorderAddress,
+                TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
         finish();
     }
 }
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index 05ad1fe..fc7b5a9 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -52,6 +52,7 @@
     private final ArrayList<ConditionRecord> mRecords = new ArrayList<ConditionRecord>();
     private final CountdownConditionProvider mCountdown = new CountdownConditionProvider();
     private final DowntimeConditionProvider mDowntime = new DowntimeConditionProvider();
+    private final NextAlarmConditionProvider mNextAlarm = new NextAlarmConditionProvider();
 
     private Condition mExitCondition;
     private ComponentName mExitConditionComponent;
@@ -99,6 +100,7 @@
         }
         mCountdown.dump(pw, filter);
         mDowntime.dump(pw, filter);
+        mNextAlarm.dump(pw, filter);
     }
 
     @Override
@@ -116,6 +118,23 @@
         registerService(mDowntime.asInterface(), DowntimeConditionProvider.COMPONENT,
                 UserHandle.USER_OWNER);
         mDowntime.setCallback(new DowntimeCallback());
+        mNextAlarm.attachBase(mContext);
+        registerService(mNextAlarm.asInterface(), NextAlarmConditionProvider.COMPONENT,
+                UserHandle.USER_OWNER);
+        mNextAlarm.setCallback(new NextAlarmConditionProvider.Callback() {
+            @Override
+            public boolean isInDowntime() {
+                return mDowntime.isInDowntime();
+            }
+        });
+    }
+
+    @Override
+    public void onUserSwitched() {
+        super.onUserSwitched();
+        if (mNextAlarm != null) {
+            mNextAlarm.onUserSwitched();
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/notification/DowntimeConditionProvider.java b/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
index efe47c3..2a4b718 100644
--- a/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
+++ b/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
@@ -158,7 +158,8 @@
         final long time = getTime(System.currentTimeMillis(), downtime.endHour, downtime.endMinute);
         final String formatted = new SimpleDateFormat(pattern, locale).format(new Date(time));
         final String summary = mContext.getString(R.string.downtime_condition_summary, formatted);
-        return new Condition(id, summary, "", "", 0, state, Condition.FLAG_RELEVANT_NOW);
+        final String line1 = mContext.getString(R.string.downtime_condition_line_one);
+        return new Condition(id, summary, line1, formatted, 0, state, Condition.FLAG_RELEVANT_NOW);
     }
 
     public boolean isDowntimeCondition(Condition condition) {
diff --git a/services/core/java/com/android/server/notification/NextAlarmConditionProvider.java b/services/core/java/com/android/server/notification/NextAlarmConditionProvider.java
new file mode 100644
index 0000000..dba203b
--- /dev/null
+++ b/services/core/java/com/android/server/notification/NextAlarmConditionProvider.java
@@ -0,0 +1,318 @@
+/*
+ * 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.server.notification;
+
+import android.app.ActivityManager;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.app.AlarmManager.AlarmClockInfo;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.service.notification.Condition;
+import android.service.notification.ConditionProviderService;
+import android.service.notification.IConditionProvider;
+import android.service.notification.ZenModeConfig;
+import android.util.TimeUtils;
+import android.text.format.DateFormat;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.R;
+import com.android.server.notification.NotificationManagerService.DumpFilter;
+
+import java.io.PrintWriter;
+import java.util.Locale;
+
+/** Built-in zen condition provider for alarm clock conditions */
+public class NextAlarmConditionProvider extends ConditionProviderService {
+    private static final String TAG = "NextAlarmConditions";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private static final String ACTION_TRIGGER = TAG + ".trigger";
+    private static final String EXTRA_TRIGGER = "trigger";
+    private static final int REQUEST_CODE = 100;
+    private static final long SECONDS = 1000;
+    private static final long HOURS = 60 * 60 * SECONDS;
+    private static final long NEXT_ALARM_UPDATE_DELAY = 1 * SECONDS;  // treat clear+set as update
+    private static final long EARLY = 5 * SECONDS;  // fire early, ensure alarm stream is unmuted
+    private static final String NEXT_ALARM_PATH = "next_alarm";
+    public static final ComponentName COMPONENT =
+            new ComponentName("android", NextAlarmConditionProvider.class.getName());
+
+    private final Context mContext = this;
+    private final H mHandler = new H();
+
+    private boolean mConnected;
+    private boolean mRegistered;
+    private AlarmManager mAlarmManager;
+    private int mCurrentUserId;
+    private long mLookaheadThreshold;
+    private long mScheduledAlarmTime;
+    private Callback mCallback;
+    private Uri mCurrentSubscription;
+    private PowerManager.WakeLock mWakeLock;
+
+    public NextAlarmConditionProvider() {
+        if (DEBUG) Slog.d(TAG, "new NextAlarmConditionProvider()");
+    }
+
+    public void dump(PrintWriter pw, DumpFilter filter) {
+        pw.println("    NextAlarmConditionProvider:");
+        pw.print("      mConnected="); pw.println(mConnected);
+        pw.print("      mRegistered="); pw.println(mRegistered);
+        pw.print("      mCurrentUserId="); pw.println(mCurrentUserId);
+        pw.print("      mScheduledAlarmTime="); pw.println(formatAlarmDebug(mScheduledAlarmTime));
+        pw.print("      mLookaheadThreshold="); pw.print(mLookaheadThreshold);
+        pw.print(" ("); TimeUtils.formatDuration(mLookaheadThreshold, pw); pw.println(")");
+        pw.print("      mCurrentSubscription="); pw.println(mCurrentSubscription);
+        pw.print("      mWakeLock="); pw.println(mWakeLock);
+    }
+
+    public void setCallback(Callback callback) {
+        mCallback = callback;
+    }
+
+    @Override
+    public void onConnected() {
+        if (DEBUG) Slog.d(TAG, "onConnected");
+        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+        final PowerManager p = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        mWakeLock = p.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+        mLookaheadThreshold = mContext.getResources()
+                .getInteger(R.integer.config_next_alarm_condition_lookahead_threshold_hrs) * HOURS;
+        init();
+        mConnected = true;
+    }
+
+    public void onUserSwitched() {
+        if (DEBUG) Slog.d(TAG, "onUserSwitched");
+        if (mConnected) {
+            init();
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (DEBUG) Slog.d(TAG, "onDestroy");
+        if (mConnected) {
+            mContext.unregisterReceiver(mReceiver);
+        }
+        mConnected = false;
+    }
+
+    @Override
+    public void onRequestConditions(int relevance) {
+        if (!mConnected || (relevance & Condition.FLAG_RELEVANT_NOW) == 0) return;
+
+        final AlarmClockInfo nextAlarm = mAlarmManager.getNextAlarmClock(mCurrentUserId);
+        if (nextAlarm == null) return;  // no next alarm
+        if (mCallback != null && mCallback.isInDowntime()) return;  // prefer downtime condition
+        if (!isWithinLookaheadThreshold(nextAlarm)) return;  // alarm not within window
+
+        // next alarm exists, and is within the configured lookahead threshold
+        notifyCondition(newConditionId(), nextAlarm, true, "request");
+    }
+
+    private boolean isWithinLookaheadThreshold(AlarmClockInfo alarm) {
+        if (alarm == null) return false;
+        final long delta = getEarlyTriggerTime(alarm) - System.currentTimeMillis();
+        return delta > 0 && (mLookaheadThreshold <= 0 || delta < mLookaheadThreshold);
+    }
+
+    @Override
+    public void onSubscribe(Uri conditionId) {
+        if (DEBUG) Slog.d(TAG, "onSubscribe " + conditionId);
+        if (!isNextAlarmCondition(conditionId)) {
+            notifyCondition(conditionId, null, false, "badCondition");
+            return;
+        }
+        mCurrentSubscription = conditionId;
+        mHandler.postEvaluate(0);
+    }
+
+    private static long getEarlyTriggerTime(AlarmClockInfo alarm) {
+        return alarm != null ? (alarm.getTriggerTime() - EARLY) : 0;
+    }
+
+    private void handleEvaluate() {
+        final AlarmClockInfo nextAlarm = mAlarmManager.getNextAlarmClock(mCurrentUserId);
+        final long triggerTime = getEarlyTriggerTime(nextAlarm);
+        final boolean withinThreshold = isWithinLookaheadThreshold(nextAlarm);
+        if (DEBUG) Slog.d(TAG, "handleEvaluate mCurrentSubscription=" + mCurrentSubscription
+                + " nextAlarm=" + formatAlarmDebug(triggerTime)
+                + " withinThreshold=" + withinThreshold);
+        if (mCurrentSubscription == null) return;  // no one cares
+        if (!withinThreshold) {
+            // triggertime invalid or in the past, condition = false
+            notifyCondition(mCurrentSubscription, nextAlarm, false, "!withinThreshold");
+            mCurrentSubscription = null;
+            return;
+        }
+        // triggertime in the future, condition = true, schedule alarm
+        notifyCondition(mCurrentSubscription, nextAlarm, true, "withinThreshold");
+        rescheduleAlarm(triggerTime);
+    }
+
+    private static String formatDuration(long millis) {
+        final StringBuilder sb = new StringBuilder();
+        TimeUtils.formatDuration(millis, sb);
+        return sb.toString();
+    }
+
+    private void rescheduleAlarm(long time) {
+        if (DEBUG) Slog.d(TAG, "rescheduleAlarm " + time);
+        final AlarmManager alarms = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+        final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, REQUEST_CODE,
+                new Intent(ACTION_TRIGGER)
+                        .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
+                        .putExtra(EXTRA_TRIGGER, time),
+                PendingIntent.FLAG_UPDATE_CURRENT);
+        alarms.cancel(pendingIntent);
+        mScheduledAlarmTime = time;
+        if (time > 0) {
+            if (DEBUG) Slog.d(TAG, String.format("Scheduling alarm for %s (in %s)",
+                    formatAlarmDebug(time), formatDuration(time - System.currentTimeMillis())));
+            alarms.setExact(AlarmManager.RTC_WAKEUP, time, pendingIntent);
+        }
+    }
+
+    private void notifyCondition(Uri id, AlarmClockInfo alarm, boolean state, String reason) {
+        final String formattedAlarm = alarm == null ? "" : formatAlarm(alarm.getTriggerTime());
+        if (DEBUG) Slog.d(TAG, "notifyCondition " + state + " alarm=" + formattedAlarm + " reason="
+                + reason);
+        notifyCondition(new Condition(id,
+                mContext.getString(R.string.zen_mode_next_alarm_summary, formattedAlarm),
+                mContext.getString(R.string.zen_mode_next_alarm_line_one),
+                formattedAlarm, 0,
+                state ? Condition.STATE_TRUE : Condition.STATE_FALSE,
+                Condition.FLAG_RELEVANT_NOW));
+    }
+
+    @Override
+    public void onUnsubscribe(Uri conditionId) {
+        if (DEBUG) Slog.d(TAG, "onUnsubscribe " + conditionId);
+        if (conditionId != null && conditionId.equals(mCurrentSubscription)) {
+            mCurrentSubscription = null;
+            rescheduleAlarm(0);
+        }
+    }
+
+    public void attachBase(Context base) {
+        attachBaseContext(base);
+    }
+
+    public IConditionProvider asInterface() {
+        return (IConditionProvider) onBind(null);
+    }
+
+    private Uri newConditionId() {
+        return new Uri.Builder().scheme(Condition.SCHEME)
+                .authority(ZenModeConfig.SYSTEM_AUTHORITY)
+                .appendPath(NEXT_ALARM_PATH)
+                .appendPath(Integer.toString(mCurrentUserId))
+                .build();
+    }
+
+    private boolean isNextAlarmCondition(Uri conditionId) {
+        return conditionId != null && conditionId.getScheme().equals(Condition.SCHEME)
+                && conditionId.getAuthority().equals(ZenModeConfig.SYSTEM_AUTHORITY)
+                && conditionId.getPathSegments().size() == 2
+                && conditionId.getPathSegments().get(0).equals(NEXT_ALARM_PATH)
+                && conditionId.getPathSegments().get(1).equals(Integer.toString(mCurrentUserId));
+    }
+
+    private void init() {
+        if (mRegistered) {
+            mContext.unregisterReceiver(mReceiver);
+        }
+        mCurrentUserId = ActivityManager.getCurrentUser();
+        final IntentFilter filter = new IntentFilter();
+        filter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
+        filter.addAction(ACTION_TRIGGER);
+        filter.addAction(Intent.ACTION_TIME_CHANGED);
+        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
+        mContext.registerReceiverAsUser(mReceiver, new UserHandle(mCurrentUserId), filter, null,
+                null);
+        mRegistered = true;
+        mHandler.postEvaluate(0);
+    }
+
+    private String formatAlarm(long time) {
+        return formatAlarm(time, "Hm", "hma");
+    }
+
+    private String formatAlarm(long time, String skeleton24, String skeleton12) {
+        final String skeleton = DateFormat.is24HourFormat(mContext) ? skeleton24 : skeleton12;
+        final String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
+        return DateFormat.format(pattern, time).toString();
+    }
+
+    private String formatAlarmDebug(AlarmClockInfo alarm) {
+        return formatAlarmDebug(alarm != null ? alarm.getTriggerTime() : 0);
+    }
+
+    private String formatAlarmDebug(long time) {
+        if (time <= 0) return Long.toString(time);
+        return String.format("%s (%s)", time, formatAlarm(time, "Hms", "hmsa"));
+    }
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            if (DEBUG) Slog.d(TAG, "onReceive " + action);
+            long delay = 0;
+            if (action.equals(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED)) {
+                delay = NEXT_ALARM_UPDATE_DELAY;
+                if (DEBUG) Slog.d(TAG, String.format("  next alarm for user %s: %s",
+                        mCurrentUserId,
+                        formatAlarmDebug(mAlarmManager.getNextAlarmClock(mCurrentUserId))));
+            }
+            mHandler.postEvaluate(delay);
+            mWakeLock.acquire(delay + 5000);  // stay awake during evaluate
+        }
+    };
+
+    public interface Callback {
+        boolean isInDowntime();
+    }
+
+    private class H extends Handler {
+        private static final int MSG_EVALUATE = 1;
+
+        public void postEvaluate(long delay) {
+            removeMessages(MSG_EVALUATE);
+            sendEmptyMessageDelayed(MSG_EVALUATE, delay);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            if (msg.what == MSG_EVALUATE) {
+                handleEvaluate();
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 61ea1e8..8d93141 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -91,6 +91,9 @@
     boolean mKeyguardGoingAwayToNotificationShade;
     boolean mKeyguardGoingAwayDisableWindowAnimations;
 
+    /** Use one animation for all entering activities after keyguard is dismissed. */
+    Animation mPostKeyguardExitAnimation;
+
     // forceHiding states.
     static final int KEYGUARD_NOT_SHOWN     = 0;
     static final int KEYGUARD_ANIMATING_IN  = 1;
@@ -220,9 +223,6 @@
         ++mAnimTransactionSequence;
 
         final WindowList windows = mService.getWindowListLocked(displayId);
-        ArrayList<WindowStateAnimator> unForceHiding = null;
-        boolean wallpaperInUnForceHiding = false;
-        WindowState wallpaper = null;
 
         if (mKeyguardGoingAway) {
             for (int i = windows.size() - 1; i >= 0; i--) {
@@ -261,6 +261,9 @@
         final AppWindowToken appShowWhenLocked = winShowWhenLocked == null ?
                 null : winShowWhenLocked.mAppToken;
 
+        boolean wallpaperInUnForceHiding = false;
+        ArrayList<WindowStateAnimator> unForceHiding = null;
+        WindowState wallpaper = null;
         for (int i = windows.size() - 1; i >= 0; i--) {
             WindowState win = windows.get(i);
             WindowStateAnimator winAnimator = win.mWinAnimator;
@@ -327,40 +330,53 @@
                 } else if (mPolicy.canBeForceHidden(win, win.mAttrs)) {
                     final boolean hideWhenLocked = !((win.mIsImWindow && showImeOverKeyguard) ||
                             (appShowWhenLocked != null && appShowWhenLocked == win.mAppToken));
-                    final boolean changed;
                     if (((mForceHiding == KEYGUARD_ANIMATING_IN)
                                 && (!winAnimator.isAnimating() || hideWhenLocked))
                             || ((mForceHiding == KEYGUARD_SHOWN) && hideWhenLocked)) {
-                        changed = win.hideLw(false, false);
-                        if ((DEBUG_KEYGUARD || WindowManagerService.DEBUG_VISIBILITY)
-                                && changed) Slog.v(TAG, "Now policy hidden: " + win);
+                        if (!win.hideLw(false, false)) {
+                            // Was already hidden
+                            continue;
+                        }
+                        if (DEBUG_KEYGUARD || WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
+                                "Now policy hidden: " + win);
                     } else {
-                        changed = win.showLw(false, false);
-                        if ((DEBUG_KEYGUARD || WindowManagerService.DEBUG_VISIBILITY)
-                                && changed) Slog.v(TAG, "Now policy shown: " + win);
-                        if (changed) {
-                            if ((mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0
-                                    && win.isVisibleNow() /*w.isReadyForDisplay()*/) {
-                                if (unForceHiding == null) {
-                                    unForceHiding = new ArrayList<WindowStateAnimator>();
-                                }
-                                unForceHiding.add(winAnimator);
-                                if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
-                                    wallpaperInUnForceHiding = true;
-                                }
+                        if (!win.showLw(false, false)) {
+                            // Was already showing.
+                            continue;
+                        }
+                        final boolean visibleNow = win.isVisibleNow();
+                        if (!visibleNow) {
+                            // Couldn't really show, must showLw() again when win becomes visible.
+                            win.hideLw(false, false);
+                            continue;
+                        }
+                        if (DEBUG_KEYGUARD || WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
+                                "Now policy shown: " + win);
+                        if ((mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
+                            if (unForceHiding == null) {
+                                unForceHiding = new ArrayList<>();
                             }
-                            final WindowState currentFocus = mService.mCurrentFocus;
-                            if (currentFocus == null || currentFocus.mLayer < win.mLayer) {
-                                // We are showing on to of the current
-                                // focus, so re-evaluate focus to make
-                                // sure it is correct.
-                                if (WindowManagerService.DEBUG_FOCUS_LIGHT) Slog.v(TAG,
-                                        "updateWindowsLocked: setting mFocusMayChange true");
-                                mService.mFocusMayChange = true;
+                            unForceHiding.add(winAnimator);
+                            if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
+                                wallpaperInUnForceHiding = true;
                             }
+                        } else if (mPostKeyguardExitAnimation != null) {
+                            // We're already in the middle of an animation. Use the existing
+                            // animation to bring in this window.
+                            winAnimator.setAnimation(mPostKeyguardExitAnimation);
+                            winAnimator.keyguardGoingAwayAnimation = true;
+                        }
+                        final WindowState currentFocus = mService.mCurrentFocus;
+                        if (currentFocus == null || currentFocus.mLayer < win.mLayer) {
+                            // We are showing on top of the current
+                            // focus, so re-evaluate focus to make
+                            // sure it is correct.
+                            if (WindowManagerService.DEBUG_FOCUS_LIGHT) Slog.v(TAG,
+                                    "updateWindowsLocked: setting mFocusMayChange true");
+                            mService.mFocusMayChange = true;
                         }
                     }
-                    if (changed && (flags & FLAG_SHOW_WALLPAPER) != 0) {
+                    if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
                         mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
                         setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
@@ -403,42 +419,44 @@
         // If we have windows that are being show due to them no longer
         // being force-hidden, apply the appropriate animation to them.
         if (unForceHiding != null) {
-            boolean startKeyguardExit = true;
-            for (int i=unForceHiding.size()-1; i>=0; i--) {
-                Animation a = null;
-                if (!mKeyguardGoingAwayDisableWindowAnimations) {
-                    a = mPolicy.createForceHideEnterAnimation(wallpaperInUnForceHiding,
-                            mKeyguardGoingAwayToNotificationShade);
-                    if (DEBUG_KEYGUARD) Slog.d(TAG, "updateWindowsLocked: created anim=" + a
-                            + " for win=" + unForceHiding.get(i));
-                } else {
-                    if (DEBUG_KEYGUARD) Slog.d(TAG, "updateWindowsLocked: skipping anim for win="
-                            + unForceHiding.get(i));
-                }
-                if (a != null) {
+            // This only happens the first time that we detect the keyguard is animating out.
+            if (mKeyguardGoingAwayDisableWindowAnimations) {
+                if (DEBUG_KEYGUARD) Slog.d(TAG, "updateWindowsLocked: skipping anim for windows");
+            } else {
+                if (DEBUG_KEYGUARD) Slog.d(TAG, "updateWindowsLocked: created anim for windows");
+                mPostKeyguardExitAnimation = mPolicy.createForceHideEnterAnimation(
+                        wallpaperInUnForceHiding, mKeyguardGoingAwayToNotificationShade);
+            }
+            if (mPostKeyguardExitAnimation != null) {
+                for (int i=unForceHiding.size()-1; i>=0; i--) {
                     final WindowStateAnimator winAnimator = unForceHiding.get(i);
-                    winAnimator.setAnimation(a);
+                    winAnimator.setAnimation(mPostKeyguardExitAnimation);
                     winAnimator.keyguardGoingAwayAnimation = true;
-                    if (startKeyguardExit && mKeyguardGoingAway) {
-                        // Do one time only.
-                        mPolicy.startKeyguardExitAnimation(mCurrentTime + a.getStartOffset(),
-                                a.getDuration());
-                        mKeyguardGoingAway = false;
-                        startKeyguardExit = false;
-                    }
                 }
             }
+        }
 
-            // Wallpaper is going away in un-force-hide motion, animate it as well.
-            if (!wallpaperInUnForceHiding && wallpaper != null
-                    && !mKeyguardGoingAwayDisableWindowAnimations) {
-                if (DEBUG_KEYGUARD) Slog.d(TAG, "updateWindowsLocked: wallpaper animating away");
-                Animation a = mPolicy.createForceHideWallpaperExitAnimation(
-                        mKeyguardGoingAwayToNotificationShade);
-                if (a != null) {
-                    WindowStateAnimator animator = wallpaper.mWinAnimator;
-                    animator.setAnimation(a);
-                }
+        if (mPostKeyguardExitAnimation != null) {
+            // We're in the midst of a keyguard exit animation.
+            if (mKeyguardGoingAway) {
+                mPolicy.startKeyguardExitAnimation(mCurrentTime +
+                        mPostKeyguardExitAnimation.getStartOffset(),
+                        mPostKeyguardExitAnimation.getDuration());
+                mKeyguardGoingAway = false;
+            } else if (mPostKeyguardExitAnimation.hasEnded()) {
+                // Done with the animation, reset.
+                mPostKeyguardExitAnimation = null;
+            }
+        }
+
+        // Wallpaper is going away in un-force-hide motion, animate it as well.
+        if (!wallpaperInUnForceHiding && wallpaper != null
+                && !mKeyguardGoingAwayDisableWindowAnimations) {
+            if (DEBUG_KEYGUARD) Slog.d(TAG, "updateWindowsLocked: wallpaper animating away");
+            Animation a = mPolicy.createForceHideWallpaperExitAnimation(
+                    mKeyguardGoingAwayToNotificationShade);
+            if (a != null) {
+                wallpaper.mWinAnimator.setAnimation(a);
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b4e2778..ccb5bfc 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -9783,7 +9783,7 @@
                                     if (!w.isDrawnLw()) {
                                         Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl
                                                 + " pv=" + w.mPolicyVisibility
-                                                + " mDrawState=" + winAnimator.mDrawState
+                                                + " mDrawState=" + winAnimator.drawStateToString()
                                                 + " ah=" + w.mAttachedHidden
                                                 + " th=" + atoken.hiddenRequested
                                                 + " a=" + winAnimator.mAnimating);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index fc3f2c2..e7c235f 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -167,14 +167,14 @@
     private static final int SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN =
             View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
 
-    static String drawStateToString(int state) {
-        switch (state) {
+    String drawStateToString() {
+        switch (mDrawState) {
             case NO_SURFACE: return "NO_SURFACE";
             case DRAW_PENDING: return "DRAW_PENDING";
             case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING";
             case READY_TO_SHOW: return "READY_TO_SHOW";
             case HAS_DRAWN: return "HAS_DRAWN";
-            default: return Integer.toString(state);
+            default: return Integer.toString(mDrawState);
         }
     }
     int mDrawState;
@@ -489,7 +489,7 @@
         if (DEBUG_STARTING_WINDOW &&
                 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
             Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
-                    + drawStateToString(mDrawState));
+                    + drawStateToString());
         }
         if (mDrawState == DRAW_PENDING) {
             if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
@@ -510,18 +510,17 @@
         if (DEBUG_STARTING_WINDOW &&
                 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
             Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
-                    + drawStateToString(mDrawState));
+                    + drawStateToString());
         }
-        if (mDrawState != COMMIT_DRAW_PENDING) {
+        if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) {
             return false;
         }
         if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) {
             Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurfaceControl);
         }
         mDrawState = READY_TO_SHOW;
-        final boolean starting = mWin.mAttrs.type == TYPE_APPLICATION_STARTING;
         final AppWindowToken atoken = mWin.mAppToken;
-        if (atoken == null || atoken.allDrawn || starting) {
+        if (atoken == null || atoken.allDrawn || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
             performShowLocked();
         }
         return true;
@@ -1868,7 +1867,7 @@
             if (dumpAll) {
                 pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl);
                 pw.print(prefix); pw.print("mDrawState=");
-                pw.print(drawStateToString(mDrawState));
+                pw.print(drawStateToString());
                 pw.print(" mLastHidden="); pw.println(mLastHidden);
             }
             pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
index 11da380..098b3ef 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
@@ -119,6 +119,7 @@
                 if (!files.valueAt(start).getBaseFile().getName().endsWith("-c")) {
                     break;
                 }
+                start++;
             }
 
             if (start == fileCount - 1) {
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 9bdbba8..34d0660 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -974,6 +974,15 @@
     public void onDisconnect() {}
 
     /**
+     * Notifies this Connection of a request to disconnect a participant of the conference managed
+     * by the connection.
+     *
+     * @param endpoint the {@link Uri} of the participant to disconnect.
+     * @hide
+     */
+    public void onDisconnectConferenceParticipant(Uri endpoint) {}
+
+    /**
      * Notifies this Connection of a request to separate from its parent conference.
      */
     public void onSeparate() {}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 4eac5ac..d98a255 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -17,6 +17,7 @@
 import android.annotation.SystemApi;
 import android.content.ComponentName;
 import android.content.Context;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -926,7 +927,6 @@
      * @param accountHandle The handle for the account the MMI code should apply to.
      * @param dialString The digits to dial.
      * @return True if the digits were processed as an MMI code, false otherwise.
-     *
      */
     public boolean handleMmi(PhoneAccountHandle accountHandle, String dialString) {
         ITelecomService service = getTelecomService();
@@ -941,6 +941,24 @@
     }
 
     /**
+     * @param accountHandle The handle for the account to derive an adn query URI for or
+     * {@code null} to return a URI which will use the default account.
+     * @return The URI (with the content:// scheme) specific to the specified {@link PhoneAccount}
+     * for the the content retrieve.
+     */
+    public Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle) {
+        ITelecomService service = getTelecomService();
+        if (service != null && accountHandle != null) {
+            try {
+                return service.getAdnUriForPhoneAccount(accountHandle);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error calling ITelecomService#getAdnUriForPhoneAccount", e);
+            }
+        }
+        return Uri.parse("content://icc/adn");
+    }
+
+    /**
      * Removes the missed-call notification if one is present.
      * <p>
      * Requires that the method-caller be set as the system dialer app.
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index fd47213..cbd9d69 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -18,6 +18,7 @@
 
 import android.content.ComponentName;
 import android.telecom.PhoneAccountHandle;
+import android.net.Uri;
 import android.os.Bundle;
 import android.telecom.PhoneAccount;
 
@@ -174,6 +175,11 @@
     boolean handlePinMmiForPhoneAccount(in PhoneAccountHandle accountHandle, String dialString);
 
     /**
+     * @see TelecomServiceImpl#getAdnUriForPhoneAccount
+     */
+    Uri getAdnUriForPhoneAccount(in PhoneAccountHandle accountHandle);
+
+    /**
      * @see TelecomServiceImpl#isTtySupported
      */
     boolean isTtySupported();
diff --git a/telephony/java/android/telephony/SubInfoRecord.java b/telephony/java/android/telephony/SubInfoRecord.java
index 4a3d67e..e08f255 100644
--- a/telephony/java/android/telephony/SubInfoRecord.java
+++ b/telephony/java/android/telephony/SubInfoRecord.java
@@ -29,98 +29,138 @@
      * Subscription Identifier, this is a device unique number
      * and not an index into an array
      */
-    public int subId;
-    /** The GID for a SIM that maybe associated with this subscription, empty if unknown */
-    public String iccId;
+    private int mId;
+
     /**
-     * The slot identifier for that currently contains the subscription
+     * The GID for a SIM that maybe associated with this subscription, empty if unknown
+     */
+    private String mIccId;
+
+    /**
+     * The index of the slot that currently contains the subscription
      * and not necessarily unique and maybe INVALID_SLOT_ID if unknown
      */
-    public int slotId;
+    private int mSimSlotIndex;
+
     /**
-     * The string displayed to the user that identifies this subscription
+     * The name displayed to the user that identifies this subscription
      */
-    public String displayName;
+    private CharSequence mDisplayName;
+
     /**
      * The source of the name, NAME_SOURCE_UNDEFINED, NAME_SOURCE_DEFAULT_SOURCE,
      * NAME_SOURCE_SIM_SOURCE or NAME_SOURCE_USER_INPUT.
      */
-    public int nameSource;
+    private int mNameSource;
+
     /**
      * The color to be used for when displaying to the user
      */
-    public int color;
+    private int mColor;
+
     /**
      * A number presented to the user identify this subscription
      */
-    public String number;
-    /**
-     * How to display the phone number, DISPLAY_NUMBER_NONE, DISPLAY_NUMBER_FIRST,
-     * DISPLAY_NUMBER_LAST
-     */
-    public int displayNumberFormat;
+    private String mNumber;
+
     /**
      * Data roaming state, DATA_RAOMING_ENABLE, DATA_RAOMING_DISABLE
      */
-    public int dataRoaming;
+    private int mDataRoaming;
+
     /**
      * SIM Icon resource identifiers. FIXME: Check with MTK what it really is
      */
-    public int[] simIconRes;
+    private int[] mSimIconRes;
+
     /**
      * Mobile Country Code
      */
-    public int mcc;
+    private int mMcc;
+
     /**
      * Mobile Network Code
      */
-    public int mnc;
+    private int mMnc;
 
+    /**
+     * @hide
     public SubInfoRecord() {
-        this.subId = SubscriptionManager.INVALID_SUB_ID;
-        this.iccId = "";
-        this.slotId = SubscriptionManager.INVALID_SLOT_ID;
-        this.displayName = "";
-        this.nameSource = 0;
-        this.color = 0;
-        this.number = "";
-        this.displayNumberFormat = 0;
-        this.dataRoaming = 0;
-        this.simIconRes = new int[2];
-        this.mcc = 0;
-        this.mnc = 0;
+        this.mId = SubscriptionManager.INVALID_SUB_ID;
+        this.mIccId = "";
+        this.mSimSlotIndex = SubscriptionManager.INVALID_SLOT_ID;
+        this.mDisplayName = "";
+        this.mNameSource = 0;
+        this.mColor = 0;
+        this.mNumber = "";
+        this.mDataRoaming = 0;
+        this.mSimIconRes = new int[2];
+        this.mMcc = 0;
+        this.mMnc = 0;
     }
+     */
 
-    public SubInfoRecord(int subId, String iccId, int slotId, String displayName, int nameSource,
-            int color, String number, int displayFormat, int roaming, int[] iconRes,
-            int mcc, int mnc) {
-        this.subId = subId;
-        this.iccId = iccId;
-        this.slotId = slotId;
-        this.displayName = displayName;
-        this.nameSource = nameSource;
-        this.color = color;
-        this.number = number;
-        this.displayNumberFormat = displayFormat;
-        this.dataRoaming = roaming;
-        this.simIconRes = iconRes;
-        this.mcc = mcc;
-        this.mnc = mnc;
+    /**
+     * @hide
+     */
+    public SubInfoRecord(int id, String iccId, int simSlotIndex, CharSequence displayName,
+            int nameSource, int color, String number, int roaming, int[] iconRes, int mcc,
+            int mnc) {
+        this.mId = id;
+        this.mIccId = iccId;
+        this.mSimSlotIndex = simSlotIndex;
+        this.mDisplayName = displayName;
+        this.mNameSource = nameSource;
+        this.mColor = color;
+        this.mNumber = number;
+        this.mDataRoaming = roaming;
+        this.mSimIconRes = iconRes;
+        this.mMcc = mcc;
+        this.mMnc = mnc;
     }
 
     /**
-     * Returns the string displayed to the user that identifies this subscription
+     * Returns the subscription ID.
      */
-    public String getLabel() {
-        return this.displayName;
+    public int getSubscriptionId() {
+        return this.mId;
     }
 
     /**
-     * Return the icon used to identify this SIM.
-     * TODO: return the correct drawable.
+     * Returns the ICC ID.
      */
-    public BitmapDrawable getIconDrawable() {
-        return new BitmapDrawable();
+    public String getIccId() {
+        return this.mIccId;
+    }
+
+    /**
+     * Returns the slot index of this Subscription's SIM card.
+     */
+    public int getSimSlotIndex() {
+        return this.mSimSlotIndex;
+    }
+
+    /**
+     * Returns the name displayed to the user that identifies this subscription
+     */
+    public CharSequence getDisplayName() {
+        return this.mDisplayName;
+    }
+
+    /**
+     * Sets the name displayed to the user that identifies this subscription
+     * @hide
+     */
+    public void setDisplayName(CharSequence name) {
+        this.mDisplayName = name;
+    }
+
+    /**
+     * Return the source of the name, eg NAME_SOURCE_UNDEFINED, NAME_SOURCE_DEFAULT_SOURCE,
+     * NAME_SOURCE_SIM_SOURCE or NAME_SOURCE_USER_INPUT.
+     */
+    public int getNameSource() {
+        return this.mNameSource;
     }
 
     /**
@@ -130,28 +170,70 @@
     public int getColor() {
         // Note: This color is currently an index into a list of drawables, but this is soon to
         // change.
-        return this.color;
+        return this.mColor;
+    }
+
+    /**
+     * Sets the color displayed to the user that identifies this subscription
+     * @hide
+     */
+    public void setColor(int color) {
+        this.mColor = color;
+    }
+
+    /**
+     * Returns the number of this subscription.
+     */
+    public String getNumber() {
+        return mNumber;
+    }
+
+    /**
+     * Return the data roaming value.
+     */
+    public int getDataRoaming() {
+        return this.mDataRoaming;
+    }
+
+    /**
+     * Return the icon used to identify this subscription.
+     */
+    public BitmapDrawable getIcon() {
+        return new BitmapDrawable();
+    }
+
+    /**
+     * Returns the MCC.
+     */
+    public int getMcc() {
+        return this.mMcc;
+    }
+
+    /**
+     * Returns the MNC.
+     */
+    public int getMnc() {
+        return this.mMnc;
     }
 
     public static final Parcelable.Creator<SubInfoRecord> CREATOR = new Parcelable.Creator<SubInfoRecord>() {
         @Override
         public SubInfoRecord createFromParcel(Parcel source) {
-            int subId = source.readInt();
+            int id = source.readInt();
             String iccId = source.readString();
-            int slotId = source.readInt();
-            String displayName = source.readString();
+            int simSlotIndex = source.readInt();
+            CharSequence displayName = source.readCharSequence();
             int nameSource = source.readInt();
             int color = source.readInt();
             String number = source.readString();
-            int displayNumberFormat = source.readInt();
             int dataRoaming = source.readInt();
             int[] iconRes = new int[2];
             source.readIntArray(iconRes);
             int mcc = source.readInt();
             int mnc = source.readInt();
 
-            return new SubInfoRecord(subId, iccId, slotId, displayName, nameSource, color, number,
-                displayNumberFormat, dataRoaming, iconRes, mcc, mnc);
+            return new SubInfoRecord(id, iccId, simSlotIndex, displayName, nameSource, color, number,
+                    dataRoaming, iconRes, mcc, mnc);
         }
 
         @Override
@@ -162,18 +244,17 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(subId);
-        dest.writeString(iccId);
-        dest.writeInt(slotId);
-        dest.writeString(displayName);
-        dest.writeInt(nameSource);
-        dest.writeInt(color);
-        dest.writeString(number);
-        dest.writeInt(displayNumberFormat);
-        dest.writeInt(dataRoaming);
-        dest.writeIntArray(simIconRes);
-        dest.writeInt(mcc);
-        dest.writeInt(mnc);
+        dest.writeInt(mId);
+        dest.writeString(mIccId);
+        dest.writeInt(mSimSlotIndex);
+        dest.writeCharSequence(mDisplayName);
+        dest.writeInt(mNameSource);
+        dest.writeInt(mColor);
+        dest.writeString(mNumber.toString());
+        dest.writeInt(mDataRoaming);
+        dest.writeIntArray(mSimIconRes);
+        dest.writeInt(mMcc);
+        dest.writeInt(mMnc);
     }
 
     @Override
@@ -183,10 +264,9 @@
 
     @Override
     public String toString() {
-        return "{mSubId=" + subId + ", mIccId=" + iccId + " mSlotId=" + slotId
-                + " mDisplayName=" + displayName + " mNameSource=" + nameSource
-                + " mColor=" + color + " mNumber=" + number
-                + " mDisplayNumberFormat=" + displayNumberFormat + " mDataRoaming=" + dataRoaming
-                + " mSimIconRes=" + simIconRes + " mMcc " + mcc + " mMnc " + mnc + "}";
+        return "{id=" + mId + ", iccId=" + mIccId + " simSlotIndex=" + mSimSlotIndex
+                + " displayName=" + mDisplayName + " nameSource=" + mNameSource + " color=" + mColor
+                + " number=" + mNumber + " dataRoaming=" + mDataRoaming + " simIconRes=" + mSimIconRes
+                + " mcc " + mMcc + " mnc " + mMnc + "}";
     }
 }
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index edfddc7..9cd533d 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -209,7 +209,7 @@
     public static final int DISPLAY_NUMBER_LAST = 2;
 
     /** @hide */
-    public static final int DISLPAY_NUMBER_DEFAULT = DISPLAY_NUMBER_FIRST;
+    public static final int DISPLAY_NUMBER_DEFAULT = DISPLAY_NUMBER_FIRST;
 
     /**
      * TelephonyProvider column name for permission for data roaming of a SIM.
diff --git a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
index 6837d22..94874c8 100644
--- a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
+++ b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
@@ -127,7 +127,7 @@
             @Override
             public boolean onLongClick(View v) {
                 if (task.id >= 0 && thumbs != null) {
-                    mAm.removeTask(task.id, ActivityManager.REMOVE_TASK_KILL_PROCESS);
+                    mAm.removeTask(task.id);
                     buildUi();
                     return true;
                 }
diff --git a/tools/layoutlib/bridge/src/android/view/WindowCallback.java b/tools/layoutlib/bridge/src/android/view/WindowCallback.java
new file mode 100644
index 0000000..78242a8
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/view/WindowCallback.java
@@ -0,0 +1,131 @@
+/*
+ * 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.view;
+
+import android.view.ActionMode.Callback;
+import android.view.WindowManager.LayoutParams;
+import android.view.accessibility.AccessibilityEvent;
+
+/**
+ * An empty implementation of {@link Window.Callback} that always returns null/false.
+ */
+public class WindowCallback implements Window.Callback {
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        return false;
+    }
+
+    @Override
+    public boolean dispatchKeyShortcutEvent(KeyEvent event) {
+        return false;
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent event) {
+        return false;
+    }
+
+    @Override
+    public boolean dispatchTrackballEvent(MotionEvent event) {
+        return false;
+    }
+
+    @Override
+    public boolean dispatchGenericMotionEvent(MotionEvent event) {
+        return false;
+    }
+
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        return false;
+    }
+
+    @Override
+    public View onCreatePanelView(int featureId) {
+        return null;
+    }
+
+    @Override
+    public boolean onCreatePanelMenu(int featureId, Menu menu) {
+        return false;
+    }
+
+    @Override
+    public boolean onPreparePanel(int featureId, View view, Menu menu) {
+        return false;
+    }
+
+    @Override
+    public boolean onMenuOpened(int featureId, Menu menu) {
+        return false;
+    }
+
+    @Override
+    public boolean onMenuItemSelected(int featureId, MenuItem item) {
+        return false;
+    }
+
+    @Override
+    public void onWindowAttributesChanged(LayoutParams attrs) {
+
+    }
+
+    @Override
+    public void onContentChanged() {
+
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasFocus) {
+
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+
+    }
+
+    @Override
+    public void onPanelClosed(int featureId, Menu menu) {
+
+    }
+
+    @Override
+    public boolean onSearchRequested() {
+        return false;
+    }
+
+    @Override
+    public ActionMode onWindowStartingActionMode(Callback callback) {
+        return null;
+    }
+
+    @Override
+    public void onActionModeStarted(ActionMode mode) {
+
+    }
+
+    @Override
+    public void onActionModeFinished(ActionMode mode) {
+
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/widget/Toolbar_Accessor.java b/tools/layoutlib/bridge/src/android/widget/Toolbar_Accessor.java
new file mode 100644
index 0000000..fdd1779
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/widget/Toolbar_Accessor.java
@@ -0,0 +1,32 @@
+/*
+ * 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.widget;
+
+import android.content.Context;
+
+/**
+ * To access non public members of classes in {@link Toolbar}
+ */
+public class Toolbar_Accessor {
+    public static ActionMenuPresenter getActionMenuPresenter(Toolbar toolbar) {
+        return toolbar.getOuterActionMenuPresenter();
+    }
+
+    public static Context getPopupContext(Toolbar toolbar) {
+        return toolbar.getPopupContext();
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 825731b..ec78712 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -19,6 +19,7 @@
 import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
 import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
 
+import com.android.annotations.NonNull;
 import com.android.ide.common.rendering.api.Capability;
 import com.android.ide.common.rendering.api.DrawableParams;
 import com.android.ide.common.rendering.api.LayoutLog;
@@ -459,7 +460,7 @@
 
     public static void setLog(LayoutLog log) {
         // check only the thread currently owning the lock can do this.
-        if (sLock.isHeldByCurrentThread() == false) {
+        if (!sLock.isHeldByCurrentThread()) {
             throw new IllegalStateException("scene must be acquired first. see #acquire(long)");
         }
 
@@ -489,7 +490,6 @@
 
     /**
      * Returns the name of a framework resource whose value is an int array.
-     * @param array
      */
     public static String resolveResourceId(int[] array) {
         sIntArrayWrapper.set(array);
@@ -502,6 +502,7 @@
      * @param name the name of the resource.
      * @return an {@link Integer} containing the resource id, or null if no resource were found.
      */
+    @NonNull
     public static Integer getResourceId(ResourceType type, String name) {
         Map<String, Integer> map = sRevRMap.get(type);
         Integer value = null;
@@ -509,11 +510,8 @@
             value = map.get(name);
         }
 
-        if (value == null) {
-            value = sDynamicIds.getId(type, name);
-        }
+        return value == null ? sDynamicIds.getId(type, name) : value;
 
-        return value;
     }
 
     /**
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index d804230..3d3afa4 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -52,7 +52,6 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
-import android.content.res.TypedArray;
 import android.database.DatabaseErrorHandler;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteDatabase.CursorFactory;
@@ -127,7 +126,6 @@
      * @param metrics the {@link DisplayMetrics}.
      * @param renderResources the configured resources (both framework and projects) for this
      * render.
-     * @param projectCallback
      * @param config the Configuration object for this render.
      * @param targetSdkVersion the targetSdkVersion of the application.
      */
@@ -331,7 +329,7 @@
             boolean attachToRoot, boolean skipCallbackParser) {
         boolean isPlatformLayout = resource.isFramework();
 
-        if (isPlatformLayout == false && skipCallbackParser == false) {
+        if (!isPlatformLayout && !skipCallbackParser) {
             // check if the project callback can provide us with a custom parser.
             ILayoutPullParser parser = getParser(resource);
 
@@ -663,7 +661,7 @@
                 }
 
                 String attrName = attribute.getFirst();
-                boolean frameworkAttr = attribute.getSecond().booleanValue();
+                boolean frameworkAttr = attribute.getSecond();
                 String value = null;
                 if (set != null) {
                     value = set.getAttributeValue(
@@ -672,7 +670,7 @@
 
                     // if this is an app attribute, and the first get fails, try with the
                     // new res-auto namespace as well
-                    if (frameworkAttr == false && value == null) {
+                    if (!frameworkAttr && value == null) {
                         value = set.getAttributeValue(BridgeConstants.NS_APP_RES_AUTO, attrName);
                     }
                 }
@@ -789,13 +787,13 @@
         List<Pair<String, Boolean>> results = new ArrayList<Pair<String, Boolean>>(attrs.length);
 
         // for each attribute, get its name so that we can search it in the style
-        for (int i = 0 ; i < attrs.length ; i++) {
-            Pair<ResourceType, String> resolvedResource = Bridge.resolveResourceId(attrs[i]);
+        for (int attr : attrs) {
+            Pair<ResourceType, String> resolvedResource = Bridge.resolveResourceId(attr);
             boolean isFramework = false;
             if (resolvedResource != null) {
                 isFramework = true;
             } else {
-                resolvedResource = mProjectCallback.resolveResourceId(attrs[i]);
+                resolvedResource = mProjectCallback.resolveResourceId(attr);
             }
 
             if (resolvedResource != null) {
@@ -841,7 +839,7 @@
 
         if (id == null) {
             // generate a new id
-            id = Integer.valueOf(++mDynamicIdGenerator);
+            id = ++mDynamicIdGenerator;
 
             // and add it to the maps.
             mDynamicIdToStyleMap.put(id, resValue);
@@ -860,19 +858,24 @@
     }
 
     public int getFrameworkResourceValue(ResourceType resType, String resName, int defValue) {
-        Integer value = Bridge.getResourceId(resType, resName);
-        if (value != null) {
-            return value.intValue();
+        if (getRenderResources().getFrameworkResource(resType, resName) != null) {
+            // Bridge.getResourceId creates a new resource id if an existing one isn't found. So,
+            // we check for the existence of the resource before calling it.
+            return Bridge.getResourceId(resType, resName);
         }
 
         return defValue;
     }
 
     public int getProjectResourceValue(ResourceType resType, String resName, int defValue) {
-        if (mProjectCallback != null) {
-            Integer value = mProjectCallback.getResourceId(resType, resName);
-            if (value != null) {
-                return value.intValue();
+        // getResourceId creates a new resource id if an existing resource id isn't found. So, we
+        // check for the existence of the resource before calling it.
+        if (getRenderResources().getProjectResource(resType, resName) != null) {
+            if (mProjectCallback != null) {
+                Integer value = mProjectCallback.getResourceId(resType, resName);
+                if (value != null) {
+                    return value;
+                }
             }
         }
 
@@ -1455,9 +1458,6 @@
         return null;
     }
 
-    /**
-     * @hide
-     */
     @Override
     public int getUserId() {
         return 0; // not used
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
index d95c815..57fd68e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
@@ -18,36 +18,24 @@
 
 import com.android.annotations.NonNull;
 import com.android.annotations.Nullable;
-import com.android.ide.common.rendering.api.ActionBarCallback;
-import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle;
-import com.android.ide.common.rendering.api.RenderResources;
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.ide.common.rendering.api.SessionParams;
 import com.android.internal.R;
-import com.android.internal.app.WindowDecorActionBar;
 import com.android.internal.view.menu.MenuBuilder;
 import com.android.internal.view.menu.MenuItemImpl;
-import com.android.internal.widget.ActionBarAccessor;
-import com.android.internal.widget.ActionBarContainer;
-import com.android.internal.widget.ActionBarView;
 import com.android.layoutlib.bridge.android.BridgeContext;
 import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.resources.ResourceType;
 
-import android.app.ActionBar;
-import android.app.ActionBar.Tab;
-import android.app.ActionBar.TabListener;
-import android.app.FragmentTransaction;
 import android.content.Context;
 import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
 import android.util.DisplayMetrics;
 import android.util.TypedValue;
-import android.view.Gravity;
 import android.view.LayoutInflater;
-import android.view.MenuInflater;
 import android.view.View;
+import android.view.View.MeasureSpec;
 import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.ActionMenuPresenter;
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 import android.widget.ListAdapter;
@@ -56,172 +44,72 @@
 
 import java.util.ArrayList;
 
-/**
- * A layout representing the action bar.
- */
-public class ActionBarLayout extends LinearLayout {
+public class ActionBarLayout {
+
+    private static final String LAYOUT_ATTR_NAME = "windowActionBarFullscreenDecorLayout";
+
+    // The Action Bar
+    @NonNull private CustomActionBarWrapper mActionBar;
 
     // Store another reference to the context so that we don't have to cast it repeatedly.
     @NonNull private final BridgeContext mBridgeContext;
-    @NonNull private final Context mThemedContext;
 
-    @NonNull private final ActionBar mActionBar;
-
-    // Data for Action Bar.
-    @Nullable private final String mIcon;
-    @Nullable private final String mTitle;
-    @Nullable private final String mSubTitle;
-    private final boolean mSplit;
-    private final boolean mShowHomeAsUp;
-    private final int mNavMode;
-
-    // Helper fields.
-    @NonNull private final MenuBuilder mMenuBuilder;
-    private final int mPopupMaxWidth;
-    @NonNull private final RenderResources res;
-    @Nullable private final ActionBarView mActionBarView;
-    @Nullable private FrameLayout mContentRoot;
-    @NonNull private final ActionBarCallback mCallback;
+    @NonNull private FrameLayout mContentRoot;
 
     // A fake parent for measuring views.
     @Nullable private ViewGroup mMeasureParent;
 
-    public ActionBarLayout(@NonNull BridgeContext context, @NonNull SessionParams params) {
+    /**
+     * Inflate the action bar and attach it to {@code parentView}
+     */
+    public ActionBarLayout(@NonNull BridgeContext context, @NonNull SessionParams params,
+            @NonNull ViewGroup parentView) {
 
-        super(context);
-        setOrientation(LinearLayout.HORIZONTAL);
-        setGravity(Gravity.CENTER_VERTICAL);
-
-        // Inflate action bar layout.
-        LayoutInflater.from(context).inflate(R.layout.screen_action_bar, this,
-                true /*attachToRoot*/);
-        mActionBar = new WindowDecorActionBar(this);
-
-        // Set contexts.
         mBridgeContext = context;
-        mThemedContext = mActionBar.getThemedContext();
 
-        // Set data for action bar.
-        mCallback = params.getProjectCallback().getActionBarCallback();
-        mIcon = params.getAppIcon();
-        mTitle = params.getAppLabel();
-        // Split Action Bar when the screen size is narrow and the application requests split action
-        // bar when narrow.
-        mSplit = context.getResources().getBoolean(R.bool.split_action_bar_is_narrow) &&
-                mCallback.getSplitActionBarWhenNarrow();
-        mNavMode = mCallback.getNavigationMode();
-        // TODO: Support Navigation Drawer Indicator.
-        mShowHomeAsUp = mCallback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP;
-        mSubTitle = mCallback.getSubTitle();
-
-
-        // Set helper fields.
-        mMenuBuilder = new MenuBuilder(mThemedContext);
-        res = mBridgeContext.getRenderResources();
-        mPopupMaxWidth = Math.max(mBridgeContext.getMetrics().widthPixels / 2,
-                mThemedContext.getResources().getDimensionPixelSize(
-                        R.dimen.config_prefDialogWidth));
-        mActionBarView = (ActionBarView) findViewById(R.id.action_bar);
-        mContentRoot = (FrameLayout) findViewById(android.R.id.content);
-
-        setupActionBar();
-    }
-
-    /**
-     * Sets up the action bar by filling the appropriate data.
-     */
-    private void setupActionBar() {
-        // Add title and sub title.
-        ResourceValue titleValue = res.findResValue(mTitle, false /*isFramework*/);
-        if (titleValue != null && titleValue.getValue() != null) {
-            mActionBar.setTitle(titleValue.getValue());
+        ResourceValue layoutName = context.getRenderResources()
+                .findItemInTheme(LAYOUT_ATTR_NAME, true);
+        if (layoutName != null) {
+            // We may need to resolve the reference obtained.
+            layoutName = context.getRenderResources().findResValue(layoutName.getValue(),
+                    layoutName.isFramework());
+        }
+        int layoutId = 0;
+        String error = null;
+        if (layoutName == null) {
+            error = "Unable to find action bar layout (" + LAYOUT_ATTR_NAME
+                    + ") in the current theme.";
         } else {
-            mActionBar.setTitle(mTitle);
-        }
-        if (mSubTitle != null) {
-            mActionBar.setSubtitle(mSubTitle);
-        }
-
-        // Add show home as up icon.
-        if (mShowHomeAsUp) {
-            mActionBar.setDisplayOptions(0xFF, ActionBar.DISPLAY_HOME_AS_UP);
-        }
-
-        // Set the navigation mode.
-        mActionBar.setNavigationMode(mNavMode);
-        if (mNavMode == ActionBar.NAVIGATION_MODE_TABS) {
-            setupTabs(3);
-        }
-
-        if (mActionBarView != null) {
-            // If the action bar style doesn't specify an icon, set the icon obtained from the session
-            // params.
-            if (!mActionBarView.hasIcon() && mIcon != null) {
-                Drawable iconDrawable = getDrawable(mIcon, false /*isFramework*/);
-                if (iconDrawable != null) {
-                    mActionBar.setIcon(iconDrawable);
-                }
-            }
-
-            // Set action bar to be split, if needed.
-            ActionBarContainer splitView = (ActionBarContainer) findViewById(R.id.split_action_bar);
-            mActionBarView.setSplitView(splitView);
-            mActionBarView.setSplitToolbar(mSplit);
-
-            inflateMenus();
-        }
-    }
-
-    /**
-     * Gets the menus to add to the action bar from the callback, resolves them, inflates them and
-     * adds them to the action bar.
-     */
-    private void inflateMenus() {
-        if (mActionBarView == null) {
-            return;
-        }
-        final MenuInflater inflater = new MenuInflater(mThemedContext);
-        for (String name : mCallback.getMenuIdNames()) {
-            if (mBridgeContext.getRenderResources().getProjectResource(ResourceType.MENU, name)
-                    != null) {
-                int id = mBridgeContext.getProjectResourceValue(ResourceType.MENU, name, -1);
-                if (id > -1) {
-                    inflater.inflate(id, mMenuBuilder);
-                }
+            layoutId = context.getFrameworkResourceValue(layoutName.getResourceType(),
+                    layoutName.getName(), 0);
+            if (layoutId == 0) {
+                error = String.format("Unable to resolve attribute \"%s\" of type \"%s\"",
+                        layoutName.getName(), layoutName.getResourceType());
             }
         }
-        mActionBarView.setMenu(mMenuBuilder, null /*callback*/);
-    }
-
-    // TODO: Use an adapter, like List View to set up tabs.
-    private void setupTabs(int num) {
-        for (int i = 1; i <= num; i++) {
-            Tab tab = mActionBar.newTab().setText("Tab" + i).setTabListener(new TabListener() {
-                @Override
-                public void onTabUnselected(Tab t, FragmentTransaction ft) {
-                    // pass
-                }
-                @Override
-                public void onTabSelected(Tab t, FragmentTransaction ft) {
-                    // pass
-                }
-                @Override
-                public void onTabReselected(Tab t, FragmentTransaction ft) {
-                    // pass
-                }
-            });
-            mActionBar.addTab(tab);
+        if (layoutId == 0) {
+            throw new RuntimeException(error);
         }
-    }
+        // Inflate action bar layout.
+        View decorContent = LayoutInflater.from(context).inflate(layoutId, parentView, true);
 
-    @Nullable
-    private Drawable getDrawable(@NonNull String name, boolean isFramework) {
-        ResourceValue value = res.findResValue(name, isFramework);
-        value = res.resolveResValue(value);
-        if (value != null) {
-            return ResourceHelper.getDrawable(value, mBridgeContext);
+        mActionBar = CustomActionBarWrapper.getActionBarWrapper(context, params, decorContent);
+
+        FrameLayout contentRoot = (FrameLayout) parentView.findViewById(android.R.id.content);
+
+        // If something went wrong and we were not able to initialize the content root,
+        // just add a frame layout inside this and return.
+        if (contentRoot == null) {
+            contentRoot = new FrameLayout(context);
+            contentRoot.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
+                    LayoutParams.MATCH_PARENT));
+            parentView.addView(contentRoot);
+            mContentRoot = contentRoot;
+        } else {
+            mContentRoot = contentRoot;
+            mActionBar.setupActionBar();
+            mActionBar.inflateMenus();
         }
-        return null;
     }
 
     /**
@@ -229,7 +117,7 @@
      * the content frame which shall serve as the new content root.
      */
     public void createMenuPopup() {
-        assert mContentRoot != null && findViewById(android.R.id.content) == mContentRoot
+        assert mContentRoot.getId() == android.R.id.content
                 : "Action Bar Menus have already been created.";
 
         if (!isOverflowPopupNeeded()) {
@@ -237,7 +125,7 @@
         }
 
         // Create a layout to hold the menus and the user's content.
-        RelativeLayout layout = new RelativeLayout(mThemedContext);
+        RelativeLayout layout = new RelativeLayout(mActionBar.getPopupContext());
         layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
                 LayoutParams.MATCH_PARENT));
         mContentRoot.addView(layout);
@@ -259,13 +147,14 @@
     @NonNull
     private View createMenuView() {
         DisplayMetrics metrics = mBridgeContext.getMetrics();
-        OverflowMenuAdapter adapter = new OverflowMenuAdapter(mMenuBuilder, mThemedContext);
+        MenuBuilder menu = mActionBar.getMenuBuilder();
+        OverflowMenuAdapter adapter = new OverflowMenuAdapter(menu, mActionBar.getPopupContext());
 
-        LinearLayout layout = new LinearLayout(mThemedContext);
+        LinearLayout layout = new LinearLayout(mActionBar.getPopupContext());
         RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
                 measureContentWidth(adapter), LayoutParams.WRAP_CONTENT);
         layoutParams.addRule(RelativeLayout.ALIGN_PARENT_END);
-        if (mSplit) {
+        if (mActionBar.isSplit()) {
             layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
             // TODO: Find correct value instead of hardcoded 10dp.
             layoutParams.bottomMargin = getPixelValue("-10dp", metrics);
@@ -273,7 +162,7 @@
             layoutParams.topMargin = getPixelValue("-10dp", metrics);
         }
         layout.setLayoutParams(layoutParams);
-        final TypedArray a = mThemedContext.obtainStyledAttributes(null,
+        final TypedArray a = mActionBar.getPopupContext().obtainStyledAttributes(null,
                 R.styleable.PopupWindow, R.attr.popupMenuStyle, 0);
         layout.setBackground(a.getDrawable(R.styleable.PopupWindow_popupBackground));
         layout.setDividerDrawable(a.getDrawable(R.attr.actionBarDivider));
@@ -282,20 +171,25 @@
         layout.setDividerPadding(getPixelValue("12dp", metrics));
         layout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
 
-        ListView listView = new ListView(mThemedContext, null, R.attr.dropDownListViewStyle);
+        ListView listView = new ListView(mActionBar.getPopupContext(), null,
+                R.attr.dropDownListViewStyle);
         listView.setAdapter(adapter);
         layout.addView(listView);
         return layout;
     }
 
     private boolean isOverflowPopupNeeded() {
-        boolean needed = mCallback.isOverflowPopupNeeded();
+        boolean needed = mActionBar.isOverflowPopupNeeded();
         if (!needed) {
             return false;
         }
         // Copied from android.widget.ActionMenuPresenter.updateMenuView()
-        ArrayList<MenuItemImpl> menus = mMenuBuilder.getNonActionItems();
-        if (ActionBarAccessor.getActionMenuPresenter(mActionBarView).isOverflowReserved() &&
+        ArrayList<MenuItemImpl> menus = mActionBar.getMenuBuilder().getNonActionItems();
+        ActionMenuPresenter presenter = mActionBar.getActionMenuPresenter();
+        if (presenter == null) {
+            throw new RuntimeException("Failed to create a Presenter for Action Bar Menus.");
+        }
+        if (presenter.isOverflowReserved() &&
                 menus != null) {
             final int count = menus.size();
             if (count == 1) {
@@ -307,7 +201,7 @@
         return needed;
     }
 
-    @Nullable
+    @NonNull
     public FrameLayout getContentRoot() {
         return mContentRoot;
     }
@@ -319,6 +213,7 @@
         View itemView = null;
         int itemType = 0;
 
+        Context context = mActionBar.getPopupContext();
         final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
         final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
         final int count = adapter.getCount();
@@ -330,15 +225,17 @@
             }
 
             if (mMeasureParent == null) {
-                mMeasureParent = new FrameLayout(mThemedContext);
+                mMeasureParent = new FrameLayout(context);
             }
 
             itemView = adapter.getView(i, itemView, mMeasureParent);
             itemView.measure(widthMeasureSpec, heightMeasureSpec);
 
             final int itemWidth = itemView.getMeasuredWidth();
-            if (itemWidth >= mPopupMaxWidth) {
-                return mPopupMaxWidth;
+            int popupMaxWidth = Math.max(mBridgeContext.getMetrics().widthPixels / 2,
+                    context.getResources().getDimensionPixelSize(R.dimen.config_prefDialogWidth));
+            if (itemWidth >= popupMaxWidth) {
+                return popupMaxWidth;
             } else if (itemWidth > maxWidth) {
                 maxWidth = itemWidth;
             }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomActionBarWrapper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomActionBarWrapper.java
new file mode 100644
index 0000000..70b9cc3
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomActionBarWrapper.java
@@ -0,0 +1,351 @@
+/*
+ * 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.layoutlib.bridge.bars;
+
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
+import com.android.ide.common.rendering.api.ActionBarCallback;
+import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle;
+import com.android.ide.common.rendering.api.RenderResources;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.ide.common.rendering.api.SessionParams;
+import com.android.internal.R;
+import com.android.internal.app.ToolbarActionBar;
+import com.android.internal.app.WindowDecorActionBar;
+import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.widget.ActionBarAccessor;
+import com.android.internal.widget.ActionBarView;
+import com.android.internal.widget.DecorToolbar;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.impl.ResourceHelper;
+
+import android.app.ActionBar;
+import android.app.ActionBar.Tab;
+import android.app.ActionBar.TabListener;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.view.MenuInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowCallback;
+import android.widget.ActionMenuPresenter;
+import android.widget.Toolbar;
+import android.widget.Toolbar_Accessor;
+
+import static com.android.SdkConstants.ANDROID_NS_NAME_PREFIX;
+import static com.android.resources.ResourceType.MENU;
+
+/**
+ * A common API to access {@link ToolbarActionBar} and {@link WindowDecorActionBar}.
+ */
+public abstract class CustomActionBarWrapper {
+
+    @NonNull protected ActionBar mActionBar;
+    @NonNull protected SessionParams mParams;
+    @NonNull protected ActionBarCallback mCallback;
+    @NonNull protected BridgeContext mContext;
+
+    /**
+     * Returns a wrapper around different implementations of the Action Bar to provide a common API.
+     *
+     * @param decorContent the top level view returned by inflating
+                     * ?attr/windowActionBarFullscreenDecorLayout
+     */
+    @NonNull
+    public static CustomActionBarWrapper getActionBarWrapper(@NonNull BridgeContext context,
+            @NonNull SessionParams params, @NonNull View decorContent) {
+        View view = decorContent.findViewById(R.id.action_bar);
+        if (view instanceof Toolbar) {
+            return new ToolbarWrapper(context, params, ((Toolbar) view)
+            );
+        } else if (view instanceof ActionBarView) {
+            return new WindowActionBarWrapper(context, params, decorContent, ((ActionBarView) view)
+            );
+        } else {
+            throw new IllegalStateException("Can't make an action bar out of " +
+                    view.getClass().getSimpleName());
+        }
+    }
+
+    CustomActionBarWrapper(@NonNull BridgeContext context, @NonNull SessionParams params,
+            @NonNull ActionBar actionBar) {
+        mActionBar = actionBar;
+        mParams = params;
+        mCallback = params.getProjectCallback().getActionBarCallback();
+        mContext = context;
+    }
+
+    protected void setupActionBar() {
+        // Do the things that are common to all implementations.
+        RenderResources res = mContext.getRenderResources();
+
+        String title = mParams.getAppLabel();
+        ResourceValue titleValue = res.findResValue(title, false);
+        if (titleValue != null && titleValue.getValue() != null) {
+            mActionBar.setTitle(titleValue.getValue());
+        } else {
+            mActionBar.setTitle(title);
+        }
+
+        String subTitle = mCallback.getSubTitle();
+        if (subTitle != null) {
+            mActionBar.setSubtitle(subTitle);
+        }
+
+        // Add show home as up icon.
+        if (mCallback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP) {
+            mActionBar.setDisplayOptions(0xFF, ActionBar.DISPLAY_HOME_AS_UP);
+        }
+    }
+
+    protected boolean isSplit() {
+        return getDecorToolbar().isSplit();
+    }
+
+    protected boolean isOverflowPopupNeeded() {
+        return mCallback.isOverflowPopupNeeded();
+    }
+
+    /**
+     * Gets the menus to add to the action bar from the callback, resolves them, inflates them and
+     * adds them to the action bar.
+     */
+    protected void inflateMenus() {
+        MenuInflater inflater = new MenuInflater(getActionMenuContext());
+        MenuBuilder menuBuilder = getMenuBuilder();
+        for (String name : mCallback.getMenuIdNames()) {
+            int id;
+            if (name.startsWith(ANDROID_NS_NAME_PREFIX)) {
+                // Framework menu.
+                name = name.substring(ANDROID_NS_NAME_PREFIX.length());
+                id = mContext.getFrameworkResourceValue(MENU, name, -1);
+            } else {
+                // Project menu.
+                id = mContext.getProjectResourceValue(MENU, name, -1);
+            }
+            if (id > -1) {
+                inflater.inflate(id, menuBuilder);
+            }
+        }
+    }
+
+    /**
+     * The context used for the ActionBar and the menus in the ActionBarView.
+     */
+    @NonNull
+    protected Context getActionMenuContext() {
+        return mActionBar.getThemedContext();
+    }
+
+    /**
+     * The context used to inflate the popup menu.
+     */
+    @NonNull
+    abstract Context getPopupContext();
+
+    /**
+     * The Menu in which to inflate the user's menus.
+     */
+    @NonNull
+    abstract MenuBuilder getMenuBuilder();
+
+    @Nullable
+    abstract ActionMenuPresenter getActionMenuPresenter();
+
+    /**
+     * Framework's wrapper over two ActionBar implementations.
+     */
+    @NonNull
+    abstract DecorToolbar getDecorToolbar();
+
+    // ---- The implementations ----
+
+    /**
+     * Material theme uses {@link Toolbar} as the action bar. This wrapper provides access to
+     * Toolbar using a common API.
+     */
+    private static class ToolbarWrapper extends CustomActionBarWrapper {
+
+        @NonNull
+        private final Toolbar mToolbar;  // This is the view.
+
+        ToolbarWrapper(@NonNull BridgeContext context, @NonNull SessionParams params,
+                @NonNull Toolbar toolbar) {
+            super(context, params, new ToolbarActionBar(toolbar, "", new WindowCallback())
+            );
+            mToolbar = toolbar;
+        }
+
+        @Override
+        protected void inflateMenus() {
+            super.inflateMenus();
+            // Inflating the menus doesn't initialize the ActionMenuPresenter. Setting a fake menu
+            // and then setting it back does the trick.
+            MenuBuilder menu = getMenuBuilder();
+            DecorToolbar decorToolbar = getDecorToolbar();
+            decorToolbar.setMenu(new MenuBuilder(getActionMenuContext()), null);
+            decorToolbar.setMenu(menu, null);
+        }
+
+        @NonNull
+        @Override
+        Context getPopupContext() {
+            return Toolbar_Accessor.getPopupContext(mToolbar);
+        }
+
+        @NonNull
+        @Override
+        MenuBuilder getMenuBuilder() {
+            return (MenuBuilder) mToolbar.getMenu();
+        }
+
+        @Nullable
+        @Override
+        ActionMenuPresenter getActionMenuPresenter() {
+            return Toolbar_Accessor.getActionMenuPresenter(mToolbar);
+        }
+
+        @NonNull
+        @Override
+        DecorToolbar getDecorToolbar() {
+            return mToolbar.getWrapper();
+        }
+    }
+
+    /**
+     * Holo theme uses {@link WindowDecorActionBar} as the action bar. This wrapper provides
+     * access to it using a common API.
+     */
+    private static class WindowActionBarWrapper extends CustomActionBarWrapper{
+
+        @NonNull
+        private final WindowDecorActionBar mActionBar;
+        private final ActionBarView mActionBarView;
+        private MenuBuilder mMenuBuilder;
+
+        public WindowActionBarWrapper(@NonNull BridgeContext context, @NonNull SessionParams params,
+                @NonNull View decorContentRoot, @NonNull ActionBarView actionBarView) {
+            super(context, params, new WindowDecorActionBar(decorContentRoot)
+            );
+            mActionBarView = actionBarView;
+            mActionBar = ((WindowDecorActionBar) super.mActionBar);
+        }
+
+        @Override
+        protected void setupActionBar() {
+            super.setupActionBar();
+
+            // Set the navigation mode.
+            int navMode = mCallback.getNavigationMode();
+            mActionBar.setNavigationMode(navMode);
+            //noinspection deprecation
+            if (navMode == ActionBar.NAVIGATION_MODE_TABS) {
+                setupTabs(3);
+            }
+
+            String icon = mParams.getAppIcon();
+            // If the action bar style doesn't specify an icon, set the icon obtained from the
+            // session params.
+            if (!mActionBar.hasIcon() && icon != null) {
+                Drawable iconDrawable = getDrawable(icon, false);
+                if (iconDrawable != null) {
+                    mActionBar.setIcon(iconDrawable);
+                }
+            }
+
+            // Set action bar to be split, if needed.
+            ViewGroup splitView = (ViewGroup) mActionBarView.findViewById(R.id.split_action_bar);
+            if (splitView != null) {
+                mActionBarView.setSplitView(splitView);
+                Resources res = mContext.getResources();
+                boolean split = res.getBoolean(R.bool.split_action_bar_is_narrow)
+                        && mCallback.getSplitActionBarWhenNarrow();
+                mActionBarView.setSplitToolbar(split);
+            }
+        }
+
+        @Override
+        protected void inflateMenus() {
+            super.inflateMenus();
+            // The super implementation doesn't set the menu on the view. Set it here.
+            mActionBarView.setMenu(getMenuBuilder(), null);
+        }
+
+        @NonNull
+        @Override
+        Context getPopupContext() {
+            return getActionMenuContext();
+        }
+
+        @NonNull
+        @Override
+        MenuBuilder getMenuBuilder() {
+            if (mMenuBuilder == null) {
+                mMenuBuilder = new MenuBuilder(getActionMenuContext());
+            }
+            return mMenuBuilder;
+        }
+
+        @Nullable
+        @Override
+        ActionMenuPresenter getActionMenuPresenter() {
+            return ActionBarAccessor.getActionMenuPresenter(mActionBarView);
+        }
+
+        @NonNull
+        @Override
+        ActionBarView getDecorToolbar() {
+            return mActionBarView;
+        }
+
+        // TODO: Use an adapter, like List View to set up tabs.
+        @SuppressWarnings("deprecation")  // For Tab
+        private void setupTabs(int num) {
+            for (int i = 1; i <= num; i++) {
+                Tab tab = mActionBar.newTab().setText("Tab" + i).setTabListener(new TabListener() {
+                    @Override
+                    public void onTabUnselected(Tab t, FragmentTransaction ft) {
+                        // pass
+                    }
+                    @Override
+                    public void onTabSelected(Tab t, FragmentTransaction ft) {
+                        // pass
+                    }
+                    @Override
+                    public void onTabReselected(Tab t, FragmentTransaction ft) {
+                        // pass
+                    }
+                });
+                mActionBar.addTab(tab);
+            }
+        }
+
+        @Nullable
+        private Drawable getDrawable(@NonNull String name, boolean isFramework) {
+            RenderResources res = mContext.getRenderResources();
+            ResourceValue value = res.findResValue(name, isFramework);
+            value = res.resolveResValue(value);
+            if (value != null) {
+                return ResourceHelper.getDrawable(value, mContext);
+            }
+            return null;
+        }
+
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index b8dce70..a2eed9a 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -353,8 +353,7 @@
 
                 // if the theme says no title/action bar, then the size will be 0
                 if (mActionBarSize > 0) {
-                    ActionBarLayout actionBar = createActionBar(context, params);
-                    backgroundLayout.addView(actionBar);
+                    ActionBarLayout actionBar = createActionBar(context, params, backgroundLayout);
                     actionBar.createMenuPopup();
                     mContentRoot = actionBar.getContentRoot();
                 } else if (mTitleBarSize > 0) {
@@ -1624,11 +1623,9 @@
     /**
      * Creates the action bar. Also queries the project callback for missing information.
      */
-    private ActionBarLayout createActionBar(BridgeContext context, SessionParams params) {
-        ActionBarLayout actionBar = new ActionBarLayout(context, params);
-        actionBar.setLayoutParams(new LinearLayout.LayoutParams(
-                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
-        return actionBar;
+    private ActionBarLayout createActionBar(BridgeContext context, SessionParams params,
+            ViewGroup parentView) {
+        return new ActionBarLayout(context, params, parentView);
     }
 
     public BufferedImage getImage() {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
index a1fae95..979aa33 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
@@ -16,6 +16,7 @@
 
 package com.android.layoutlib.bridge.util;
 
+import com.android.annotations.NonNull;
 import com.android.resources.ResourceType;
 import com.android.util.Pair;
 
@@ -48,6 +49,7 @@
      * @param name the name of the resource
      * @return an integer.
      */
+    @NonNull
     public Integer getId(ResourceType type, String name) {
         return getId(Pair.of(type, name));
     }
@@ -59,10 +61,11 @@
      * @param resource the type/name of the resource
      * @return an integer.
      */
+    @NonNull
     public Integer getId(Pair<ResourceType, String> resource) {
         Integer value = mDynamicIds.get(resource);
         if (value == null) {
-            value = Integer.valueOf(++mDynamicSeed);
+            value = ++mDynamicSeed;
             mDynamicIds.put(resource, value);
             mRevDynamicIds.put(value, resource);
         }