Merge "CEC: Hide CEC devices behind non-CEC switch" into lmp-dev
diff --git a/Android.mk b/Android.mk
index 52c2d16..5485e9f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -128,6 +128,7 @@
 	core/java/android/content/pm/IOnAppsChangedListener.aidl \
 	core/java/android/content/pm/IPackageDataObserver.aidl \
 	core/java/android/content/pm/IPackageDeleteObserver.aidl \
+	core/java/android/content/pm/IPackageDeleteObserver2.aidl \
 	core/java/android/content/pm/IPackageInstallObserver.aidl \
 	core/java/android/content/pm/IPackageInstallObserver2.aidl \
 	core/java/android/content/pm/IPackageInstaller.aidl \
diff --git a/api/current.txt b/api/current.txt
index e1460f2..d4f2cc5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8673,6 +8673,7 @@
     ctor public PackageInstaller.CommitCallback();
     method public abstract void onFailure(int, java.lang.String, android.os.Bundle);
     method public abstract void onSuccess();
+    method public abstract void onUserActionRequired(android.content.Intent);
     field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.content.pm.extra.PACKAGE_NAME";
     field public static final int FAILURE_CONFLICT = 2; // 0x2
     field public static final int FAILURE_INCOMPATIBLE = 4; // 0x4
@@ -8705,6 +8706,7 @@
     ctor public PackageInstaller.UninstallCallback();
     method public abstract void onFailure(java.lang.String);
     method public abstract void onSuccess();
