Merge "Add a checkbox option to 'require password to decrypt'" into lmp-dev
diff --git a/api/current.txt b/api/current.txt
index 09497a5..953cfe0 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -22333,7 +22333,6 @@
     field public static final java.lang.String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
     field public static final java.lang.String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
     field public static final java.lang.String DISALLOW_MOUNT_PHYSICAL_MEDIA = "no_physical_media";
-    field public static final java.lang.String DISALLOW_OUTGOING_BEAM = "no_outgoing_beam";
     field public static final java.lang.String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls";
     field public static final java.lang.String DISALLOW_REMOVE_USER = "no_remove_user";
     field public static final java.lang.String DISALLOW_SHARE_LOCATION = "no_share_location";
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 0e98175..4b705dd 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3847,14 +3847,14 @@
      * their launch had come from the original activity.
      * @hide
      */
-    public void startActivityAsCaller(Intent intent, @Nullable Bundle options) {
+    public void startActivityAsCaller(Intent intent, @Nullable Bundle options, int userId) {
         if (mParent != null) {
             throw new RuntimeException("Can't be called from a child");
         }
         Instrumentation.ActivityResult ar =
                 mInstrumentation.execStartActivityAsCaller(
                         this, mMainThread.getApplicationThread(), mToken, this,
-                        intent, -1, options);
+                        intent, -1, options, userId);
         if (ar != null) {
             mMainThread.sendActivityResult(
                 mToken, mEmbeddedID, -1, ar.getResultCode(),
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 6c67c09..4e2ff0b 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -184,8 +184,9 @@
                     ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
             Bundle options = data.readInt() != 0
                     ? Bundle.CREATOR.createFromParcel(data) : null;
+            int userId = data.readInt();
             int result = startActivityAsCaller(app, callingPackage, intent, resolvedType,
-                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
+                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options, userId);
             reply.writeNoException();
             reply.writeInt(result);
             return true;
@@ -2435,7 +2436,7 @@
     }
     public int startActivityAsCaller(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
-            int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
+            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
@@ -2459,6 +2460,7 @@
         } else {
             data.writeInt(0);
         }
+        data.writeInt(userId);
         mRemote.transact(START_ACTIVITY_AS_CALLER_TRANSACTION, data, reply, 0);
         reply.readException();
         int result = reply.readInt();
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index 841bd16..49ab7c1 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -388,7 +388,7 @@
             dest.writeInt(throwLineNumber);
             dest.writeString(stackTrace);
             int total = dest.dataPosition()-start;
-            if (total > 10*1024) {
+            if (total > 20*1024) {
                 Slog.d("Error", "ERR: exClass=" + exceptionClassName);
                 Slog.d("Error", "ERR: exMsg=" + exceptionMessage);
                 Slog.d("Error", "ERR: file=" + throwFileName);
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index b72addf..be26f30 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -69,7 +69,7 @@
             ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException;
     public int startActivityAsCaller(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
-            int flags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException;
+            int flags, ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException;
     public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho,
             int requestCode, int flags, ProfilerInfo profilerInfo, Bundle options,
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index ba3a234..60a013e 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1671,7 +1671,7 @@
      */
     public ActivityResult execStartActivityAsCaller(
             Context who, IBinder contextThread, IBinder token, Activity target,
-            Intent intent, int requestCode, Bundle options) {
+            Intent intent, int requestCode, Bundle options, int userId) {
         IApplicationThread whoThread = (IApplicationThread) contextThread;
         if (mActivityMonitors != null) {
             synchronized (mSync) {
@@ -1695,7 +1695,7 @@
                 .startActivityAsCaller(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target != null ? target.mEmbeddedID : null,
-                        requestCode, 0, null, options);
+                        requestCode, 0, null, options, userId);
             checkStartActivityResult(result, intent);
         } catch (RemoteException e) {
         }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 2eba29a..a30ae57 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -439,14 +439,20 @@
             = "android.app.action.SET_NEW_PASSWORD";
 
     /**
-     * Flag used by {@link #addCrossProfileIntentFilter} to allow access of certain intents from a
-     * managed profile to its parent.
+     * Flag used by {@link #addCrossProfileIntentFilter} to allow access
+     * <em>from</em> a managed profile <em>to</em> its parent. That is, any
+     * matching activities in the parent profile are included in the
+     * disambiguation list shown when an app in the managed profile calls
+     * {@link Activity#startActivity(Intent)}.
      */
     public static final int FLAG_PARENT_CAN_ACCESS_MANAGED = 0x0001;
 
     /**
-     * Flag used by {@link #addCrossProfileIntentFilter} to allow access of certain intents from the
-     * parent to its managed profile.
+     * Flag used by {@link #addCrossProfileIntentFilter} to allow access
+     * <em>from</em> a parent <em>to</em> its managed profile. That is, any
+     * matching activities in the managed profile are included in the
+     * disambiguation list shown when an app in the parent profile calls
+     * {@link Activity#startActivity(Intent)}.
      */
     public static final int FLAG_MANAGED_CAN_ACCESS_PARENT = 0x0002;
 
@@ -1335,7 +1341,7 @@
      * {@link DeviceAdminInfo#USES_POLICY_RESET_PASSWORD} to be able to call
      * this method; if it has not, a security exception will be thrown.
      *
-     * Can not be called from a managed profile.
+     * <p>Calling this from a managed profile will throw a security exception.
      *
      * @param password The new password for the user.
      * @param flags May be 0 or {@link #RESET_PASSWORD_REQUIRE_ENTRY}.
@@ -1881,8 +1887,8 @@
 
     /**
      * Called by an application that is administering the device to disable all cameras
-     * on the device.  After setting this, no applications will be able to access any cameras
-     * on the device.
+     * on the device, for this user. After setting this, no applications running as this user
+     * will be able to access any cameras on the device.
      *
      * <p>The calling device admin must have requested
      * {@link DeviceAdminInfo#USES_POLICY_DISABLE_CAMERA} to be able to call
@@ -1902,8 +1908,8 @@
     }
 
     /**
-     * Determine whether or not the device's cameras have been disabled either by the current
-     * admin, if specified, or all admins.
+     * Determine whether or not the device's cameras have been disabled for this user,
+     * either by the current admin, if specified, or all admins.
      * @param admin The name of the admin component to check, or null to check if any admins
      * have disabled the camera
      */
@@ -2012,6 +2018,8 @@
      * {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} to be able to call
      * this method; if it has not, a security exception will be thrown.
      *
+     * <p>Calling this from a managed profile will throw a security exception.
+     *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param which {@link #KEYGUARD_DISABLE_FEATURES_NONE} (default),
      * {@link #KEYGUARD_DISABLE_WIDGETS_ALL}, {@link #KEYGUARD_DISABLE_SECURE_CAMERA},
diff --git a/core/java/android/content/pm/IPackageInstaller.aidl b/core/java/android/content/pm/IPackageInstaller.aidl
index 6daefc8..ba62cd6 100644
--- a/core/java/android/content/pm/IPackageInstaller.aidl
+++ b/core/java/android/content/pm/IPackageInstaller.aidl
@@ -20,6 +20,7 @@
 import android.content.pm.IPackageInstallerCallback;
 import android.content.pm.IPackageInstallerSession;
 import android.content.pm.PackageInstaller;
+import android.content.pm.ParceledListSlice;
 import android.content.IntentSender;
 
 import android.graphics.Bitmap;
@@ -37,8 +38,8 @@
 
     PackageInstaller.SessionInfo getSessionInfo(int sessionId);
 
-    List<PackageInstaller.SessionInfo> getAllSessions(int userId);
-    List<PackageInstaller.SessionInfo> getMySessions(String installerPackageName, int userId);
+    ParceledListSlice getAllSessions(int userId);
+    ParceledListSlice getMySessions(String installerPackageName, int userId);
 
     void registerCallback(IPackageInstallerCallback callback, int userId);
     void unregisterCallback(IPackageInstallerCallback callback);
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 765b2a9..b66bd01 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -235,6 +235,9 @@
     public int installLocation = INSTALL_LOCATION_INTERNAL_ONLY;
 
     /** @hide */
+    public boolean coreApp;
+
+    /** @hide */
     public boolean requiredForAllUsers;
 
     /** @hide */
@@ -293,6 +296,7 @@
         dest.writeTypedArray(reqFeatures, parcelableFlags);
         dest.writeTypedArray(featureGroups, parcelableFlags);
         dest.writeInt(installLocation);
+        dest.writeInt(coreApp ? 1 : 0);
         dest.writeInt(requiredForAllUsers ? 1 : 0);
         dest.writeString(restrictedAccountType);
         dest.writeString(requiredAccountType);
@@ -337,6 +341,7 @@
         reqFeatures = source.createTypedArray(FeatureInfo.CREATOR);
         featureGroups = source.createTypedArray(FeatureGroupInfo.CREATOR);
         installLocation = source.readInt();
+        coreApp = source.readInt() != 0;
         requiredForAllUsers = source.readInt() != 0;
         restrictedAccountType = source.readString();
         requiredAccountType = source.readString();
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index f249c5f..80efd0b 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -399,7 +399,7 @@
         }
 
         try {
-            return mInstaller.getAllSessions(mUserId);
+            return mInstaller.getAllSessions(mUserId).getList();
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
@@ -410,7 +410,7 @@
      */
     public @NonNull List<SessionInfo> getMySessions() {
         try {
-            return mInstaller.getMySessions(mInstallerPackageName, mUserId);
+            return mInstaller.getMySessions(mInstallerPackageName, mUserId).getList();
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 3364741..ca4ff6a 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -415,6 +415,7 @@
         pi.sharedUserLabel = p.mSharedUserLabel;
         pi.applicationInfo = generateApplicationInfo(p, flags, state, userId);
         pi.installLocation = p.installLocation;
+        pi.coreApp = p.coreApp;
         if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0
                 || (pi.applicationInfo.flags&ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
             pi.requiredForAllUsers = p.mRequiredForAllUsers;
@@ -1384,6 +1385,8 @@
                 PARSE_DEFAULT_INSTALL_LOCATION);
         pkg.applicationInfo.installLocation = pkg.installLocation;
 
+        pkg.coreApp = attrs.getAttributeBooleanValue(null, "coreApp", false);
+
         sa.recycle();
 
         /* Set the global "forward lock" flag */
@@ -4267,6 +4270,8 @@
 
         public int installLocation;
 
+        public boolean coreApp;
+
         /* An app that's required for all users and cannot be uninstalled for a user */
         public boolean mRequiredForAllUsers;
 
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 1368f39..3234e77 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -367,6 +367,7 @@
      * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
+     * @hide
      */
     public static final String DISALLOW_OUTGOING_BEAM = "no_outgoing_beam";
 
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index d9493752..6e2f84a 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -20,26 +20,28 @@
 
 import android.app.Activity;
 import android.app.ActivityManagerNative;
+import android.app.ActivityThread;
 import android.app.AppGlobals;
-import android.os.Bundle;
+import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.IPackageManager;
 import android.content.pm.UserInfo;
+import android.os.Bundle;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.Slog;
 import android.widget.Toast;
+
 import java.util.List;
-import java.util.Set;
 
-/*
- * This is used in conjunction with the {@link setCrossProfileIntentFilter} method of
- * {@link DevicePolicyManager} to enable intents to be passed in and out of a managed profile.
+/**
+ * This is used in conjunction with
+ * {@link DevicePolicyManager#addCrossProfileIntentFilter} to enable intents to
+ * be passed in and out of a managed profile.
  */
-
 public class IntentForwarderActivity extends Activity  {
 
     public static String TAG = "IntentForwarderActivity";
@@ -104,7 +106,23 @@
             final boolean shouldShowDisclosure =
                     !UserHandle.isSameApp(ri.activityInfo.applicationInfo.uid, Process.SYSTEM_UID);
 
-            startActivityAsUser(newIntent, userDest);
+            try {
+                startActivityAsCaller(newIntent, null, userDest.getIdentifier());
+            } catch (RuntimeException e) {
+                int launchedFromUid = -1;
+                String launchedFromPackage = "?";
+                try {
+                    launchedFromUid = ActivityManagerNative.getDefault().getLaunchedFromUid(
+                            getActivityToken());
+                    launchedFromPackage = ActivityManagerNative.getDefault().getLaunchedFromPackage(
+                            getActivityToken());
+                } catch (RemoteException ignored) {
+                }
+
+                Slog.wtf(TAG, "Unable to launch as UID " + launchedFromUid + " package "
+                        + launchedFromPackage + ", while running in "
+                        + ActivityThread.currentProcessName(), e);
+            }
 
             if (shouldShowDisclosure) {
                 Toast.makeText(this, getString(userMessageId), Toast.LENGTH_LONG).show();
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index aa55d23..0062e2d 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -641,7 +641,7 @@
             return;
         }
         try {
-            startActivityAsCaller(intent, null);
+            startActivityAsCaller(intent, null, UserHandle.USER_NULL);
         } catch (RuntimeException e) {
             String launchedFromPackage;
             try {
diff --git a/core/res/res/values-mcc234-mnc08/config.xml b/core/res/res/values-mcc234-mnc08/config.xml
new file mode 100644
index 0000000..13d4d8f
--- /dev/null
+++ b/core/res/res/values-mcc234-mnc08/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>23430</item>
+        <item>23433</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4aabc84..c156887 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4839,17 +4839,17 @@
     <string name="day_of_week_label_typeface">sans-serif</string>
 
     <!-- Notify use that they are in Lock-to-app -->
-    <string name="lock_to_app_toast">To unpin this screen, touch and hold  Back and Recents at the same time.</string>
+    <string name="lock_to_app_toast">To unpin this screen, touch and hold Back and Overview at the same time.</string>
     <!-- Notify use that they are in Lock-to-app in accessibility mode -->
-    <string name="lock_to_app_toast_accessible">To unpin this screen, touch and hold Recents.</string>
+    <string name="lock_to_app_toast_accessible">To unpin this screen, touch and hold Overview.</string>
     <!-- Notify user that they are locked in lock-to-app mode -->
     <string name="lock_to_app_toast_locked">Screen is pinned. Unpinning isn\'t allowed by your organization.</string>
     <!-- Lock-to-app dialog title. -->
     <string name="lock_to_app_title">Use screen pinning?</string>
     <!-- Lock-to-app dialog description. -->
-    <string name="lock_to_app_description">Screen pinning locks the display in a single view.\n\nTo exit, touch and hold Back and Recents at the same time.</string>
+    <string name="lock_to_app_description">Screen pinning locks the display in a single view.\n\nTo unpin, touch and hold Back and Overview at the same time.</string>
     <!-- Lock-to-app dialog description when in accessibility mode. -->
-    <string name="lock_to_app_description_accessible">Screen pinning locks the display in a single view.\n\nTo exit, touch and hold Recents.</string>
+    <string name="lock_to_app_description_accessible">Screen pinning locks the display in a single view.\n\nTo unpin, touch and hold Overview.</string>
     <!-- Lock-to-app negative response. -->
     <string name="lock_to_app_negative">NO, THANKS</string>
     <!-- Lock-to-app positive response. -->
diff --git a/docs/html/design/media/dialogs_examples.png b/docs/html/design/media/dialogs_examples.png
index 6ffcee2..c136476 100644
--- a/docs/html/design/media/dialogs_examples.png
+++ b/docs/html/design/media/dialogs_examples.png
Binary files differ
diff --git a/docs/html/design/media/navigation_drawer_titles_icons.png b/docs/html/design/media/navigation_drawer_titles_icons.png
index 902a72d..7cf1e0c 100644
--- a/docs/html/design/media/navigation_drawer_titles_icons.png
+++ b/docs/html/design/media/navigation_drawer_titles_icons.png
Binary files differ
diff --git a/docs/html/design/media/selection_adjusting_actions.png b/docs/html/design/media/selection_adjusting_actions.png
index 32a7fec..0799b6b 100644
--- a/docs/html/design/media/selection_adjusting_actions.png
+++ b/docs/html/design/media/selection_adjusting_actions.png
Binary files differ
diff --git a/docs/html/design/media/touch_feedback_communication.png b/docs/html/design/media/touch_feedback_communication.png
index 1d4a9dc..f8162d0 100644
--- a/docs/html/design/media/touch_feedback_communication.png
+++ b/docs/html/design/media/touch_feedback_communication.png
Binary files differ
diff --git a/docs/html/design/media/ui_overview_notifications.png b/docs/html/design/media/ui_overview_notifications.png
index 7975657..6043412 100644
--- a/docs/html/design/media/ui_overview_notifications.png
+++ b/docs/html/design/media/ui_overview_notifications.png
Binary files differ
diff --git a/docs/html/guide/topics/connectivity/nfc/nfc.jd b/docs/html/guide/topics/connectivity/nfc/nfc.jd
index 19ce4d7..520f520 100644
--- a/docs/html/guide/topics/connectivity/nfc/nfc.jd
+++ b/docs/html/guide/topics/connectivity/nfc/nfc.jd
@@ -105,8 +105,8 @@
 the specification of the type of record that you want to create. Android
 also supports other types of tags that do not contain NDEF data, which you can work with by using
 the classes in the {@link android.nfc.tech} package. To learn more
-about these technologies, see the <a href="{@docRoot}guide/topics/connectivity/nfc/advanced-nfc.html">Advanced
-NFC</a> topic. Working with these other types of tags involves
+about these technologies, see the <a href="{@docRoot}guide/topics/connectivity/nfc/advanced-nfc.html
+">Advanced NFC</a> topic. Working with these other types of tags involves
 writing your own protocol stack to communicate with the tags, so we recommend using NDEF when
 possible for ease of development and maximum support for Android-powered devices.
 </p>
@@ -477,8 +477,8 @@
   <li>{@link android.nfc.NfcAdapter#EXTRA_TAG} (required): A {@link android.nfc.Tag} object
 representing the scanned tag.</li>
   <li>{@link android.nfc.NfcAdapter#EXTRA_NDEF_MESSAGES} (optional): An array of NDEF messages
-parsed from the tag. This extra is mandatory on {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED}
-intents.</li>
+parsed from the tag. This extra is mandatory on
+{@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intents.</li>
   <li>{@link android.nfc.NfcAdapter#EXTRA_ID} (optional): The low-level ID of the tag.</li></ul>
 
 <p>To obtain these extras, check to see if your activity was launched with one of
@@ -513,7 +513,8 @@
 <p>This section describes how to create common types of NDEF records to help you when writing to
 NFC tags or sending data with Android Beam. Starting with Android 4.0 (API level 14), the
 {@link android.nfc.NdefRecord#createUri createUri()} method is available to help you create
-URI records automatically. Starting in Android 4.1 (API level 16), {@link android.nfc.NdefRecord#createExternal createExternal()}
+URI records automatically. Starting in Android 4.1 (API level 16),
+{@link android.nfc.NdefRecord#createExternal createExternal()}
 and {@link android.nfc.NdefRecord#createMime createMime()} are available to help you create
 MIME and external type NDEF records. Use these helper methods whenever possible to avoid mistakes
 when manually creating NDEF records.</p>
@@ -528,7 +529,8 @@
   <a href="#well-known-uri"><code>RTD_URI</code></a> type instead
   of {@link android.nfc.NdefRecord#TNF_ABSOLUTE_URI}, because it is more efficient.</p>
 
-<p>You can create a {@link android.nfc.NdefRecord#TNF_ABSOLUTE_URI} NDEF record in the following way:</p>
+<p>You can create a {@link android.nfc.NdefRecord#TNF_ABSOLUTE_URI} NDEF record in the following way
+:</p>
 
 <pre>
 NdefRecord uriRecord = new NdefRecord(
@@ -549,7 +551,8 @@
 </pre>
 
 <h3 id="mime">TNF_MIME_MEDIA</h3>
-<p>You can create a {@link android.nfc.NdefRecord#TNF_MIME_MEDIA} NDEF record in the following ways.</p>
+<p>You can create a {@link android.nfc.NdefRecord#TNF_MIME_MEDIA} NDEF record in the following ways:
+</p>
 
 <p>Using the {@link android.nfc.NdefRecord#createMime createMime()} method:</p>
 <pre>
@@ -576,7 +579,8 @@
 
 <h3 id="well-known-text">TNF_WELL_KNOWN with RTD_TEXT</h3>
 
-<p>You can create a {@link android.nfc.NdefRecord#TNF_WELL_KNOWN} NDEF record in the following way:</p>
+<p>You can create a {@link android.nfc.NdefRecord#TNF_WELL_KNOWN} NDEF record in the following way:
+</p>
 <pre>
 public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) {
     byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));
@@ -606,7 +610,8 @@
 
 <h3 id="well-known-uri">TNF_WELL_KNOWN with RTD_URI</h3>
 
-<p>You can create a {@link android.nfc.NdefRecord#TNF_WELL_KNOWN} NDEF record in the following ways.</p>
+<p>You can create a {@link android.nfc.NdefRecord#TNF_WELL_KNOWN} NDEF record in the following ways:
+</p>
 
 <p>Using the {@link android.nfc.NdefRecord#createUri(String)} method:</p>
 <pre>
@@ -642,7 +647,8 @@
 </pre>
 
 <h3 id="ext-type">TNF_EXTERNAL_TYPE</h3>
-<p>You can create a {@link android.nfc.NdefRecord#TNF_EXTERNAL_TYPE} NDEF record in the following ways:</p>
+<p>You can create a {@link android.nfc.NdefRecord#TNF_EXTERNAL_TYPE} NDEF record in the following
+ways:</p>
 
 <p>Using the {@link android.nfc.NdefRecord#createExternal createExternal()} method:
 <pre>
@@ -681,19 +687,19 @@
 declares that the <code>urn:nfc:ext:</code> portion of the URN must be ommitted from the
 NDEF record. So all you need to provide is the domain (<code>example.com</code> in the example)
 and type (<code>externalType</code> in the example) separated by a colon.
-When dispatching TNF_EXTERNAL_TYPE, Android converts the <code>urn:nfc:ext:example.com:externalType</code> URN to a
-<code>vnd.android.nfc://ext/example.com:externalType</code> URI, which is what the intent filter in the example
-declares.</p>
+When dispatching TNF_EXTERNAL_TYPE, Android converts the <code>urn:nfc:ext:example.com:externalType
+</code> URN to a <code>vnd.android.nfc://ext/example.com:externalType</code> URI, which is what the
+intent filter in the example declares.</p>
 
 <h3 id="aar">Android Application Records</h3>
 
 <p>
 Introduced in Android 4.0 (API level 14), an Android Application Record (AAR) provides a stronger
 certainty that your application is started when an NFC tag is scanned. An AAR has the package name
-of an application embedded inside an NDEF record. You can add an AAR to any NDEF record of your NDEF message,
-because Android searches the entire NDEF message for AARs. If it finds an AAR, it starts the application based
-on the package name inside the AAR. If the application is not present on the device,
-Google Play is launched to download the application.</p>
+of an application embedded inside an NDEF record. You can add an AAR to any NDEF record of your NDEF
+message, because Android searches the entire NDEF message for AARs. If it finds an AAR, it starts
+the application based on the package name inside the AAR. If the application is not present on the
+device, Google Play is launched to download the application.</p>
 
 <p>AARs are useful if you want to prevent other applications from filtering for the same intent and
 potentially handling specific tags that you have deployed. AARs are only supported at the
@@ -717,11 +723,11 @@
 
 </p>
 
-<p class="note"><strong>Note:</strong> You can override AARs and the intent dispatch system with the <a
-href="{@docRoot}guide/topics/connectivity/nfc/advanced-nfc.html#foreground-dispatch">foreground dispatch
-system</a>, which allows a foreground activity to have priority when an NFC tag is discovered.
-With this method, the activity must be in the foreground to
-override AARs and the intent dispatch system.</p>
+<p class="note"><strong>Note:</strong> You can override AARs and the intent dispatch system with the
+ <ahref="{@docRoot}guide/topics/connectivity/nfc/advanced-nfc.html#foreground-dispatch">foreground
+ dispatch system</a>, which allows a foreground activity to have priority when an NFC tag is
+ discovered. With this method, the activity must be in the foreground to override AARs and the
+ intent dispatch system.</p>
 
 <p>If you still want to filter for scanned tags that do not contain an AAR, you can declare
 intent filters as normal. This is useful if your application is interested in other tags
@@ -799,9 +805,9 @@
 
   <p class="note"><strong>Note:</strong> If your activity enables Android Beam and is
 in the foreground, the standard intent dispatch system is disabled. However, if your activity also
-enables <a href="{@docRoot}guide/topics/connectivity/nfc/advanced-nfc.html#foreground-dispatch">foreground
-dispatching</a>, then it can still scan tags that match the intent filters set in the foreground
-dispatching.</p>
+enables <a href="{@docRoot}guide/topics/connectivity/nfc/advanced-nfc.html#foreground-dispatch">
+foreground dispatching</a>, then it can still scan tags that match the intent filters set in the
+foreground dispatching.</p>
 
   <p>To enable Android Beam:</p>
 
diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd
index b9803e4..20388be 100644
--- a/docs/html/tools/sdk/tools-notes.jd
+++ b/docs/html/tools/sdk/tools-notes.jd
@@ -29,6 +29,38 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>SDK Tools, Revision 23.0.5</a> <em>(October 2014)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <dl>
+    <dt>Dependencies:</dt>
+
+    <dd>
+      <ul>
+        <li>Android SDK Platform-tools revision 19 or later.</li>
+        <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
+          designed for use with ADT 23.0.4 and later. If you haven't already, update your
+        <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 23.0.4.</li>
+        <li>If you are developing outside Eclipse, you must have
+          <a href="http://ant.apache.org/">Apache Ant</a> 1.8 or later.</li>
+      </ul>
+    </dd>
+
+    <dt>General Notes:</dt>
+    <dd>
+      <ul>
+        <li>Fixed Windows 32-bit compilation issue.</li>
+      </ul>
+    </dd>
+  </div>
+</div>
+
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>SDK Tools, Revision 23.0.4</a> <em>(October 2014)</em>
   </p>
 
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 84ada6f..20254f0 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -286,7 +286,9 @@
                 mFileProvider, new RemotePrintDocument.RemoteAdapterDeathObserver() {
             @Override
             public void onDied() {
-                if (isFinishing()) {
+                // If we are finishing or we are in a state that we do not need any
+                // data from the printing app, then no need to finish.
+                if (isFinishing() || (isFinalState(mState) && !mPrintedDocument.isUpdating())) {
                     return;
                 }
                 setState(STATE_PRINT_CANCELED);
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 9ee18f3..71b9b61 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -40,8 +40,8 @@
 
     <!-- Message that is read when you enter recent apps in TalkBack -->
     <plurals name="status_bar_accessibility_recent_apps">
-        <item quantity="one">1 recent app</item>
-        <item quantity="other">%d recent apps</item>
+        <item quantity="one">1 screen in Overview</item>
+        <item quantity="other">%d screens in Overview</item>
     </plurals>
 
     <!-- The label in the bar at the top of the status bar when there are no notifications
@@ -206,7 +206,7 @@
     <!-- Content description of the menu button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_menu">Menu</string>
     <!-- Content description of the recents button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
-    <string name="accessibility_recent">Recent screens</string>
+    <string name="accessibility_recent">Overview</string>
     <!-- Content description of the search button for accessibility. [CHAR LIMIT=NONE] -->
     <string name="accessibility_search_light">Search</string>
     <!-- Content description of the camera button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
@@ -413,7 +413,7 @@
     <!-- Content description for the settings button in the status bar header. [CHAR LIMIT=NONE] -->
     <string name="accessibility_desc_settings">Settings</string>
     <!-- Content description for the recent apps panel (not shown on the screen). [CHAR LIMIT=NONE] -->
-    <string name="accessibility_desc_recent_apps">Recent screens.</string>
+    <string name="accessibility_desc_recent_apps">Overview.</string>
 
     <!-- Content description of the user tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_user">User <xliff:g id="user" example="John Doe">%s</xliff:g>.</string>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index d8c99f8..a7ff0bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -372,6 +372,7 @@
     }
 
     protected void onTrackingStarted() {
+        mClosing = false;
         mTracking = true;
         mCollapseAfterPeek = false;
         mBar.onTrackingStarted(PanelView.this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index e4a1c27..853628e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -738,8 +738,9 @@
             if (mExpandedOnStart) {
 
                 // We are collapsing the shade, so the first child can get as most as high as the
-                // current height.
-                mFirstChildMaxHeight = mFirstChildWhileExpanding.getActualHeight();
+                // current height or the end value of the animation.
+                mFirstChildMaxHeight = StackStateAnimator.getFinalActualHeight(
+                        mFirstChildWhileExpanding);
             } else {
                 updateFirstChildMaxSizeToMaxHeight();
             }
@@ -801,9 +802,14 @@
         this.mIsExpanded = isExpanded;
     }
 
-    public void notifyChildrenChanged(ViewGroup hostView) {
+    public void notifyChildrenChanged(final ViewGroup hostView) {
         if (mIsExpansionChanging) {
-            updateFirstChildHeightWhileExpanding(hostView);
+            hostView.post(new Runnable() {
+                @Override
+                public void run() {
+                    updateFirstChildHeightWhileExpanding(hostView);
+                }
+            });
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index a69390e..433357e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -709,7 +709,7 @@
         };
     }
 
-    private <T> T getChildTag(View child, int tag) {
+    private static <T> T getChildTag(View child, int tag) {
         return (T) child.getTag(tag);
     }
 
@@ -848,4 +848,20 @@
             currentAnimator.cancel();
         }
     }
+
+    /**
+     * Get the end value of the height animation running on a view or the actualHeight
+     * if no animation is running.
+     */
+    public static int getFinalActualHeight(ExpandableView view) {
+        if (view == null) {
+            return 0;
+        }
+        ValueAnimator heightAnimator = getChildTag(view, TAG_ANIMATOR_HEIGHT);
+        if (heightAnimator == null) {
+            return view.getActualHeight();
+        } else {
+            return getChildTag(view, TAG_END_HEIGHT);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 0b253f5..f02a815 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -69,6 +69,7 @@
     static final boolean DEBUG_DELAYED_SERVICE = ActivityManagerService.DEBUG_SERVICE;
     static final boolean DEBUG_DELAYED_STARTS = DEBUG_DELAYED_SERVICE;
     static final boolean DEBUG_MU = ActivityManagerService.DEBUG_MU;
+    static final boolean LOG_SERVICE_START_STOP = false;
     static final String TAG = ActivityManagerService.TAG;
     static final String TAG_MU = ActivityManagerService.TAG_MU;
 
@@ -1447,8 +1448,10 @@
             String nameTerm;
             int lastPeriod = r.shortName.lastIndexOf('.');
             nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
-            EventLogTags.writeAmCreateService(
-                    r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
+            if (LOG_SERVICE_START_STOP) {
+                EventLogTags.writeAmCreateService(
+                        r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
+            }
             synchronized (r.stats.getBatteryStats()) {
                 r.stats.startLaunchedLocked();
             }
@@ -1632,8 +1635,10 @@
         }
 
         if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
-        EventLogTags.writeAmDestroyService(
-                r.userId, System.identityHashCode(r), (r.app != null) ? r.app.pid : -1);
+        if (LOG_SERVICE_START_STOP) {
+            EventLogTags.writeAmDestroyService(
+                    r.userId, System.identityHashCode(r), (r.app != null) ? r.app.pid : -1);
+        }
 
         final ServiceMap smap = getServiceMap(r.userId);
         smap.mServicesByName.remove(r.name);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 8357366..8dfb321 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3561,7 +3561,7 @@
     @Override
     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
-            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
+            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
 
         // This is very dangerous -- it allows you to perform a start activity (including
         // permission grants) as any app that may launch one of your own activities.  So
@@ -3599,11 +3599,15 @@
             targetPackage = sourceRecord.launchedFromPackage;
         }
 
+        if (userId == UserHandle.USER_NULL) {
+            userId = UserHandle.getUserId(sourceRecord.app.uid);
+        }
+
         // TODO: Switch to user app stacks here.
         try {
             int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
-                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
+                    null, null, options, userId, null, null);
             return ret;
         } catch (SecurityException e) {
             // XXX need to figure out how to propagate to original app.
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 198273e..1a0e45e 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -205,17 +205,20 @@
                     pw.print(" resultWho="); pw.print(resultWho);
                     pw.print(" resultCode="); pw.println(requestCode);
         }
-        final String iconFilename = taskDescription.getIconFilename();
-        if (iconFilename != null || taskDescription.getLabel() != null ||
-                taskDescription.getPrimaryColor() != 0) {
-            pw.print(prefix); pw.print("taskDescription:");
-                    pw.print(" iconFilename="); pw.print(taskDescription.getIconFilename());
-                    pw.print(" label=\""); pw.print(taskDescription.getLabel()); pw.print("\"");
-                    pw.print(" color=");
-                    pw.println(Integer.toHexString(taskDescription.getPrimaryColor()));
-        }
-        if (iconFilename == null && taskDescription.getIcon() != null) {
-            pw.print(prefix); pw.println("taskDescription contains Bitmap");
+        if (taskDescription != null) {
+            final String iconFilename = taskDescription.getIconFilename();
+            if (iconFilename != null || taskDescription.getLabel() != null ||
+                    taskDescription.getPrimaryColor() != 0) {
+                pw.print(prefix); pw.print("taskDescription:");
+                        pw.print(" iconFilename="); pw.print(taskDescription.getIconFilename());
+                        pw.print(" label=\""); pw.print(taskDescription.getLabel());
+                                pw.print("\"");
+                        pw.print(" color=");
+                        pw.println(Integer.toHexString(taskDescription.getPrimaryColor()));
+            }
+            if (iconFilename == null && taskDescription.getIcon() != null) {
+                pw.print(prefix); pw.println("taskDescription contains Bitmap");
+            }
         }
         if (results != null) {
             pw.print(prefix); pw.print("results="); pw.println(results);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java b/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
index b2300a6..fc53c50 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
@@ -73,8 +73,9 @@
     }
 
     /**
-     * Called right after the action is created. Initialization or first step to take
-     * for the action can be done in this method.
+     * Called after the action is created. Initialization or first step to take
+     * for the action can be done in this method. Shall update {@code mState} to
+     * indicate that the action has started.
      *
      * @return true if the operation is successful; otherwise false.
      */
@@ -162,6 +163,10 @@
         mActionTimer.sendTimerMessage(state, delayMillis);
     }
 
+    boolean started() {
+        return mState != STATE_NONE;
+    }
+
     protected final void sendCommand(HdmiCecMessage cmd) {
         mService.sendCecCommand(cmd);
     }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 41ac589..8f9af61 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -617,14 +617,25 @@
     @ServiceThreadOnly
     void addAndStartAction(final HdmiCecFeatureAction action) {
         assertRunOnServiceThread();
+        mActions.add(action);
         if (mService.isPowerStandbyOrTransient()) {
-            Slog.w(TAG, "Skip the action during Standby: " + action);
+            Slog.i(TAG, "Not ready to start action. Queued for deferred start:" + action);
             return;
         }
-        mActions.add(action);
         action.start();
     }
 
+    @ServiceThreadOnly
+    void startQueuedActions() {
+        assertRunOnServiceThread();
+        for (HdmiCecFeatureAction action : mActions) {
+            if (!action.started()) {
+                Slog.i(TAG, "Starting queued action:" + action);
+                action.start();
+            }
+        }
+    }
+
     // See if we have an action of a given type in progress.
     @ServiceThreadOnly
     <T extends HdmiCecFeatureAction> boolean hasAction(final Class<T> clazz) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index b0ddf2ac..780d54b 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -39,11 +39,18 @@
     }
 
     @Override
+    void init() {
+        super.init();
+        mIsActiveSource = false;
+    }
+
+    @Override
     @ServiceThreadOnly
     protected void onAddressAllocated(int logicalAddress, int reason) {
         assertRunOnServiceThread();
         mService.sendCecCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
                 mAddress, mService.getPhysicalAddress(), mDeviceType));
+        startQueuedActions();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index bd9f04b..0fb4b48 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -142,6 +142,7 @@
         launchRoutingControl(reason != HdmiControlService.INITIATED_BY_ENABLE_CEC &&
                 reason != HdmiControlService.INITIATED_BY_BOOT_UP);
         launchDeviceDiscovery();
+        startQueuedActions();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 4d9b4e9..60d1520 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -415,12 +415,17 @@
         assertRunOnServiceThread();
         // A container for [Device type, Local device info].
         ArrayList<HdmiCecLocalDevice> localDevices = new ArrayList<>();
-        clearLocalDevices();
         for (int type : mLocalDevices) {
-            final HdmiCecLocalDevice localDevice = HdmiCecLocalDevice.create(this, type);
+            HdmiCecLocalDevice localDevice = mCecController.getLocalDevice(type);
+            if (localDevice == null) {
+                localDevice = HdmiCecLocalDevice.create(this, type);
+            }
             localDevice.init();
             localDevices.add(localDevice);
         }
+        // It's now safe to flush existing local devices from mCecController since they were
+        // already moved to 'localDevices'.
+        clearLocalDevices();
         allocateLogicalAddress(localDevices, initiatedBy);
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 9db3fba..2150e9a 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -45,6 +45,7 @@
 import android.content.pm.PackageInstaller.SessionInfo;
 import android.content.pm.PackageInstaller.SessionParams;
 import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.CompressFormat;
 import android.graphics.BitmapFactory;
@@ -714,7 +715,7 @@
     }
 
     @Override
-    public List<SessionInfo> getAllSessions(int userId) {
+    public ParceledListSlice<SessionInfo> getAllSessions(int userId) {
         mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "getAllSessions");
 
         final List<SessionInfo> result = new ArrayList<>();
@@ -726,11 +727,11 @@
                 }
             }
         }
-        return result;
+        return new ParceledListSlice<>(result);
     }
 
     @Override
-    public List<SessionInfo> getMySessions(String installerPackageName, int userId) {
+    public ParceledListSlice<SessionInfo> getMySessions(String installerPackageName, int userId) {
         mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "getMySessions");
         mAppOps.checkPackage(Binder.getCallingUid(), installerPackageName);
 
@@ -744,7 +745,7 @@
                 }
             }
         }
-        return result;
+        return new ParceledListSlice<>(result);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a8a946a..b79e157 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -80,6 +80,7 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
+import android.app.AppGlobals;
 import android.app.IActivityManager;
 import android.app.admin.IDevicePolicyManager;
 import android.app.backup.IBackupManager;
@@ -4471,62 +4472,164 @@
         }
 
         if (pkgs != null) {
-            // Filter out packages that aren't recently used.
-            //
-            // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
-            // should do a full dexopt.
-            if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
-                // TODO: add a property to control this?
-                long dexOptLRUThresholdInMinutes;
-                if (mLazyDexOpt) {
-                    dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
-                } else {
-                    dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
-                }
-                long dexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
-
-                int total = pkgs.size();
-                int skipped = 0;
-                long now = System.currentTimeMillis();
-                for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
-                    PackageParser.Package pkg = i.next();
-                    long then = pkg.mLastPackageUsageTimeInMills;
-                    if (then + dexOptLRUThresholdInMills < now) {
-                        if (DEBUG_DEXOPT) {
-                            Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
-                                  ((then == 0) ? "never" : new Date(then)));
-                        }
-                        i.remove();
-                        skipped++;
+            // Sort apps by importance for dexopt ordering. Important apps are given more priority
+            // in case the device runs out of space.
+            ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>();
+            // Give priority to core apps.
+            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
+                PackageParser.Package pkg = it.next();
+                if (pkg.coreApp) {
+                    if (DEBUG_DEXOPT) {
+                        Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName);
                     }
+                    sortedPkgs.add(pkg);
+                    it.remove();
                 }
+            }
+            // Give priority to system apps that listen for pre boot complete.
+            Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
+            HashSet<String> pkgNames = getPackageNamesForIntent(intent);
+            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
+                PackageParser.Package pkg = it.next();
+                if (pkgNames.contains(pkg.packageName)) {
+                    if (DEBUG_DEXOPT) {
+                        Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName);
+                    }
+                    sortedPkgs.add(pkg);
+                    it.remove();
+                }
+            }
+            // Give priority to system apps.
+            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
+                PackageParser.Package pkg = it.next();
+                if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
+                    if (DEBUG_DEXOPT) {
+                        Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
+                    }
+                    sortedPkgs.add(pkg);
+                    it.remove();
+                }
+            }
+            // Give priority to updated system apps.
+            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
+                PackageParser.Package pkg = it.next();
+                if (isUpdatedSystemApp(pkg)) {
+                    if (DEBUG_DEXOPT) {
+                        Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
+                    }
+                    sortedPkgs.add(pkg);
+                    it.remove();
+                }
+            }
+            // Give priority to apps that listen for boot complete.
+            intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
+            pkgNames = getPackageNamesForIntent(intent);
+            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
+                PackageParser.Package pkg = it.next();
+                if (pkgNames.contains(pkg.packageName)) {
+                    if (DEBUG_DEXOPT) {
+                        Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName);
+                    }
+                    sortedPkgs.add(pkg);
+                    it.remove();
+                }
+            }
+            // Filter out packages that aren't recently used.
+            filterRecentlyUsedApps(pkgs);
+            // Add all remaining apps.
+            for (PackageParser.Package pkg : pkgs) {
                 if (DEBUG_DEXOPT) {
-                    Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
+                    Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName);
                 }
+                sortedPkgs.add(pkg);
             }
 
             int i = 0;
-            for (PackageParser.Package pkg : pkgs) {
-                i++;
-                if (DEBUG_DEXOPT) {
-                    Log.i(TAG, "Optimizing app " + i + " of " + pkgs.size()
-                          + ": " + pkg.packageName);
+            int total = sortedPkgs.size();
+            File dataDir = Environment.getDataDirectory();
+            long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir);
+            if (lowThreshold == 0) {
+                throw new IllegalStateException("Invalid low memory threshold");
+            }
+            for (PackageParser.Package pkg : sortedPkgs) {
+                long usableSpace = dataDir.getUsableSpace();
+                if (usableSpace < lowThreshold) {
+                    Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace);
+                    break;
                 }
-                if (!isFirstBoot()) {
-                    try {
-                        ActivityManagerNative.getDefault().showBootMessage(
-                                mContext.getResources().getString(
-                                        R.string.android_upgrading_apk,
-                                        i, pkgs.size()), true);
-                    } catch (RemoteException e) {
+                performBootDexOpt(pkg, ++i, total);
+            }
+        }
+    }
+
+    private void filterRecentlyUsedApps(HashSet<PackageParser.Package> pkgs) {
+        // Filter out packages that aren't recently used.
+        //
+        // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
+        // should do a full dexopt.
+        if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
+            // TODO: add a property to control this?
+            long dexOptLRUThresholdInMinutes;
+            if (mLazyDexOpt) {
+                dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
+            } else {
+                dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
+            }
+            long dexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
+
+            int total = pkgs.size();
+            int skipped = 0;
+            long now = System.currentTimeMillis();
+            for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
+                PackageParser.Package pkg = i.next();
+                long then = pkg.mLastPackageUsageTimeInMills;
+                if (then + dexOptLRUThresholdInMills < now) {
+                    if (DEBUG_DEXOPT) {
+                        Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
+                              ((then == 0) ? "never" : new Date(then)));
                     }
-                }
-                PackageParser.Package p = pkg;
-                synchronized (mInstallLock) {
-                    performDexOptLI(p, null /* instruction sets */, false /* force dex */, false /* defer */,
-                            true /* include dependencies */);
+                    i.remove();
+                    skipped++;
                 }
             }
+            if (DEBUG_DEXOPT) {
+                Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
+            }
+        }
+    }
+
+    private HashSet<String> getPackageNamesForIntent(Intent intent) {
+        List<ResolveInfo> ris = null;
+        try {
+            ris = AppGlobals.getPackageManager().queryIntentReceivers(
+                    intent, null, 0, UserHandle.USER_OWNER);
+        } catch (RemoteException e) {
+        }
+        HashSet<String> pkgNames = new HashSet<String>();
+        if (ris != null) {
+            for (ResolveInfo ri : ris) {
+                pkgNames.add(ri.activityInfo.packageName);
+            }
+        }
+        return pkgNames;
+    }
+
+    private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) {
+        if (DEBUG_DEXOPT) {
+            Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName);
+        }
+        if (!isFirstBoot()) {
+            try {
+                ActivityManagerNative.getDefault().showBootMessage(
+                        mContext.getResources().getString(R.string.android_upgrading_apk,
+                                curr, total), true);
+            } catch (RemoteException e) {
+            }
+        }
+        PackageParser.Package p = pkg;
+        synchronized (mInstallLock) {
+            performDexOptLI(p, null /* instruction sets */, false /* force dex */,
+                            false /* defer */, true /* include dependencies */);
         }
     }
 
@@ -5077,6 +5180,9 @@
 
         if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        } else {
+            // Only allow system apps to be flagged as core apps.
+            pkg.coreApp = false;
         }
 
         if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 9473495..7de56c8 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -2371,7 +2371,8 @@
                 intent.getType(), flags, 0);
         if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent
                 + " results: " + ri);
-        int match = 0;
+        int systemMatch = 0;
+        int thirdPartyMatch = 0;
         if (ri != null && ri.size() > 1) {
             boolean haveAct = false;
             ComponentName haveNonSys = null;
@@ -2380,13 +2381,10 @@
                 ActivityInfo ai = ri.get(i).activityInfo;
                 set[i] = new ComponentName(ai.packageName, ai.name);
                 if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
-                    if (ri.get(i).match >= match) {
-                        // If any of the matches are not system apps, then
-                        // there is a third party app that is now an option...
-                        // so don't set a default since we don't want to hide it.
-                        // Only do this if the match of this one is at least as good
-                        // as what we have found as the built-in app; if it isn't
-                        // as good, the user won't want it anyway, right?
+                    if (ri.get(i).match >= thirdPartyMatch) {
+                        // Keep track of the best match we find of all third
+                        // party apps, for use later to determine if we actually
+                        // want to set a preferred app for this intent.
                         if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
                                 + ai.packageName + "/" + ai.name + ": non-system!");
                         haveNonSys = set[i];
@@ -2397,12 +2395,19 @@
                     if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
                             + ai.packageName + "/" + ai.name + ": default!");
                     haveAct = true;
-                    match = ri.get(i).match;
+                    systemMatch = ri.get(i).match;
                 } else {
                     if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
                             + ai.packageName + "/" + ai.name + ": skipped");
                 }
             }
+            if (haveNonSys != null && thirdPartyMatch < systemMatch) {
+                // If we have a matching third party app, but its match is not as
+                // good as the built-in system app, then we don't want to actually
+                // consider it a match because presumably the built-in app is still
+                // the thing we want users to see by default.
+                haveNonSys = null;
+            }
             if (haveAct && haveNonSys == null) {
                 IntentFilter filter = new IntentFilter();
                 if (intent.getAction() != null) {
@@ -2435,7 +2440,7 @@
                         Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn);
                     }
                 }
-                PreferredActivity pa = new PreferredActivity(filter, match, set, cn, true);
+                PreferredActivity pa = new PreferredActivity(filter, systemMatch, set, cn, true);
                 editPreferredActivitiesLPw(userId).addFilter(pa);
             } else if (haveNonSys == null) {
                 StringBuilder sb = new StringBuilder();
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index f8f20dc..af4ae44 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2924,9 +2924,6 @@
             return;
         }
         enforceCrossUserPermission(userHandle);
-        if ((flags & DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0) {
-            enforceNotManagedProfile(userHandle, "wipe external storage");
-        }
         synchronized (this) {
             // This API can only be called by an active device admin,
             // so try to retrieve it to check that the caller is one.
@@ -3526,7 +3523,6 @@
             return;
         }
         enforceCrossUserPermission(userHandle);
-        enforceNotManagedProfile(userHandle, "enable/disable cameras");
         synchronized (this) {
             if (who == null) {
                 throw new NullPointerException("ComponentName is null");
@@ -5320,6 +5316,9 @@
         @Override
         public List<String> getCrossProfileWidgetProviders(int profileId) {
             synchronized (DevicePolicyManagerService.this) {
+                if (mDeviceOwner == null) {
+                    return Collections.emptyList();
+                }
                 ComponentName ownerComponent = mDeviceOwner.getProfileOwnerComponent(profileId);
                 if (ownerComponent == null) {
                     return Collections.emptyList();