+    method public abstract void onUserActionRequired(android.content.Intent);
   }
 
   public class PackageItemInfo {
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 1f25dd0..c5e91e3 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -19,12 +19,13 @@
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
+import android.app.PackageDeleteObserver;
 import android.app.PackageInstallObserver;
 import android.content.ComponentName;
+import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageDataObserver;
-import android.content.pm.IPackageDeleteObserver;
 import android.content.pm.IPackageInstaller;
 import android.content.pm.IPackageManager;
 import android.content.pm.InstallSessionInfo;
@@ -760,7 +761,7 @@
         String extraPackage;
 
         @Override
-        public void packageInstalled(String name, Bundle extras, int status) {
+        public void onPackageInstalled(String name, int status, String msg, Bundle extras) {
             synchronized (this) {
                 finished = true;
                 result = status;
@@ -790,6 +791,11 @@
         }
 
         @Override
+        public void onUserActionRequired(Intent intent) {
+            setResult(false, "Unexepected user action required!");
+        }
+
+        @Override
         public void onSuccess() {
             setResult(true, null);
         }
@@ -1268,11 +1274,12 @@
         }
     }
 
-    class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
+    class LocalPackageDeleteObserver extends PackageDeleteObserver {
         boolean finished;
         boolean result;
 
-        public void packageDeleted(String packageName, int returnCode) {
+        @Override
+        public void onPackageDeleted(String name, int returnCode, String msg) {
             synchronized (this) {
                 finished = true;
                 result = returnCode == PackageManager.DELETE_SUCCEEDED;
@@ -1346,9 +1353,9 @@
     }
 
     private boolean deletePackage(String packageName, int flags, int userId) {
-        PackageDeleteObserver obs = new PackageDeleteObserver();
+        LocalPackageDeleteObserver obs = new LocalPackageDeleteObserver();
         try {
-            mInstaller.uninstall(packageName, flags, obs, userId);
+            mInstaller.uninstall(packageName, flags, obs.getBinder(), userId);
 
             synchronized (obs) {
                 while (!obs.finished) {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index edcfd74..84b5516 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -28,6 +28,7 @@
 import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageDeleteObserver2;
 import android.content.pm.IPackageInstallObserver;
 import android.content.pm.IPackageManager;
 import android.content.pm.IPackageMoveObserver;
@@ -1287,6 +1288,7 @@
             // Should never happen!
         }
     }
+
     @Override
     public void clearApplicationUserData(String packageName,
                                          IPackageDataObserver observer) {
@@ -1661,7 +1663,8 @@
         }
 
         @Override
-        public void packageInstalled(String basePackageName, Bundle extras, int returnCode) {
+        public void onPackageInstalled(String basePackageName, int returnCode, String msg,
+                Bundle extras) {
             try {
                 mLegacy.packageInstalled(basePackageName, returnCode);
             } catch (RemoteException ignored) {
@@ -1669,6 +1672,22 @@
         }
     }
 
+    private static class LegacyPackageDeleteObserver extends PackageDeleteObserver {
+        private final IPackageDeleteObserver mLegacy;
+
+        public LegacyPackageDeleteObserver(IPackageDeleteObserver legacy) {
+            mLegacy = legacy;
+        }
+
+        @Override
+        public void onPackageDeleted(String basePackageName, int returnCode, String msg) {
+            try {
+                mLegacy.packageDeleted(basePackageName, returnCode);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
     private final ContextImpl mContext;
     private final IPackageManager mPM;
 
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 5b36b8b..5684a7a 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2577,7 +2577,8 @@
 
         private RemoteViews applyStandardTemplate(int resId, boolean fitIn1U) {
             Bitmap profileIcon = getProfileBadge();
-            RemoteViews contentView = new BuilderRemoteViews(mContext.getPackageName(), resId);
+            RemoteViews contentView = new BuilderRemoteViews(mContext.getPackageName(),
+                    mOriginatingUserId, resId);
             boolean showLine3 = false;
             boolean showLine2 = false;
 
@@ -4576,8 +4577,8 @@
             super(parcel);
         }
 
-        public BuilderRemoteViews(String packageName, int layoutId) {
-            super(packageName, layoutId);
+        public BuilderRemoteViews(String packageName, int userId, int layoutId) {
+            super(packageName, userId, layoutId);
         }
 
         @Override
diff --git a/core/java/android/app/PackageDeleteObserver.java b/core/java/android/app/PackageDeleteObserver.java
new file mode 100644
index 0000000..9b83ec1
--- /dev/null
+++ b/core/java/android/app/PackageDeleteObserver.java
@@ -0,0 +1,46 @@
+/*
+ * 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.app;
+
+import android.content.Intent;
+import android.content.pm.IPackageDeleteObserver2;
+
+/** {@hide} */
+public class PackageDeleteObserver {
+    private final IPackageDeleteObserver2.Stub mBinder = new IPackageDeleteObserver2.Stub() {
+        @Override
+        public void onUserActionRequired(Intent intent) {
+            PackageDeleteObserver.this.onUserActionRequired(intent);
+        }
+
+        @Override
+        public void onPackageDeleted(String basePackageName, int returnCode, String msg) {
+            PackageDeleteObserver.this.onPackageDeleted(basePackageName, returnCode, msg);
+        }
+    };
+
+    /** {@hide} */
+    public IPackageDeleteObserver2 getBinder() {
+        return mBinder;
+    }
+
+    public void onUserActionRequired(Intent intent) {
+    }
+
+    public void onPackageDeleted(String basePackageName, int returnCode, String msg) {
+    }
+}
diff --git a/core/java/android/app/PackageInstallObserver.java b/core/java/android/app/PackageInstallObserver.java
index 1b2504e..ff28679 100644
--- a/core/java/android/app/PackageInstallObserver.java
+++ b/core/java/android/app/PackageInstallObserver.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.content.Intent;
 import android.content.pm.IPackageInstallObserver2;
 import android.os.Bundle;
 
@@ -23,9 +24,15 @@
 public class PackageInstallObserver {
     private final IPackageInstallObserver2.Stub mBinder = new IPackageInstallObserver2.Stub() {
         @Override
-        public void packageInstalled(String basePackageName, Bundle extras, int returnCode,
-                String msg) {
-            PackageInstallObserver.this.packageInstalled(basePackageName, extras, returnCode, msg);
+        public void onUserActionRequired(Intent intent) {
+            PackageInstallObserver.this.onUserActionRequired(intent);
+        }
+
+        @Override
+        public void onPackageInstalled(String basePackageName, int returnCode,
+                String msg, Bundle extras) {
+            PackageInstallObserver.this.onPackageInstalled(basePackageName, returnCode, msg,
+                    extras);
         }
     };
 
@@ -34,6 +41,9 @@
         return mBinder;
     }
 
+    public void onUserActionRequired(Intent intent) {
+    }
+
     /**
      * This method will be called to report the result of the package
      * installation attempt.
@@ -49,11 +59,7 @@
      *            basic outcome
      * @hide
      */
-    public void packageInstalled(String basePackageName, Bundle extras, int returnCode) {
-    }
-
-    public void packageInstalled(String basePackageName, Bundle extras, int returnCode,
-            String msg) {
-        packageInstalled(basePackageName, extras, returnCode);
+    public void onPackageInstalled(String basePackageName, int returnCode, String msg,
+            Bundle extras) {
     }
 }
diff --git a/core/java/android/app/PackageUninstallObserver.java b/core/java/android/app/PackageUninstallObserver.java
deleted file mode 100644
index 83fc380..0000000
--- a/core/java/android/app/PackageUninstallObserver.java
+++ /dev/null
@@ -1,37 +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.
- */
-
-package android.app;
-
-import android.content.pm.IPackageDeleteObserver;
-
-/** {@hide} */
-public class PackageUninstallObserver {
-    private final IPackageDeleteObserver.Stub mBinder = new IPackageDeleteObserver.Stub() {
-        @Override
-        public void packageDeleted(String basePackageName, int returnCode) {
-            PackageUninstallObserver.this.onUninstallFinished(basePackageName, returnCode);
-        }
-    };
-
-    /** {@hide} */
-    public IPackageDeleteObserver getBinder() {
-        return mBinder;
-    }
-
-    public void onUninstallFinished(String basePackageName, int returnCode) {
-    }
-}
diff --git a/core/java/android/content/pm/IPackageDeleteObserver2.aidl b/core/java/android/content/pm/IPackageDeleteObserver2.aidl
new file mode 100644
index 0000000..bff3baa
--- /dev/null
+++ b/core/java/android/content/pm/IPackageDeleteObserver2.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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.content.pm;
+
+import android.content.Intent;
+
+/** {@hide} */
+oneway interface IPackageDeleteObserver2 {
+    void onUserActionRequired(in Intent intent);
+    void onPackageDeleted(String packageName, int returnCode, String msg);
+}
diff --git a/core/java/android/content/pm/IPackageInstallObserver2.aidl b/core/java/android/content/pm/IPackageInstallObserver2.aidl
index 824d730..bb5f22a 100644
--- a/core/java/android/content/pm/IPackageInstallObserver2.aidl
+++ b/core/java/android/content/pm/IPackageInstallObserver2.aidl
@@ -16,7 +16,7 @@
 
 package android.content.pm;
 
-import android.content.IntentSender;
+import android.content.Intent;
 import android.os.Bundle;
 
 /**
@@ -25,6 +25,8 @@
  * @hide
  */
 oneway interface IPackageInstallObserver2 {
+    void onUserActionRequired(in Intent intent);
+
     /**
      * The install operation has completed.  {@code returnCode} holds a numeric code
      * indicating success or failure.  In certain cases the {@code extras} Bundle will
@@ -40,5 +42,5 @@
      * </tr>
      * </table>
      */
-    void packageInstalled(String basePackageName, in Bundle extras, int returnCode, String msg);
+    void onPackageInstalled(String basePackageName, int returnCode, String msg, in Bundle extras);
 }
diff --git a/core/java/android/content/pm/IPackageInstaller.aidl b/core/java/android/content/pm/IPackageInstaller.aidl
index 0c65034..176a81c 100644
--- a/core/java/android/content/pm/IPackageInstaller.aidl
+++ b/core/java/android/content/pm/IPackageInstaller.aidl
@@ -16,7 +16,7 @@
 
 package android.content.pm;
 
-import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageDeleteObserver2;
 import android.content.pm.IPackageInstallerCallback;
 import android.content.pm.IPackageInstallerSession;
 import android.content.pm.InstallSessionInfo;
@@ -35,6 +35,6 @@
     void registerCallback(IPackageInstallerCallback callback, int userId);
     void unregisterCallback(IPackageInstallerCallback callback);
 
-    void uninstall(String packageName, int flags, in IPackageDeleteObserver observer, int userId);
-    void uninstallSplit(String packageName, String splitName, int flags, in IPackageDeleteObserver observer, int userId);
+    void uninstall(String packageName, int flags, in IPackageDeleteObserver2 observer, int userId);
+    void uninstallSplit(String packageName, String splitName, int flags, in IPackageDeleteObserver2 observer, int userId);
 }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 2d6d3c9..44478d4 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -24,10 +24,10 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ContainerEncryptionParams;
 import android.content.pm.FeatureInfo;
-import android.content.pm.IPackageInstallObserver;
 import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.IPackageInstaller;
 import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageDeleteObserver2;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageMoveObserver;
 import android.content.pm.IPackageStatsObserver;
@@ -202,6 +202,10 @@
 
     void setInstallerPackageName(in String targetPackage, in String installerPackageName);
 
+    /** @deprecated rawr, don't call AIDL methods directly! */
+    void deletePackageAsUser(in String packageName, IPackageDeleteObserver observer,
+            int userId, int flags);
+
     /**
      * Delete a package for a specific user.
      *
@@ -210,8 +214,7 @@
      * @param userId the id of the user for whom to delete the package
      * @param flags - possible values: {@link #DONT_DELETE_DATA}
      */
-    void deletePackageAsUser(in String packageName, IPackageDeleteObserver observer,
-            int userId, int flags);
+    void deletePackage(in String packageName, IPackageDeleteObserver2 observer, int userId, int flags);
 
     String getInstallerPackageName(in String packageName);
 
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 299afff..01c080d 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -20,8 +20,9 @@
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.app.PackageDeleteObserver;
 import android.app.PackageInstallObserver;
-import android.app.PackageUninstallObserver;
+import android.content.Intent;
 import android.os.Bundle;
 import android.os.FileBridge;
 import android.os.Handler;
@@ -536,15 +537,25 @@
     }
 
     /**
-     * Final result of an uninstall request.
+     * Events for a specific uninstall request.
      */
     public static abstract class UninstallCallback {
+        /**
+         * User action is required to proceed. You can start the given intent
+         * activity to involve the user and continue.
+         * <p>
+         * You may choose to immediately launch the intent if the user is
+         * actively using your app. However, you should use a notification to
+         * guide the user back into your app if not currently active.
+         */
+        public abstract void onUserActionRequired(Intent intent);
+
         public abstract void onSuccess();
         public abstract void onFailure(String msg);
     }
 
     /** {@hide} */
-    private static class UninstallCallbackDelegate extends PackageUninstallObserver {
+    private static class UninstallCallbackDelegate extends PackageDeleteObserver {
         private final UninstallCallback target;
 
         public UninstallCallbackDelegate(UninstallCallback target) {
@@ -552,11 +563,16 @@
         }
 
         @Override
-        public void onUninstallFinished(String basePackageName, int returnCode) {
+        public void onUserActionRequired(Intent intent) {
+            target.onUserActionRequired(intent);
+        }
+
+        @Override
+        public void onPackageDeleted(String basePackageName, int returnCode, String msg) {
             if (returnCode == PackageManager.DELETE_SUCCEEDED) {
                 target.onSuccess();
             } else {
-                final String msg = PackageManager.deleteStatusToString(returnCode);
+                msg = PackageManager.deleteStatusToString(returnCode) + ": " + msg;
                 target.onFailure(msg);
             }
         }
@@ -612,6 +628,16 @@
 
         public static final String EXTRA_PACKAGE_NAME = "android.content.pm.extra.PACKAGE_NAME";
 
+        /**
+         * User action is required to proceed. You can start the given intent
+         * activity to involve the user and continue.
+         * <p>
+         * You may choose to immediately launch the intent if the user is
+         * actively using your app. However, you should use a notification to
+         * guide the user back into your app if not currently active.
+         */
+        public abstract void onUserActionRequired(Intent intent);
+
         public abstract void onSuccess();
         public abstract void onFailure(int failureReason, String msg, Bundle extras);
     }
@@ -625,8 +651,13 @@
         }
 
         @Override
-        public void packageInstalled(String basePackageName, Bundle extras, int returnCode,
-                String msg) {
+        public void onUserActionRequired(Intent intent) {
+            target.onUserActionRequired(intent);
+        }
+
+        @Override
+        public void onPackageInstalled(String basePackageName, int returnCode, String msg,
+                Bundle extras) {
             if (returnCode == PackageManager.INSTALL_SUCCEEDED) {
                 target.onSuccess();
             } else {
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index d14f226..f9333d5 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -276,12 +276,12 @@
         if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
             HardwareCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
             try {
-                canvas.save();
+                final int saveCount = canvas.save();
                 canvas.translate(mInsetLeft, mInsetTop);
                 callbacks.onHardwarePreDraw(canvas);
                 canvas.drawRenderNode(view.getDisplayList());
                 callbacks.onHardwarePostDraw(canvas);
-                canvas.restore();
+                canvas.restoreToCount(saveCount);
                 mRootNodeNeedsUpdate = false;
             } finally {
                 mRootNode.end(canvas);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 671aa10..a326aad 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -735,15 +735,23 @@
 
     void setLayoutParams(WindowManager.LayoutParams attrs, boolean newView) {
         synchronized (this) {
-            int oldSoftInputMode = mWindowAttributes.softInputMode;
+            final int oldInsetLeft = mWindowAttributes.surfaceInsets.left;
+            final int oldInsetTop = mWindowAttributes.surfaceInsets.top;
+            final int oldInsetRight = mWindowAttributes.surfaceInsets.right;
+            final int oldInsetBottom = mWindowAttributes.surfaceInsets.bottom;
+            final int oldSoftInputMode = mWindowAttributes.softInputMode;
+
             // Keep track of the actual window flags supplied by the client.
             mClientWindowLayoutFlags = attrs.flags;
-            // preserve compatible window flag if exists.
-            int compatibleWindowFlag = mWindowAttributes.privateFlags
+
+            // Preserve compatible window flag if exists.
+            final int compatibleWindowFlag = mWindowAttributes.privateFlags
                     & WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-            // transfer over system UI visibility values as they carry current state.
+
+            // Transfer over system UI visibility values as they carry current state.
             attrs.systemUiVisibility = mWindowAttributes.systemUiVisibility;
             attrs.subtreeSystemUiVisibility = mWindowAttributes.subtreeSystemUiVisibility;
+
             mWindowAttributesChangesFlag = mWindowAttributes.copyFrom(attrs);
             if ((mWindowAttributesChangesFlag
                     & WindowManager.LayoutParams.TRANSLUCENT_FLAGS_CHANGED) != 0) {
@@ -755,20 +763,25 @@
             }
             mWindowAttributes.privateFlags |= compatibleWindowFlag;
 
+            // Restore old surface insets.
+            mWindowAttributes.surfaceInsets.set(
+                    oldInsetLeft, oldInsetTop, oldInsetRight, oldInsetBottom);
+
             applyKeepScreenOnFlag(mWindowAttributes);
 
             if (newView) {
                 mSoftInputMode = attrs.softInputMode;
                 requestLayout();
             }
+
             // Don't lose the mode we last auto-computed.
-            if ((attrs.softInputMode&WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
+            if ((attrs.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
                     == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED) {
                 mWindowAttributes.softInputMode = (mWindowAttributes.softInputMode
                         & ~WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
-                        | (oldSoftInputMode
-                                & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST);
+                        | (oldSoftInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST);
             }
+
             mWindowAttributesChanged = true;
             scheduleTraversals();
         }
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 66c4b81..58f9801 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -19,6 +19,7 @@
 import android.content.UndoManager;
 import android.content.UndoOperation;
 import android.content.UndoOwner;
+import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.InputFilter;
@@ -26,6 +27,7 @@
 
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
+import com.android.internal.view.menu.MenuBuilder;
 import com.android.internal.widget.EditableInputConnection;
 
 import android.R;
@@ -2810,7 +2812,12 @@
 
         @Override
         public boolean onCreateActionMode(ActionMode mode, Menu menu) {
-            TypedArray styledAttributes = mTextView.getContext().obtainStyledAttributes(
+            final boolean legacy = mTextView.getContext().getApplicationInfo().targetSdkVersion <
+                    Build.VERSION_CODES.L;
+            final Context context = !legacy && menu instanceof MenuBuilder ?
+                    ((MenuBuilder) menu).getContext() :
+                    mTextView.getContext();
+            final TypedArray styledAttributes = context.obtainStyledAttributes(
                     com.android.internal.R.styleable.SelectionModeDrawables);
 
             mode.setTitle(mTextView.getContext().getString(
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 1098fa2..8aef304 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -18,6 +18,7 @@
 
 import android.app.ActivityOptions;
 import android.app.ActivityThread;
+import android.app.Application;
 import android.app.PendingIntent;
 import android.appwidget.AppWidgetHostView;
 import android.content.Context;
@@ -81,12 +82,6 @@
     private ApplicationInfo mApplication;
 
     /**
-     * The package name of the package containing the layout
-     * resource. (Added to the parcel)
-     */
-    private final String mPackage;
-
-    /**
      * The resource ID of the layout file. (Added to the parcel)
      */
     private final int mLayoutId;
@@ -1635,11 +1630,34 @@
      * @param layoutId The id of the layout resource
      */
     public RemoteViews(String packageName, int layoutId) {
-        mPackage = packageName;
+        this(getApplicationInfo(packageName, UserHandle.myUserId()), layoutId);
+    }
+
+    /**
+     * Create a new RemoteViews object that will display the views contained
+     * in the specified layout file.
+     *
+     * @param packageName Name of the package that contains the layout resource.
+     * @param userId The user under which the package is running.
+     * @param layoutId The id of the layout resource.
+     *
+     * @hide
+     */
+    public RemoteViews(String packageName, int userId, int layoutId) {
+        this(getApplicationInfo(packageName, userId), layoutId);
+    }
+
+    /**
+     * Create a new RemoteViews object that will display the views contained
+     * in the specified layout file.
+     *
+     * @param application The application whose content is shown by the views.
+     * @param layoutId The id of the layout resource.
+     */
+    private RemoteViews(ApplicationInfo application, int layoutId) {
+        mApplication = application;
         mLayoutId = layoutId;
         mBitmapCache = new BitmapCache();
-        mApplication = ActivityThread.currentApplication().getApplicationInfo();
-
         // setup the memory usage statistics
         mMemoryUsageCounter = new MemoryUsageCounter();
         recalculateMemoryUsage();
@@ -1660,10 +1678,11 @@
         if (landscape == null || portrait == null) {
             throw new RuntimeException("Both RemoteViews must be non-null");
         }
-        if (landscape.getPackage().compareTo(portrait.getPackage()) != 0) {
-            throw new RuntimeException("Both RemoteViews must share the same package");
+        if (landscape.mApplication.uid != portrait.mApplication.uid
+                || !landscape.mApplication.packageName.equals(portrait.mApplication.packageName)) {
+            throw new RuntimeException("Both RemoteViews must share the same package and user");
         }
-        mPackage = portrait.getPackage();
+        mApplication = portrait.mApplication;
         mLayoutId = portrait.getLayoutId();
 
         mLandscape = landscape;
@@ -1700,7 +1719,7 @@
         }
 
         if (mode == MODE_NORMAL) {
-            mPackage = parcel.readString();
+            mApplication = parcel.readParcelable(null);
             mLayoutId = parcel.readInt();
             mIsWidgetCollectionChild = parcel.readInt() == 1;
 
@@ -1764,12 +1783,10 @@
             // MODE_HAS_LANDSCAPE_AND_PORTRAIT
             mLandscape = new RemoteViews(parcel, mBitmapCache);
             mPortrait = new RemoteViews(parcel, mBitmapCache);
-            mPackage = mPortrait.getPackage();
+            mApplication = mPortrait.mApplication;
             mLayoutId = mPortrait.getLayoutId();
         }
 
-        mApplication = parcel.readParcelable(null);
-
         // setup the memory usage statistics
         mMemoryUsageCounter = new MemoryUsageCounter();
         recalculateMemoryUsage();
@@ -1786,7 +1803,7 @@
     }
 
     public String getPackage() {
-        return mPackage;
+        return mApplication.packageName;
     }
 
     /**
@@ -2565,19 +2582,7 @@
                 return context.createApplicationContext(mApplication,
                         Context.CONTEXT_RESTRICTED);
             } catch (NameNotFoundException e) {
-                Log.e(LOG_TAG, "Package name " + mPackage + " not found");
-            }
-        }
-
-        if (mPackage != null) {
-            if (context.getPackageName().equals(mPackage)) {
-                return context;
-            }
-            try {
-                return context.createPackageContext(
-                        mPackage, Context.CONTEXT_RESTRICTED);
-            } catch (NameNotFoundException e) {
-                Log.e(LOG_TAG, "Package name " + mPackage + " not found");
+                Log.e(LOG_TAG, "Package name " + mApplication.packageName + " not found");
             }
         }
 
@@ -2614,7 +2619,7 @@
             if (mIsRoot) {
                 mBitmapCache.writeBitmapsToParcel(dest, flags);
             }
-            dest.writeString(mPackage);
+            dest.writeParcelable(mApplication, flags);
             dest.writeInt(mLayoutId);
             dest.writeInt(mIsWidgetCollectionChild ? 1 : 0);
             int count;
@@ -2638,8 +2643,28 @@
             mLandscape.writeToParcel(dest, flags);
             mPortrait.writeToParcel(dest, flags);
         }
+    }
 
-        dest.writeParcelable(mApplication, 0);
+    private static ApplicationInfo getApplicationInfo(String packageName, int userId) {
+        // Get the application for the passed in package and user.
+        Application application = ActivityThread.currentApplication();
+        if (application == null) {
+            throw new IllegalStateException("Cannot create remote views out of an aplication.");
+        }
+
+        ApplicationInfo applicationInfo = application.getApplicationInfo();
+        if (UserHandle.getUserId(applicationInfo.uid) != userId
+                || !applicationInfo.packageName.equals(packageName)) {
+            try {
+                Context context = application.getApplicationContext().createPackageContextAsUser(
+                        packageName, 0, new UserHandle(userId));
+                applicationInfo = context.getApplicationInfo();
+            } catch (NameNotFoundException nnfe) {
+                throw new IllegalArgumentException("No such package " + packageName);
+            }
+        }
+
+        return applicationInfo;
     }
 
     /**
diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml
index 6988881..ccbb8bc 100644
--- a/core/res/res/values/colors_material.xml
+++ b/core/res/res/values/colors_material.xml
@@ -89,8 +89,8 @@
     <color name="material_teal_A200">#ff18ffff</color>
     <color name="material_teal_A400">#ff00e5ff</color>
 
-    <!-- Accent color used by Settings -->
-    <color name="material_dark_teal_A400">#ff009688</color>
+    <color name="material_deep_teal_A200">#ff80cbc4</color>
+    <color name="material_deep_teal_A500">#ff009688</color>
 
     <color name="material_green_100">#ffb7e1cd</color>
     <color name="material_green_300">#ff57bb8a</color>
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 42ebb82..e7001c3 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -372,7 +372,7 @@
         <!-- Color palette -->
         <item name="colorPrimaryDark">@color/material_blue_grey_900</item>
         <item name="colorPrimary">@color/material_blue_grey_800</item>
-        <item name="colorAccent">@color/material_light_blue_A200</item>
+        <item name="colorAccent">@color/material_deep_teal_A200</item>
 
         <item name="colorControlNormal">?attr/textColorSecondary</item>
         <item name="colorControlActivated">?attr/colorAccent</item>
@@ -712,9 +712,9 @@
         <item name="fastScrollOverlayPosition">atThumb</item>
 
         <!-- Color palette -->
-        <item name="colorPrimaryDark">@color/material_blue_grey_600</item>
-        <item name="colorPrimary">@color/material_blue_grey_400</item>
-        <item name="colorAccent">@color/material_light_blue_A200</item>
+        <item name="colorPrimaryDark">@color/material_blue_grey_100</item>
+        <item name="colorPrimary">@color/material_blue_grey_50</item>
+        <item name="colorAccent">@color/material_deep_teal_A500</item>
 
         <item name="colorControlNormal">?attr/textColorSecondary</item>
         <item name="colorControlActivated">?attr/colorAccent</item>
@@ -1229,7 +1229,7 @@
     <style name="Theme.Material.Settings" parent="@style/Theme.Material.Light.DarkActionBar">
         <item name="colorPrimary">@color/material_blue_grey_900</item>
         <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
-        <item name="colorAccent">@color/material_dark_teal_A400</item>
+        <item name="colorAccent">@color/material_deep_teal_A500</item>
     </style>
 
 </resources>
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 66daf87..591f543 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -78,6 +78,10 @@
     private static final int ZORDER_MEDIA_OVERLAY = 1;
     private static final int ZORDER_ON_TOP = 2;
 
+    private static final int CAPTION_DEFAULT = 0;
+    private static final int CAPTION_ENABLED = 1;
+    private static final int CAPTION_DISABLED = 2;
+
     private static final Object sMainTvViewLock = new Object();
     private static TvView sMainTvView;
 
@@ -107,6 +111,7 @@
     private int mSurfaceViewRight;
     private int mSurfaceViewTop;
     private int mSurfaceViewBottom;
+    private int mCaptionEnabled;
 
     private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
         @Override
@@ -353,6 +358,7 @@
      * @param enabled {@code true} to enable, {@code false} to disable.
      */
     public void setCaptionEnabled(boolean enabled) {
+        mCaptionEnabled = enabled ? CAPTION_ENABLED : CAPTION_DISABLED;
         if (mSession != null) {
             mSession.setCaptionEnabled(enabled);
         }
@@ -832,6 +838,9 @@
                     }
                 }
                 createSessionOverlayView();
+                if (mCaptionEnabled != CAPTION_DEFAULT) {
+                    mSession.setCaptionEnabled(mCaptionEnabled == CAPTION_ENABLED);
+                }
                 mSession.tune(mChannelUri, mTuneParams);
                 if (mHasStreamVolume) {
                     mSession.setStreamVolume(mStreamVolume);
diff --git a/packages/PrintSpooler/res/values/themes.xml b/packages/PrintSpooler/res/values/themes.xml
index 7d0da14..db319e9 100644
--- a/packages/PrintSpooler/res/values/themes.xml
+++ b/packages/PrintSpooler/res/values/themes.xml
@@ -16,16 +16,13 @@
 
 <resources>
 
-    <style name="PrintActivity" parent="@android:style/Theme.Material">
+    <style name="PrintActivity" parent="@android:style/Theme.Material.Settings">
         <item name="android:windowIsTranslucent">true</item>
         <item name="android:windowBackground">@android:color/transparent</item>
         <item name="android:windowContentOverlay">@null</item>
         <item name="android:windowActionBar">false</item>
         <item name="android:windowNoTitle">true</item>
         <item name="android:backgroundDimEnabled">false</item>
-        <item name="android:colorPrimary">@*android:color/material_blue_grey_900</item>
-        <item name="android:colorPrimaryDark">@*android:color/material_blue_grey_950</item>
-        <item name="android:colorAccent">@*android:color/material_dark_teal_A400</item>
     </style>
 
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 1c60c18..6beccc5 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -84,4 +84,8 @@
     <!-- The width/height of the phone/camera/unlock icon on keyguard. -->
     <dimen name="keyguard_affordance_height">80dp</dimen>
     <dimen name="keyguard_affordance_width">120dp</dimen>
+
+    <!-- The width of the region on the left/right edge of the screen for performing the camera/
+     phone hints. -->
+    <dimen name="edge_tap_area_width">80dp</dimen>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index 19bf121..6779e4e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -156,7 +156,6 @@
         drawBackgroundCircle(canvas);
         drawArrow(canvas);
         canvas.save();
-        updateIconColor();
         canvas.scale(mImageScale, mImageScale, getWidth() / 2, getHeight() / 2);
         super.onDraw(canvas);
         canvas.restore();
@@ -267,6 +266,7 @@
         if (!radiusNeedsAnimation) {
             if (mCircleAnimator == null) {
                 mCircleRadius = circleRadius;
+                updateIconColor();
                 invalidate();
                 if (nowHidden) {
                     if (mPreviewView != null) {
@@ -323,6 +323,7 @@
             @Override
             public void onAnimationUpdate(ValueAnimator animation) {
                 mCircleRadius = (float) animation.getAnimatedValue();
+                updateIconColor();
                 invalidate();
             }
         });
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index c673b98..b4faea1 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -38,6 +38,7 @@
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageDeleteObserver2;
 import android.content.pm.IPackageInstaller;
 import android.content.pm.IPackageInstallerCallback;
 import android.content.pm.IPackageInstallerSession;
@@ -540,17 +541,17 @@
     }
 
     @Override
-    public void uninstall(String packageName, int flags, IPackageDeleteObserver observer,
+    public void uninstall(String packageName, int flags, IPackageDeleteObserver2 observer,
             int userId) {
         mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "uninstall");
 
         // TODO: enforce installer of record or permission
-        mPm.deletePackageAsUser(packageName, observer, userId, flags);
+        mPm.deletePackage(packageName, observer, userId, flags);
     }
 
     @Override
     public void uninstallSplit(String basePackageName, String overlayName, int flags,
-            IPackageDeleteObserver observer, int userId) {
+            IPackageDeleteObserver2 observer, int userId) {
         mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "uninstallSplit");
 
         // TODO: flesh out once PM has split support
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 26019db..5443fbc 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -24,6 +24,7 @@
 import static android.system.OsConstants.O_RDONLY;
 import static android.system.OsConstants.O_WRONLY;
 
+import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.IPackageInstallerSession;
@@ -134,8 +135,8 @@
                     Slog.e(TAG, "Install failed: " + e);
                     destroyInternal();
                     try {
-                        mRemoteObserver.packageInstalled(mPackageName, null, e.error,
-                                e.getMessage());
+                        mRemoteObserver.onPackageInstalled(mPackageName, e.error, e.getMessage(),
+                                null);
                     } catch (RemoteException ignored) {
                     }
                     mCallback.onSessionFinished(PackageInstallerSession.this, false);
@@ -377,11 +378,16 @@
         final IPackageInstallObserver2 remoteObserver = mRemoteObserver;
         final IPackageInstallObserver2 localObserver = new IPackageInstallObserver2.Stub() {
             @Override
-            public void packageInstalled(String basePackageName, Bundle extras, int returnCode,
-                    String msg) {
+            public void onUserActionRequired(Intent intent) {
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
+                    Bundle extras) {
                 destroyInternal();
                 try {
-                    remoteObserver.packageInstalled(basePackageName, extras, returnCode, msg);
+                    remoteObserver.onPackageInstalled(basePackageName, returnCode, msg, extras);
                 } catch (RemoteException ignored) {
                 }
                 final boolean success = (returnCode == PackageManager.INSTALL_SUCCEEDED);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 6bedcfb..df1269ee 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -85,6 +85,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
+import android.app.PackageDeleteObserver;
 import android.app.admin.IDevicePolicyManager;
 import android.app.backup.IBackupManager;
 import android.content.BroadcastReceiver;
@@ -101,6 +102,7 @@
 import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageDeleteObserver2;
 import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.IPackageInstaller;
 import android.content.pm.IPackageManager;
@@ -1063,8 +1065,8 @@
                         if (args.observer != null) {
                             try {
                                 Bundle extras = extrasForInstallResult(res);
-                                args.observer.packageInstalled(res.name, extras, res.returnCode,
-                                        res.returnMsg);
+                                args.observer.onPackageInstalled(res.name, res.returnCode,
+                                        res.returnMsg, extras);
                             } catch (RemoteException e) {
                                 Slog.i(TAG, "Observer no longer exists.");
                             }
@@ -7723,7 +7725,7 @@
         if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) {
             try {
                 if (observer != null) {
-                    observer.packageInstalled("", null, INSTALL_FAILED_USER_RESTRICTED, null);
+                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
                 }
             } catch (RemoteException re) {
             }
@@ -10486,9 +10488,15 @@
     }
 
     @Override
-    public void deletePackageAsUser(final String packageName,
-                                    final IPackageDeleteObserver observer,
-                                    final int userId, final int flags) {
+    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
+            int flags) {
+        deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
+                flags);
+    }
+
+    @Override
+    public void deletePackage(final String packageName,
+            final IPackageDeleteObserver2 observer, final int userId, final int flags) {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.DELETE_PACKAGES, null);
         final int uid = Binder.getCallingUid();
@@ -10499,7 +10507,8 @@
         }
         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
             try {
-                observer.packageDeleted(packageName, PackageManager.DELETE_FAILED_USER_RESTRICTED);
+                observer.onPackageDeleted(packageName,
+                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
             } catch (RemoteException re) {
             }
             return;
@@ -10519,7 +10528,8 @@
         }
         if (uninstallBlocked) {
             try {
-                observer.packageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED);
+                observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED,
+                        null);
             } catch (RemoteException re) {
             }
             return;
@@ -10535,7 +10545,7 @@
                 final int returnCode = deletePackageX(packageName, userId, flags);
                 if (observer != null) {
                     try {
-                        observer.packageDeleted(packageName, returnCode);
+                        observer.onPackageDeleted(packageName, returnCode, null);
                     } catch (RemoteException e) {
                         Log.i(TAG, "Observer no longer exists.");
                     } //end catch
@@ -13407,4 +13417,20 @@
             return false;
         }
     }
+
+    private static class LegacyPackageDeleteObserver extends PackageDeleteObserver {
+        private final IPackageDeleteObserver mLegacy;
+
+        public LegacyPackageDeleteObserver(IPackageDeleteObserver legacy) {
+            mLegacy = legacy;
+        }
+
+        @Override
+        public void onPackageDeleted(String basePackageName, int returnCode, String msg) {
+            try {
+                mLegacy.packageDeleted(basePackageName, returnCode);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
 }
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 755a77a..ccbdadd 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -752,6 +752,7 @@
     config.screenWidthDp = 320;
     config.screenHeightDp = 480;
     config.smallestScreenWidthDp = 320;
+    config.screenLayout |= ResTable_config::SCREENSIZE_NORMAL;
     assets.setConfiguration(config);
 
     const ResTable& res = assets.getResources(false);