Merge "Only unbind agents of the user that is being refreshed" into lmp-dev
diff --git a/api/current.txt b/api/current.txt
index ef9d879..0d1cee4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3792,7 +3792,6 @@
 
   public class ActivityOptions {
     method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
-    method public static deprecated android.app.ActivityOptions makeLaunchTaskBehindAnimation();
     method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int);
     method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.view.View, java.lang.String);
     method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.util.Pair<android.view.View, java.lang.String>...);
@@ -5510,7 +5509,6 @@
     field public static final java.lang.String EXTRA_ADD_EXPLANATION = "android.app.extra.ADD_EXPLANATION";
     field public static final java.lang.String EXTRA_DEVICE_ADMIN = "android.app.extra.DEVICE_ADMIN";
     field public static final java.lang.String EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE = "android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE";
-    field public static final java.lang.String EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME = "android.app.extra.PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION";
@@ -8909,6 +8907,7 @@
     field public static final java.lang.String FEATURE_PRINTING = "android.software.print";
     field public static final java.lang.String FEATURE_SCREEN_LANDSCAPE = "android.hardware.screen.landscape";
     field public static final java.lang.String FEATURE_SCREEN_PORTRAIT = "android.hardware.screen.portrait";
+    field public static final java.lang.String FEATURE_SECURELY_REMOVES_USERS = "android.software.securely_removes_users";
     field public static final java.lang.String FEATURE_SENSOR_ACCELEROMETER = "android.hardware.sensor.accelerometer";
     field public static final java.lang.String FEATURE_SENSOR_AMBIENT_TEMPERATURE = "android.hardware.sensor.ambient_temperature";
     field public static final java.lang.String FEATURE_SENSOR_BAROMETER = "android.hardware.sensor.barometer";
@@ -8933,6 +8932,7 @@
     field public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND = "android.hardware.touchscreen.multitouch.jazzhand";
     field public static final java.lang.String FEATURE_USB_ACCESSORY = "android.hardware.usb.accessory";
     field public static final java.lang.String FEATURE_USB_HOST = "android.hardware.usb.host";
+    field public static final java.lang.String FEATURE_VERIFIED_BOOT = "android.software.verified_boot";
     field public static final java.lang.String FEATURE_WATCH = "android.hardware.type.watch";
     field public static final java.lang.String FEATURE_WEBVIEW = "android.software.webview";
     field public static final java.lang.String FEATURE_WIFI = "android.hardware.wifi";
@@ -12683,7 +12683,7 @@
     method public void onCaptureProgressed(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureResult);
     method public void onCaptureSequenceAborted(android.hardware.camera2.CameraCaptureSession, int);
     method public void onCaptureSequenceCompleted(android.hardware.camera2.CameraCaptureSession, int, long);
-    method public void onCaptureStarted(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, long);
+    method public void onCaptureStarted(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, long, long);
   }
 
   public static abstract class CameraCaptureSession.StateCallback {
@@ -14421,6 +14421,7 @@
     field public static final int QUALITY_CIF = 3; // 0x3
     field public static final int QUALITY_HIGH = 1; // 0x1
     field public static final int QUALITY_HIGH_SPEED_1080P = 2004; // 0x7d4
+    field public static final int QUALITY_HIGH_SPEED_2160P = 2005; // 0x7d5
     field public static final int QUALITY_HIGH_SPEED_480P = 2002; // 0x7d2
     field public static final int QUALITY_HIGH_SPEED_720P = 2003; // 0x7d3
     field public static final int QUALITY_HIGH_SPEED_HIGH = 2001; // 0x7d1
@@ -14665,7 +14666,7 @@
   }
 
   public static final class MediaCodec.CodecException extends java.lang.IllegalStateException {
-    method public int getErrorCode();
+    method public java.lang.String getDiagnosticInfo();
     method public boolean isRecoverable();
     method public boolean isTransient();
   }
@@ -14673,6 +14674,7 @@
   public static final class MediaCodec.CryptoException extends java.lang.RuntimeException {
     ctor public MediaCodec.CryptoException(int, java.lang.String);
     method public int getErrorCode();
+    field public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4; // 0x4
     field public static final int ERROR_KEY_EXPIRED = 2; // 0x2
     field public static final int ERROR_NO_KEY = 1; // 0x1
     field public static final int ERROR_RESOURCE_BUSY = 3; // 0x3
@@ -15002,7 +15004,7 @@
 
   public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException {
     ctor public MediaDrm.MediaDrmStateException(int, java.lang.String);
-    method public int getErrorCode();
+    method public java.lang.String getDiagnosticInfo();
   }
 
   public static abstract interface MediaDrm.OnEventListener {
@@ -22501,6 +22503,7 @@
     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";
@@ -27267,6 +27270,7 @@
     method public android.view.SurfaceHolder getSurfaceHolder();
     method public boolean isPreview();
     method public boolean isVisible();
+    method public void onApplyWindowInsets(android.view.WindowInsets);
     method public android.os.Bundle onCommand(java.lang.String, int, int, int, android.os.Bundle, boolean);
     method public void onCreate(android.view.SurfaceHolder);
     method public void onDesiredSizeChanged(int, int);
@@ -29033,7 +29037,6 @@
     method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
     method public boolean setGlobalPreferredNetworkType();
     method public void setLine1NumberForDisplay(java.lang.String, java.lang.String);
-    method public void setLine1NumberForDisplay(long, java.lang.String, java.lang.String);
     method public boolean setOperatorBrandOverride(java.lang.String);
     field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
     field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
@@ -34975,12 +34978,18 @@
 
   public final class WindowInsets {
     ctor public WindowInsets(android.view.WindowInsets);
+    method public android.view.WindowInsets consumeStableInsets();
     method public android.view.WindowInsets consumeSystemWindowInsets();
+    method public int getStableInsetBottom();
+    method public int getStableInsetLeft();
+    method public int getStableInsetRight();
+    method public int getStableInsetTop();
     method public int getSystemWindowInsetBottom();
     method public int getSystemWindowInsetLeft();
     method public int getSystemWindowInsetRight();
     method public int getSystemWindowInsetTop();
     method public boolean hasInsets();
+    method public boolean hasStableInsets();
     method public boolean hasSystemWindowInsets();
     method public boolean isConsumed();
     method public boolean isRound();
diff --git a/api/removed.txt b/api/removed.txt
index 3c16276..c8a3b4b 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -22,14 +22,6 @@
 
 }
 
-package android.service.notification {
-
-  public static class NotificationListenerService.Ranking {
-    method public boolean meetsInterruptionFilter();
-  }
-
-}
-
 package android.view {
 
   public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable {
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index ffffb6c..213c7f6 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -520,11 +520,6 @@
         return opts;
     }
 
-    @Deprecated
-    public static ActivityOptions makeLaunchTaskBehindAnimation() {
-        return makeTaskLaunchBehind();
-    }
-
     /** @hide */
     public boolean getLaunchTaskBehind() {
         return mAnimationType == ANIM_LAUNCH_TASK_BEHIND;
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index 181eb63..3b5900b 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 import android.app.IWallpaperManagerCallback;
@@ -73,6 +74,11 @@
     int getHeightHint();
 
     /**
+     * Sets extra padding that we would like the wallpaper to have outside of the display.
+     */
+    void setDisplayPadding(in Rect padding);
+
+    /**
      * Returns the name of the wallpaper. Private API.
      */
     String getName();
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c831c25..f9e4895 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -545,8 +545,26 @@
      */
     public int visibility;
 
+    /**
+     * Notification visibility: Show this notification in its entirety on all lockscreens.
+     *
+     * {@see #visibility}
+     */
     public static final int VISIBILITY_PUBLIC = 1;
+
+    /**
+     * Notification visibility: Show this notification on all lockscreens, but conceal sensitive or
+     * private information on secure lockscreens.
+     *
+     * {@see #visibility}
+     */
     public static final int VISIBILITY_PRIVATE = 0;
+
+    /**
+     * Notification visibility: Do not reveal any part of this notification on a secure lockscreen.
+     *
+     * {@see #visibility}
+     */
     public static final int VISIBILITY_SECRET = -1;
 
     /**
@@ -824,6 +842,13 @@
     public static final String EXTRA_COMPACT_ACTIONS = "android.compactActions";
 
     /**
+     * {@link #extras} key: the user that built the notification.
+     *
+     * @hide
+     */
+    public static final String EXTRA_ORIGINATING_USERID = "android.originatingUserId";
+
+    /**
      * Value for {@link #EXTRA_AS_HEADS_UP} that indicates this notification should not be
      * displayed in the heads up space.
      *
@@ -1862,6 +1887,11 @@
         private int mColor = COLOR_DEFAULT;
 
         /**
+         * The user that built the notification originally.
+         */
+        private int mOriginatingUserId;
+
+        /**
          * Contains extras related to rebuilding during the build phase.
          */
         private Bundle mRebuildBundle = new Bundle();
@@ -2581,7 +2611,7 @@
             // Note: This assumes that the current user can read the profile badge of the
             // originating user.
             return mContext.getPackageManager().getUserBadgeForDensity(
-                    new UserHandle(mContext.getUserId()), 0);
+                    new UserHandle(mOriginatingUserId), 0);
         }
 
         private Bitmap getProfileBadge() {
@@ -2721,9 +2751,9 @@
             } else {
                 contentView.setViewVisibility(R.id.text2, View.GONE);
                 if (hasProgress && (mProgressMax != 0 || mProgressIndeterminate)) {
+                    contentView.setViewVisibility(R.id.progress, View.VISIBLE);
                     contentView.setProgressBar(
                             R.id.progress, mProgressMax, mProgress, mProgressIndeterminate);
-                    contentView.setViewVisibility(R.id.progress, View.VISIBLE);
                     showLine2 = true;
                 } else {
                     contentView.setViewVisibility(R.id.progress, View.GONE);
@@ -3052,6 +3082,7 @@
          */
         public void populateExtras(Bundle extras) {
             // Store original information used in the construction of this object
+            extras.putInt(EXTRA_ORIGINATING_USERID, mOriginatingUserId);
             extras.putParcelable(EXTRA_REBUILD_CONTEXT_APPLICATION_INFO,
                     mContext.getApplicationInfo());
             extras.putCharSequence(EXTRA_TITLE, mContentTitle);
@@ -3283,6 +3314,7 @@
 
             // Extras.
             Bundle extras = n.extras;
+            mOriginatingUserId = extras.getInt(EXTRA_ORIGINATING_USERID);
             mContentTitle = extras.getCharSequence(EXTRA_TITLE);
             mContentText = extras.getCharSequence(EXTRA_TEXT);
             mSubText = extras.getCharSequence(EXTRA_SUB_TEXT);
@@ -3315,6 +3347,7 @@
          * object.
          */
         public Notification build() {
+            mOriginatingUserId = mContext.getUserId();
             mHasThreeLines = hasThreeLines();
 
             Notification n = buildUnstyled();
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 48ff5b6..8bfe6d3 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.annotation.SystemApi;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -951,6 +952,48 @@
     }
 
     /**
+     * Specify extra padding that the wallpaper should have outside of the display.
+     * That is, the given padding supplies additional pixels the wallpaper should extend
+     * outside of the display itself.
+     * @param padding The number of pixels the wallpaper should extend beyond the display,
+     * on its left, top, right, and bottom sides.
+     * @hide
+     */
+    @SystemApi
+    public void setDisplayPadding(Rect padding) {
+        try {
+            if (sGlobals.mService == null) {
+                Log.w(TAG, "WallpaperService not running");
+            } else {
+                sGlobals.mService.setDisplayPadding(padding);
+            }
+        } catch (RemoteException e) {
+            // Ignore
+        }
+    }
+
+    /**
+     * Apply a raw offset to the wallpaper window.  Should only be used in
+     * combination with {@link #setDisplayPadding(android.graphics.Rect)} when you
+     * have ensured that the wallpaper will extend outside of the display area so that
+     * it can be moved without leaving part of the display uncovered.
+     * @param x The offset, in pixels, to apply to the left edge.
+     * @param y The offset, in pixels, to apply to the top edge.
+     * @hide
+     */
+    @SystemApi
+    public void setDisplayOffset(IBinder windowToken, int x, int y) {
+        try {
+            //Log.v(TAG, "Sending new wallpaper display offsets from app...");
+            WindowManagerGlobal.getWindowSession().setWallpaperDisplayOffset(
+                    windowToken, x, y);
+            //Log.v(TAG, "...app returning after sending display offset!");
+        } catch (RemoteException e) {
+            // Ignore.
+        }
+    }
+
+    /**
      * Set the position of the current wallpaper within any larger space, when
      * that wallpaper is visible behind the given window.  The X and Y offsets
      * are floating point numbers ranging from 0 to 1, representing where the
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 926a348..5b02313 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -97,8 +97,7 @@
      * Provisioning adds a managed profile and sets the mdm as the profile owner who has full
      * control over the profile
      *
-     * <p>This intent must contain the extras {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}
-     * {@link #EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME} and {@link #EXTRA_DEVICE_ADMIN}.
+     * <p>This intent must contain the extra {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}.
      *
      * <p> When managed provisioning has completed, an intent of the type
      * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} is broadcasted to the
@@ -142,18 +141,15 @@
         = "android.app.extra.deviceAdminPackageName";
 
     /**
-     * A String extra holding the default name of the profile that is created during managed profile
-     * provisioning.
+     * A String extra that, holds the email address of the account which a managed profile is
+     * created for. Used with {@link #ACTION_PROVISION_MANAGED_PROFILE} and
+     * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE}.
      *
-     * <p>Use with {@link #ACTION_PROVISION_MANAGED_PROFILE}
-     */
-    public static final String EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME
-        = "android.app.extra.PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME";
-
-    /**
-     * A bundle key, used in the bundle extra {@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}. The
-     * corresponding value holds the email address of the account which the managed profile is
-     * created for.
+     * <p> If the {@link #ACTION_PROVISION_MANAGED_PROFILE} intent that starts managed provisioning
+     * contains this extra, it is forwarded in the
+     * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} intent to the mobile
+     * device management application that was set as the profile owner during provisioning.
+     * It is usually used to avoid that the user has to enter their email address twice.
      */
     public static final String KEY_PROVISIONING_EMAIL_ADDRESS
         = "android.app.key.PROVISIONING_EMAIL_ADDRESS";
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index 1bb4eba..9151a16 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -218,6 +218,7 @@
      */
     @SystemApi
     public boolean isBackupEnabled() {
+        checkServiceBinder();
         if (sService != null) {
             try {
                 return sService.isBackupEnabled();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 8e64e36..5ce968b 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -201,12 +201,6 @@
     public static final int MATCH_DEFAULT_ONLY   = 0x00010000;
 
     /**
-     * Resolution and querying flag: do not resolve intents cross-profile.
-     * @hide
-     */
-    public static final int NO_CROSS_PROFILE = 0x00020000;
-
-    /**
      * Flag for {@link addCrossProfileIntentFilter}: if this flag is set:
      * when resolving an intent that matches the {@link CrossProfileIntentFilter}, the current
      * profile will be skipped.
@@ -1531,6 +1525,22 @@
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+     * The device supports verified boot.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_VERIFIED_BOOT = "android.software.verified_boot";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+     * The device supports secure removal of users. When a user is deleted the data associated
+     * with that user is securely deleted and no longer available.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_SECURELY_REMOVES_USERS
+            = "android.software.securely_removes_users";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
      * The device has a full implementation of the android.webkit.* APIs. Devices
      * lacking this feature will not have a functioning WebView implementation.
      */
@@ -2440,7 +2450,6 @@
      * @see #MATCH_DEFAULT_ONLY
      * @see #GET_INTENT_FILTERS
      * @see #GET_RESOLVED_FILTER
-     * @see #NO_CROSS_PROFILE
      * @hide
      */
     public abstract List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index e0fd532..ddb0a6d 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1099,9 +1099,12 @@
                     }
                 }
             }
-        } catch (GeneralSecurityException | IOException | RuntimeException e) {
+        } catch (GeneralSecurityException e) {
             throw new PackageParserException(INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING,
                     "Failed to collect certificates from " + apkPath, e);
+        } catch (IOException | RuntimeException e) {
+            throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
+                    "Failed to collect certificates from " + apkPath, e);
         } finally {
             closeQuietly(jarFile);
         }
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index c0383a3..c03be32 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -89,6 +89,7 @@
 
     /** User is only partially created. */
     public boolean partial;
+    public boolean guestToRemove;
 
     public UserInfo(int id, String name, int flags) {
         this(id, name, null, flags);
@@ -147,6 +148,7 @@
         lastLoggedInTime = orig.lastLoggedInTime;
         partial = orig.partial;
         profileGroupId = orig.profileGroupId;
+        guestToRemove = orig.guestToRemove;
     }
 
     public UserHandle getUserHandle() {
@@ -172,6 +174,7 @@
         dest.writeLong(lastLoggedInTime);
         dest.writeInt(partial ? 1 : 0);
         dest.writeInt(profileGroupId);
+        dest.writeInt(guestToRemove ? 1 : 0);
     }
 
     public static final Parcelable.Creator<UserInfo> CREATOR
@@ -194,5 +197,6 @@
         lastLoggedInTime = source.readLong();
         partial = source.readInt() != 0;
         profileGroupId = source.readInt();
+        guestToRemove = source.readInt() != 0;
     }
 }
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index 29e42ea..ce83028 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -483,7 +483,9 @@
          * and in the buffers sent to each output Surface. These buffer
          * timestamps are accessible through, for example,
          * {@link android.media.Image#getTimestamp() Image.getTimestamp()} or
-         * {@link android.graphics.SurfaceTexture#getTimestamp()}.</p>
+         * {@link android.graphics.SurfaceTexture#getTimestamp()}.
+         * The frame number included is equal to the frame number that will be included in
+         * {@link CaptureResult#getFrameNumber}.</p>
          *
          * <p>For the simplest way to play a shutter sound camera shutter or a
          * video recording start/stop sound, see the
@@ -494,10 +496,21 @@
          * @param session the session returned by {@link CameraDevice#createCaptureSession}
          * @param request the request for the capture that just begun
          * @param timestamp the timestamp at start of capture, in nanoseconds.
+         * @param frameNumber the frame number for this capture
          *
          * @see android.media.MediaActionSound
          */
         public void onCaptureStarted(CameraCaptureSession session,
+                CaptureRequest request, long timestamp, long frameNumber) {
+            // Temporary trampoline for API change transition
+            onCaptureStarted(session, request, timestamp);
+        }
+
+        /**
+         * Temporary for API change transition
+         * @hide
+         */
+        public void onCaptureStarted(CameraCaptureSession session,
                 CaptureRequest request, long timestamp) {
             // default empty implementation
         }
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 6d0d505..93eb3de 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -731,6 +731,8 @@
     /**
      * <p>List of areas to use for
      * metering.</p>
+     * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AE android.control.maxRegionsAe} is 0.
+     * Otherwise will always be present.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
      * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
@@ -746,7 +748,9 @@
      * outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
      * the camera device will ignore the sections outside the region and output the
      * used sections in the result metadata.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      *
+     * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AE
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      */
@@ -820,6 +824,8 @@
     /**
      * <p>List of areas to use for focus
      * estimation.</p>
+     * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AF android.control.maxRegionsAf} is 0.
+     * Otherwise will always be present.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
      * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
@@ -835,7 +841,9 @@
      * outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
      * the camera device will ignore the sections outside the region and output the
      * used sections in the result metadata.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      *
+     * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AF
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      */
@@ -921,6 +929,8 @@
     /**
      * <p>List of areas to use for illuminant
      * estimation.</p>
+     * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AWB android.control.maxRegionsAwb} is 0.
+     * Otherwise will always be present.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
      * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
@@ -936,7 +946,9 @@
      * outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
      * the camera device will ignore the sections outside the region and output the
      * used sections in the result metadata.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      *
+     * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AWB
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      */
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 754d83e..01276a2 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -582,6 +582,8 @@
     /**
      * <p>List of areas to use for
      * metering.</p>
+     * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AE android.control.maxRegionsAe} is 0.
+     * Otherwise will always be present.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
      * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
@@ -597,7 +599,9 @@
      * outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
      * the camera device will ignore the sections outside the region and output the
      * used sections in the result metadata.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      *
+     * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AE
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      */
@@ -870,6 +874,8 @@
     /**
      * <p>List of areas to use for focus
      * estimation.</p>
+     * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AF android.control.maxRegionsAf} is 0.
+     * Otherwise will always be present.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
      * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
@@ -885,7 +891,9 @@
      * outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
      * the camera device will ignore the sections outside the region and output the
      * used sections in the result metadata.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      *
+     * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AF
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      */
@@ -1369,6 +1377,8 @@
     /**
      * <p>List of areas to use for illuminant
      * estimation.</p>
+     * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AWB android.control.maxRegionsAwb} is 0.
+     * Otherwise will always be present.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
      * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
@@ -1384,7 +1394,9 @@
      * outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata,
      * the camera device will ignore the sections outside the region and output the
      * used sections in the result metadata.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      *
+     * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AWB
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      */
diff --git a/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java b/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java
index 02c3d87..c66a3a4 100644
--- a/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java
+++ b/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java
@@ -48,7 +48,8 @@
     /**
      * Invoke a method by its name.
      *
-     * <p>If more than one method exists in {@code targetClass}, the first method will be used.</p>
+     * <p>If more than one method exists in {@code targetClass}, the first method with the right
+     * number of arguments will be used, and later calls will all use that method.</p>
      *
      * @param methodName
      *          The name of the method, which will be matched 1:1 to the destination method
@@ -68,8 +69,9 @@
         Method targetMethod = mMethods.get(methodName);
         if (targetMethod == null) {
             for (Method method : mTargetClass.getMethods()) {
-                // TODO future: match by # of params and types of params if possible
-                if (method.getName().equals(methodName)) {
+                // TODO future: match types of params if possible
+                if (method.getName().equals(methodName) &&
+                        (params.length == method.getParameterTypes().length) ) {
                     targetMethod = method;
                     mMethods.put(methodName, targetMethod);
                     break;
diff --git a/core/java/android/hardware/camera2/impl/CallbackProxies.java b/core/java/android/hardware/camera2/impl/CallbackProxies.java
index e5ddb7a..f0217ac 100644
--- a/core/java/android/hardware/camera2/impl/CallbackProxies.java
+++ b/core/java/android/hardware/camera2/impl/CallbackProxies.java
@@ -98,8 +98,8 @@
 
         @Override
         public void onCaptureStarted(CameraDevice camera,
-                CaptureRequest request, long timestamp) {
-            mProxy.invoke("onCaptureStarted", camera, request, timestamp);
+                CaptureRequest request, long timestamp, long frameNumber) {
+            mProxy.invoke("onCaptureStarted", camera, request, timestamp, frameNumber);
         }
 
         @Override
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index d454092..f011d60 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -803,7 +803,7 @@
          * @see android.media.MediaActionSound
          */
         public void onCaptureStarted(CameraDevice camera,
-                CaptureRequest request, long timestamp) {
+                CaptureRequest request, long timestamp, long frameNumber) {
             // default empty implementation
         }
 
@@ -1237,8 +1237,10 @@
         @Override
         public void onCaptureStarted(final CaptureResultExtras resultExtras, final long timestamp) {
             int requestId = resultExtras.getRequestId();
+            final long frameNumber = resultExtras.getFrameNumber();
+
             if (DEBUG) {
-                Log.d(TAG, "Capture started for id " + requestId);
+                Log.d(TAG, "Capture started for id " + requestId + " frame number " + frameNumber);
             }
             final CaptureCallbackHolder holder;
 
@@ -1263,7 +1265,7 @@
                                 holder.getCallback().onCaptureStarted(
                                     CameraDeviceImpl.this,
                                     holder.getRequest(resultExtras.getSubsequenceId()),
-                                    timestamp);
+                                    timestamp, frameNumber);
                             }
                         }
                     });
diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
index a8d1018..3c0e0e4 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
@@ -675,15 +675,13 @@
          * request.availableRequestKeys
          */
         {
-            CaptureRequest.Key<?> availableKeys[] = new CaptureRequest.Key<?>[] {
+            CaptureRequest.Key<?> defaultAvailableKeys[] = new CaptureRequest.Key<?>[] {
                     CaptureRequest.CONTROL_AE_ANTIBANDING_MODE,
                     CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION,
                     CaptureRequest.CONTROL_AE_LOCK,
                     CaptureRequest.CONTROL_AE_MODE,
-                    CaptureRequest.CONTROL_AE_REGIONS,
                     CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,
                     CaptureRequest.CONTROL_AF_MODE,
-                    CaptureRequest.CONTROL_AF_REGIONS,
                     CaptureRequest.CONTROL_AF_TRIGGER,
                     CaptureRequest.CONTROL_AWB_LOCK,
                     CaptureRequest.CONTROL_AWB_MODE,
@@ -704,21 +702,32 @@
                     CaptureRequest.SCALER_CROP_REGION,
                     CaptureRequest.STATISTICS_FACE_DETECT_MODE,
             };
-            m.set(REQUEST_AVAILABLE_REQUEST_KEYS, getTagsForKeys(availableKeys));
+            ArrayList<CaptureRequest.Key<?>> availableKeys =
+                    new ArrayList<CaptureRequest.Key<?>>(Arrays.asList(defaultAvailableKeys));
+
+            if (p.getMaxNumMeteringAreas() > 0) {
+                availableKeys.add(CaptureRequest.CONTROL_AE_REGIONS);
+            }
+            if (p.getMaxNumFocusAreas() > 0) {
+                availableKeys.add(CaptureRequest.CONTROL_AF_REGIONS);
+            }
+
+            CaptureRequest.Key<?> availableRequestKeys[] =
+                    new CaptureRequest.Key<?>[availableKeys.size()];
+            availableKeys.toArray(availableRequestKeys);
+            m.set(REQUEST_AVAILABLE_REQUEST_KEYS, getTagsForKeys(availableRequestKeys));
         }
 
         /*
          * request.availableResultKeys
          */
         {
-            CaptureResult.Key<?> availableKeys[] = new CaptureResult.Key<?>[] {
+            CaptureResult.Key<?> defaultAvailableKeys[] = new CaptureResult.Key<?>[] {
                     CaptureResult.CONTROL_AE_ANTIBANDING_MODE                      ,
                     CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION                 ,
                     CaptureResult.CONTROL_AE_LOCK                                  ,
                     CaptureResult.CONTROL_AE_MODE                                  ,
-                    CaptureResult.CONTROL_AE_REGIONS                               ,
                     CaptureResult.CONTROL_AF_MODE                                  ,
-                    CaptureResult.CONTROL_AF_REGIONS                               ,
                     CaptureResult.CONTROL_AF_STATE                                 ,
                     CaptureResult.CONTROL_AWB_MODE                                 ,
                     CaptureResult.CONTROL_AWB_LOCK                                 ,
@@ -737,7 +746,20 @@
                     CaptureResult.STATISTICS_FACE_DETECT_MODE                      ,
 //                    CaptureResult.STATISTICS_FACES                                 ,
             };
-            m.set(REQUEST_AVAILABLE_RESULT_KEYS, getTagsForKeys(availableKeys));
+            List<CaptureResult.Key<?>> availableKeys =
+                    new ArrayList<CaptureResult.Key<?>>(Arrays.asList(defaultAvailableKeys));
+
+            if (p.getMaxNumMeteringAreas() > 0) {
+                availableKeys.add(CaptureResult.CONTROL_AE_REGIONS);
+            }
+            if (p.getMaxNumFocusAreas() > 0) {
+                availableKeys.add(CaptureResult.CONTROL_AF_REGIONS);
+            }
+
+            CaptureResult.Key<?> availableResultKeys[] =
+                    new CaptureResult.Key<?>[availableKeys.size()];
+            availableKeys.toArray(availableResultKeys);
+            m.set(REQUEST_AVAILABLE_RESULT_KEYS, getTagsForKeys(availableResultKeys));
         }
 
         /*
diff --git a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
index 090a822..ddaa6ee 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
@@ -322,7 +322,7 @@
         }
 
         // control.aeRegions
-        {
+        if (p.getMaxNumMeteringAreas() > 0) {
             if (VERBOSE) {
                 String meteringAreas = p.get("metering-areas");
                 Log.v(TAG, "mapAe - parameter dump; metering-areas: " + meteringAreas);
@@ -342,7 +342,7 @@
         m.set(CaptureResult.CONTROL_AF_MODE, convertLegacyAfMode(p.getFocusMode()));
 
         // control.afRegions
-        {
+        if (p.getMaxNumFocusAreas() > 0) {
             if (VERBOSE) {
                 String focusAreas = p.get("focus-areas");
                 Log.v(TAG, "mapAe - parameter dump; focus-areas: " + focusAreas);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index ec77a5e..33fda4a 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -43,190 +43,208 @@
     private final Context mContext;
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from adding and removing
-     * accounts.
+     * Specifies if a user is disallowed from adding and removing accounts.
      * The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from changing Wi-Fi
+     * Specifies if a user is disallowed from changing Wi-Fi
      * access points. The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_CONFIG_WIFI = "no_config_wifi";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from installing applications.
+     * Specifies if a user is disallowed from installing applications.
      * The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_INSTALL_APPS = "no_install_apps";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from uninstalling applications.
+     * Specifies if a user is disallowed from uninstalling applications.
      * The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from toggling location sharing.
+     * Specifies if a user is disallowed from toggling location sharing.
      * The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_SHARE_LOCATION = "no_share_location";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from enabling the
+     * Specifies if a user is disallowed from enabling the
      * "Unknown Sources" setting, that allows installation of apps from unknown sources.
      * The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from configuring bluetooth.
+     * Specifies if a user is disallowed from configuring bluetooth.
      * The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_CONFIG_BLUETOOTH = "no_config_bluetooth";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from transferring files over
+     * Specifies if a user is disallowed from transferring files over
      * USB. This can only be set by device owners. The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_USB_FILE_TRANSFER = "no_usb_file_transfer";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from configuring user
+     * Specifies if a user is disallowed from configuring user
      * credentials. The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_CONFIG_CREDENTIALS = "no_config_credentials";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from removing itself and other
+     * Specifies if a user is disallowed from removing itself and other
      * users. The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_REMOVE_USER = "no_remove_user";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from enabling or
+     * Specifies if a user is disallowed from enabling or
      * accessing debugging features. The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_DEBUGGING_FEATURES = "no_debugging_features";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from configuring VPN.
+     * Specifies if a user is disallowed from configuring VPN.
      * The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_CONFIG_VPN = "no_config_vpn";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from configuring Tethering
+     * Specifies if a user is disallowed from configuring Tethering
      * & portable hotspots. This can only be set by device owners. The default value is
      * <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_CONFIG_TETHERING = "no_config_tethering";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from factory resetting
+     * Specifies if a user is disallowed from factory resetting
      * from Settings. This can only be set by device owners. The default value is
      * <code>false</code>.
-     * <p>
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_FACTORY_RESET = "no_factory_reset";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from adding new users and
+     * Specifies if a user is disallowed from adding new users and
      * profiles. This can only be set by device owners. The default value is <code>false</code>.
-     * <p>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_ADD_USER = "no_add_user";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from disabling application
+     * Specifies if a user is disallowed from disabling application
      * verification. The default value is <code>false</code>.
-     * <p>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String ENSURE_VERIFY_APPS = "ensure_verify_apps";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from configuring cell
+     * Specifies if a user is disallowed from configuring cell
      * broadcasts. This can only be set by device owners. The default value is <code>false</code>.
-     * <p>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_CONFIG_CELL_BROADCASTS = "no_config_cell_broadcasts";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from configuring mobile
+     * Specifies if a user is disallowed from configuring mobile
      * networks. This can only be set by device owners. The default value is <code>false</code>.
-     * <p>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_CONFIG_MOBILE_NETWORKS = "no_config_mobile_networks";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from modifying
+     * Specifies if a user is disallowed from modifying
      * applications in Settings or launchers. The following actions will not be allowed when this
      * restriction is enabled:
      * <li>uninstalling apps</li>
@@ -237,69 +255,75 @@
      * <li>clearing app defaults</li>
      * <p>
      * The default value is <code>false</code>.
-     * <p>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_APPS_CONTROL = "no_control_apps";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from mounting
+     * Specifies if a user is disallowed from mounting
      * physical external media. This can only be set by device owners. The default value is
      * <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_MOUNT_PHYSICAL_MEDIA = "no_physical_media";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from adjusting microphone
+     * Specifies if a user is disallowed from adjusting microphone
      * volume. If set, the microphone will be muted. This can only be set by device owners.
      * The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_UNMUTE_MICROPHONE = "no_unmute_microphone";
 
     /**
-     * Key for user restrictions. Specifies if a user is disallowed from adjusting the master
+     * Specifies if a user is disallowed from adjusting the master
      * volume. If set, the master volume will be muted. This can only be set by device owners.
      * The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_ADJUST_VOLUME = "no_adjust_volume";
 
     /**
-     * Key for user restrictions. Specifies that the user is not allowed to make outgoing
+     * Specifies that the user is not allowed to make outgoing
      * phone calls. Emergency calls are still permitted.
      * The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls";
 
     /**
-     * Key for user restrictions. Specifies that the user is not allowed to send or receive
+     * Specifies that the user is not allowed to send or receive
      * SMS messages. This can only be set by device owners. The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_SMS = "no_sms";
 
     /**
-     * Key for user restrictions. Specifies that windows besides app windows should not be
+     * Specifies that windows besides app windows should not be
      * created. This will block the creation of the following types of windows.
      * <li>{@link LayoutParams#TYPE_TOAST}</li>
      * <li>{@link LayoutParams#TYPE_PHONE}</li>
@@ -309,25 +333,38 @@
      * <li>{@link LayoutParams#TYPE_SYSTEM_OVERLAY}</li>
      *
      * <p>This can only be set by device owners. The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_CREATE_WINDOWS = "no_create_windows";
 
     /**
-     * Key for user restrictions. Specifies if what is copied in the clipboard of this profile can
+     * Specifies if what is copied in the clipboard of this profile can
      * be pasted in related profiles. Does not restrict if the clipboard of related profiles can be
      * pasted in this profile.
      * The default value is <code>false</code>.
-     * <p/>
-     * Type: Boolean
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
      */
     public static final String DISALLOW_CROSS_PROFILE_COPY_PASTE = "no_cross_profile_copy_paste";
 
+    /**
+     * Specifies if the user is not allowed to use NFC to beam out data from apps.
+     * The default value is <code>false</code>.
+     *
+     * <p/>Key for user restrictions.
+     * <p/>Type: Boolean
+     * @see #setUserRestrictions(Bundle)
+     * @see #getUserRestrictions()
+     */
+    public static final String DISALLOW_OUTGOING_BEAM = "no_outgoing_beam";
+
     /** @hide */
     public static final int PIN_VERIFICATION_FAILED_INCORRECT = -3;
     /** @hide */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f4c2dc8..01fda47 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3739,6 +3739,13 @@
                 "show_note_about_notification_hiding";
 
         /**
+         * Set to 1 by the system after trust agents have been initialized.
+         * @hide
+         */
+        public static final String TRUST_AGENTS_INITIALIZED =
+                "trust_agents_initialized";
+
+        /**
          * The Logging ID (a unique 64-bit value) as a hex string.
          * Used as a pseudonymous identifier for logging.
          * @deprecated This identifier is poorly initialized and has
diff --git a/core/java/android/service/notification/IStatusBarNotificationHolder.aidl b/core/java/android/service/notification/IStatusBarNotificationHolder.aidl
index fd6b59e..c25cdb2 100644
--- a/core/java/android/service/notification/IStatusBarNotificationHolder.aidl
+++ b/core/java/android/service/notification/IStatusBarNotificationHolder.aidl
@@ -20,5 +20,6 @@
 
 /** @hide */
 interface IStatusBarNotificationHolder {
+    /** Fetch the held StatusBarNotification. This method should only be called once per Holder */
     StatusBarNotification get();
 }
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index d744070..b22fd9c 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -756,15 +756,6 @@
             return mVisibilityOverride;
         }
 
-        /**
-         * Returns whether the notification meets the user's interruption
-         * filter.
-         *
-         * @removed
-         */
-        public boolean meetsInterruptionFilter() {
-            return mMatchesInterruptionFilter;
-        }
 
         /**
          * Returns whether the notification matches the user's interruption
diff --git a/core/java/android/service/wallpaper/IWallpaperEngine.aidl b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
index faccde2..de527e9 100644
--- a/core/java/android/service/wallpaper/IWallpaperEngine.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
@@ -16,6 +16,7 @@
 
 package android.service.wallpaper;
 
+import android.graphics.Rect;
 import android.view.MotionEvent;
 import android.os.Bundle;
 
@@ -24,6 +25,7 @@
  */
 oneway interface IWallpaperEngine {
     void setDesiredSize(int width, int height);
+    void setDisplayPadding(in Rect padding);
     void setVisibility(boolean visible);
     void dispatchPointer(in MotionEvent event);
     void dispatchWallpaperCommand(String action, int x, int y,
diff --git a/core/java/android/service/wallpaper/IWallpaperService.aidl b/core/java/android/service/wallpaper/IWallpaperService.aidl
index bc7a1d7..5fd0157 100644
--- a/core/java/android/service/wallpaper/IWallpaperService.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperService.aidl
@@ -16,6 +16,7 @@
 
 package android.service.wallpaper;
 
+import android.graphics.Rect;
 import android.service.wallpaper.IWallpaperConnection;
 
 /**
@@ -24,5 +25,5 @@
 oneway interface IWallpaperService {
     void attach(IWallpaperConnection connection,
     		IBinder windowToken, int windowType, boolean isPreview,
-    		int reqWidth, int reqHeight);
+    		int reqWidth, int reqHeight, in Rect padding);
 }
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index f3c26c8..26e9a30 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -16,6 +16,14 @@
 
 package android.service.wallpaper;
 
+import android.content.res.TypedArray;
+import android.os.Build;
+import android.os.SystemProperties;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.ViewRootImpl;
+import android.view.WindowInsets;
+import com.android.internal.R;
 import com.android.internal.os.HandlerCaller;
 import com.android.internal.view.BaseIWindow;
 import com.android.internal.view.BaseSurfaceHolder;
@@ -56,6 +64,8 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
+import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
+
 /**
  * A wallpaper service is responsible for showing a live wallpaper behind
  * applications that would like to sit on top of it.  This service object
@@ -90,7 +100,8 @@
     private static final int DO_ATTACH = 10;
     private static final int DO_DETACH = 20;
     private static final int DO_SET_DESIRED_SIZE = 30;
-    
+    private static final int DO_SET_DISPLAY_PADDING = 40;
+
     private static final int MSG_UPDATE_SURFACE = 10000;
     private static final int MSG_VISIBILITY_CHANGED = 10010;
     private static final int MSG_WALLPAPER_OFFSETS = 10020;
@@ -150,13 +161,23 @@
                 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
         int mCurWindowFlags = mWindowFlags;
         int mCurWindowPrivateFlags = mWindowPrivateFlags;
+        TypedValue mOutsetBottom;
         final Rect mVisibleInsets = new Rect();
         final Rect mWinFrame = new Rect();
         final Rect mOverscanInsets = new Rect();
         final Rect mContentInsets = new Rect();
         final Rect mStableInsets = new Rect();
+        final Rect mDispatchedOverscanInsets = new Rect();
+        final Rect mDispatchedContentInsets = new Rect();
+        final Rect mDispatchedStableInsets = new Rect();
+        final Rect mFinalSystemInsets = new Rect();
+        final Rect mFinalStableInsets = new Rect();
         final Configuration mConfiguration = new Configuration();
-        
+
+        private boolean mIsEmulator;
+        private boolean mIsCircularEmulator;
+        private boolean mWindowIsRound;
+
         final WindowManager.LayoutParams mLayout
                 = new WindowManager.LayoutParams();
         IWindowSession mSession;
@@ -406,7 +427,7 @@
          */
         public void onCreate(SurfaceHolder surfaceHolder) {
         }
-        
+
         /**
          * Called right before the engine is going away.  After this the
          * surface will be destroyed and this Engine object is no longer
@@ -414,7 +435,7 @@
          */
         public void onDestroy() {
         }
-        
+
         /**
          * Called to inform you of the wallpaper becoming visible or
          * hidden.  <em>It is very important that a wallpaper only use
@@ -422,7 +443,17 @@
          */
         public void onVisibilityChanged(boolean visible) {
         }
-        
+
+        /**
+         * Called with the current insets that are in effect for the wallpaper.
+         * This gives you the part of the overall wallpaper surface that will
+         * generally be visible to the user (ignoring position offsets applied to it).
+         *
+         * @param insets Insets to apply.
+         */
+        public void onApplyWindowInsets(WindowInsets insets) {
+        }
+
         /**
          * Called as the user performs touch-screen interaction with the
          * window that is currently showing this wallpaper.  Note that the
@@ -432,7 +463,7 @@
          */
         public void onTouchEvent(MotionEvent event) {
         }
-        
+
         /**
          * Called to inform you of the wallpaper's offsets changing
          * within its contain, corresponding to the container's
@@ -443,7 +474,7 @@
                 float xOffsetStep, float yOffsetStep,
                 int xPixelOffset, int yPixelOffset) {
         }
-        
+
         /**
          * Process a command that was sent to the wallpaper with
          * {@link WallpaperManager#sendWallpaperCommand}.
@@ -465,14 +496,14 @@
                 Bundle extras, boolean resultRequested) {
             return null;
         }
-        
+
         /**
          * Called when an application has changed the desired virtual size of
          * the wallpaper.
          */
         public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) {
         }
-        
+
         /**
          * Convenience for {@link SurfaceHolder.Callback#surfaceChanged
          * SurfaceHolder.Callback.surfaceChanged()}.
@@ -561,16 +592,20 @@
             if (mDestroyed) {
                 Log.w(TAG, "Ignoring updateSurface: destroyed");
             }
-            
+
+            boolean fixedSize = false;
             int myWidth = mSurfaceHolder.getRequestedWidth();
             if (myWidth <= 0) myWidth = ViewGroup.LayoutParams.MATCH_PARENT;
+            else fixedSize = true;
             int myHeight = mSurfaceHolder.getRequestedHeight();
             if (myHeight <= 0) myHeight = ViewGroup.LayoutParams.MATCH_PARENT;
-            
+            else fixedSize = true;
+
             final boolean creating = !mCreated;
             final boolean surfaceCreating = !mSurfaceCreated;
             final boolean formatChanged = mFormat != mSurfaceHolder.getRequestedFormat();
             boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
+            boolean insetsChanged = !mCreated;
             final boolean typeChanged = mType != mSurfaceHolder.getRequestedType();
             final boolean flagsChanged = mCurWindowFlags != mWindowFlags ||
                     mCurWindowPrivateFlags != mWindowPrivateFlags;
@@ -607,6 +642,32 @@
                     mLayout.token = mWindowToken;
 
                     if (!mCreated) {
+                        // Retrieve watch round and outset info
+                        final WindowManager windowService = (WindowManager)getSystemService(
+                                Context.WINDOW_SERVICE);
+                        TypedArray windowStyle = obtainStyledAttributes(
+                                com.android.internal.R.styleable.Window);
+                        final Display display = windowService.getDefaultDisplay();
+                        final boolean shouldUseBottomOutset =
+                                display.getDisplayId() == Display.DEFAULT_DISPLAY;
+                        if (shouldUseBottomOutset && windowStyle.hasValue(
+                                R.styleable.Window_windowOutsetBottom)) {
+                            if (mOutsetBottom == null) mOutsetBottom = new TypedValue();
+                            windowStyle.getValue(R.styleable.Window_windowOutsetBottom,
+                                    mOutsetBottom);
+                        } else {
+                            mOutsetBottom = null;
+                        }
+                        mWindowIsRound = getResources().getBoolean(
+                                com.android.internal.R.bool.config_windowIsRound);
+                        windowStyle.recycle();
+
+                        // detect emulator
+                        mIsEmulator = Build.HARDWARE.contains("goldfish");
+                        mIsCircularEmulator = SystemProperties.getBoolean(
+                                ViewRootImpl.PROPERTY_EMULATOR_CIRCULAR, false);
+
+                        // Add window
                         mLayout.type = mIWallpaperEngine.mWindowType;
                         mLayout.gravity = Gravity.START|Gravity.TOP;
                         mLayout.setTitle(WallpaperService.this.getClass().getName());
@@ -627,6 +688,11 @@
                     mSurfaceHolder.mSurfaceLock.lock();
                     mDrawingAllowed = true;
 
+                    if (!fixedSize) {
+                        mLayout.surfaceInsets.set(mIWallpaperEngine.mDisplayPadding);
+                    } else {
+                        mLayout.surfaceInsets.set(0, 0, 0, 0);
+                    }
                     final int relayoutResult = mSession.relayout(
                         mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
                             View.VISIBLE, 0, mWinFrame, mOverscanInsets, mContentInsets,
@@ -636,16 +702,39 @@
                             + ", frame=" + mWinFrame);
                     
                     int w = mWinFrame.width();
+                    int h = mWinFrame.height();
+
+                    if (!fixedSize) {
+                        final Rect padding = mIWallpaperEngine.mDisplayPadding;
+                        w += padding.left + padding.right;
+                        h += padding.top + padding.bottom;
+                        mOverscanInsets.left += padding.left;
+                        mOverscanInsets.top += padding.top;
+                        mOverscanInsets.right += padding.right;
+                        mOverscanInsets.bottom += padding.bottom;
+                        mContentInsets.left += padding.left;
+                        mContentInsets.top += padding.top;
+                        mContentInsets.right += padding.right;
+                        mContentInsets.bottom += padding.bottom;
+                        mStableInsets.left += padding.left;
+                        mStableInsets.top += padding.top;
+                        mStableInsets.right += padding.right;
+                        mStableInsets.bottom += padding.bottom;
+                    }
+
                     if (mCurWidth != w) {
                         sizeChanged = true;
                         mCurWidth = w;
                     }
-                    int h = mWinFrame.height();
                     if (mCurHeight != h) {
                         sizeChanged = true;
                         mCurHeight = h;
                     }
 
+                    insetsChanged |= !mDispatchedOverscanInsets.equals(mOverscanInsets);
+                    insetsChanged |= !mDispatchedContentInsets.equals(mContentInsets);
+                    insetsChanged |= !mDispatchedStableInsets.equals(mStableInsets);
+
                     mSurfaceHolder.setSurfaceFrameSize(w, h);
                     mSurfaceHolder.mSurfaceLock.unlock();
 
@@ -702,6 +791,25 @@
                             }
                         }
 
+                        if (insetsChanged) {
+                            mDispatchedOverscanInsets.set(mOverscanInsets);
+                            mDispatchedContentInsets.set(mContentInsets);
+                            mDispatchedStableInsets.set(mStableInsets);
+                            final boolean isRound = (mIsEmulator && mIsCircularEmulator)
+                                    || mWindowIsRound;
+                            mFinalSystemInsets.set(mDispatchedOverscanInsets);
+                            mFinalStableInsets.set(mDispatchedStableInsets);
+                            if (mOutsetBottom != null) {
+                                final DisplayMetrics metrics = getResources().getDisplayMetrics();
+                                mFinalSystemInsets.bottom =
+                                        ( (int) mOutsetBottom.getDimension(metrics) )
+                                        + mIWallpaperEngine.mDisplayPadding.bottom;
+                            }
+                            WindowInsets insets = new WindowInsets(mFinalSystemInsets,
+                                    null, mFinalStableInsets, isRound);
+                            onApplyWindowInsets(insets);
+                        }
+
                         if (redrawNeeded) {
                             onSurfaceRedrawNeeded(mSurfaceHolder);
                             SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
@@ -781,7 +889,7 @@
             mReportedVisible = false;
             updateSurface(false, false, false);
         }
-        
+
         void doDesiredSizeChanged(int desiredWidth, int desiredHeight) {
             if (!mDestroyed) {
                 if (DEBUG) Log.v(TAG, "onDesiredSizeChanged("
@@ -792,14 +900,24 @@
                 doOffsetsChanged(true);
             }
         }
-        
+
+        void doDisplayPaddingChanged(Rect padding) {
+            if (!mDestroyed) {
+                if (DEBUG) Log.v(TAG, "onDisplayPaddingChanged(" + padding + "): " + this);
+                if (!mIWallpaperEngine.mDisplayPadding.equals(padding)) {
+                    mIWallpaperEngine.mDisplayPadding.set(padding);
+                    updateSurface(true, false, false);
+                }
+            }
+        }
+
         void doVisibilityChanged(boolean visible) {
             if (!mDestroyed) {
                 mVisible = visible;
                 reportVisibility();
             }
         }
-        
+
         void reportVisibility() {
             if (!mDestroyed) {
                 boolean visible = mVisible && mScreenOn;
@@ -956,12 +1074,13 @@
         boolean mShownReported;
         int mReqWidth;
         int mReqHeight;
-        
+        final Rect mDisplayPadding = new Rect();
+
         Engine mEngine;
-        
+
         IWallpaperEngineWrapper(WallpaperService context,
                 IWallpaperConnection conn, IBinder windowToken,
-                int windowType, boolean isPreview, int reqWidth, int reqHeight) {
+                int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding) {
             mCaller = new HandlerCaller(context, context.getMainLooper(), this, true);
             mConnection = conn;
             mWindowToken = windowToken;
@@ -969,16 +1088,22 @@
             mIsPreview = isPreview;
             mReqWidth = reqWidth;
             mReqHeight = reqHeight;
+            mDisplayPadding.set(padding);
             
             Message msg = mCaller.obtainMessage(DO_ATTACH);
             mCaller.sendMessage(msg);
         }
-        
+
         public void setDesiredSize(int width, int height) {
             Message msg = mCaller.obtainMessageII(DO_SET_DESIRED_SIZE, width, height);
             mCaller.sendMessage(msg);
         }
-        
+
+        public void setDisplayPadding(Rect padding) {
+            Message msg = mCaller.obtainMessageO(DO_SET_DISPLAY_PADDING, padding);
+            mCaller.sendMessage(msg);
+        }
+
         public void setVisibility(boolean visible) {
             Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED,
                     visible ? 1 : 0);
@@ -1041,6 +1166,9 @@
                     mEngine.doDesiredSizeChanged(message.arg1, message.arg2);
                     return;
                 }
+                case DO_SET_DISPLAY_PADDING: {
+                    mEngine.doDisplayPaddingChanged((Rect) message.obj);
+                }
                 case MSG_UPDATE_SURFACE:
                     mEngine.updateSurface(true, false, false);
                     break;
@@ -1102,9 +1230,9 @@
 
         @Override
         public void attach(IWallpaperConnection conn, IBinder windowToken,
-                int windowType, boolean isPreview, int reqWidth, int reqHeight) {
+                int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding) {
             new IWallpaperEngineWrapper(mTarget, conn, windowToken,
-                    windowType, isPreview, reqWidth, reqHeight);
+                    windowType, isPreview, reqWidth, reqHeight, padding);
         }
     }
 
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 0f3f182..037ed28 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -177,6 +177,11 @@
 
     void wallpaperOffsetsComplete(IBinder window);
 
+    /**
+     * Apply a raw offset to the wallpaper service when shown behind this window.
+     */
+    void setWallpaperDisplayOffset(IBinder windowToken, int x, int y);
+
     Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
             int z, in Bundle extras, boolean sync);
 
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 1e28e33..4074529 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -39,7 +39,7 @@
 
     private static native Bitmap nativeScreenshot(IBinder displayToken,
             Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
-            boolean allLayers, boolean useIdentityTransform);
+            boolean allLayers, boolean useIdentityTransform, int rotation);
     private static native void nativeScreenshot(IBinder displayToken, Surface consumer,
             Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
             boolean allLayers, boolean useIdentityTransform);
@@ -688,17 +688,23 @@
      * @param useIdentityTransform Replace whatever transformation (rotation,
      * scaling, translation) the surface layers are currently using with the
      * identity transformation while taking the screenshot.
+     * @param rotation Apply a custom clockwise rotation to the screenshot, i.e.
+     * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take
+     * screenshots in its native portrait orientation by default, so this is
+     * useful for returning screenshots that are independent of device
+     * orientation.
      * @return Returns a Bitmap containing the screen contents, or null
      * if an error occurs. Make sure to call Bitmap.recycle() as soon as
      * possible, once its content is not needed anymore.
      */
     public static Bitmap screenshot(Rect sourceCrop, int width, int height,
-            int minLayer, int maxLayer, boolean useIdentityTransform) {
+            int minLayer, int maxLayer, boolean useIdentityTransform,
+            int rotation) {
         // TODO: should take the display as a parameter
         IBinder displayToken = SurfaceControl.getBuiltInDisplay(
                 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
         return nativeScreenshot(displayToken, sourceCrop, width, height,
-                minLayer, maxLayer, false, useIdentityTransform);
+                minLayer, maxLayer, false, useIdentityTransform, rotation);
     }
 
     /**
@@ -717,7 +723,8 @@
         // TODO: should take the display as a parameter
         IBinder displayToken = SurfaceControl.getBuiltInDisplay(
                 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
-        return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true, false);
+        return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true,
+                false, Surface.ROTATION_0);
     }
 
     private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop,
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 80b9ade..43ab4ef 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -121,7 +121,7 @@
     private static final String PROPERTY_MEDIA_DISABLED = "config.disable_media";
 
     // property used by emulator to determine display shape
-    private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular";
+    public static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular";
 
     /**
      * Maximum time we allow the user to roll the trackball enough to generate
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index 571a8f0..24c3c1a 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -378,35 +378,75 @@
     }
 
     /**
-     * @hide
+     * Returns the top stable inset in pixels.
+     *
+     * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
+     * partially or fully obscured by the system UI elements.  This value does not change
+     * based on the visibility state of those elements; for example, if the status bar is
+     * normally shown, but temporarily hidden, the stable inset will still provide the inset
+     * associated with the status bar being shown.</p>
+     *
+     * @return The top stable inset
      */
     public int getStableInsetTop() {
         return mStableInsets.top;
     }
 
     /**
-     * @hide
+     * Returns the left stable inset in pixels.
+     *
+     * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
+     * partially or fully obscured by the system UI elements.  This value does not change
+     * based on the visibility state of those elements; for example, if the status bar is
+     * normally shown, but temporarily hidden, the stable inset will still provide the inset
+     * associated with the status bar being shown.</p>
+     *
+     * @return The left stable inset
      */
     public int getStableInsetLeft() {
         return mStableInsets.left;
     }
 
     /**
-     * @hide
+     * Returns the right stable inset in pixels.
+     *
+     * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
+     * partially or fully obscured by the system UI elements.  This value does not change
+     * based on the visibility state of those elements; for example, if the status bar is
+     * normally shown, but temporarily hidden, the stable inset will still provide the inset
+     * associated with the status bar being shown.</p>
+     *
+     * @return The right stable inset
      */
     public int getStableInsetRight() {
         return mStableInsets.right;
     }
 
     /**
-     * @hide
+     * Returns the bottom stable inset in pixels.
+     *
+     * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
+     * partially or fully obscured by the system UI elements.  This value does not change
+     * based on the visibility state of those elements; for example, if the status bar is
+     * normally shown, but temporarily hidden, the stable inset will still provide the inset
+     * associated with the status bar being shown.</p>
+     *
+     * @return The bottom stable inset
      */
     public int getStableInsetBottom() {
         return mStableInsets.bottom;
     }
 
     /**
-     * @hide
+     * Returns true if this WindowInsets has nonzero stable insets.
+     *
+     * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
+     * partially or fully obscured by the system UI elements.  This value does not change
+     * based on the visibility state of those elements; for example, if the status bar is
+     * normally shown, but temporarily hidden, the stable inset will still provide the inset
+     * associated with the status bar being shown.</p>
+     *
+     * @return true if any of the stable inset values are nonzero
      */
     public boolean hasStableInsets() {
         return mStableInsets.top != 0 || mStableInsets.left != 0 || mStableInsets.right != 0
@@ -414,7 +454,9 @@
     }
 
     /**
-     * @hide
+     * Returns a copy of this WindowInsets with the stable insets fully consumed.
+     *
+     * @return A modified copy of this WindowInsets
      */
     public WindowInsets consumeStableInsets() {
         final WindowInsets result = new WindowInsets(this);
diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java
index e7ada27..1671faa 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtype.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtype.java
@@ -211,18 +211,6 @@
      }
 
     /**
-     * Constructor with no subtype ID specified, overridesImplicitlyEnabledSubtype not specified.
-     * Arguments for this constructor have the same meanings as
-     * {@link InputMethodSubtype#InputMethodSubtype(int, int, String, String, String, boolean,
-     * boolean, int)} except "id" and "overridesImplicitlyEnabledSubtype".
-     * @hide
-     */
-    public InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue,
-            boolean isAuxiliary) {
-        this(nameId, iconId, locale, mode, extraValue, isAuxiliary, false);
-    }
-
-    /**
      * Constructor with no subtype ID specified.
      * @deprecated use {@link InputMethodSubtypeBuilder} instead.
      * Arguments for this constructor have the same meanings as
diff --git a/core/java/android/widget/ActionMenuView.java b/core/java/android/widget/ActionMenuView.java
index 6ca4a9e..7198e52 100644
--- a/core/java/android/widget/ActionMenuView.java
+++ b/core/java/android/widget/ActionMenuView.java
@@ -611,6 +611,7 @@
             mMenu = new MenuBuilder(context);
             mMenu.setCallback(new MenuBuilderCallback());
             mPresenter = new ActionMenuPresenter(context);
+            mPresenter.setReserveOverflow(true);
             mPresenter.setCallback(mActionMenuPresenterCallback != null
                     ? mActionMenuPresenterCallback : new ActionMenuPresenterCallback());
             mMenu.addMenuPresenter(mPresenter, mPopupContext);
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index d263625..efd6fc0 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -2356,7 +2356,7 @@
         final int rowsCount = getCount() / columnsCount;
         final int selectionMode = getSelectionModeForAccessibility();
         final CollectionInfo collectionInfo = CollectionInfo.obtain(
-                columnsCount, rowsCount, false, selectionMode);
+                rowsCount, columnsCount, false, selectionMode);
         info.setCollectionInfo(collectionInfo);
     }
 
@@ -2385,7 +2385,7 @@
         final boolean isHeading = lp != null && lp.viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER;
         final boolean isSelected = isItemChecked(position);
         final CollectionItemInfo itemInfo = CollectionItemInfo.obtain(
-                column, 1, row, 1, isHeading, isSelected);
+                row, 1, column, 1, isHeading, isSelected);
         info.setCollectionItemInfo(itemInfo);
     }
 }
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 1368cd3..2e9858c 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -3882,9 +3882,10 @@
         super.onInitializeAccessibilityNodeInfo(info);
         info.setClassName(ListView.class.getName());
 
-        final int count = getCount();
+        final int rowsCount = getCount();
         final int selectionMode = getSelectionModeForAccessibility();
-        final CollectionInfo collectionInfo = CollectionInfo.obtain(1, count, false, selectionMode);
+        final CollectionInfo collectionInfo = CollectionInfo.obtain(
+                rowsCount, 1, false, selectionMode);
         info.setCollectionInfo(collectionInfo);
     }
 
@@ -3897,7 +3898,7 @@
         final boolean isHeading = lp != null && lp.viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER;
         final boolean isSelected = isItemChecked(position);
         final CollectionItemInfo itemInfo = CollectionItemInfo.obtain(
-                0, 1, position, 1, isHeading, isSelected);
+                position, 1, 0, 1, isHeading, isSelected);
         info.setCollectionItemInfo(itemInfo);
     }
 }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 3e1b674..80ea6ea 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8423,6 +8423,33 @@
     @Override
     public boolean performAccessibilityAction(int action, Bundle arguments) {
         switch (action) {
+            case AccessibilityNodeInfo.ACTION_CLICK: {
+                boolean handled = false;
+
+                // Simulate View.onTouchEvent for an ACTION_UP event.
+                if (isClickable() || isLongClickable()) {
+                    if (isFocusable() && !isFocused()) {
+                        requestFocus();
+                    }
+
+                    performClick();
+                    handled = true;
+                }
+
+                // Simulate TextView.onTouchEvent for an ACTION_UP event.
+                if ((mMovement != null || onCheckIsTextEditor()) && isEnabled()
+                        && mText instanceof Spannable && mLayout != null
+                        && (isTextEditable() || isTextSelectable()) && isFocused()) {
+                    // Show the IME, except when selecting in read-only text.
+                    final InputMethodManager imm = InputMethodManager.peekInstance();
+                    viewClicked(imm);
+                    if (!isTextSelectable() && mEditor.mShowSoftInputOnFocus && imm != null) {
+                        handled |= imm.showSoftInput(this, 0);
+                    }
+                }
+
+                return handled;
+            }
             case AccessibilityNodeInfo.ACTION_COPY: {
                 if (isFocused() && canCopy()) {
                     if (onTextContextMenuItem(ID_COPY)) {
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 2106d38..dbaa4b8 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -129,6 +129,7 @@
 	android/graphics/Xfermode.cpp \
 	android/graphics/YuvToJpegEncoder.cpp \
 	android/graphics/pdf/PdfDocument.cpp \
+	android/graphics/pdf/PdfEditor.cpp \
 	android/graphics/pdf/PdfRenderer.cpp \
 	android_media_AudioRecord.cpp \
 	android_media_AudioSystem.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 62d8036..a63258c 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -126,6 +126,7 @@
 extern int register_android_graphics_SurfaceTexture(JNIEnv* env);
 extern int register_android_graphics_Xfermode(JNIEnv* env);
 extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env);
+extern int register_android_graphics_pdf_PdfEditor(JNIEnv* env);
 extern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env);
 extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
 extern int register_android_view_RenderNode(JNIEnv* env);
@@ -1305,6 +1306,7 @@
     REG_JNI(register_android_graphics_Xfermode),
     REG_JNI(register_android_graphics_YuvImage),
     REG_JNI(register_android_graphics_pdf_PdfDocument),
+    REG_JNI(register_android_graphics_pdf_PdfEditor),
     REG_JNI(register_android_graphics_pdf_PdfRenderer),
 
     REG_JNI(register_android_database_CursorWindow),
diff --git a/core/jni/android/graphics/pdf/PdfEditor.cpp b/core/jni/android/graphics/pdf/PdfEditor.cpp
new file mode 100644
index 0000000..5f60c9e
--- /dev/null
+++ b/core/jni/android/graphics/pdf/PdfEditor.cpp
@@ -0,0 +1,161 @@
+/*
+ * 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.
+ */
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "fpdfview.h"
+#include "fpdfedit.h"
+#include "fpdfsave.h"
+
+#include <android_runtime/AndroidRuntime.h>
+#include <vector>
+#include <utils/Log.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+namespace android {
+
+static Mutex sLock;
+
+static int sUnmatchedInitRequestCount = 0;
+
+static void initializeLibraryIfNeeded() {
+    Mutex::Autolock _l(sLock);
+    if (sUnmatchedInitRequestCount == 0) {
+        FPDF_InitLibrary(NULL);
+    }
+    sUnmatchedInitRequestCount++;
+}
+
+static void destroyLibraryIfNeeded() {
+    Mutex::Autolock _l(sLock);
+    sUnmatchedInitRequestCount--;
+    if (sUnmatchedInitRequestCount == 0) {
+       FPDF_DestroyLibrary();
+    }
+}
+
+static int getBlock(void* param, unsigned long position, unsigned char* outBuffer,
+        unsigned long size) {
+    const int fd = reinterpret_cast<intptr_t>(param);
+    const int readCount = pread(fd, outBuffer, size, position);
+    if (readCount < 0) {
+        ALOGE("Cannot read from file descriptor. Error:%d", errno);
+        return 0;
+    }
+    return 1;
+}
+
+static jlong nativeOpen(JNIEnv* env, jclass thiz, jint fd, jlong size) {
+    initializeLibraryIfNeeded();
+
+    FPDF_FILEACCESS loader;
+    loader.m_FileLen = size;
+    loader.m_Param = reinterpret_cast<void*>(intptr_t(fd));
+    loader.m_GetBlock = &getBlock;
+
+    FPDF_DOCUMENT document = FPDF_LoadCustomDocument(&loader, NULL);
+
+    if (!document) {
+        const long error = FPDF_GetLastError();
+        jniThrowException(env, "java/io/IOException",
+                "cannot create document. Error:" + error);
+        destroyLibraryIfNeeded();
+        return -1;
+    }
+
+    return reinterpret_cast<jlong>(document);
+}
+
+static void nativeClose(JNIEnv* env, jclass thiz, jlong documentPtr) {
+    FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
+    FPDF_CloseDocument(document);
+    destroyLibraryIfNeeded();
+}
+
+static jint nativeGetPageCount(JNIEnv* env, jclass thiz, jlong documentPtr) {
+    FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
+    return FPDF_GetPageCount(document);
+}
+
+static jint nativeRemovePage(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex) {
+    FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
+    FPDFPage_Delete(document, pageIndex);
+    return FPDF_GetPageCount(document);
+}
+
+struct PdfToFdWriter : FPDF_FILEWRITE {
+    int dstFd;
+};
+
+static bool writeAllBytes(const int fd, const void* buffer, const size_t byteCount) {
+    char* writeBuffer = static_cast<char*>(const_cast<void*>(buffer));
+    size_t remainingBytes = byteCount;
+    while (remainingBytes > 0) {
+        ssize_t writtenByteCount = write(fd, writeBuffer, remainingBytes);
+        if (writtenByteCount == -1) {
+            if (errno == EINTR) {
+                continue;
+            }
+            __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
+                    "Error writing to buffer: %d", errno);
+            return false;
+        }
+        remainingBytes -= writtenByteCount;
+        writeBuffer += writtenByteCount;
+    }
+    return true;
+}
+
+static int writeBlock(FPDF_FILEWRITE* owner, const void* buffer, unsigned long size) {
+    const PdfToFdWriter* writer = reinterpret_cast<PdfToFdWriter*>(owner);
+    const bool success = writeAllBytes(writer->dstFd, buffer, size);
+    if (success < 0) {
+        ALOGE("Cannot write to file descriptor. Error:%d", errno);
+        return 0;
+    }
+    return 1;
+}
+
+static void nativeWrite(JNIEnv* env, jclass thiz, jlong documentPtr, jint fd) {
+    FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
+    PdfToFdWriter writer;
+    writer.dstFd = fd;
+    writer.WriteBlock = &writeBlock;
+    const bool success = FPDF_SaveAsCopy(document, &writer, FPDF_NO_INCREMENTAL);
+    if (!success) {
+        jniThrowException(env, "java/io/IOException",
+                "cannot write to fd. Error:" + errno);
+        destroyLibraryIfNeeded();
+    }
+}
+
+static JNINativeMethod gPdfEditor_Methods[] = {
+    {"nativeOpen", "(IJ)J", (void*) nativeOpen},
+    {"nativeClose", "(J)V", (void*) nativeClose},
+    {"nativeGetPageCount", "(J)I", (void*) nativeGetPageCount},
+    {"nativeRemovePage", "(JI)I", (void*) nativeRemovePage},
+    {"nativeWrite", "(JI)V", (void*) nativeWrite}
+};
+
+int register_android_graphics_pdf_PdfEditor(JNIEnv* env) {
+    return android::AndroidRuntime::registerNativeMethods(
+            env, "android/graphics/pdf/PdfEditor", gPdfEditor_Methods,
+            NELEM(gPdfEditor_Methods));
+};
+
+};
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 8f30f5d..06c22ae 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -117,7 +117,8 @@
 
 static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
         jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
-        jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) {
+        jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform,
+        int rotation) {
     sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
     if (displayToken == NULL) {
         return NULL;
@@ -131,17 +132,13 @@
 
     SkAutoTDelete<ScreenshotClient> screenshot(new ScreenshotClient());
     status_t res;
-    if (width > 0 && height > 0) {
-        if (allLayers) {
-            res = screenshot->update(displayToken, sourceCrop, width, height,
-                    useIdentityTransform);
-        } else {
-            res = screenshot->update(displayToken, sourceCrop, width, height,
-                    minLayer, maxLayer, useIdentityTransform);
-        }
-    } else {
-        res = screenshot->update(displayToken, sourceCrop, useIdentityTransform);
+    if (allLayers) {
+        minLayer = 0;
+        maxLayer = -1UL;
     }
+
+    res = screenshot->update(displayToken, sourceCrop, width, height,
+        minLayer, maxLayer, useIdentityTransform, static_cast<uint32_t>(rotation));
     if (res != NO_ERROR) {
         return NULL;
     }
@@ -588,7 +585,7 @@
             (void*)nativeRelease },
     {"nativeDestroy", "(J)V",
             (void*)nativeDestroy },
-    {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZ)Landroid/graphics/Bitmap;",
+    {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/Bitmap;",
             (void*)nativeScreenshotBitmap },
     {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V",
             (void*)nativeScreenshot },
diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
index c84a466..2e2d0c7 100644
--- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
+++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
@@ -175,17 +175,23 @@
                 continue;
             }
         }
-        // Skip whitespace.
-        while (*pos == ' ') {
-            pos++;
-        }
-        // Next field is tag.
-        rawTag = strtoll(pos, &endPos, 16);
-        //ALOGI("Index #%d: %s", idx, buffer);
-        if (pos == endPos) {
-            ALOGE("bad tag: %s", pos);
-            fclose(fp);
-            return -1;
+
+        // Ignore whitespace
+        while (*pos == ' ') pos++;
+
+        // Find end of tag field
+        endPos = pos;
+        while (*endPos != ' ') endPos++;
+
+        // Three digit field is always 0x0, otherwise parse
+        if (endPos - pos == 3) {
+            rawTag = 0;
+        } else {
+            if (sscanf(pos, "%llx", &rawTag) != 1) {
+                ALOGE("bad tag: %s", pos);
+                fclose(fp);
+                return -1;
+            }
         }
         s.tag = rawTag >> 32;
         if (limitTag != -1 && s.tag != limitTag) {
@@ -193,10 +199,10 @@
             continue;
         }
         pos = endPos;
-        // Skip whitespace.
-        while (*pos == ' ') {
-            pos++;
-        }
+
+        // Ignore whitespace
+        while (*pos == ' ') pos++;
+
         // Parse remaining fields.
         if (sscanf(pos, "%u %u %llu %llu %llu %llu",
                 &s.uid, &s.set, &s.rxBytes, &s.rxPackets,
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 72dd930..8a1d5af 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2502,7 +2502,7 @@
     <permission android:name="android.permission.PACKAGE_USAGE_STATS"
         android:label="@string/permlab_pkgUsageStats"
         android:description="@string/permdesc_pkgUsageStats"
-        android:protectionLevel="signature|system|development|appop" />
+        android:protectionLevel="signature|development|appop" />
     <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
 
     <!-- @SystemApi Allows an application to collect battery statistics -->
diff --git a/core/res/res/drawable/emulator_circular_window_overlay.xml b/core/res/res/drawable/emulator_circular_window_overlay.xml
new file mode 100644
index 0000000..7616b37
--- /dev/null
+++ b/core/res/res/drawable/emulator_circular_window_overlay.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Default to an empty shape drawable -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+</shape>
diff --git a/core/res/res/layout/alert_dialog_material.xml b/core/res/res/layout/alert_dialog_material.xml
index 5f9066a..be89e41 100644
--- a/core/res/res/layout/alert_dialog_material.xml
+++ b/core/res/res/layout/alert_dialog_material.xml
@@ -33,8 +33,7 @@
             android:gravity="center_vertical|start"
             android:paddingStart="@dimen/alert_dialog_padding_material"
             android:paddingEnd="@dimen/alert_dialog_padding_material"
-            android:paddingTop="@dimen/alert_dialog_padding_material"
-            android:paddingBottom="8dip">
+            android:paddingTop="@dimen/alert_dialog_padding_top_material">
             <ImageView android:id="@+id/icon"
                 android:layout_width="32dip"
                 android:layout_height="32dip"
@@ -57,7 +56,8 @@
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:orientation="vertical"
-        android:minHeight="64dp">
+        android:minHeight="64dp"
+        android:paddingTop="@dimen/alert_dialog_padding_top_material">
         <ScrollView android:id="@+id/scrollView"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
@@ -67,9 +67,7 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:paddingStart="@dimen/alert_dialog_padding_material"
-                android:paddingEnd="@dimen/alert_dialog_padding_material"
-                android:paddingTop="@dimen/alert_dialog_padding_material"
-                android:paddingBottom="@dimen/alert_dialog_padding_material" />
+                android:paddingEnd="@dimen/alert_dialog_padding_material" />
         </ScrollView>
     </LinearLayout>
 
@@ -89,15 +87,14 @@
         android:layout_height="wrap_content"
         android:layoutDirection="locale"
         android:orientation="horizontal"
-        android:paddingStart="6dp"
-        android:paddingEnd="6dp"
-        android:paddingBottom="6dp">
+        android:paddingStart="12dp"
+        android:paddingEnd="12dp"
+        android:paddingTop="8dp"
+        android:paddingBottom="8dp">
         <Button android:id="@+id/button3"
             style="?attr/buttonBarNeutralButtonStyle"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:maxLines="2"
-            android:minHeight="@dimen/alert_dialog_button_bar_height" />
+            android:layout_height="wrap_content" />
         <Space
             android:layout_width="0dp"
             android:layout_height="0dp"
@@ -106,14 +103,10 @@
         <Button android:id="@+id/button2"
             style="?attr/buttonBarNegativeButtonStyle"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:maxLines="2"
-            android:minHeight="@dimen/alert_dialog_button_bar_height" />
+            android:layout_height="wrap_content" />
         <Button android:id="@+id/button1"
             style="?attr/buttonBarPositiveButtonStyle"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:maxLines="2"
-            android:minHeight="@dimen/alert_dialog_button_bar_height" />
+            android:layout_height="wrap_content" />
     </LinearLayout>
 </LinearLayout>
diff --git a/core/res/res/layout/alert_dialog_progress_material.xml b/core/res/res/layout/alert_dialog_progress_material.xml
index b9d0814..d005a44 100644
--- a/core/res/res/layout/alert_dialog_progress_material.xml
+++ b/core/res/res/layout/alert_dialog_progress_material.xml
@@ -17,32 +17,27 @@
 
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="wrap_content"
-    android:layout_height="match_parent">
-    <ProgressBar android:id="@+id/progress"
-        style="?android:attr/progressBarStyleHorizontal"
+    android:layout_height="match_parent"
+    android:paddingStart="@dimen/alert_dialog_padding_material"
+    android:paddingTop="@dimen/alert_dialog_padding_top_material"
+    android:paddingEnd="@dimen/alert_dialog_padding_material"
+    android:paddingBottom="@dimen/alert_dialog_padding_top_material">
+    <ProgressBar
+        android:id="@+id/progress"
+        style="?attr/progressBarStyleHorizontal"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginTop="16dip"
-        android:layout_marginBottom="1dip"
-        android:layout_marginStart="16dip"
-        android:layout_marginEnd="16dip"
         android:layout_centerHorizontal="true" />
     <TextView
         android:id="@+id/progress_percent"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:paddingBottom="16dip"
-        android:layout_marginStart="16dip"
-        android:layout_marginEnd="16dip"
         android:layout_alignParentStart="true"
         android:layout_below="@id/progress" />
     <TextView
         android:id="@+id/progress_number"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:paddingBottom="16dip"
-        android:layout_marginStart="16dip"
-        android:layout_marginEnd="16dip"
         android:layout_alignParentEnd="true"
         android:layout_below="@id/progress" />
 </RelativeLayout>
diff --git a/core/res/res/layout/dialog_custom_title_material.xml b/core/res/res/layout/dialog_custom_title_material.xml
index 550b72e..248a05e 100644
--- a/core/res/res/layout/dialog_custom_title_material.xml
+++ b/core/res/res/layout/dialog_custom_title_material.xml
@@ -23,17 +23,17 @@
     android:fitsSystemWindows="true">
     <FrameLayout android:id="@android:id/title_container"
         android:layout_width="match_parent"
-        android:layout_height="?android:attr/windowTitleSize"
+        android:layout_height="?attr/windowTitleSize"
         android:layout_weight="0"
         android:gravity="center_vertical|start"
-        style="?android:attr/windowTitleBackgroundStyle" />
+        style="?attr/windowTitleBackgroundStyle" />
     <FrameLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:orientation="vertical"
-        android:foreground="?android:attr/windowContentOverlay">
-        <FrameLayout android:id="@android:id/content"
+        android:foreground="?attr/windowContentOverlay">
+        <FrameLayout android:id="@id/content"
             android:layout_width="match_parent"
             android:layout_height="match_parent" />
     </FrameLayout>
diff --git a/core/res/res/layout/dialog_title_icons_material.xml b/core/res/res/layout/dialog_title_icons_material.xml
index 28e20d9..21396da 100644
--- a/core/res/res/layout/dialog_title_icons_material.xml
+++ b/core/res/res/layout/dialog_title_icons_material.xml
@@ -28,16 +28,16 @@
         android:layout_height="wrap_content"
         android:orientation="horizontal"
         android:gravity="center_vertical"
-        android:paddingStart="16dip"
-        android:paddingEnd="16dip"
-        android:paddingTop="16dip">
+        android:paddingStart="@dimen/alert_dialog_padding_material"
+        android:paddingEnd="@dimen/alert_dialog_padding_material"
+        android:paddingTop="@dimen/alert_dialog_padding_material">
         <ImageView android:id="@+id/left_icon"
             android:layout_width="32dip"
             android:layout_height="32dip"
             android:scaleType="fitCenter"
             android:layout_marginEnd="8dip" />
-        <TextView android:id="@android:id/title"
-            style="?android:attr/windowTitleStyle"
+        <TextView android:id="@id/title"
+            style="?attr/windowTitleStyle"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_weight="0" />
@@ -52,8 +52,8 @@
         android:layout_width="match_parent" android:layout_height="wrap_content"
         android:layout_weight="1"
         android:orientation="vertical"
-        android:foreground="?android:attr/windowContentOverlay">
-        <FrameLayout android:id="@android:id/content"
+        android:foreground="?attr/windowContentOverlay">
+        <FrameLayout android:id="@id/content"
             android:layout_width="match_parent"
             android:layout_height="match_parent" />
     </FrameLayout>
diff --git a/core/res/res/layout/dialog_title_material.xml b/core/res/res/layout/dialog_title_material.xml
index 918c8f1..fcf6164 100644
--- a/core/res/res/layout/dialog_title_material.xml
+++ b/core/res/res/layout/dialog_title_material.xml
@@ -29,15 +29,15 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:textAlignment="viewStart"
-        android:paddingStart="16dip"
-        android:paddingEnd="16dip"
-        android:paddingTop="16dip" />
+        android:paddingStart="@dimen/alert_dialog_padding_material"
+        android:paddingEnd="@dimen/alert_dialog_padding_material"
+        android:paddingTop="@dimen/alert_dialog_padding_top_material" />
     <FrameLayout
         android:layout_width="match_parent" android:layout_height="wrap_content"
         android:layout_weight="1"
         android:orientation="vertical"
-        android:foreground="?android:attr/windowContentOverlay">
-        <FrameLayout android:id="@android:id/content"
+        android:foreground="?attr/windowContentOverlay">
+        <FrameLayout android:id="@id/content"
             android:layout_width="match_parent"
             android:layout_height="match_parent" />
     </FrameLayout>
diff --git a/core/res/res/layout/notification_template_part_line2.xml b/core/res/res/layout/notification_template_part_line2.xml
index 7e99c5e..aeef3ab 100644
--- a/core/res/res/layout/notification_template_part_line2.xml
+++ b/core/res/res/layout/notification_template_part_line2.xml
@@ -45,13 +45,13 @@
             android:visibility="gone"
             />
     </LinearLayout>
-    <ProgressBar
+    <ViewStub
         android:id="@android:id/progress"
+        android:layout="@layout/notification_template_progressbar"
         android:layout_width="match_parent"
         android:layout_height="15dp"
         android:layout_marginEnd="8dp"
         android:visibility="gone"
         android:layout_weight="0"
-        style="@style/Widget.Material.Light.ProgressBar.Horizontal"
         />
 </merge>
diff --git a/core/res/res/layout/notification_template_progressbar.xml b/core/res/res/layout/notification_template_progressbar.xml
new file mode 100644
index 0000000..61480b8
--- /dev/null
+++ b/core/res/res/layout/notification_template_progressbar.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/progress"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    style="@style/Widget.Material.Light.ProgressBar.Horizontal"
+    />
diff --git a/core/res/res/layout/progress_dialog_material.xml b/core/res/res/layout/progress_dialog_material.xml
index 84d06b5..54af106 100644
--- a/core/res/res/layout/progress_dialog_material.xml
+++ b/core/res/res/layout/progress_dialog_material.xml
@@ -19,21 +19,27 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content">
 
-    <LinearLayout android:id="@+id/body"
+    <LinearLayout
+        android:id="@+id/body"
         android:orientation="horizontal"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:baselineAligned="false"
-        android:padding="16dip">
+        android:paddingStart="@dimen/alert_dialog_padding_material"
+        android:paddingTop="@dimen/alert_dialog_padding_top_material"
+        android:paddingEnd="@dimen/alert_dialog_padding_material"
+        android:paddingBottom="@dimen/alert_dialog_padding_top_material">
 
-        <ProgressBar android:id="@android:id/progress"
+        <ProgressBar
+            android:id="@id/progress"
             style="?android:attr/progressBarStyle"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:max="10000"
-            android:layout_marginEnd="16dip" />
+            android:layout_marginEnd="@dimen/alert_dialog_padding_material" />
 
-        <TextView android:id="@+id/message"
+        <TextView
+            android:id="@+id/message"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="center_vertical" />
diff --git a/core/res/res/values-mcc302-mnc220/config.xml b/core/res/res/values-mcc302-mnc220/config.xml
index 5259152..06b6efe 100644
--- a/core/res/res/values-mcc302-mnc220/config.xml
+++ b/core/res/res/values-mcc302-mnc220/config.xml
@@ -25,4 +25,6 @@
         <item>302720</item>
         <item>302780</item>
     </string-array>
+
+    <integer name="config_mobile_mtu">1410</integer>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc004/config.xml b/core/res/res/values-mcc310-mnc004/config.xml
index 2778b6e..423e250 100644
--- a/core/res/res/values-mcc310-mnc004/config.xml
+++ b/core/res/res/values-mcc310-mnc004/config.xml
@@ -34,11 +34,4 @@
     </string-array>
 
     <bool name="config_auto_attach_data_on_creation">false</bool>
-
-    <!-- Values for GPS configuration (Verizon) -->
-    <string-array translatable="false" name="config_gpsParameters">
-        <item>CAPABILITIES=0x31</item>
-        <item>LPP_PROFILE=3</item>
-        <item>GPS_LOCK=3</item>
-    </string-array>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc120/config.xml b/core/res/res/values-mcc310-mnc120/config.xml
index 3b95db5..62001d9 100644
--- a/core/res/res/values-mcc310-mnc120/config.xml
+++ b/core/res/res/values-mcc310-mnc120/config.xml
@@ -25,10 +25,4 @@
     -->
     <integer name="config_mobile_mtu">1422</integer>
 
-    <!-- Values for GPS configuration (Sprint) -->
-    <string-array translatable="false" name="config_gpsParameters">
-        <item>CAPABILITIES=0x31</item>
-        <item>GPS_LOCK=3</item>
-        <item>LPP_PROFILE=2</item>
-    </string-array>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc150/config.xml b/core/res/res/values-mcc310-mnc150/config.xml
index 00d2db8..f1936f4 100644
--- a/core/res/res/values-mcc310-mnc150/config.xml
+++ b/core/res/res/values-mcc310-mnc150/config.xml
@@ -33,10 +33,4 @@
         <item>315</item>
         <item>316</item>
     </string-array>
-    <!-- Values for GPS configuration (AT&T) -->
-    <string-array translatable="false" name="config_gpsParameters">
-        <item>CAPABILITIES=0x33</item>
-        <item>LPP_PROFILE=3</item>
-        <item>GPS_LOCK=1</item>
-    </string-array>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc260/config.xml b/core/res/res/values-mcc310-mnc260/config.xml
index f8fff3b..28cd695 100644
--- a/core/res/res/values-mcc310-mnc260/config.xml
+++ b/core/res/res/values-mcc310-mnc260/config.xml
@@ -29,11 +29,4 @@
          carrier provisioning. If false: hard disabled. If true: then depends on carrier
          provisioning, availability etc -->
     <bool name="config_carrier_volte_vt_available">true</bool>
-
-    <!-- Values for GPS configuration (T-Mobile) -->
-    <string-array translatable="false" name="config_gpsParameters">
-        <item>CAPABILITEIS=0x33</item>
-        <item>GPS_LOCK=1</item>
-        <item>LPP_PROFILE=2</item>
-    </string-array>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410/config.xml b/core/res/res/values-mcc310-mnc410/config.xml
index edf6d9f..b863aae 100644
--- a/core/res/res/values-mcc310-mnc410/config.xml
+++ b/core/res/res/values-mcc310-mnc410/config.xml
@@ -40,12 +40,6 @@
         <item>315</item>
         <item>316</item>
     </string-array>
-    <!-- Values for GPS configuration (AT&T) -->
-    <string-array translatable="false" name="config_gpsParameters">
-        <item>CAPABILITIES=0x33</item>
-        <item>GPS_LOCK=1</item>
-        <item>LPP_PROFILE=3</item>
-    </string-array>
     <!-- Do not translate. Defines the slots is Two Digit Number for dialing normally not USSD -->
     <string-array name="config_twoDigitNumberPattern">
         <item>"0"</item>
diff --git a/core/res/res/values-mcc311-mnc190/config.xml b/core/res/res/values-mcc311-mnc190/config.xml
index b4e436d..a6c4d1b 100644
--- a/core/res/res/values-mcc311-mnc190/config.xml
+++ b/core/res/res/values-mcc311-mnc190/config.xml
@@ -37,11 +37,4 @@
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
     <string translatable="false" name="config_tether_apndata">Tether,broadband.cellular1.net,,,,,,,,,311,190,,DUN</string>
 
-    <!-- Values for GPS configuration (Sprint) -->
-    <string-array translatable="false" name="config_gpsParameters">
-        <item>CAPABILITIES=0x31</item>
-        <item>GPS_LOCK=3</item>
-        <item>LPP_PROFILE=2</item>
-    </string-array>
-
 </resources>
diff --git a/core/res/res/values-mcc311-mnc480/config.xml b/core/res/res/values-mcc311-mnc480/config.xml
index 57ecd31..cf19235 100644
--- a/core/res/res/values-mcc311-mnc480/config.xml
+++ b/core/res/res/values-mcc311-mnc480/config.xml
@@ -44,11 +44,4 @@
     <bool name="config_carrier_volte_vt_available">false</bool>
 
     <bool name="config_auto_attach_data_on_creation">false</bool>
-
-    <!-- Values for GPS configuration (Verizon) -->
-    <string-array translatable="false" name="config_gpsParameters">
-        <item>CAPABILITIES=0x31</item>
-        <item>GPS_LOCK=3</item>
-        <item>LPP_PROFILE=3</item>
-    </string-array>
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index cf4064f..a00ed5d 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4483,12 +4483,12 @@
         <!-- The row boundary delimiting the top of the group of cells
         occupied by this view. -->
         <attr name="layout_row" format="integer" />
-        <!-- The row span: the difference between the bottom and top
+        <!-- The row span: the difference between the top and bottom
         boundaries delimiting the group of cells occupied by this view.
         The default is one.
         See {@link android.widget.GridLayout.Spec}. -->
         <attr name="layout_rowSpan" format="integer" min="1" />
-        <!-- The relative proportion of horizontal space that should be allocated to this view
+        <!-- The relative proportion of vertical space that should be allocated to this view
         during excess space distribution. -->
         <attr name="layout_rowWeight" format="float" />
         <!-- The column boundary delimiting the left of the group of cells
@@ -4499,7 +4499,7 @@
         The default is one.
         See {@link android.widget.GridLayout.Spec}. -->
         <attr name="layout_columnSpan" format="integer" min="1" />
-        <!-- The relative proportion of vertical space that should be allocated to this view
+        <!-- The relative proportion of horizontal space that should be allocated to this view
         during excess space distribution. -->
         <attr name="layout_columnWeight" format="float" />
         <!-- Gravity specifies how a component should be placed in its group of cells.
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index f3b3077..b36387f 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -351,6 +351,9 @@
          point on the move. A value of 0 means no periodic scans will be used in the framework. -->
     <integer translatable="false" name="config_wifi_framework_scan_interval">300000</integer>
 
+    <!-- Integer indicating associated scan interval in milliseconds -->
+    <integer translatable="false" name="config_wifi_framework_associated_scan_interval">10000</integer>
+
     <!-- Wifi driver stop delay, in milliseconds.
          Default value is 2 minutes. -->
     <integer translatable="false" name="config_wifi_driver_stop_delay">120000</integer>
@@ -1611,6 +1614,10 @@
     <!-- default window ShowCircularMask property -->
     <bool name="config_windowShowCircularMask">false</bool>
 
+    <!-- default value for whether circular emulators (ro.emulator.circular)
+         should show a display overlay on the screen -->
+    <bool name="config_windowEnableCircularEmulatorDisplayOverlay">false</bool>
+
     <!-- Defines the default set of global actions. Actions may still be disabled or hidden based
          on the current state of the device.
          Each item must be one of the following strings:
@@ -1715,16 +1722,22 @@
     <string-array translatable="false" name="config_gpsParameters">
         <item>SUPL_HOST=supl.google.com</item>
         <item>SUPL_PORT=7275</item>
-        <item>XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra2.bin</item>
-        <item>XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra2.bin</item>
-        <item>XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra2.bin</item>
         <item>NTP_SERVER=north-america.pool.ntp.org</item>
         <item>SUPL_VER=0x20000</item>
-        <item>CAPABILITIES=0x33</item>
-        <item>LPP_PROFILE=0</item>
-        <item>NMEA_PROVIDER=0</item>
-        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
-        <item>ERR_ESTIMATE=0</item>
-        <item>INTERMEDIATE_POS=0</item>
     </string-array>
+
+    <!-- If there is no preload VM number in the sim card, carriers such as
+         Verizon require to load a default vm number from the configurantion.
+         Define config_default_vm_number for this purpose. And there are two
+         optional formats for this configuration as below:
+         (1)<item>voicemail number</item>
+         (2)<item>voicemail number;gid</item>
+         The logic to pick up the correct voicemail number:
+         (1) If the config_default_vm_number array has no gid special item, the last one will be
+         picked
+         (2) If the config_default_vm_number array has gid special item and  it matches the current
+         sim's gid, it will be picked.
+         (3) If the config_default_vm_number array has gid special item but it doesn't match the
+         current sim's gid, the last one without gid will be picked -->
+    <string-array translatable="false" name="config_default_vm_number" />
 </resources>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index 5f7f0ed..275a5ec 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -77,5 +77,6 @@
     <!-- Default rounded corner for controls -->
     <dimen name="control_corner_material">2dp</dimen>
 
-    <dimen name="alert_dialog_padding_material">18dp</dimen>
+    <dimen name="alert_dialog_padding_material">24dp</dimen>
+    <dimen name="alert_dialog_padding_top_material">18dp</dimen>
 </resources>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index a7335af..26c7d10 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -474,6 +474,13 @@
         <item name="stateListAnimator">@anim/disabled_anim_material</item>
     </style>
 
+    <!-- Alert dialog button bar button -->
+    <style name="Widget.Material.Button.ButtonBar.AlertDialog" parent="Widget.Material.Button.Borderless.Colored">
+        <item name="minWidth">64dp</item>
+        <item name="maxLines">2</item>
+        <item name="minHeight">@dimen/alert_dialog_button_bar_height</item>
+    </style>
+
     <!-- Small borderless ink button -->
     <style name="Widget.Material.Button.Borderless.Small">
         <item name="minHeight">48dip</item>
@@ -496,7 +503,6 @@
 
     <style name="Widget.Material.ButtonBar.AlertDialog">
         <item name="background">@null</item>
-        <item name="minHeight">@dimen/alert_dialog_button_bar_height</item>
     </style>
 
     <style name="Widget.Material.SearchView">
@@ -936,6 +942,7 @@
     <style name="Widget.Material.Light.Button.Small" parent="Widget.Material.Button.Small"/>
     <style name="Widget.Material.Light.Button.Borderless" parent="Widget.Material.Button.Borderless"/>
     <style name="Widget.Material.Light.Button.Borderless.Colored" parent="Widget.Material.Button.Borderless.Colored"/>
+    <style name="Widget.Material.Light.Button.ButtonBar.AlertDialog" parent="Widget.Material.Button.ButtonBar.AlertDialog" />
     <style name="Widget.Material.Light.Button.Borderless.Small" parent="Widget.Material.Button.Borderless.Small"/>
     <style name="Widget.Material.Light.Button.Inset" parent="Widget.Material.Button.Inset"/>
     <style name="Widget.Material.Light.Button.Toggle" parent="Widget.Material.Button.Toggle" />
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ecfbefe..c28f3a6 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -293,6 +293,7 @@
   <java-symbol type="bool" name="config_windowIsRound" />
   <java-symbol type="bool" name="config_hasRecents" />
   <java-symbol type="bool" name="config_windowShowCircularMask" />
+  <java-symbol type="bool" name="config_windowEnableCircularEmulatorDisplayOverlay" />
 
   <java-symbol type="integer" name="config_bluetooth_max_advertisers" />
   <java-symbol type="integer" name="config_bluetooth_max_scan_filters" />
@@ -312,6 +313,7 @@
   <java-symbol type="integer" name="config_shortPressOnPowerBehavior" />
   <java-symbol type="integer" name="config_toastDefaultGravity" />
   <java-symbol type="integer" name="config_wifi_framework_scan_interval" />
+  <java-symbol type="integer" name="config_wifi_framework_associated_scan_interval" />
   <java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
   <java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" />
   <java-symbol type="integer" name="db_connection_pool_size" />
@@ -1155,6 +1157,7 @@
   <java-symbol type="drawable" name="ic_corp_badge" />
   <java-symbol type="drawable" name="ic_corp_icon_badge" />
   <java-symbol type="drawable" name="ic_corp_icon" />
+  <java-symbol type="drawable" name="emulator_circular_window_overlay" />
 
   <java-symbol type="drawable" name="sim_light_blue" />
   <java-symbol type="drawable" name="sim_light_green" />
@@ -2005,4 +2008,5 @@
   <java-symbol type="id" name="date_picker_month_day_year_layout" />
   <java-symbol type="attr" name="closeItemLayout" />
   <java-symbol type="layout" name="resolver_different_item_header" />
+  <java-symbol type="array" name="config_default_vm_number" />
 </resources>
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index ab5cd5a..4aca02e 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -333,7 +333,7 @@
         <item name="dividerVertical">?attr/listDivider</item>
         <item name="dividerHorizontal">?attr/listDivider</item>
         <item name="buttonBarStyle">@style/Widget.Material.ButtonBar</item>
-        <item name="buttonBarButtonStyle">@style/Widget.Material.Button.Borderless.Colored</item>
+        <item name="buttonBarButtonStyle">@style/Widget.Material.Button.ButtonBar.AlertDialog</item>
         <item name="segmentedButtonStyle">@style/Widget.Material.SegmentedButton</item>
 
         <!-- SearchView attributes -->
@@ -679,7 +679,7 @@
         <item name="dividerVertical">?attr/listDivider</item>
         <item name="dividerHorizontal">?attr/listDivider</item>
         <item name="buttonBarStyle">@style/Widget.Material.Light.ButtonBar</item>
-        <item name="buttonBarButtonStyle">@style/Widget.Material.Light.Button.Borderless.Colored</item>
+        <item name="buttonBarButtonStyle">@style/Widget.Material.Light.Button.ButtonBar.AlertDialog</item>
         <item name="segmentedButtonStyle">@style/Widget.Material.Light.SegmentedButton</item>
 
         <!-- SearchView attributes -->
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java
index 77e1c530..80d5668 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java
@@ -322,8 +322,13 @@
      * If the device is already associated with a WiFi, disconnect and forget it,
      * We don't verify whether the connection is successful or not, leave this to the test
      */
-    protected boolean connectToWifi(String knownSSID) {
-        WifiConfiguration config = WifiConfigurationHelper.createOpenConfig(knownSSID);
+    protected boolean connectToWifi(String ssid, String password) {
+        WifiConfiguration config;
+        if (password == null) {
+            config = WifiConfigurationHelper.createOpenConfig(ssid);
+        } else {
+            config = WifiConfigurationHelper.createPskConfig(ssid, password);
+        }
         return connectToWifiWithConfiguration(config);
     }
 
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
index b94306a..b6eb674 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
@@ -35,8 +35,9 @@
  */
 
 public class ConnectivityManagerTestRunner extends InstrumentationTestRunner {
-    public boolean mWifiOnlyFlag = false;
-    public String mTestSsid = null;
+    public boolean mWifiOnly = false;
+    public String mSsid = null;
+    public String mPassword = null;
 
     @Override
     public TestSuite getAllTests() {
@@ -54,13 +55,29 @@
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
-        String testSSID = (String) icicle.get("ssid");
-        if (testSSID != null) {
-            mTestSsid = testSSID;
+        String ssid = icicle.getString("ssid");
+        if (ssid != null) {
+            mSsid = ssid;
+        }
+        String password = (String) icicle.get("password");
+        if (password != null) {
+            mPassword = password;
         }
         String wifiOnlyFlag = (String) icicle.get("wifi-only");
         if (wifiOnlyFlag != null) {
-            mWifiOnlyFlag = true;
+            mWifiOnly = true;
         }
     }
+
+    public String getWifiSsid() {
+        return mSsid;
+    }
+
+    public String getWifiPassword() {
+        return mPassword;
+    }
+
+    public boolean isWifiOnly() {
+        return mWifiOnly;
+    }
 }
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index b280106..d5051df 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -33,7 +33,8 @@
         super(ConnectivityManagerMobileTest.class.getSimpleName());
     }
 
-    private String mTestAccessPoint;
+    private String mSsid;
+    private String mPassword;
     private boolean mWifiOnlyFlag;
 
     @Override
@@ -41,8 +42,9 @@
         super.setUp();
         ConnectivityManagerTestRunner mRunner =
                 (ConnectivityManagerTestRunner)getInstrumentation();
-        mTestAccessPoint = mRunner.mTestSsid;
-        mWifiOnlyFlag = mRunner.mWifiOnlyFlag;
+        mSsid = mRunner.getWifiSsid();
+        mPassword = mRunner.getWifiPassword();
+        mWifiOnlyFlag = mRunner.isWifiOnly();
 
         // Each test case will start with cellular connection
         if (Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
@@ -120,11 +122,10 @@
     // Test case 2: test connection to a given AP
     @LargeTest
     public void testConnectToWifi() {
-        assertNotNull("SSID is null", mTestAccessPoint);
+        assertNotNull("SSID is null", mSsid);
 
         // assert that we are able to connect to the ap
-        assertTrue("failed to connect to " + mTestAccessPoint,
-                connectToWifi(mTestAccessPoint));
+        assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
         // assert that WifiManager reports correct state
         assertTrue("wifi not enabled", waitForWifiState(
                 WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
@@ -144,14 +145,14 @@
     // Test case 3: connect & reconnect to Wifi with known AP
     @LargeTest
     public void testConnectToWifWithKnownAP() {
-        assertNotNull("SSID is null", mTestAccessPoint);
+        assertNotNull("SSID is null", mSsid);
         // enable WiFi
         assertTrue("failed to enable wifi", enableWifi());
         // wait for wifi enable
         assertTrue("wifi not enabled", waitForWifiState(
                 WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
         // Connect to AP
-        assertTrue("failed to connect to " + mTestAccessPoint, connectToWifi(mTestAccessPoint));
+        assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
         // verify wifi connected as reported by ConnectivityManager
         assertTrue("wifi not connected", waitForNetworkState(
                 ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
@@ -191,7 +192,7 @@
     // Test case 4:  test disconnect and clear wifi settings
     @LargeTest
     public void testDisconnectWifi() {
-        assertNotNull("SSID is null", mTestAccessPoint);
+        assertNotNull("SSID is null", mSsid);
 
         // enable WiFi
         assertTrue("failed to enable wifi", enableWifi());
@@ -199,8 +200,7 @@
         assertTrue("wifi not enabled", waitForWifiState(
                 WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
         // connect to Wifi
-        assertTrue("failed to connect to " + mTestAccessPoint,
-                connectToWifi(mTestAccessPoint));
+        assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
 
         assertTrue("wifi not connected", waitForNetworkState(
                 ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
@@ -257,7 +257,7 @@
     // Test case 6: test connectivity with airplane mode on but wifi enabled
     @LargeTest
     public void testDataConnectionOverAMWithWifi() {
-        assertNotNull("SSID is null", mTestAccessPoint);
+        assertNotNull("SSID is null", mSsid);
         // enable airplane mode
         mCm.setAirplaneMode(true);
         // assert there is active network connection after airplane mode disabled
@@ -265,8 +265,7 @@
                 waitUntilNoActiveNetworkConnection(LONG_TIMEOUT));
 
         // connect to Wifi
-        assertTrue("failed to connect to " + mTestAccessPoint,
-                connectToWifi(mTestAccessPoint));
+        assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
         assertTrue("wifi not connected", waitForNetworkState(
                 ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
         // verify that connection actually works
@@ -280,15 +279,14 @@
     @LargeTest
     public void testDataConnectionWithWifiToAMToWifi () {
         // connect to mTestAccessPoint
-        assertNotNull("SSID is null", mTestAccessPoint);
+        assertNotNull("SSID is null", mSsid);
         // enable WiFi
         assertTrue("failed to enable wifi", enableWifi());
         // wait for wifi enable
         assertTrue("wifi not enabled", waitForWifiState(
                 WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
         // connect to Wifi
-        assertTrue("failed to connect to " + mTestAccessPoint,
-                connectToWifi(mTestAccessPoint));
+        assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
         assertTrue("wifi not connected", waitForNetworkState(
                 ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
 
@@ -313,15 +311,14 @@
     // Test case 8: test wifi state change while connecting/disconnecting to/from an AP
     @LargeTest
     public void testWifiStateChange () {
-        assertNotNull("SSID is null", mTestAccessPoint);
+        assertNotNull("SSID is null", mSsid);
         // enable WiFi
         assertTrue("failed to enable wifi", enableWifi());
         // wait for wifi enable
         assertTrue("wifi not enabled", waitForWifiState(
                 WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
         // connect to Wifi
-        assertTrue("failed to connect to " + mTestAccessPoint,
-                connectToWifi(mTestAccessPoint));
+        assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
         assertTrue("wifi not connected", waitForNetworkState(
                 ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
         assertNotNull("not associated with any AP", mWifiManager.getConnectionInfo().getBSSID());
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
index bcf2e45..db547e2 100644
--- a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
@@ -60,10 +60,10 @@
         super.setUp();
         DownloadManagerTestRunner mRunner = (DownloadManagerTestRunner)getInstrumentation();
         externalDownloadUriValue = normalizeUri(mRunner.externalDownloadUriValue);
-        assertNotNull(externalDownloadUriValue);
+        assertNotNull("download url is null", externalDownloadUriValue);
 
         externalLargeDownloadUriValue = normalizeUri(mRunner.externalDownloadUriValue);
-        assertNotNull(externalLargeDownloadUriValue);
+        assertNotNull("large download url is null", externalLargeDownloadUriValue);
     }
 
     /**
@@ -140,7 +140,7 @@
 
             dlRequest = mDownloadManager.enqueue(request);
             waitForDownloadToStart(dlRequest);
-            assertTrue(dlRequest != -1);
+            assertTrue("request id is -1 from download manager", dlRequest != -1);
 
             // Store ID of download for later retrieval
             outputFile = new DataOutputStream(fileOutput);
@@ -183,7 +183,7 @@
             mContext.deleteFile(DOWNLOAD_STARTED_FLAG);
         }
 
-        assertTrue(dlRequest != -1);
+        assertTrue("request id is -1 from download manager", dlRequest != -1);
         Cursor cursor = getCursor(dlRequest);
         ParcelFileDescriptor pfd = null;
         try {
@@ -193,7 +193,7 @@
             int status = cursor.getInt(columnIndex);
             int currentWaitTime = 0;
 
-            assertTrue(waitForDownload(dlRequest, 15 * 60 * 1000));
+            assertTrue("download not finished", waitForDownload(dlRequest, 15 * 60 * 1000));
 
             Log.i(LOG_TAG, "Verifying download information...");
             // Verify specific info about the file (size, name, etc)...
@@ -233,7 +233,7 @@
         dlRequest = mDownloadManager.enqueue(request);
 
         // Rather large file, so wait up to 15 mins...
-        assertTrue(waitForDownload(dlRequest, 15 * 60 * 1000));
+        assertTrue("download not finished", waitForDownload(dlRequest, 15 * 60 * 1000));
 
         Cursor cursor = getCursor(dlRequest);
         ParcelFileDescriptor pfd = null;
@@ -317,7 +317,7 @@
             Log.i(LOG_TAG, "Turning on WiFi...");
             setWiFiStateOn(true);
             Log.i(LOG_TAG, "Waiting up to 10 minutes for download to complete...");
-            assertTrue(waitForDownload(dlRequest, 10 * 60 * 1000));
+            assertTrue("download not finished", waitForDownload(dlRequest, 10 * 60 * 1000));
             ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
             verifyFileSize(pfd, filesize);
         } finally {
@@ -385,7 +385,7 @@
             setWiFiStateOn(true);
 
             Log.i(LOG_TAG, "Waiting up to 10 minutes for download to complete...");
-            assertTrue(waitForDownload(dlRequest, 10 * 60 * 1000));
+            assertTrue("download not finished", waitForDownload(dlRequest, 10 * 60 * 1000));
             ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
             verifyFileSize(pfd, filesize);
         } finally {
@@ -456,7 +456,7 @@
             setAirplaneModeOn(false);
 
             Log.i(LOG_TAG, "Waiting up to 10 minutes for donwload to complete...");
-            assertTrue(waitForDownload(dlRequest, 10 * 60 * 1000)); // wait up to 10 mins
+            assertTrue("download not finished", waitForDownload(dlRequest, 10 * 60 * 1000)); // wait up to 10 mins
             ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
             verifyFileSize(pfd, filesize);
         } finally {
@@ -489,11 +489,11 @@
                 Request request = new Request(remoteUri);
                 request.setTitle(filename);
                 dlRequest = mDownloadManager.enqueue(request);
-                assertTrue(dlRequest != -1);
+                assertTrue("request id is -1 from download manager", dlRequest != -1);
                 downloadIds.add(dlRequest);
             }
 
-            assertTrue(waitForMultipleDownloads(downloadIds, 15 * 60 * 2000));  // wait 15 mins max
+            assertTrue("download not finished", waitForMultipleDownloads(downloadIds, 15 * 60 * 2000));  // wait 15 mins max
         } finally {
             removeAllCurrentDownloads();
         }
diff --git a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
index fa1bd8f..5958c3a 100644
--- a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
+++ b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
@@ -26,6 +26,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodSubtype;
+import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -159,8 +160,15 @@
 
     private static InputMethodSubtype createDummyInputMethodSubtype(String locale, String mode,
             boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype) {
-        return new InputMethodSubtype(0, 0, locale, mode, "", isAuxiliary,
-                overridesImplicitlyEnabledSubtype);
+        return new InputMethodSubtypeBuilder()
+                .setSubtypeNameResId(0)
+                .setSubtypeIconResId(0)
+                .setSubtypeLocale(locale)
+                .setSubtypeMode(mode)
+                .setSubtypeExtraValue("")
+                .setIsAuxiliary(isAuxiliary)
+                .setOverridesImplicitlyEnabledSubtype(overridesImplicitlyEnabledSubtype)
+                .build();
     }
 
     private static InputMethodInfo createDefaultAutoDummyVoiceIme() {
diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd
index 1e5fc4d..808f04a 100644
--- a/docs/html/about/dashboards/index.jd
+++ b/docs/html/about/dashboards/index.jd
@@ -64,7 +64,7 @@
 </div>
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on August 12, 2014.
+<p style="clear:both"><em>Data collected during a 7-day period ending on September 9, 2014.
 <br/>Any versions with less than 0.1% distribution are not shown.</em>
 </p>
 
@@ -95,7 +95,8 @@
 </div>
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on August 12, 2014.
+<p style="clear:both"><em>Data collected during a 7-day period ending on September 9, 2014.
+
 <br/>Any screen configurations with less than 0.1% distribution are not shown.</em></p>
 
 
@@ -114,7 +115,7 @@
 
 
 <img alt="" style="float:right"
-src="//chart.googleapis.com/chart?chs=400x250&cht=p&chd=t%3A0.1%2C80.2%2C19.7&chf=bg%2Cs%2C00000000&chl=GL%201.1%20only%7CGL%202.0%7CGL%203.0&chco=c4df9b%2C6fad0c" />
+src="//chart.googleapis.com/chart?chs=400x250&cht=p&chd=t%3A77.5%2C22.5&chf=bg%2Cs%2C00000000&chl=GL%202.0%7CGL%203.0&chco=c4df9b%2C6fad0c" />
 
 <p>To declare which version of OpenGL ES your application requires, you should use the {@code
 android:glEsVersion} attribute of the <a
@@ -131,22 +132,18 @@
 <th scope="col">Distribution</th>
 </tr>
 <tr>
-<td>1.1 only</th>
-<td>0.1%</td>
+<td>2.0</td>
+<td>77.5%</td>
 </tr>
 <tr>
-<td>2.0</th>
-<td>80.2%</td>
-</tr>
-<tr>
-<td>3.0</th>
-<td>19.7%</td>
+<td>3.0</td>
+<td>22.5%</td>
 </tr>
 </table>
 
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on August 12, 2014</em></p>
+<p style="clear:both"><em>Data collected during a 7-day period ending on September 9, 2014</em></p>
 
 
 
@@ -164,7 +161,7 @@
 var VERSION_DATA =
 [
   {
-    "chart": "//chart.googleapis.com/chart?cht=p&chs=500x250&chl=Froyo%7CGingerbread%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat&chd=t%3A0.7%2C13.6%2C10.6%2C54.2%2C20.9&chf=bg%2Cs%2C00000000&chco=c4df9b%2C6fad0c",
+    "chart": "//chart.googleapis.com/chart?chco=c4df9b%2C6fad0c&cht=p&chs=500x250&chl=Froyo%7CGingerbread%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat&chd=t%3A0.7%2C11.4%2C9.6%2C53.8%2C24.5&chf=bg%2Cs%2C00000000",
     "data": [
       {
         "api": 8,
@@ -174,41 +171,38 @@
       {
         "api": 10,
         "name": "Gingerbread",
-        "perc": "13.6"
+        "perc": "11.4"
       },
       {
         "api": 15,
         "name": "Ice Cream Sandwich",
-        "perc": "10.6"
+        "perc": "9.6"
       },
       {
         "api": 16,
         "name": "Jelly Bean",
-        "perc": "26.5"
+        "perc": "25.1"
       },
       {
         "api": 17,
         "name": "Jelly Bean",
-        "perc": "19.8"
+        "perc": "20.7"
       },
       {
         "api": 18,
         "name": "Jelly Bean",
-        "perc": "7.9"
+        "perc": "8.0"
       },
       {
         "api": 19,
         "name": "KitKat",
-        "perc": "20.9"
+        "perc": "24.5"
       }
     ]
   }
 ];
 
 
-
-
-
 var SCREEN_DATA =
 [
   {
@@ -216,27 +210,27 @@
       "Large": {
         "hdpi": "0.6",
         "ldpi": "0.5",
-        "mdpi": "4.2",
-        "tvdpi": "1.6",
-        "xhdpi": "0.5"
+        "mdpi": "4.3",
+        "tvdpi": "1.7",
+        "xhdpi": "0.6"
       },
       "Normal": {
-        "hdpi": "35.5",
-        "mdpi": "11.8",
-        "xhdpi": "18.4",
-        "xxhdpi": "15.2"
+        "hdpi": "35.7",
+        "mdpi": "10.6",
+        "xhdpi": "19.2",
+        "xxhdpi": "16.2"
       },
       "Small": {
-        "ldpi": "7.4"
+        "ldpi": "6.2"
       },
       "Xlarge": {
         "hdpi": "0.3",
-        "mdpi": "3.6",
+        "mdpi": "3.7",
         "xhdpi": "0.4"
       }
     },
-    "densitychart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chd=t%3A7.9%2C19.6%2C1.6%2C36.4%2C19.3%2C15.2&chf=bg%2Cs%2C00000000&chco=c4df9b%2C6fad0c",
-    "layoutchart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chl=Xlarge%7CLarge%7CNormal%7CSmall&chd=t%3A4.3%2C7.4%2C80.9%2C7.4&chf=bg%2Cs%2C00000000&chco=c4df9b%2C6fad0c"
+    "densitychart": "//chart.googleapis.com/chart?chco=c4df9b%2C6fad0c&cht=p&chs=400x250&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chd=t%3A6.7%2C18.6%2C1.7%2C36.6%2C20.2%2C16.2&chf=bg%2Cs%2C00000000",
+    "layoutchart": "//chart.googleapis.com/chart?chco=c4df9b%2C6fad0c&cht=p&chs=400x250&chl=Xlarge%7CLarge%7CNormal%7CSmall&chd=t%3A4.4%2C7.7%2C81.7%2C6.2&chf=bg%2Cs%2C00000000"
   }
 ];
 
diff --git a/graphics/java/android/graphics/pdf/PdfEditor.java b/graphics/java/android/graphics/pdf/PdfEditor.java
new file mode 100644
index 0000000..9837139
--- /dev/null
+++ b/graphics/java/android/graphics/pdf/PdfEditor.java
@@ -0,0 +1,162 @@
+/*
+ * 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.graphics.pdf;
+
+import android.annotation.NonNull;
+import android.os.ParcelFileDescriptor;
+import android.system.ErrnoException;
+import android.system.OsConstants;
+import dalvik.system.CloseGuard;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
+
+import java.io.IOException;
+
+/**
+ * Class for editing PDF files.
+ *
+ * @hide
+ */
+public final class PdfEditor {
+
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
+    private final long mNativeDocument;
+
+    private int mPageCount;
+
+    private ParcelFileDescriptor mInput;
+
+    /**
+     * Creates a new instance.
+     * <p>
+     * <strong>Note:</strong> The provided file descriptor must be <strong>seekable</strong>,
+     * i.e. its data being randomly accessed, e.g. pointing to a file. After finishing
+     * with this class you must call {@link #close()}.
+     * </p>
+     * <p>
+     * <strong>Note:</strong> This class takes ownership of the passed in file descriptor
+     * and is responsible for closing it when the editor is closed.
+     * </p>
+     *
+     * @param input Seekable file descriptor to read from.
+     *
+     * @see #close()
+     */
+    public PdfEditor(@NonNull ParcelFileDescriptor input) throws IOException {
+        if (input == null) {
+            throw new NullPointerException("input cannot be null");
+        }
+
+        final long size;
+        try {
+            Libcore.os.lseek(input.getFileDescriptor(), 0, OsConstants.SEEK_SET);
+            size = Libcore.os.fstat(input.getFileDescriptor()).st_size;
+        } catch (ErrnoException ee) {
+            throw new IllegalArgumentException("file descriptor not seekable");
+        }
+
+        mInput = input;
+        mNativeDocument = nativeOpen(mInput.getFd(), size);
+        mPageCount = nativeGetPageCount(mNativeDocument);
+        mCloseGuard.open("close");
+    }
+
+    /**
+     * Gets the number of pages in the document.
+     *
+     * @return The page count.
+     */
+    public int getPageCount() {
+        throwIfClosed();
+        return mPageCount;
+    }
+
+    /**
+     * Removes the page with a given index.
+     *
+     * @param pageIndex The page to remove.
+     */
+    public void removePage(int pageIndex) {
+        throwIfClosed();
+        throwIfPageNotInDocument(pageIndex);
+        mPageCount = nativeRemovePage(mNativeDocument, pageIndex);
+    }
+
+    /**
+     * Writes the PDF file to the provided destination.
+     * <p>
+     * <strong>Note:</strong> This method takes ownership of the passed in file
+     * descriptor and is responsible for closing it when writing completes.
+     * </p>
+     * @param output The destination.
+     */
+    public void write(ParcelFileDescriptor output) throws IOException {
+        try {
+            throwIfClosed();
+            nativeWrite(mNativeDocument, output.getFd());
+        } finally {
+            IoUtils.closeQuietly(output);
+        }
+    }
+
+    /**
+     * Closes this editor. You should not use this instance
+     * after this method is called.
+     */
+    public void close() {
+        throwIfClosed();
+        doClose();
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            mCloseGuard.warnIfOpen();
+            if (mInput != null) {
+                doClose();
+            }
+        } finally {
+            super.finalize();
+        }
+    }
+
+    private void doClose() {
+        nativeClose(mNativeDocument);
+        IoUtils.closeQuietly(mInput);
+        mInput = null;
+        mCloseGuard.close();
+    }
+
+    private void throwIfClosed() {
+        if (mInput == null) {
+            throw new IllegalStateException("Already closed");
+        }
+    }
+
+    private void throwIfPageNotInDocument(int pageIndex) {
+        if (pageIndex < 0 || pageIndex >= mPageCount) {
+            throw new IllegalArgumentException("Invalid page index");
+        }
+    }
+
+    private static native long nativeOpen(int fd, long size);
+    private static native void nativeClose(long documentPtr);
+    private static native int nativeGetPageCount(long documentPtr);
+    private static native int nativeRemovePage(long documentPtr, int pageIndex);
+    private static native void nativeWrite(long documentPtr, int fd);
+}
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
index 1072b3c..359c294 100644
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ b/graphics/java/android/graphics/pdf/PdfRenderer.java
@@ -239,7 +239,7 @@
     }
 
     private void throwIfPageNotInDocument(int pageIndex) {
-        if (pageIndex >= mPageCount) {
+        if (pageIndex < 0 || pageIndex >= mPageCount) {
             throw new IllegalArgumentException("Invalid page index");
         }
     }
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 9855f71..f853d1f 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -551,9 +551,13 @@
 }
 
 void Caches::bindTexture(GLenum target, GLuint texture) {
-    if (mBoundTextures[mTextureUnit] != texture) {
+    if (target == GL_TEXTURE_2D) {
+        bindTexture(texture);
+    } else {
+        // GLConsumer directly calls glBindTexture() with
+        // target=GL_TEXTURE_EXTERNAL_OES, don't cache this target
+        // since the cached state could be stale
         glBindTexture(target, texture);
-        mBoundTextures[mTextureUnit] = texture;
     }
 }
 
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 726b74d..7aa628c 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -431,6 +431,7 @@
 
     uint32_t mFunctorsCount;
 
+    // Caches texture bindings for the GL_TEXTURE_2D target
     GLuint mBoundTextures[REQUIRED_TEXTURE_UNITS_COUNT];
 
     OverdrawColorSet mOverdrawDebugColorSet;
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
index e30ac19..281ca02 100644
--- a/libs/hwui/PathTessellator.cpp
+++ b/libs/hwui/PathTessellator.cpp
@@ -162,14 +162,21 @@
     }
 
     /**
-     * Outset the bounds of point data (for line endpoints or points) to account for AA stroke
+     * Outset the bounds of point data (for line endpoints or points) to account for stroke
      * geometry.
+     *
+     * bounds are in pre-scaled space.
      */
     void expandBoundsForStroke(Rect* bounds) const {
-        float outset = halfStrokeWidth;
-        if (outset == 0) outset = 0.5f;
-        bounds->outset(outset * inverseScaleX + Vertex::GeometryFudgeFactor(),
-                outset * inverseScaleY + Vertex::GeometryFudgeFactor());
+        if (halfStrokeWidth == 0) {
+            // hairline, outset by (0.5f + fudge factor) in post-scaling space
+            bounds->outset(fabs(inverseScaleX) * (0.5f + Vertex::GeometryFudgeFactor()),
+                    fabs(inverseScaleY) * (0.5f + Vertex::GeometryFudgeFactor()));
+        } else {
+            // non hairline, outset by half stroke width pre-scaled, and fudge factor post scaled
+            bounds->outset(halfStrokeWidth + fabs(inverseScaleX) * Vertex::GeometryFudgeFactor(),
+                    halfStrokeWidth + fabs(inverseScaleY) * Vertex::GeometryFudgeFactor());
+        }
     }
 };
 
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index e3b8985..6da3c0b 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -36,6 +36,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.ServiceManager;
@@ -1959,7 +1960,42 @@
             return;
         }
 
-        if (!querySoundEffectsEnabled()) {
+        if (!querySoundEffectsEnabled(Process.myUserHandle().getIdentifier())) {
+            return;
+        }
+
+        IAudioService service = getService();
+        try {
+            service.playSoundEffect(effectType);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Dead object in playSoundEffect"+e);
+        }
+    }
+
+    /**
+     * Plays a sound effect (Key clicks, lid open/close...)
+     * @param effectType The type of sound effect. One of
+     *            {@link #FX_KEY_CLICK},
+     *            {@link #FX_FOCUS_NAVIGATION_UP},
+     *            {@link #FX_FOCUS_NAVIGATION_DOWN},
+     *            {@link #FX_FOCUS_NAVIGATION_LEFT},
+     *            {@link #FX_FOCUS_NAVIGATION_RIGHT},
+     *            {@link #FX_KEYPRESS_STANDARD},
+     *            {@link #FX_KEYPRESS_SPACEBAR},
+     *            {@link #FX_KEYPRESS_DELETE},
+     *            {@link #FX_KEYPRESS_RETURN},
+     *            {@link #FX_KEYPRESS_INVALID},
+     * @param userId The current user to pull sound settings from
+     * NOTE: This version uses the UI settings to determine
+     * whether sounds are heard or not.
+     * @hide
+     */
+    public void  playSoundEffect(int effectType, int userId) {
+        if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) {
+            return;
+        }
+
+        if (!querySoundEffectsEnabled(userId)) {
             return;
         }
 
@@ -2006,8 +2042,9 @@
     /**
      * Settings has an in memory cache, so this is fast.
      */
-    private boolean querySoundEffectsEnabled() {
-        return Settings.System.getInt(mContext.getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED, 0) != 0;
+    private boolean querySoundEffectsEnabled(int user) {
+        return Settings.System.getIntForUser(mContext.getContentResolver(),
+                Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0;
     }
 
 
diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java
index 8883d28..5651fc9 100644
--- a/media/java/android/media/CamcorderProfile.java
+++ b/media/java/android/media/CamcorderProfile.java
@@ -177,9 +177,15 @@
      */
     public static final int QUALITY_HIGH_SPEED_1080P = 2004;
 
+    /**
+     * High speed ( >= 100fps) quality level corresponding to the 2160p (3840 x 2160)
+     * resolution.
+     */
+    public static final int QUALITY_HIGH_SPEED_2160P = 2005;
+
     // Start and end of high speed quality list
     private static final int QUALITY_HIGH_SPEED_LIST_START = QUALITY_HIGH_SPEED_LOW;
-    private static final int QUALITY_HIGH_SPEED_LIST_END = QUALITY_HIGH_SPEED_1080P;
+    private static final int QUALITY_HIGH_SPEED_LIST_END = QUALITY_HIGH_SPEED_2160P;
 
     /**
      * Default recording duration in seconds before the session is terminated.
@@ -313,6 +319,7 @@
      * @see #QUALITY_HIGH_SPEED_480P
      * @see #QUALITY_HIGH_SPEED_720P
      * @see #QUALITY_HIGH_SPEED_1080P
+     * @see #QUALITY_HIGH_SPEED_2160P
     */
     public static CamcorderProfile get(int cameraId, int quality) {
         if (!((quality >= QUALITY_LIST_START &&
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 675916b..1c7c9ea 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -672,6 +672,11 @@
             super(detailMessage);
             mErrorCode = errorCode;
             mActionCode = actionCode;
+
+            // TODO get this from codec
+            final String sign = errorCode < 0 ? "neg_" : "";
+            mDiagnosticInfo =
+                "android.media.MediaCodec.error_" + sign + Math.abs(errorCode);
         }
 
         /**
@@ -696,15 +701,28 @@
          * Retrieve the error code associated with a CodecException.
          * This is opaque diagnostic information and may depend on
          * hardware or API level.
+         *
+         * @hide
          */
         public int getErrorCode() {
             return mErrorCode;
         }
 
+        /**
+         * Retrieve a human readable diagnostic information string
+         * associated with the exception. DO NOT SHOW THIS TO END-USERS!
+         * This string will not be localized or generally comprehensible
+         * to end-users.
+         */
+        public String getDiagnosticInfo() {
+            return mDiagnosticInfo;
+        }
+
         /* Must be in sync with android_media_MediaCodec.cpp */
         private final static int ACTION_TRANSIENT = 1;
         private final static int ACTION_RECOVERABLE = 2;
 
+        private final String mDiagnosticInfo;
         private final int mErrorCode;
         private final int mActionCode;
     }
@@ -737,6 +755,13 @@
         public static final int ERROR_RESOURCE_BUSY = 3;
 
         /**
+         * This indicates that the output protection levels supported by the
+         * device are not sufficient to meet the requirements set by the
+         * content owner in the license policy.
+         */
+        public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4;
+
+        /**
          * Retrieve the error code associated with a CryptoException
          */
         public int getErrorCode() {
diff --git a/media/java/android/media/MediaCodecList.java b/media/java/android/media/MediaCodecList.java
index 85e9b16..0dcbd65 100644
--- a/media/java/android/media/MediaCodecList.java
+++ b/media/java/android/media/MediaCodecList.java
@@ -118,6 +118,7 @@
 
     /** @hide */
     public static MediaCodecInfo getInfoFor(String codec) {
+        initCodecList();
         return sAllCodecInfos[findCodecByName(codec)];
     }
 
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index ca707d8..1490732 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -188,18 +188,37 @@
      */
     public static final class MediaDrmStateException extends java.lang.IllegalStateException {
         private final int mErrorCode;
+        private final String mDiagnosticInfo;
 
         public MediaDrmStateException(int errorCode, String detailMessage) {
             super(detailMessage);
             mErrorCode = errorCode;
+
+            // TODO get this from DRM session
+            final String sign = errorCode < 0 ? "neg_" : "";
+            mDiagnosticInfo =
+                "android.media.MediaDrm.error_" + sign + Math.abs(errorCode);
+
         }
 
         /**
          * Retrieve the associated error code
+         *
+         * @hide
          */
         public int getErrorCode() {
             return mErrorCode;
         }
+
+        /**
+         * Retrieve a human readable diagnostic information string
+         * associated with the exception. DO NOT SHOW THIS TO END-USERS!
+         * This string will not be localized or generally comprehensible
+         * to end-users.
+         */
+        public String getDiagnosticInfo() {
+            return mDiagnosticInfo;
+        }
     }
 
     /**
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 9343aa4..afa0b6e 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1929,6 +1929,7 @@
         mSubtitleController.setAnchor(anchor);
     }
 
+    private final Object mInbandSubtitleLock = new Object();
     private SubtitleTrack[] mInbandSubtitleTracks;
     private int mSelectedSubtitleTrackIndex = -1;
     private Vector<SubtitleTrack> mOutOfBandSubtitleTracks;
@@ -2036,19 +2037,21 @@
         }
 
         TrackInfo[] tracks = getInbandTrackInfo();
-        SubtitleTrack[] inbandTracks = new SubtitleTrack[tracks.length];
-        for (int i=0; i < tracks.length; i++) {
-            if (tracks[i].getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
-                if (i < mInbandSubtitleTracks.length) {
-                    inbandTracks[i] = mInbandSubtitleTracks[i];
-                } else {
-                    SubtitleTrack track = mSubtitleController.addTrack(
-                            tracks[i].getFormat());
-                    inbandTracks[i] = track;
+        synchronized (mInbandSubtitleLock) {
+            SubtitleTrack[] inbandTracks = new SubtitleTrack[tracks.length];
+            for (int i=0; i < tracks.length; i++) {
+                if (tracks[i].getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
+                    if (i < mInbandSubtitleTracks.length) {
+                        inbandTracks[i] = mInbandSubtitleTracks[i];
+                    } else {
+                        SubtitleTrack track = mSubtitleController.addTrack(
+                                tracks[i].getFormat());
+                        inbandTracks[i] = track;
+                    }
                 }
             }
+            mInbandSubtitleTracks = inbandTracks;
         }
-        mInbandSubtitleTracks = inbandTracks;
         mSubtitleController.selectDefaultTrack();
     }
 
@@ -2224,9 +2227,9 @@
                 try {
                     Libcore.os.lseek(fd3, offset2, OsConstants.SEEK_SET);
                     byte[] buffer = new byte[4096];
-                    for (int total = 0; total < length2;) {
-                        int remain = (int)length2 - total;
-                        int bytes = IoBridge.read(fd3, buffer, 0, Math.min(buffer.length, remain));
+                    for (long total = 0; total < length2;) {
+                        int bytesToRead = (int) Math.min(buffer.length, length2 - total);
+                        int bytes = IoBridge.read(fd3, buffer, 0, bytesToRead);
                         if (bytes < 0) {
                             break;
                         } else {
@@ -2358,6 +2361,18 @@
             throws IllegalStateException {
         // handle subtitle track through subtitle controller
         SubtitleTrack track = null;
+        synchronized (mInbandSubtitleLock) {
+            if (mInbandSubtitleTracks.length == 0) {
+                TrackInfo[] tracks = getInbandTrackInfo();
+                mInbandSubtitleTracks = new SubtitleTrack[tracks.length];
+                for (int i=0; i < tracks.length; i++) {
+                    if (tracks[i].getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
+                        mInbandSubtitleTracks[i] = mSubtitleController.addTrack(tracks[i].getFormat());
+                    }
+                }
+            }
+        }
+
         if (index < mInbandSubtitleTracks.length) {
             track = mInbandSubtitleTracks[index];
         } else if (index < mInbandSubtitleTracks.length + mOutOfBandSubtitleTracks.size()) {
@@ -3256,9 +3271,7 @@
                 if (DEBUG) Log.d(TAG, "scheduleUpdate");
                 int i = registerListener(listener);
 
-                if (mStopped) {
-                    scheduleNotification(NOTIFY_STOP, 0 /* delay */);
-                } else {
+                if (!mStopped) {
                     mTimes[i] = 0;
                     scheduleNotification(NOTIFY_TIME, 0 /* delay */);
                 }
diff --git a/media/java/android/media/SubtitleController.java b/media/java/android/media/SubtitleController.java
index 37adb8c..f82dbe0 100644
--- a/media/java/android/media/SubtitleController.java
+++ b/media/java/android/media/SubtitleController.java
@@ -275,7 +275,7 @@
                      mSelectedTrack.getFormat().getInteger(
                             MediaFormat.KEY_IS_FORCED_SUBTITLE, 0) != 0)) {
                     show();
-                } else {
+                } else if (mSelectedTrack != null && !mSelectedTrack.isTimedText()) {
                     hide();
                 }
                 mVisibilityIsExplicit = false;
diff --git a/media/java/android/media/tv/TvContentRating.java b/media/java/android/media/tv/TvContentRating.java
index 7d1c7c6..b4ec2b3 100644
--- a/media/java/android/media/tv/TvContentRating.java
+++ b/media/java/android/media/tv/TvContentRating.java
@@ -247,6 +247,10 @@
  *         <td>TV content rating system for Iceland</td>
  *     </tr>
  *     <tr>
+ *         <td>JP_TV</td>
+ *         <td>TV content rating system for Japan</td>
+ *     </tr>
+ *     <tr>
  *         <td>KR_TV</td>
  *         <td>TV content rating system for South Korea</td>
  *     </tr>
@@ -912,6 +916,23 @@
  *         <td>Programs suitable for ages 18 and older</td>
  *     </tr>
  *     <tr>
+ *         <td valign="top" rowspan="4">JP_TV</td>
+ *         <td>JP_TV_G</td>
+ *         <td>General, suitable for all ages</td>
+ *     </tr>
+ *     <tr>
+ *         <td>JP_TV_PG12</td>
+ *         <td>Parental guidance requested for young people under 12 years</td>
+ *     </tr>
+ *     <tr>
+ *         <td>JP_TV_R15</td>
+ *         <td>For persons aged 15 and above only</td>
+ *     </tr>
+ *     <tr>
+ *         <td>JP_TV_R18</td>
+ *         <td>For persons aged 18 and above only</td>
+ *     </tr>
+ *     <tr>
  *         <td valign="top" rowspan="5">KR_TV</td>
  *         <td>KR_TV_ALL</td>
  *         <td>Appropriate for all ages</td>
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index f1e1099..1cf589d 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -62,6 +62,7 @@
     jint cryptoErrorNoKey;
     jint cryptoErrorKeyExpired;
     jint cryptoErrorResourceBusy;
+    jint cryptoErrorInsufficientOutputProtection;
 } gCryptoErrorCodes;
 
 static struct CodecActionCodes {
@@ -756,6 +757,9 @@
         case ERROR_DRM_RESOURCE_BUSY:
             err = gCryptoErrorCodes.cryptoErrorResourceBusy;
             break;
+        case ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION:
+            err = gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection;
+            break;
         default:  /* Other negative DRM error codes go out as is. */
             break;
     }
@@ -1434,6 +1438,11 @@
     gCryptoErrorCodes.cryptoErrorResourceBusy =
         env->GetStaticIntField(clazz.get(), field);
 
+    field = env->GetStaticFieldID(clazz.get(), "ERROR_INSUFFICIENT_OUTPUT_PROTECTION", "I");
+    CHECK(field != NULL);
+    gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection =
+        env->GetStaticIntField(clazz.get(), field);
+
     clazz.reset(env->FindClass("android/media/MediaCodec$CodecException"));
     CHECK(clazz.get() != NULL);
     field = env->GetStaticFieldID(clazz.get(), "ACTION_TRANSIENT", "I");
diff --git a/packages/PrintSpooler/Android.mk b/packages/PrintSpooler/Android.mk
index c4a55d1..27d1b23 100644
--- a/packages/PrintSpooler/Android.mk
+++ b/packages/PrintSpooler/Android.mk
@@ -19,7 +19,9 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_SRC_FILES += src/com/android/printspooler/renderer/IPdfRenderer.aidl
+LOCAL_SRC_FILES += \
+        src/com/android/printspooler/renderer/IPdfRenderer.aidl \
+        src/com/android/printspooler/renderer/IPdfEditor.aidl
 
 LOCAL_PACKAGE_NAME := PrintSpooler
 
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index 9efda2f..adff596 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -54,7 +54,7 @@
         </service>
 
         <service
-            android:name=".renderer.PdfRendererService"
+            android:name=".renderer.PdfManipulationService"
             android:isolatedProcess="true">
         </service>
 
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
index a581e8a..1d8261b 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
@@ -37,7 +37,7 @@
 import android.view.View;
 import com.android.internal.annotations.GuardedBy;
 import com.android.printspooler.renderer.IPdfRenderer;
-import com.android.printspooler.renderer.PdfRendererService;
+import com.android.printspooler.renderer.PdfManipulationService;
 import com.android.printspooler.util.BitmapSerializeUtils;
 import dalvik.system.CloseGuard;
 import libcore.io.IoUtils;
@@ -490,7 +490,8 @@
             new AsyncTask<Void, Void, Integer>() {
                 @Override
                 protected void onPreExecute() {
-                    Intent intent = new Intent(mContext, PdfRendererService.class);
+                    Intent intent = new Intent(PdfManipulationService.ACTION_GET_RENDERER);
+                    intent.setClass(mContext, PdfManipulationService.class);
                     mContext.bindService(intent, AsyncRenderer.this, Context.BIND_AUTO_CREATE);
                 }
 
@@ -555,7 +556,7 @@
                         callback.run();
                     }
                 }
-            }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
+            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
         }
 
         public void destroy() {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfEditor.aidl b/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfEditor.aidl
new file mode 100644
index 0000000..b450ccb
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfEditor.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.printspooler.renderer;
+
+import android.os.ParcelFileDescriptor;
+import android.print.PageRange;
+
+/**
+ * Interface for communication with a remote pdf editor.
+ */
+interface IPdfEditor {
+    int openDocument(in ParcelFileDescriptor source);
+    void removePages(in PageRange[] pages);
+    void write(in ParcelFileDescriptor destination);
+    void closeDocument();
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfRenderer.aidl b/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfRenderer.aidl
index 1fba2b1..8e595d7 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfRenderer.aidl
+++ b/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfRenderer.aidl
@@ -29,5 +29,4 @@
     oneway void renderPage(int pageIndex, int bitmapWidth, int bitmapHeight,
         in PrintAttributes attributes, in ParcelFileDescriptor destination);
     oneway void closeDocument();
-    oneway void writePages(in PageRange[] pages);
 }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfRendererService.java b/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java
similarity index 62%
rename from packages/PrintSpooler/src/com/android/printspooler/renderer/PdfRendererService.java
rename to packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java
index 4d02c01..62716b2 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfRendererService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java
@@ -23,6 +23,7 @@
 import android.graphics.Color;
 import android.graphics.Matrix;
 import android.graphics.Rect;
+import android.graphics.pdf.PdfEditor;
 import android.graphics.pdf.PdfRenderer;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
@@ -32,15 +33,21 @@
 import android.print.PrintAttributes.Margins;
 import android.util.Log;
 import android.view.View;
+import com.android.printspooler.util.PageRangeUtils;
 import libcore.io.IoUtils;
 import com.android.printspooler.util.BitmapSerializeUtils;
 import java.io.IOException;
 
 /**
- * Service for rendering PDF documents in an isolated process.
+ * Service for manipulation of PDF documents in an isolated process.
  */
-public final class PdfRendererService extends Service {
-    private static final String LOG_TAG = "PdfRendererService";
+public final class PdfManipulationService extends Service {
+    public static final String ACTION_GET_RENDERER =
+            "com.android.printspooler.renderer.ACTION_GET_RENDERER";
+    public static final String ACTION_GET_EDITOR =
+            "com.android.printspooler.renderer.ACTION_GET_EDITOR";
+
+    private static final String LOG_TAG = "PdfManipulationService";
     private static final boolean DEBUG = false;
 
     private static final int MILS_PER_INCH = 1000;
@@ -48,7 +55,18 @@
 
     @Override
     public IBinder onBind(Intent intent) {
-        return new PdfRendererImpl();
+        String action = intent.getAction();
+        switch (action) {
+            case ACTION_GET_RENDERER: {
+                return new PdfRendererImpl();
+            }
+            case ACTION_GET_EDITOR: {
+                return new PdfEditorImpl();
+            }
+            default: {
+                throw new IllegalArgumentException("Invalid intent action:" + action);
+            }
+        }
     }
 
     private final class PdfRendererImpl extends IPdfRenderer.Stub {
@@ -60,15 +78,17 @@
         @Override
         public int openDocument(ParcelFileDescriptor source) throws RemoteException {
             synchronized (mLock) {
-                throwIfOpened();
-                if (DEBUG) {
-                    Log.i(LOG_TAG, "openDocument()");
-                }
                 try {
+                    throwIfOpened();
+                    if (DEBUG) {
+                        Log.i(LOG_TAG, "openDocument()");
+                    }
                     mRenderer = new PdfRenderer(source);
                     return mRenderer.getPageCount();
-                } catch (IOException ioe) {
-                    throw new RemoteException("Cannot open file");
+                } catch (IOException|IllegalStateException e) {
+                    IoUtils.closeQuietly(source);
+                    Log.e(LOG_TAG, "Cannot open file", e);
+                    throw new RemoteException(e.toString());
                 }
             }
         }
@@ -108,7 +128,7 @@
                     }
                     matrix.postScale(displayScale, displayScale);
 
-                    Configuration configuration = PdfRendererService.this.getResources()
+                    Configuration configuration = PdfManipulationService.this.getResources()
                             .getConfiguration();
                     if (configuration.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
                         matrix.postTranslate(bitmapWidth - srcWidthPts * displayScale, 0);
@@ -147,24 +167,13 @@
             synchronized (mLock) {
                 throwIfNotOpened();
                 if (DEBUG) {
-                    Log.i(LOG_TAG, "openDocument()");
+                    Log.i(LOG_TAG, "closeDocument()");
                 }
                 mRenderer.close();
                 mRenderer = null;
             }
         }
 
-        @Override
-        public void writePages(PageRange[] pages) {
-            synchronized (mLock) {
-                throwIfNotOpened();
-                if (DEBUG) {
-                    Log.i(LOG_TAG, "writePages()");
-                }
-                // TODO: Implement dropping undesired pages.
-            }
-        }
-
         private Bitmap getBitmapForSize(int width, int height) {
             if (mBitmap != null) {
                 if (mBitmap.getWidth() == width && mBitmap.getHeight() == height) {
@@ -191,6 +200,91 @@
         }
     }
 
+    private final class PdfEditorImpl extends IPdfEditor.Stub {
+        private final Object mLock = new Object();
+
+        private PdfEditor mEditor;
+
+        @Override
+        public int openDocument(ParcelFileDescriptor source) throws RemoteException {
+            synchronized (mLock) {
+                try {
+                    throwIfOpened();
+                    if (DEBUG) {
+                        Log.i(LOG_TAG, "openDocument()");
+                    }
+                    mEditor = new PdfEditor(source);
+                    return mEditor.getPageCount();
+                } catch (IOException|IllegalStateException e) {
+                    IoUtils.closeQuietly(source);
+                    Log.e(LOG_TAG, "Cannot open file", e);
+                    throw new RemoteException(e.toString());
+                }
+            }
+        }
+
+        @Override
+        public void removePages(PageRange[] ranges) {
+            synchronized (mLock) {
+                throwIfNotOpened();
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "removePages()");
+                }
+
+                ranges = PageRangeUtils.normalize(ranges);
+
+                final int rangeCount = ranges.length;
+                for (int i = rangeCount - 1; i >= 0; i--) {
+                    PageRange range = ranges[i];
+                    for (int j = range.getEnd(); j >= range.getStart(); j--) {
+                        mEditor.removePage(j);
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void write(ParcelFileDescriptor destination) throws RemoteException {
+            synchronized (mLock) {
+                try {
+                    throwIfNotOpened();
+                    if (DEBUG) {
+                        Log.i(LOG_TAG, "write()");
+                    }
+                    mEditor.write(destination);
+                } catch (IOException | IllegalStateException e) {
+                    IoUtils.closeQuietly(destination);
+                    Log.e(LOG_TAG, "Error writing PDF to file.", e);
+                    throw new RemoteException(e.toString());
+                }
+            }
+        }
+
+        @Override
+        public void closeDocument() {
+            synchronized (mLock) {
+                throwIfNotOpened();
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "closeDocument()");
+                }
+                mEditor.close();
+                mEditor = null;
+            }
+        }
+
+        private void throwIfOpened() {
+            if (mEditor != null) {
+                throw new IllegalStateException("Already opened");
+            }
+        }
+
+        private void throwIfNotOpened() {
+            if (mEditor == null) {
+                throw new IllegalStateException("Not opened");
+            }
+        }
+    }
+
     private static int pointsFromMils(int mils) {
         return (int) (((float) mils / MILS_PER_INCH) * POINTS_IN_INCH);
     }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 535081f..c517f2d 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -23,6 +23,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.ServiceConnection;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
@@ -30,9 +31,12 @@
 import android.database.DataSetObserver;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
 import android.print.IPrintDocumentAdapter;
 import android.print.PageRange;
 import android.print.PrintAttributes;
@@ -74,6 +78,8 @@
 import com.android.printspooler.model.PrintSpoolerService;
 import com.android.printspooler.model.RemotePrintDocument;
 import com.android.printspooler.model.RemotePrintDocument.RemotePrintDocumentInfo;
+import com.android.printspooler.renderer.IPdfEditor;
+import com.android.printspooler.renderer.PdfManipulationService;
 import com.android.printspooler.util.MediaSizeUtils;
 import com.android.printspooler.util.MediaSizeUtils.MediaSizeComparator;
 import com.android.printspooler.util.PageRangeUtils;
@@ -81,8 +87,15 @@
 import com.android.printspooler.widget.PrintContentView;
 import com.android.printspooler.widget.PrintContentView.OptionsStateChangeListener;
 import com.android.printspooler.widget.PrintContentView.OptionsStateController;
+import libcore.io.IoUtils;
+import libcore.io.Streams;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -186,6 +199,7 @@
     private ImageView mPrintButton;
 
     private ProgressMessageController mProgressMessageController;
+    private MutexFileProvider mFileProvider;
 
     private MediaSizeComparator mMediaSizeComparator;
 
@@ -257,9 +271,8 @@
         setTitle(R.string.print_dialog);
         setContentView(R.layout.print_activity);
 
-        final MutexFileProvider fileProvider;
         try {
-            fileProvider = new MutexFileProvider(
+            mFileProvider = new MutexFileProvider(
                     PrintSpoolerService.generateFileForPrintJob(
                             PrintActivity.this, mPrintJob.getId()));
         } catch (IOException ioe) {
@@ -268,12 +281,13 @@
         }
 
         mPrintPreviewController = new PrintPreviewController(PrintActivity.this,
-                fileProvider);
+                mFileProvider);
         mPrintedDocument = new RemotePrintDocument(PrintActivity.this,
                 IPrintDocumentAdapter.Stub.asInterface(documentAdapter),
-                fileProvider, new RemotePrintDocument.DocumentObserver() {
+                mFileProvider, new RemotePrintDocument.DocumentObserver() {
             @Override
             public void onDestroy() {
+                setState(STATE_PRINT_CANCELED);
                 finish();
             }
         }, PrintActivity.this);
@@ -369,7 +383,7 @@
     @Override
     public void onRequestContentUpdate() {
         if (canUpdateDocument()) {
-            updateDocument(true, false);
+            updateDocument(false);
         }
     }
 
@@ -386,7 +400,7 @@
     @Override
     public void onActionPerformed() {
         if (mState == STATE_UPDATE_FAILED
-                && canUpdateDocument() && updateDocument(true, true)) {
+                && canUpdateDocument() && updateDocument(true)) {
             ensurePreviewUiShown();
             setState(STATE_CONFIGURING);
             updateOptionsUi();
@@ -557,14 +571,13 @@
         if (resultCode == RESULT_OK && data != null) {
             setState(STATE_PRINT_COMPLETED);
             updateOptionsUi();
-            Uri uri = data.getData();
-            mPrintedDocument.writeContent(getContentResolver(), uri);
+            final Uri uri = data.getData();
             // Calling finish here does not invoke lifecycle callbacks but we
             // update the print job in onPause if finishing, hence post a message.
             mDestinationSpinner.post(new Runnable() {
                 @Override
                 public void run() {
-                    finish();
+                    shredPagesAndFinish(uri);
                 }
             });
         } else if (resultCode == RESULT_CANCELED) {
@@ -708,7 +721,7 @@
 
         // Update the content if needed.
         if (canUpdateDocument()) {
-            updateDocument(true, false);
+            updateDocument(false);
         }
     }
 
@@ -840,7 +853,7 @@
         if (mCurrentPrinter == mDestinationSpinnerAdapter.getPdfPrinter()) {
             startCreateDocumentActivity();
         } else {
-            finish();
+            shredPagesAndFinish(null);
         }
     }
 
@@ -893,7 +906,7 @@
         attributes.setMinMargins(defaults.getMinMargins());
     }
 
-    private boolean updateDocument(boolean preview, boolean clearLastError) {
+    private boolean updateDocument(boolean clearLastError) {
         if (!clearLastError && mPrintedDocument.hasUpdateError()) {
             return false;
         }
@@ -902,6 +915,7 @@
             mPrintedDocument.clearUpdateError();
         }
 
+        final boolean preview = mState != STATE_PRINT_CONFIRMED;
         final PageRange[] pages;
         if (preview) {
             pages = mPrintPreviewController.getRequestedPages();
@@ -959,7 +973,7 @@
         mPrintPreviewController.closeOptions();
 
         if (canUpdateDocument()) {
-            updateDocument(false, false);
+            updateDocument(false);
         }
 
         if (!mPrintedDocument.isUpdating()) {
@@ -1433,7 +1447,7 @@
         if (mCurrentPrinter.equals(printer)) {
             setState(STATE_CONFIGURING);
             if (canUpdateDocument()) {
-                updateDocument(true, false);
+                updateDocument(false);
             }
             ensurePreviewUiShown();
             updateOptionsUi();
@@ -1492,6 +1506,18 @@
         return true;
     }
 
+    private void shredPagesAndFinish(final Uri writeToUri) {
+        new PageShredder(this, mPrintJob, mFileProvider, new Runnable() {
+            @Override
+            public void run() {
+                if (writeToUri != null) {
+                    mPrintedDocument.writeContent(getContentResolver(), writeToUri);
+                }
+                finish();
+            }
+        }).shred();
+    }
+
     private final class SpinnerItem<T> {
         final T value;
         final CharSequence label;
@@ -1942,7 +1968,7 @@
                     || (becameActive && hasCapab) || (isActive && gotCapab));
 
             if (updateNeeded && canUpdateDocument()) {
-                updateDocument(true, false);
+                updateDocument(false);
             }
 
             updateOptionsUi();
@@ -2033,7 +2059,7 @@
             }
 
             if (canUpdateDocument()) {
-                updateDocument(true, false);
+                updateDocument(false);
             }
 
             updateOptionsUi();
@@ -2158,7 +2184,7 @@
             updateOptionsUi();
 
             if (hadErrors && canUpdateDocument()) {
-                updateDocument(true, false);
+                updateDocument(false);
             }
         }
     }
@@ -2198,4 +2224,176 @@
             updateOptionsUi();
         }
     }
+
+    private static final class PageShredder implements ServiceConnection {
+        private static final String TEMP_FILE_PREFIX = "print_job";
+        private static final String TEMP_FILE_EXTENSION = ".pdf";
+
+        private final Context mContext;
+
+        private final MutexFileProvider mFileProvider;
+
+        private final PrintJobInfo mPrintJob;
+
+        private final PageRange[] mPagesToShred;
+
+        private final Runnable mCallback;
+
+        public PageShredder(Context context, PrintJobInfo printJob,
+                MutexFileProvider fileProvider, Runnable callback) {
+            mContext = context;
+            mPrintJob = printJob;
+            mFileProvider = fileProvider;
+            mCallback = callback;
+            mPagesToShred = computePagesToShred(mPrintJob);
+        }
+
+        public void shred() {
+            // If we have only the pages we want, done.
+            if (mPagesToShred.length <= 0) {
+                mCallback.run();
+                return;
+            }
+
+            // Bind to the manipulation service and the work
+            // will be performed upon connection to the service.
+            Intent intent = new Intent(PdfManipulationService.ACTION_GET_EDITOR);
+            intent.setClass(mContext, PdfManipulationService.class);
+            mContext.bindService(intent, this, Context.BIND_AUTO_CREATE);
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            final IPdfEditor editor = IPdfEditor.Stub.asInterface(service);
+            new AsyncTask<Void, Void, Void>() {
+                @Override
+                protected Void doInBackground(Void... params) {
+                    try {
+                        // It's OK to access the data members as they are
+                        // final and this code is the last one to touch
+                        // them as shredding is the very last step, so the
+                        // UI is not interactive at this point.
+                        shredPages(editor);
+                        updatePrintJob();
+                    } finally {
+                        mContext.unbindService(PageShredder.this);
+                        mCallback.run();
+                    }
+                    return null;
+                }
+            }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            /* do nothing */
+        }
+
+        private void shredPages(IPdfEditor editor) {
+            File tempFile = null;
+            ParcelFileDescriptor src = null;
+            ParcelFileDescriptor dst = null;
+            InputStream in = null;
+            OutputStream out = null;
+            try {
+                File jobFile = mFileProvider.acquireFile(null);
+                src = ParcelFileDescriptor.open(jobFile, ParcelFileDescriptor.MODE_READ_WRITE);
+
+                // Open the document.
+                editor.openDocument(src);
+
+                // We passed the fd over IPC, close this one.
+                src.close();
+
+                // Drop the pages.
+                editor.removePages(mPagesToShred);
+
+                // Write the modified PDF to a temp file.
+                tempFile = File.createTempFile(TEMP_FILE_PREFIX, TEMP_FILE_EXTENSION,
+                        mContext.getCacheDir());
+                dst = ParcelFileDescriptor.open(tempFile, ParcelFileDescriptor.MODE_READ_WRITE);
+                editor.write(dst);
+                dst.close();
+
+                // Close the document.
+                editor.closeDocument();
+
+                // Copy the temp file over the print job file.
+                jobFile.delete();
+                in = new FileInputStream(tempFile);
+                out = new FileOutputStream(jobFile);
+                Streams.copy(in, out);
+            } catch (IOException|RemoteException e) {
+                Log.e(LOG_TAG, "Error dropping pages", e);
+            } finally {
+                IoUtils.closeQuietly(src);
+                IoUtils.closeQuietly(dst);
+                IoUtils.closeQuietly(in);
+                IoUtils.closeQuietly(out);
+                if (tempFile != null) {
+                    tempFile.delete();
+                }
+            }
+        }
+
+        private void updatePrintJob() {
+            // Update the print job pages.
+            final int newPageCount = PageRangeUtils.getNormalizedPageCount(
+                    mPrintJob.getPages(), 0);
+            mPrintJob.setPages(new PageRange[]{PageRange.ALL_PAGES});
+
+            // Update the print job document info.
+            PrintDocumentInfo oldDocInfo = mPrintJob.getDocumentInfo();
+            PrintDocumentInfo newDocInfo = new PrintDocumentInfo
+                    .Builder(oldDocInfo.getName())
+                    .setContentType(oldDocInfo.getContentType())
+                    .setPageCount(newPageCount)
+                    .build();
+            mPrintJob.setDocumentInfo(newDocInfo);
+        }
+
+        private static PageRange[] computePagesToShred(PrintJobInfo printJob) {
+            List<PageRange> rangesToShred = new ArrayList<>();
+            PageRange previousRange = null;
+
+            final int pageCount = printJob.getDocumentInfo().getPageCount();
+
+            PageRange[] printedPages = printJob.getPages();
+            final int rangeCount = printedPages.length;
+            for (int i = 0; i < rangeCount; i++) {
+                PageRange range = PageRangeUtils.asAbsoluteRange(printedPages[i], pageCount);
+
+                if (previousRange == null) {
+                    final int startPageIdx = 0;
+                    final int endPageIdx = range.getStart() - 1;
+                    if (startPageIdx <= endPageIdx) {
+                        PageRange removedRange = new PageRange(startPageIdx, endPageIdx);
+                        rangesToShred.add(removedRange);
+                    }
+                } else {
+                    final int startPageIdx = previousRange.getEnd() + 1;
+                    final int endPageIdx = range.getStart() - 1;
+                    if (startPageIdx <= endPageIdx) {
+                        PageRange removedRange = new PageRange(startPageIdx, endPageIdx);
+                        rangesToShred.add(removedRange);
+                    }
+                }
+
+                if (i == rangeCount - 1) {
+                    final int startPageIdx = range.getEnd() + 1;
+                    final int endPageIdx = printJob.getDocumentInfo().getPageCount() - 1;
+                    if (startPageIdx <= endPageIdx) {
+                        PageRange removedRange = new PageRange(startPageIdx, endPageIdx);
+                        rangesToShred.add(removedRange);
+                    }
+                }
+
+                previousRange = range;
+            }
+
+            PageRange[] result = new PageRange[rangesToShred.size()];
+            rangesToShred.toArray(result);
+            return result;
+        }
+    }
 }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java
index a25e05e..5d858ca 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java
@@ -185,8 +185,10 @@
             public void run() {
                 // At this point the other end will write to the file, hence
                 // we have to close it and reopen after the write completes.
-                Message operation = mHandler.obtainMessage(MyHandler.MSG_CLOSE);
-                mHandler.enqueueOperation(operation);
+                if (mPageAdapter.isOpened()) {
+                    Message operation = mHandler.obtainMessage(MyHandler.MSG_CLOSE);
+                    mHandler.enqueueOperation(operation);
+                }
             }
         });
     }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 17593fe..6d08970 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -70,7 +70,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 110;
+    private static final int DATABASE_VERSION = 111;
 
     private Context mContext;
     private int mUserHandle;
@@ -1770,6 +1770,24 @@
             upgradeVersion = 110;
         }
 
+        if (upgradeVersion < 111) {
+            // reset ringer mode, so it doesn't force zen mode to follow
+            if (mUserHandle == UserHandle.USER_OWNER) {
+                db.beginTransaction();
+                SQLiteStatement stmt = null;
+                try {
+                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
+                            + " VALUES(?,?);");
+                    loadSetting(stmt, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                    if (stmt != null) stmt.close();
+                }
+            }
+            upgradeVersion = 111;
+        }
+
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
diff --git a/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_bounce.xml b/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_bounce.xml
new file mode 100644
index 0000000..a571cbc
--- /dev/null
+++ b/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_bounce.xml
@@ -0,0 +1,59 @@
+<?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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal">
+
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.6"
+        android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+        android:interpolator="@android:interpolator/accelerate_cubic"
+        android:duration="133"/>
+
+    <translate android:fromYDelta="0" android:toYDelta="10%"
+        android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+        android:interpolator="@android:interpolator/accelerate_cubic"
+        android:duration="350"/>
+
+    <scale android:fromXScale="1.0" android:toXScale="0.9"
+        android:fromYScale="1.0" android:toYScale="0.9"
+        android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+        android:pivotX="50%p" android:pivotY="50%p"
+        android:interpolator="@android:interpolator/fast_out_slow_in"
+        android:duration="350" />
+
+    <alpha android:fromAlpha="1.0" android:toAlpha="1.6666666666"
+        android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true"
+        android:interpolator="@android:interpolator/decelerate_cubic"
+        android:startOffset="350"
+        android:duration="133"/>
+
+    <translate android:fromYDelta="0%" android:toYDelta="-8.8888888888%"
+        android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true"
+        android:interpolator="@android:interpolator/decelerate_cubic"
+        android:startOffset="350"
+        android:duration="350"/>
+
+    <scale android:fromXScale="1.0" android:toXScale="1.1111111111"
+        android:fromYScale="1.0" android:toYScale="1.1111111111"
+        android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true"
+        android:pivotX="50%p" android:pivotY="50%p"
+        android:interpolator="@android:interpolator/decelerate_cubic"
+        android:startOffset="350"
+        android:duration="350" />
+</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_source.xml b/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_source.xml
new file mode 100644
index 0000000..f0fd684
--- /dev/null
+++ b/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_source.xml
@@ -0,0 +1,34 @@
+<?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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal">
+
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.6"
+        android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+        android:interpolator="@android:interpolator/accelerate_cubic"
+        android:duration="150"/>
+
+    <scale android:fromXScale="1.0" android:toXScale="0.9"
+        android:fromYScale="1.0" android:toYScale="0.9"
+        android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+        android:pivotX="50%p" android:pivotY="50%p"
+        android:interpolator="@android:interpolator/fast_out_slow_in"
+        android:duration="300" />
+</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_target.xml b/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_target.xml
new file mode 100644
index 0000000..170ac82
--- /dev/null
+++ b/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_target.xml
@@ -0,0 +1,28 @@
+<?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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top">
+
+    <translate android:fromYDelta="110%" android:toYDelta="0%"
+               android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+               android:interpolator="@android:interpolator/decelerate_quint"
+               android:startOffset="50"
+               android:duration="250" />
+</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_bounce.xml b/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_bounce.xml
new file mode 100644
index 0000000..46045ac
--- /dev/null
+++ b/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_bounce.xml
@@ -0,0 +1,33 @@
+<?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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top">
+
+    <translate android:fromYDelta="0%" android:toYDelta="10%"
+               android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+               android:interpolator="@android:interpolator/decelerate_quint"
+               android:duration="300" />
+
+    <translate android:fromYDelta="10%" android:toYDelta="0%"
+               android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true"
+               android:interpolator="@android:interpolator/accelerate_quint"
+               android:startOffset="300"
+               android:duration="300" />
+</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_source.xml b/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_source.xml
new file mode 100644
index 0000000..ad5341b
--- /dev/null
+++ b/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_source.xml
@@ -0,0 +1,27 @@
+<?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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top">
+
+    <translate android:fromYDelta="0%" android:toYDelta="110%"
+               android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+               android:interpolator="@android:interpolator/accelerate_quint"
+               android:duration="300" />
+</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_target.xml b/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_target.xml
new file mode 100644
index 0000000..7687f02
--- /dev/null
+++ b/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_target.xml
@@ -0,0 +1,36 @@
+<?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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal">
+
+    <alpha android:fromAlpha="0.6" android:toAlpha="1.0"
+        android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+        android:interpolator="@android:interpolator/decelerate_cubic"
+        android:startOffset="75"
+        android:duration="150"/>
+
+    <scale android:fromXScale="0.9" android:toXScale="1.0"
+        android:fromYScale="0.9" android:toYScale="1.0"
+        android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+        android:interpolator="@android:interpolator/linear_out_slow_in"
+        android:pivotX="50%p" android:pivotY="50%p"
+        android:startOffset="75"
+        android:duration="225" />
+</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/recents_button_bg.xml b/packages/SystemUI/res/drawable/recents_button_bg.xml
index a4cb088..7456365 100644
--- a/packages/SystemUI/res/drawable/recents_button_bg.xml
+++ b/packages/SystemUI/res/drawable/recents_button_bg.xml
@@ -15,4 +15,5 @@
 -->
 
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="?android:attr/colorControlHighlight" />
\ No newline at end of file
+    android:color="#40ffffff">
+</ripple>
diff --git a/packages/SystemUI/res/layout/signal_cluster_view.xml b/packages/SystemUI/res/layout/signal_cluster_view.xml
index 3a8a17d..5889c55 100644
--- a/packages/SystemUI/res/layout/signal_cluster_view.xml
+++ b/packages/SystemUI/res/layout/signal_cluster_view.xml
@@ -43,6 +43,12 @@
             android:layout_width="wrap_content"
             />
     </FrameLayout>
+    <View
+        android:id="@+id/wifi_signal_spacer"
+        android:layout_width="4dp"
+        android:layout_height="4dp"
+        android:visibility="gone"
+        />
     <FrameLayout
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index 5aafb66..83477c0 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -33,6 +33,8 @@
     <!-- Set to true to enable the user switcher on the keyguard. -->
     <bool name="config_keyguardUserSwitcher">true</bool>
 
-    <!-- Transposes the recents layout in landscape. -->
-    <bool name="recents_transpose_layout_with_orientation">false</bool>
+    <!-- Transposes the search bar layout in landscape. -->
+    <bool name="recents_has_transposed_search_bar">true</bool>
+    <!-- Transposes the nav bar in landscape (only used for purposes of layout). -->
+    <bool name="recents_has_transposed_nav_bar">false</bool>
 </resources>
diff --git a/packages/SystemUI/res/values-sw720dp/config.xml b/packages/SystemUI/res/values-sw720dp/config.xml
index d8bb8d7d..fbeadcd 100644
--- a/packages/SystemUI/res/values-sw720dp/config.xml
+++ b/packages/SystemUI/res/values-sw720dp/config.xml
@@ -39,5 +39,10 @@
     <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow
          card. -->
     <integer name="keyguard_max_notification_count">5</integer>
+
+    <!-- Transposes the search bar layout in landscape. -->
+    <bool name="recents_has_transposed_search_bar">false</bool>
+    <!-- Transposes the nav bar in landscape (only used for purposes of layout). -->
+    <bool name="recents_has_transposed_nav_bar">false</bool>
 </resources>
 
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index c0e2b10..5a1c318 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -155,8 +155,10 @@
     <integer name="recents_max_task_stack_view_dim">96</integer>
     <!-- The delay to enforce between each alt-tab key press. -->
     <integer name="recents_alt_tab_key_delay">200</integer>
-    <!-- Transposes the recents layout in landscape. -->
-    <bool name="recents_transpose_layout_with_orientation">true</bool>
+    <!-- Transposes the search bar layout in landscape. -->
+    <bool name="recents_has_transposed_search_bar">true</bool>
+    <!-- Transposes the nav bar in landscape (only used for purposes of layout). -->
+    <bool name="recents_has_transposed_nav_bar">true</bool>
 
     <!-- Whether to enable KeyguardService or not -->
     <bool name="config_enableKeyguardService">true</bool>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 8cd4ce6..4495318 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -476,4 +476,12 @@
     <fraction name="battery_subpixel_smoothing_right">0%</fraction>
 
     <dimen name="battery_margin_bottom">0dp</dimen>
+
+    <!-- Extra padding between the mobile data type icon and the strength indicator when the data
+         type icon is wide. -->
+    <dimen name="wide_type_icon_start_padding">2dp</dimen>
+
+    <!-- Extra padding between the mobile data type icon and the strength indicator when the data
+         type icon is wide for the tile in quick settings. -->
+    <dimen name="wide_type_icon_start_padding_qs">3dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 23d9748..147efaf 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -798,6 +798,12 @@
     <!-- Notification when resuming an existing guest session: Action that continues with the current session [CHAR LIMIT=35] -->
     <string name="guest_wipe_session_dontwipe">Yes, continue</string>
 
+    <!-- Title for add user confirmation dialog [CHAR LIMIT=30] -->
+    <string name="user_add_user_title" msgid="2108112641783146007">Add new user?</string>
+
+    <!-- Message for add user confirmation dialog - short version. [CHAR LIMIT=none] -->
+    <string name="user_add_user_message_short" msgid="1511354412249044381">When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users. </string>
+
 
     <!-- Zen mode condition: time duration in minutes. [CHAR LIMIT=NONE] -->
     <plurals name="zen_mode_duration_minutes">
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 8d35eb0..50ba68e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -17,6 +17,7 @@
 package com.android.systemui.keyguard;
 
 import android.app.Activity;
+import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.PendingIntent;
@@ -487,7 +488,7 @@
         mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
 
         mLockPatternUtils = new LockPatternUtils(mContext);
-        mLockPatternUtils.setCurrentUser(UserHandle.USER_OWNER);
+        mLockPatternUtils.setCurrentUser(ActivityManager.getCurrentUser());
 
         // Assume keyguard is showing (unless it's disabled) until we know for sure...
         mShowing = (mUpdateMonitor.isDeviceProvisioned() || mLockPatternUtils.isSecure())
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java b/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java
index 377fcc0..b86e67c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java
@@ -59,7 +59,7 @@
                 .getDimensionPixelSize(R.dimen.qs_dual_tile_padding_horizontal);
 
         mFirstLine = initTextView();
-        mFirstLine.setPadding(mHorizontalPaddingPx, 0, 0, 0);
+        mFirstLine.setPadding(mHorizontalPaddingPx, 0, mHorizontalPaddingPx, 0);
         final LinearLayout firstLineLayout = new LinearLayout(mContext);
         firstLineLayout.setPadding(0, 0, 0, 0);
         firstLineLayout.setOrientation(LinearLayout.HORIZONTAL);
@@ -104,6 +104,7 @@
             lp.topMargin = h * 4 / 5;
             mSecondLine.setLayoutParams(lp);
             mFirstLine.setMinHeight(h);
+            mFirstLine.setPadding(mHorizontalPaddingPx, 0, 0, 0);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 2b071cc..cb685fe 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -373,6 +373,7 @@
         public boolean activityOut;
         public int overlayIconId;
         public boolean filter;
+        public boolean isOverlayIconWide;
 
         @Override
         public boolean copyTo(State other) {
@@ -380,13 +381,15 @@
             final boolean changed = o.enabled != enabled
                     || o.connected != connected || o.activityIn != activityIn
                     || o.activityOut != activityOut
-                    || o.overlayIconId != overlayIconId;
+                    || o.overlayIconId != overlayIconId
+                    || o.isOverlayIconWide != isOverlayIconWide;
             o.enabled = enabled;
             o.connected = connected;
             o.activityIn = activityIn;
             o.activityOut = activityOut;
             o.overlayIconId = overlayIconId;
             o.filter = filter;
+            o.isOverlayIconWide = isOverlayIconWide;
             return super.copyTo(other) || changed;
         }
 
@@ -399,6 +402,7 @@
             rt.insert(rt.length() - 1, ",activityOut=" + activityOut);
             rt.insert(rt.length() - 1, ",overlayIconId=" + overlayIconId);
             rt.insert(rt.length() - 1, ",filter=" + filter);
+            rt.insert(rt.length() - 1, ",wideOverlayIcon=" + isOverlayIconWide);
             return rt;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index e6175d2..8d7edb9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -230,7 +230,7 @@
         final int w = MeasureSpec.getSize(widthMeasureSpec);
         final int h = MeasureSpec.getSize(heightMeasureSpec);
         final int iconSpec = exactly(mIconSizePx);
-        mIcon.measure(iconSpec, iconSpec);
+        mIcon.measure(MeasureSpec.makeMeasureSpec(w, MeasureSpec.AT_MOST), iconSpec);
         labelView().measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(h, MeasureSpec.AT_MOST));
         if (mDual) {
             mDivider.measure(widthMeasureSpec, exactly(mDivider.getLayoutParams().height));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
index 0ecdeaa..cfcd74e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
@@ -37,11 +37,16 @@
     private ImageView mIn;
     private ImageView mOut;
 
+    private int mWideOverlayIconStartPadding;
+
     public SignalTileView(Context context) {
         super(context);
 
         mIn = addTrafficView(R.drawable.ic_qs_signal_in);
         mOut = addTrafficView(R.drawable.ic_qs_signal_out);
+
+        mWideOverlayIconStartPadding = context.getResources().getDimensionPixelSize(
+                R.dimen.wide_type_icon_start_padding_qs);
     }
 
     private ImageView addTrafficView(int icon) {
@@ -106,6 +111,11 @@
         } else {
             mOverlay.setVisibility(GONE);
         }
+        if (s.overlayIconId > 0 && s.isOverlayIconWide) {
+            mSignal.setPaddingRelative(mWideOverlayIconStartPadding, 0, 0, 0);
+        } else {
+            mSignal.setPaddingRelative(0, 0, 0, 0);
+        }
         Drawable drawable = mSignal.getDrawable();
         if (state.autoMirrorDrawable && drawable != null) {
             drawable.setAutoMirrored(true);
@@ -122,10 +132,9 @@
             view.animate()
                 .setDuration(visible ? SHORT_DURATION : DEFAULT_DURATION)
                 .alpha(newAlpha)
-                .withLayer()
                 .start();
         } else {
             view.setAlpha(newAlpha);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 8743207..359a259 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -23,10 +23,8 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.TextView;
 
 import com.android.systemui.R;
-import com.android.systemui.qs.DataUsageGraph;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.qs.QSTileView;
 import com.android.systemui.qs.SignalTileView;
@@ -34,8 +32,6 @@
 import com.android.systemui.statusbar.policy.NetworkController.DataUsageInfo;
 import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
 
-import java.text.DecimalFormat;
-
 /** Quick settings tile: Cellular **/
 public class CellularTile extends QSTile<QSTile.SignalState> {
     private static final Intent CELLULAR_SETTINGS = new Intent().setComponent(new ComponentName(
@@ -95,6 +91,7 @@
                 : !cb.enabled || cb.airplaneModeEnabled ? R.drawable.ic_qs_signal_disabled
                 : cb.mobileSignalIconId > 0 ? cb.mobileSignalIconId
                 : R.drawable.ic_qs_signal_no_signal;
+        state.isOverlayIconWide = cb.isDataTypeIconWide;
         state.autoMirrorDrawable = !cb.noSim;
         state.overlayIconId = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiConnected
                 ? cb.dataTypeIconId
@@ -142,6 +139,7 @@
         boolean activityOut;
         String enabledDesc;
         boolean noSim;
+        boolean isDataTypeIconWide;
     }
 
     private final NetworkSignalChangedCallback mCallback = new NetworkSignalChangedCallback() {
@@ -162,7 +160,8 @@
                 int mobileSignalIconId,
                 String mobileSignalContentDescriptionId, int dataTypeIconId,
                 boolean activityIn, boolean activityOut,
-                String dataTypeContentDescriptionId, String description, boolean noSim) {
+                String dataTypeContentDescriptionId, String description, boolean noSim,
+                boolean isDataTypeIconWide) {
             final CallbackInfo info = new CallbackInfo();  // TODO pool?
             info.enabled = enabled;
             info.wifiEnabled = mWifiEnabled;
@@ -176,6 +175,7 @@
             info.activityOut = activityOut;
             info.enabledDesc = description;
             info.noSim = noSim;
+            info.isDataTypeIconWide = isDataTypeIconWide;
             refreshState(info);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 4fc2ee4..0985812 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -206,7 +206,8 @@
                 int mobileSignalIconId,
                 String mobileSignalContentDescriptionId, int dataTypeIconId,
                 boolean activityIn, boolean activityOut,
-                String dataTypeContentDescriptionId, String description, boolean noSim) {
+                String dataTypeContentDescriptionId, String description, boolean noSim,
+                boolean isDataTypeIconWide) {
             // noop
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index 5fa9fa4..787de4e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -139,7 +139,8 @@
                 // Notify recents to hide itself
                 Intent intent = new Intent(ACTION_HIDE_RECENTS_ACTIVITY);
                 intent.setPackage(mContext.getPackageName());
-                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
+                        Intent.FLAG_RECEIVER_FOREGROUND);
                 intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, triggeredFromAltTab);
                 intent.putExtra(EXTRA_TRIGGERED_FROM_HOME_KEY, triggeredFromHomeKey);
                 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
@@ -190,10 +191,14 @@
                 Task.TaskKey toTaskKey;
                 if (showNextTask) {
                     toTaskKey = group.getNextTaskInGroup(task);
-                    // XXX: We will actually set the appropriate launch animations here
+                    launchOpts = ActivityOptions.makeCustomAnimation(mContext,
+                            R.anim.recents_launch_next_affiliated_task_target,
+                            R.anim.recents_launch_next_affiliated_task_source);
                 } else {
                     toTaskKey = group.getPrevTaskInGroup(task);
-                    // XXX: We will actually set the appropriate launch animations here
+                    launchOpts = ActivityOptions.makeCustomAnimation(mContext,
+                            R.anim.recents_launch_prev_affiliated_task_target,
+                            R.anim.recents_launch_prev_affiliated_task_source);
                 }
                 if (toTaskKey != null) {
                     toTask = stack.findTaskWithId(toTaskKey.id);
@@ -204,7 +209,11 @@
 
         // Return early if there is no next task
         if (toTask == null) {
-            // XXX: We will actually show a bounce animation here
+            if (showNextTask) {
+                // XXX: Show the next-task bounce animation
+            } else {
+                // XXX: Show the prev-task bounce animation
+            }
             return;
         }
 
@@ -243,8 +252,8 @@
         mConfig = RecentsConfiguration.reinitialize(mContext, mSystemServicesProxy);
         mConfig.updateOnConfigurationChange();
         mConfig.getTaskStackBounds(mWindowRect.width(), mWindowRect.height(), mStatusBarHeight,
-                mNavBarWidth, mTaskStackBounds);
-        if (mConfig.isLandscape && mConfig.transposeRecentsLayoutWithOrientation) {
+                (mConfig.hasTransposedNavBar ? mNavBarWidth : 0), mTaskStackBounds);
+        if (mConfig.isLandscape && mConfig.hasTransposedNavBar) {
             mSystemInsets.set(0, mStatusBarHeight, mNavBarWidth, 0);
         } else {
             mSystemInsets.set(0, mStatusBarHeight, 0, mNavBarHeight);
@@ -316,7 +325,8 @@
             // Notify recents to toggle itself
             Intent intent = new Intent(ACTION_TOGGLE_RECENTS_ACTIVITY);
             intent.setPackage(mContext.getPackageName());
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
+                    Intent.FLAG_RECEIVER_FOREGROUND);
             mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
             mLastToggleTime = System.currentTimeMillis();
             return;
@@ -590,7 +600,8 @@
             // Send the broadcast to notify Recents that the animation has started
             Intent intent = new Intent(ACTION_START_ENTER_ANIMATION);
             intent.setPackage(mContext.getPackageName());
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
+                    Intent.FLAG_RECEIVER_FOREGROUND);
             mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
                     fallbackReceiver, null, Activity.RESULT_CANCELED, null, null);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 396be3b..ed5c126 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -57,7 +57,8 @@
 
     /** Layout */
     boolean isLandscape;
-    boolean transposeRecentsLayoutWithOrientation;
+    boolean hasTransposedSearchBar;
+    boolean hasTransposedNavBar;
 
     /** Loading */
     public int maxNumTasksToLoad;
@@ -174,8 +175,8 @@
 
         // Layout
         isLandscape = res.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
-        transposeRecentsLayoutWithOrientation =
-                res.getBoolean(R.bool.recents_transpose_layout_with_orientation);
+        hasTransposedSearchBar = res.getBoolean(R.bool.recents_has_transposed_search_bar);
+        hasTransposedNavBar = res.getBoolean(R.bool.recents_has_transposed_nav_bar);
 
         // Insets
         displayRect.set(0, 0, dm.widthPixels, dm.heightPixels);
@@ -329,13 +330,12 @@
     /** Returns whether the nav bar scrim should be visible. */
     public boolean hasNavBarScrim() {
         // Only show the scrim if we have recent tasks, and if the nav bar is not transposed
-        return !launchedWithNoRecentTasks &&
-                (!transposeRecentsLayoutWithOrientation || !isLandscape);
+        return !launchedWithNoRecentTasks && (!hasTransposedNavBar || !isLandscape);
     }
 
     /** Returns whether the current layout is horizontal. */
     public boolean hasHorizontalLayout() {
-        return isLandscape && transposeRecentsLayoutWithOrientation;
+        return isLandscape && hasTransposedSearchBar;
     }
 
     /**
@@ -346,7 +346,7 @@
                                    Rect taskStackBounds) {
         Rect searchBarBounds = new Rect();
         getSearchBarBounds(windowWidth, windowHeight, topInset, searchBarBounds);
-        if (isLandscape && transposeRecentsLayoutWithOrientation) {
+        if (isLandscape && hasTransposedSearchBar) {
             // In landscape, the search bar appears on the left
             taskStackBounds.set(searchBarBounds.right, topInset, windowWidth - rightInset, windowHeight);
         } else {
@@ -367,7 +367,7 @@
             searchBarSize = 0;
         }
 
-        if (isLandscape && transposeRecentsLayoutWithOrientation) {
+        if (isLandscape && hasTransposedSearchBar) {
             // In landscape, the search bar appears on the left
             searchBarSpaceBounds.set(0, topInset, searchBarSize, windowHeight);
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 887cbac..bbd0a0d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -56,6 +56,7 @@
 import android.view.DisplayInfo;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
 import com.android.systemui.recents.Constants;
 
 import java.io.IOException;
@@ -73,6 +74,7 @@
 
     final static BitmapFactory.Options sBitmapOptions;
 
+    AccessibilityManager mAccm;
     ActivityManager mAm;
     IActivityManager mIam;
     AppWidgetManager mAwm;
@@ -97,6 +99,7 @@
 
     /** Private constructor */
     public SystemServicesProxy(Context context) {
+        mAccm = AccessibilityManager.getInstance(context);
         mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
         mIam = ActivityManagerNative.getDefault();
         mAwm = AppWidgetManager.getInstance(context);
@@ -442,6 +445,15 @@
     }
 
     /**
+     * Returns whether touch exploration is currently enabled.
+     */
+    public boolean isTouchExplorationEnabled() {
+        if (mAccm == null) return false;
+
+        return mAccm.isEnabled() && mAccm.isTouchExplorationEnabled();
+    }
+
+    /**
      * Returns a global setting.
      */
     public int getGlobalSetting(Context context, String setting) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index dbed136..895b9d1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -22,11 +22,15 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.FrameLayout;
 import com.android.systemui.R;
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.misc.DozeTrigger;
+import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.model.RecentsPackageMonitor;
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.model.Task;
@@ -67,6 +71,7 @@
     DebugOverlayView mDebugOverlay;
     Rect mTaskStackBounds = new Rect();
     int mFocusedTaskIndex = -1;
+    int mPrevAccessibilityFocusedIndex = -1;
 
     // Optimizations
     int mStackViewsAnimationDuration;
@@ -244,6 +249,9 @@
     /** Synchronizes the views with the model */
     boolean synchronizeStackViewsWithModel() {
         if (mStackViewsDirty) {
+            RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+            SystemServicesProxy ssp = loader.getSystemServicesProxy();
+
             // Get all the task transforms
             ArrayList<Task> tasks = mStack.getTasks();
             float stackScroll = mStackScroller.getStackScroll();
@@ -293,6 +301,18 @@
                 // Animate the task into place
                 tv.updateViewPropertiesToTaskTransform(mCurrentTaskTransforms.get(taskIndex),
                         mStackViewsAnimationDuration);
+
+                // Request accessibility focus on the next view if we removed the task
+                // that previously held accessibility focus
+                childCount = getChildCount();
+                if (childCount > 0 && ssp.isTouchExplorationEnabled()) {
+                    TaskView atv = (TaskView) getChildAt(childCount - 1);
+                    int indexOfTask = mStack.indexOfTask(atv.getTask());
+                    if (mPrevAccessibilityFocusedIndex != indexOfTask) {
+                        tv.requestAccessibilityFocus();
+                        mPrevAccessibilityFocusedIndex = indexOfTask;
+                    }
+                }
             }
 
             // Reset the request-synchronize params
@@ -432,6 +452,22 @@
     }
 
     @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        int childCount = getChildCount();
+        if (childCount > 0) {
+            TaskView backMostTask = (TaskView) getChildAt(0);
+            TaskView frontMostTask = (TaskView) getChildAt(childCount - 1);
+            event.setFromIndex(mStack.indexOfTask(backMostTask.getTask()));
+            event.setToIndex(mStack.indexOfTask(frontMostTask.getTask()));
+            event.setContentDescription(frontMostTask.getTask().activityLabel);
+        }
+        event.setItemCount(mStack.getTaskCount());
+        event.setScrollY(mStackScroller.mScroller.getCurrY());
+        event.setMaxScrollY(mStackScroller.progressToScrollRange(mLayoutAlgorithm.mMaxScrollP));
+    }
+
+    @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         return mTouchHandler.onInterceptTouchEvent(ev);
     }
@@ -447,6 +483,8 @@
         // Synchronize the views
         synchronizeStackViewsWithModel();
         clipTaskViews();
+        // Notify accessibility
+        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SCROLLED);
     }
 
     /** Computes the stack and task rects */
@@ -623,6 +661,15 @@
                     mStartEnterAnimationCompleted = true;
                     // Start dozing
                     mUIDozeTrigger.startDozing();
+                    // Focus the first view if accessibility is enabled
+                    RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+                    SystemServicesProxy ssp = loader.getSystemServicesProxy();
+                    int childCount = getChildCount();
+                    if (childCount > 0 && ssp.isTouchExplorationEnabled()) {
+                        TaskView tv = ((TaskView) getChildAt(childCount - 1));
+                        tv.requestAccessibilityFocus();
+                        mPrevAccessibilityFocusedIndex = mStack.indexOfTask(tv.getTask());
+                    }
                 }
             });
         }
@@ -812,6 +859,11 @@
     public void prepareViewToEnterPool(TaskView tv) {
         Task task = tv.getTask();
 
+        // Clear the accessibility focus for that view
+        if (tv.isAccessibilityFocused()) {
+            tv.clearAccessibilityFocus();
+        }
+
         // Report that this tasks's data is no longer being used
         RecentsTaskLoader.getInstance().unloadTaskData(task);
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 6fe86be..4563597 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -840,7 +840,7 @@
     @Override
      public void onClick(final View v) {
         final TaskView tv = this;
-        final boolean delayViewClick = (v != this);
+        final boolean delayViewClick = (v != this) && (v != mActionButtonView);
         if (delayViewClick) {
             // We purposely post the handler delayed to allow for the touch feedback to draw
             postDelayed(new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index c8fb1e6..4d85352 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -71,6 +71,7 @@
 import android.view.ViewGroup.LayoutParams;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
+import android.view.accessibility.AccessibilityManager;
 import android.view.animation.AnimationUtils;
 import android.widget.DateTimeView;
 import android.widget.ImageView;
@@ -161,6 +162,7 @@
     final protected SparseArray<UserInfo> mCurrentProfiles = new SparseArray<UserInfo>();
 
     protected int mLayoutDirection = -1; // invalid
+    protected AccessibilityManager mAccessibilityManager;
     private Locale mLocale;
     private float mFontScale;
 
@@ -442,6 +444,9 @@
 
         mNotificationData = new NotificationData(this);
 
+        mAccessibilityManager = (AccessibilityManager)
+                mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
+
         mDreamManager = IDreamManager.Stub.asInterface(
                 ServiceManager.checkService(DreamService.DREAM_SERVICE));
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
@@ -1924,9 +1929,6 @@
                 : null;
 
         // Reapply the RemoteViews
-        if (entry.row != null) {
-            entry.row.resetHeight();
-        }
         contentView.reapply(mContext, entry.expanded, mOnClickHandler);
         if (bigContentView != null && entry.getBigContentView() != null) {
             bigContentView.reapply(mContext, entry.getBigContentView(),
@@ -1945,6 +1947,7 @@
             entry.row.setOnClickListener(null);
         }
         entry.row.notifyContentUpdated();
+        entry.row.resetHeight();
     }
 
     protected void notifyHeadsUpScreenOn(boolean screenOn) {
@@ -1977,10 +1980,13 @@
         boolean hasTicker = mHeadsUpTicker && !TextUtils.isEmpty(notification.tickerText);
         boolean isAllowed = notification.extras.getInt(Notification.EXTRA_AS_HEADS_UP,
                 Notification.HEADS_UP_ALLOWED) != Notification.HEADS_UP_NEVER;
+        boolean accessibilityForcesLaunch = isFullscreen
+                && mAccessibilityManager.isTouchExplorationEnabled();
 
         final KeyguardTouchDelegate keyguard = KeyguardTouchDelegate.getInstance(mContext);
         boolean interrupt = (isFullscreen || (isHighPriority && (isNoisy || hasTicker)))
                 && isAllowed
+                && !accessibilityForcesLaunch
                 && mPowerManager.isScreenOn()
                 && !keyguard.isShowingAndNotOccluded()
                 && !keyguard.isInputRestricted();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 740211f..18ef024 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -50,10 +50,14 @@
     private int mAirplaneIconId = 0;
     private String mWifiDescription, mMobileDescription, mMobileTypeDescription;
     private boolean mRoaming;
+    private boolean mIsMobileTypeIconWide;
 
     ViewGroup mWifiGroup, mMobileGroup;
     ImageView mVpn, mWifi, mMobile, mMobileType, mAirplane;
     View mWifiAirplaneSpacer;
+    View mWifiSignalSpacer;
+
+    private int mWideTypeIconStartPadding;
 
     public SignalClusterView(Context context) {
         this(context, null);
@@ -80,6 +84,13 @@
     }
 
     @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mWideTypeIconStartPadding = getContext().getResources().getDimensionPixelSize(
+                R.dimen.wide_type_icon_start_padding);
+    }
+
+    @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
 
@@ -91,6 +102,7 @@
         mMobileType     = (ImageView) findViewById(R.id.mobile_type);
         mAirplane       = (ImageView) findViewById(R.id.airplane);
         mWifiAirplaneSpacer =         findViewById(R.id.wifi_airplane_spacer);
+        mWifiSignalSpacer =           findViewById(R.id.wifi_signal_spacer);
 
         apply();
     }
@@ -131,13 +143,15 @@
 
     @Override
     public void setMobileDataIndicators(boolean visible, int strengthIcon, int typeIcon,
-            String contentDescription, String typeContentDescription, boolean roaming) {
+            String contentDescription, String typeContentDescription, boolean roaming,
+            boolean isTypeIconWide) {
         mMobileVisible = visible;
         mMobileStrengthId = strengthIcon;
         mMobileTypeId = typeIcon;
         mMobileDescription = contentDescription;
         mMobileTypeDescription = typeContentDescription;
         mRoaming = roaming;
+        mIsMobileTypeIconWide = isTypeIconWide;
 
         apply();
     }
@@ -230,6 +244,14 @@
             mWifiAirplaneSpacer.setVisibility(View.GONE);
         }
 
+        if (mRoaming && mMobileVisible && mWifiVisible) {
+            mWifiSignalSpacer.setVisibility(View.VISIBLE);
+        } else {
+            mWifiSignalSpacer.setVisibility(View.GONE);
+        }
+
+        mMobile.setPaddingRelative(mIsMobileTypeIconWide ? mWideTypeIconStartPadding : 0, 0, 0, 0);
+
         if (DEBUG) Log.d(TAG,
                 String.format("mobile: %s sig=%d typ=%d",
                     (mMobileVisible ? "VISIBLE" : "GONE"),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java
index c620046..64d80cc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java
@@ -90,7 +90,6 @@
                     .alpha(endValue)
                     .setInterpolator(interpolator)
                     .setDuration(260)
-                    .withLayer()
                     .withEndAction(new Runnable() {
                         @Override
                         public void run() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
index dc49118..685c184 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -74,8 +74,10 @@
                     mKeyguardUserSwitcher.show(true /* animate */);
                 }
             } else {
-                mQsPanel.showDetailAdapter(true,
-                        mQsPanel.getHost().getUserSwitcherController().userDetailAdapter);
+                if (mQsPanel != null) {
+                    mQsPanel.showDetailAdapter(true,
+                            mQsPanel.getHost().getUserSwitcherController().userDetailAdapter);
+                }
             }
         } else {
             Intent intent = ContactsContract.QuickContact.composeQuickContactsIntent(
@@ -93,9 +95,12 @@
             final UserManager um = UserManager.get(getContext());
             String text;
             if (um.isUserSwitcherEnabled()) {
-                UserSwitcherController controller = mQsPanel.getHost()
-                        .getUserSwitcherController();
-                String currentUser = controller.getCurrentUserName(mContext);
+                String currentUser = null;
+                if (mQsPanel != null) {
+                    UserSwitcherController controller = mQsPanel.getHost()
+                            .getUserSwitcherController();
+                    currentUser = controller.getCurrentUserName(mContext);
+                }
                 if (TextUtils.isEmpty(currentUser)) {
                     text = mContext.getString(R.string.accessibility_multi_user_switch_switcher);
                 } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarViewTaskSwitchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarViewTaskSwitchHelper.java
index b633453..79bb1cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarViewTaskSwitchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarViewTaskSwitchHelper.java
@@ -31,7 +31,6 @@
     private final GestureDetector mTaskSwitcherDetector;
     private final int mScrollTouchSlop;
     private final int mMinFlingVelocity;
-    private boolean mInterceptTouches;
     private int mTouchDownX;
     private int mTouchDownY;
 
@@ -56,11 +55,11 @@
         // task switcher detector
         mTaskSwitcherDetector.onTouchEvent(event);
         int action = event.getAction();
+        boolean interceptTouches = false;
         switch (action & MotionEvent.ACTION_MASK) {
             case MotionEvent.ACTION_DOWN: {
                 mTouchDownX = (int) event.getX();
                 mTouchDownY = (int) event.getY();
-                mInterceptTouches = false;
                 break;
             }
             case MotionEvent.ACTION_MOVE: {
@@ -72,21 +71,19 @@
                         ? xDiff > mScrollTouchSlop && xDiff > yDiff
                         : yDiff > mScrollTouchSlop && yDiff > xDiff;
                 if (exceededTouchSlop) {
-                    mInterceptTouches = true;
+                    interceptTouches = true;
                     return true;
                 }
                 break;
             }
             case MotionEvent.ACTION_CANCEL:
             case MotionEvent.ACTION_UP:
-                mInterceptTouches = false;
                 break;
         }
-        return mInterceptTouches;
+        return interceptTouches;
     }
 
     public boolean onTouchEvent(MotionEvent event) {
-        if (!mInterceptTouches) return false;
         return mTaskSwitcherDetector.onTouchEvent(event);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 0499b14..9585e17 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -23,6 +23,8 @@
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
 import android.util.AttributeSet;
 import android.util.MathUtils;
 import android.view.MotionEvent;
@@ -60,6 +62,10 @@
     private static final float HEADER_RUBBERBAND_FACTOR = 2.05f;
     private static final float LOCK_ICON_ACTIVE_SCALE = 1.2f;
 
+    private static final int DOZE_BACKGROUND_COLOR = 0xff000000;
+    private static final int TAG_KEY_ANIM = R.id.scrim;
+    private static final long DOZE_BACKGROUND_ANIM_DURATION = ScrimController.ANIMATION_DURATION;
+
     private KeyguardAffordanceHelper mAfforanceHelper;
     private StatusBarHeaderView mHeader;
     private KeyguardUserSwitcher mKeyguardUserSwitcher;
@@ -1724,13 +1730,58 @@
         if (dozing == mDozing) return;
         mDozing = dozing;
         if (mDozing) {
-            setBackgroundColor(0xff000000);
+            setBackgroundColorAlpha(this, DOZE_BACKGROUND_COLOR, 0xff, false /*animate*/);
         } else {
-            setBackground(null);
+            setBackgroundColorAlpha(this, DOZE_BACKGROUND_COLOR, 0, true /*animate*/);
         }
         updateKeyguardStatusBarVisibility();
     }
 
+    private static void setBackgroundColorAlpha(final View target, int rgb, int targetAlpha,
+            boolean animate) {
+        int currentAlpha = getBackgroundAlpha(target);
+        if (currentAlpha == targetAlpha) {
+            return;
+        }
+        final int r = Color.red(rgb);
+        final int g = Color.green(rgb);
+        final int b = Color.blue(rgb);
+        Object runningAnim = target.getTag(TAG_KEY_ANIM);
+        if (runningAnim instanceof ValueAnimator) {
+            ((ValueAnimator) runningAnim).cancel();
+        }
+        if (!animate) {
+            target.setBackgroundColor(Color.argb(targetAlpha, r, g, b));
+            return;
+        }
+        ValueAnimator anim = ValueAnimator.ofInt(currentAlpha, targetAlpha);
+        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                int value = (int) animation.getAnimatedValue();
+                target.setBackgroundColor(Color.argb(value, r, g, b));
+            }
+        });
+        anim.setDuration(DOZE_BACKGROUND_ANIM_DURATION);
+        anim.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                target.setTag(TAG_KEY_ANIM, null);
+            }
+        });
+        anim.start();
+        target.setTag(TAG_KEY_ANIM, anim);
+    }
+
+    private static int getBackgroundAlpha(View view) {
+        if (view.getBackground() instanceof ColorDrawable) {
+            ColorDrawable drawable = (ColorDrawable) view.getBackground();
+            return Color.alpha(drawable.getColor());
+        } else {
+            return 0;
+        }
+    }
+
     public void setShadeEmpty(boolean shadeEmpty) {
         mShadeEmpty = shadeEmpty;
         updateEmptyShadeView();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 128c687..5d4c831 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1082,7 +1082,6 @@
     };
 
     private long mLastLockToAppLongPress;
-    private AccessibilityManager mAccessibilityManager;
     private View.OnLongClickListener mLongPressBackRecentsListener =
             new View.OnLongClickListener() {
         @Override
@@ -3874,10 +3873,6 @@
         try {
             boolean sendBackLongPress = false;
             IActivityManager activityManager = ActivityManagerNative.getDefault();
-            if (mAccessibilityManager == null) {
-                mAccessibilityManager = (AccessibilityManager)
-                        mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
-            }
             boolean isAccessiblityEnabled = mAccessibilityManager.isEnabled();
             if (activityManager.isInLockTaskMode() && !isAccessiblityEnabled) {
                 long time = System.currentTimeMillis();
@@ -3953,6 +3948,13 @@
         return !mNotificationData.getActiveNotifications().isEmpty();
     }
 
+    public void wakeUpIfDozing(long time) {
+        if (mDozeServiceHost != null && mDozeServiceHost.isDozing()) {
+            PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+            pm.wakeUp(time);
+        }
+    }
+
     private final class ShadeUpdates {
         private final ArraySet<String> mVisibleNotifications = new ArraySet<String>();
         private final ArraySet<String> mNewVisibleNotifications = new ArraySet<String>();
@@ -3997,6 +3999,10 @@
                     + mCurrentDozeService + "]";
         }
 
+        public boolean isDozing() {
+            return mCurrentDozeService != null;
+        }
+
         public void firePowerSaveChanged(boolean active) {
             for (Callback callback : mCallbacks) {
                 callback.onPowerSaveChanged(active);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 455c336..be48df7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -38,11 +38,12 @@
     private static final String TAG = "ScrimController";
     private static final boolean DEBUG = false;
 
+    public static final long ANIMATION_DURATION = 220;
+
     private static final float SCRIM_BEHIND_ALPHA = 0.62f;
     private static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.55f;
     private static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f;
     private static final float SCRIM_IN_FRONT_ALPHA = 0.75f;
-    private static final long ANIMATION_DURATION = 220;
     private static final int TAG_KEY_ANIM = R.id.scrim;
 
     private static final long PULSE_IN_ANIMATION_DURATION = 1000;
@@ -131,6 +132,7 @@
         mDozing = dozing;
         if (!mDozing) {
             cancelPulsing();
+            mAnimateChange = true;
         }
         scheduleUpdate();
     }
@@ -163,7 +165,7 @@
         if (mAnimateKeyguardFadingOut) {
             setScrimInFrontColor(0f);
             setScrimBehindColor(0f);
-        }else if (!mKeyguardShowing && !mBouncerShowing) {
+        } else if (!mKeyguardShowing && !mBouncerShowing) {
             updateScrimNormal();
             setScrimInFrontColor(0);
         } else {
@@ -217,8 +219,8 @@
             mScrimInFront.setClickable(false);
         } else {
 
-            // Eat touch events.
-            mScrimInFront.setClickable(true);
+            // Eat touch events (unless dozing).
+            mScrimInFront.setClickable(!mDozing);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 1811d8d..a5217ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -128,6 +128,10 @@
                 && mService.getBarState() == StatusBarState.KEYGUARD
                 && !mService.isBouncerShowing()) {
             intercept = mDragDownHelper.onInterceptTouchEvent(ev);
+            // wake up on a touch down event, if dozing
+            if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
+                mService.wakeUpIfDozing(ev.getEventTime());
+            }
         }
         if (!intercept) {
             super.onInterceptTouchEvent(ev);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
index b2009c3..7f155a1d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -28,6 +28,7 @@
 import android.view.ViewGroup;
 import android.view.ViewOutlineProvider;
 import android.view.ViewTreeObserver;
+import android.view.accessibility.AccessibilityEvent;
 import android.widget.FrameLayout;
 
 import com.android.systemui.ExpandHelper;
@@ -111,6 +112,7 @@
             mContentHolder.setVisibility(View.VISIBLE);
             mContentHolder.setAlpha(mMaxAlpha);
             mContentHolder.addView(mHeadsUp.row);
+            sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
 
             mSwipeHelper.snapChild(mContentHolder, 1f);
             mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay;
@@ -126,6 +128,14 @@
         return true;
     }
 
+    @Override
+    protected void onVisibilityChanged(View changedView, int visibility) {
+        super.onVisibilityChanged(changedView, visibility);
+        if (changedView.getVisibility() == VISIBLE) {
+            sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+        }
+    }
+
     public boolean isShowing(String key) {
         return mHeadsUp != null && mHeadsUp.key.equals(key);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index d9a3e14..16c0e66 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -18,10 +18,12 @@
 
 import android.animation.Animator;
 import android.animation.ObjectAnimator;
+import android.app.ActivityManager;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.hardware.input.InputManager;
+import android.media.AudioManager;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.util.AttributeSet;
@@ -57,6 +59,7 @@
     private boolean mSupportsLongpress = true;
     private Animator mAnimateToQuiescent = new ObjectAnimator();
     private Drawable mBackground;
+    private AudioManager mAudioManager;
 
     private final Runnable mCheckLongPress = new Runnable() {
         public void run() {
@@ -99,6 +102,7 @@
 
         setClickable(true);
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
     }
 
     @Override
@@ -251,6 +255,10 @@
         return true;
     }
 
+    public void playSoundEffect(int soundConstant) {
+        mAudioManager.playSoundEffect(soundConstant, ActivityManager.getCurrentUser());
+    };
+
     public void sendEvent(int action, int flags) {
         sendEvent(action, flags, SystemClock.uptimeMillis());
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index b64dcbe..2ed9366 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -30,7 +30,8 @@
         void onMobileDataSignalChanged(boolean enabled, int mobileSignalIconId,
                 String mobileSignalContentDescriptionId, int dataTypeIconId,
                 boolean activityIn, boolean activityOut,
-                String dataTypeContentDescriptionId, String description, boolean noSim);
+                String dataTypeContentDescriptionId, String description, boolean noSim,
+                boolean isDataTypeIconWide);
         void onAirplaneModeChanged(boolean enabled);
         void onMobileDataEnabled(boolean enabled);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index f04d6a5..5088089 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -63,9 +63,6 @@
     static final boolean DEBUG = false;
     static final boolean CHATTY = false; // additional diagnostics, but not logspew
 
-    private static final int FLIGHT_MODE_ICON = R.drawable.stat_sys_airplane_mode;
-    private static final int ROAMING_ICON = R.drawable.stat_sys_data_fully_connected_roam;
-
     // telephony
     boolean mHspaDataDistinguishable;
     final TelephonyManager mPhone;
@@ -165,7 +162,8 @@
     public interface SignalCluster {
         void setWifiIndicators(boolean visible, int strengthIcon, String contentDescription);
         void setMobileDataIndicators(boolean visible, int strengthIcon, int typeIcon,
-                String contentDescription, String typeContentDescription, boolean roaming);
+                String contentDescription, String typeContentDescription, boolean roaming,
+                boolean isTypeIconWide);
         void setIsAirplaneMode(boolean is, int airplaneIcon);
     }
 
@@ -358,6 +356,16 @@
         mMobileDataController.setMobileDataEnabled(enabled);
     }
 
+    private boolean isTypeIconWide(int iconId) {
+        return TelephonyIcons.ICON_LTE == iconId || TelephonyIcons.ICON_1X == iconId
+                || TelephonyIcons.ICON_3G == iconId || TelephonyIcons.ICON_4G == iconId;
+    }
+
+    private boolean isQsTypeIconWide(int iconId) {
+        return TelephonyIcons.QS_ICON_LTE == iconId || TelephonyIcons.QS_ICON_1X == iconId
+                || TelephonyIcons.QS_ICON_3G == iconId || TelephonyIcons.QS_ICON_4G == iconId;
+    }
+
     public void refreshSignalCluster(SignalCluster cluster) {
         if (mDemoMode) return;
         cluster.setWifiIndicators(
@@ -374,7 +382,8 @@
                     mDataTypeIconId,
                     mContentDescriptionWimax,
                     mContentDescriptionDataType,
-                    mDataTypeIconId == ROAMING_ICON);
+                    mDataTypeIconId == TelephonyIcons.ROAMING_ICON,
+                    false /* isTypeIconWide */ );
         } else {
             // normal mobile data
             cluster.setMobileDataIndicators(
@@ -383,7 +392,8 @@
                     mDataTypeIconId,
                     mContentDescriptionPhoneSignal,
                     mContentDescriptionDataType,
-                    mDataTypeIconId == ROAMING_ICON);
+                    mDataTypeIconId == TelephonyIcons.ROAMING_ICON,
+                    isTypeIconWide(mDataTypeIconId));
         }
         cluster.setIsAirplaneMode(mAirplaneMode, mAirplaneIconId);
     }
@@ -409,18 +419,20 @@
         if (isEmergencyOnly()) {
             cb.onMobileDataSignalChanged(false, mQSPhoneSignalIconId,
                     mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
-                    mContentDescriptionDataType, null, mNoSim);
+                    mContentDescriptionDataType, null, mNoSim, isQsTypeIconWide(mQSDataTypeIconId));
         } else {
             if (mIsWimaxEnabled && mWimaxConnected) {
                 // Wimax is special
                 cb.onMobileDataSignalChanged(true, mQSPhoneSignalIconId,
                         mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
-                        mContentDescriptionDataType, mNetworkName, mNoSim);
+                        mContentDescriptionDataType, mNetworkName, mNoSim,
+                        isQsTypeIconWide(mQSDataTypeIconId));
             } else {
                 // Normal mobile data
                 cb.onMobileDataSignalChanged(mHasMobileDataFeature, mQSPhoneSignalIconId,
                         mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
-                        mContentDescriptionDataType, mNetworkName, mNoSim);
+                        mContentDescriptionDataType, mNetworkName, mNoSim,
+                        isQsTypeIconWide(mQSDataTypeIconId));
             }
         }
         cb.onAirplaneModeChanged(mAirplaneMode);
@@ -754,7 +766,7 @@
                                 R.string.accessibility_data_connection_4g);
                     } else {
                         mDataIconList = TelephonyIcons.DATA_LTE[mInetCondition];
-                        mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_lte;
+                        mDataTypeIconId = TelephonyIcons.ICON_LTE;
                         mQSDataTypeIconId = TelephonyIcons.QS_DATA_LTE[mInetCondition];
                         mContentDescriptionDataType = mContext.getString(
                                 R.string.accessibility_data_connection_lte);
@@ -780,11 +792,11 @@
 
         if (isCdma()) {
             if (isCdmaEri()) {
-                mDataTypeIconId = ROAMING_ICON;
+                mDataTypeIconId = TelephonyIcons.ROAMING_ICON;
                 mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition];
             }
         } else if (mPhone.isNetworkRoaming()) {
-                mDataTypeIconId = ROAMING_ICON;
+                mDataTypeIconId = TelephonyIcons.ROAMING_ICON;
                 mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition];
         }
     }
@@ -1164,7 +1176,7 @@
             // look again; your radios are now airplanes
             mContentDescriptionPhoneSignal = mContext.getString(
                     R.string.accessibility_airplane_mode);
-            mAirplaneIconId = FLIGHT_MODE_ICON;
+            mAirplaneIconId = TelephonyIcons.FLIGHT_MODE_ICON;
             mPhoneSignalIconId = mDataSignalIconId = mDataTypeIconId = mQSDataTypeIconId = 0;
             mQSPhoneSignalIconId = 0;
 
@@ -1198,11 +1210,11 @@
             mQSDataTypeIconId = 0;
             if (isCdma()) {
                 if (isCdmaEri()) {
-                    mDataTypeIconId = ROAMING_ICON;
+                    mDataTypeIconId = TelephonyIcons.ROAMING_ICON;
                     mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition];
                 }
             } else if (mPhone.isNetworkRoaming()) {
-                mDataTypeIconId = ROAMING_ICON;
+                mDataTypeIconId = TelephonyIcons.ROAMING_ICON;
                 mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition];
             }
         }
@@ -1509,7 +1521,7 @@
             if (airplane != null) {
                 boolean show = airplane.equals("show");
                 for (SignalCluster cluster : mSignalClusters) {
-                    cluster.setIsAirplaneMode(show, FLIGHT_MODE_ICON);
+                    cluster.setIsAirplaneMode(show, TelephonyIcons.FLIGHT_MODE_ICON);
                 }
             }
             String fully = args.getString("fully");
@@ -1540,23 +1552,23 @@
                 String datatype = args.getString("datatype");
                 if (datatype != null) {
                     mDemoDataTypeIconId =
-                            datatype.equals("1x") ? R.drawable.stat_sys_data_fully_connected_1x :
-                            datatype.equals("3g") ? R.drawable.stat_sys_data_fully_connected_3g :
-                            datatype.equals("4g") ? R.drawable.stat_sys_data_fully_connected_4g :
+                            datatype.equals("1x") ? TelephonyIcons.ICON_1X :
+                            datatype.equals("3g") ? TelephonyIcons.ICON_3G :
+                            datatype.equals("4g") ? TelephonyIcons.ICON_4G :
                             datatype.equals("e") ? R.drawable.stat_sys_data_fully_connected_e :
                             datatype.equals("g") ? R.drawable.stat_sys_data_fully_connected_g :
                             datatype.equals("h") ? R.drawable.stat_sys_data_fully_connected_h :
-                            datatype.equals("lte") ? R.drawable.stat_sys_data_fully_connected_lte :
-                            datatype.equals("roam") ? ROAMING_ICON :
+                            datatype.equals("lte") ? TelephonyIcons.ICON_LTE :
+                            datatype.equals("roam") ? TelephonyIcons.ROAMING_ICON :
                             0;
                     mDemoQSDataTypeIconId =
-                            datatype.equals("1x") ? R.drawable.ic_qs_signal_1x :
-                            datatype.equals("3g") ? R.drawable.ic_qs_signal_3g :
-                            datatype.equals("4g") ? R.drawable.ic_qs_signal_4g :
+                            datatype.equals("1x") ? TelephonyIcons.QS_ICON_1X :
+                            datatype.equals("3g") ? TelephonyIcons.QS_ICON_3G :
+                            datatype.equals("4g") ? TelephonyIcons.QS_ICON_4G :
                             datatype.equals("e") ? R.drawable.ic_qs_signal_e :
                             datatype.equals("g") ? R.drawable.ic_qs_signal_g :
                             datatype.equals("h") ? R.drawable.ic_qs_signal_h :
-                            datatype.equals("lte") ? R.drawable.ic_qs_signal_lte :
+                            datatype.equals("lte") ? TelephonyIcons.QS_ICON_LTE :
                             datatype.equals("roam") ? R.drawable.ic_qs_signal_r :
                             0;
                 }
@@ -1575,7 +1587,8 @@
                             mDemoDataTypeIconId,
                             "Demo",
                             "Demo",
-                            mDemoDataTypeIconId == ROAMING_ICON);
+                            mDemoDataTypeIconId == TelephonyIcons.ROAMING_ICON,
+                            isTypeIconWide(mDemoDataTypeIconId));
                 }
                 refreshViews();
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
index 84c53ce..1f2b918 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
@@ -188,5 +188,16 @@
         R.drawable.ic_qs_signal_lte
     };
 
+    static final int FLIGHT_MODE_ICON = R.drawable.stat_sys_airplane_mode;
+    static final int ROAMING_ICON = R.drawable.stat_sys_data_fully_connected_roam;
+    static final int ICON_LTE = R.drawable.stat_sys_data_fully_connected_lte;
+    static final int ICON_3G = R.drawable.stat_sys_data_fully_connected_3g;
+    static final int ICON_4G = R.drawable.stat_sys_data_fully_connected_4g;
+    static final int ICON_1X = R.drawable.stat_sys_data_fully_connected_1x;
+
+    static final int QS_ICON_LTE = R.drawable.ic_qs_signal_lte;
+    static final int QS_ICON_3G = R.drawable.ic_qs_signal_3g;
+    static final int QS_ICON_4G = R.drawable.ic_qs_signal_4g;
+    static final int QS_ICON_1X = R.drawable.ic_qs_signal_1x;
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 52fa621..d02826f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -73,6 +73,7 @@
 
     private ArrayList<UserRecord> mUsers = new ArrayList<>();
     private Dialog mExitGuestDialog;
+    private Dialog mAddUserDialog;
     private int mLastNonGuestUser = UserHandle.USER_OWNER;
     private boolean mSimpleUserSwitcher;
     private boolean mAddUsersWhenLocked;
@@ -228,8 +229,8 @@
             // No guest user. Create one.
             id = mUserManager.createGuest(mContext, mContext.getString(R.string.guest_nickname)).id;
         } else if (record.isAddUser) {
-            id = mUserManager.createUser(
-                    mContext.getString(R.string.user_new_user_name), 0 /* flags */).id;
+            showAddUserDialog();
+            return;
         } else {
             id = record.info.id;
         }
@@ -260,6 +261,14 @@
         mExitGuestDialog.show();
     }
 
+    private void showAddUserDialog() {
+        if (mAddUserDialog != null && mAddUserDialog.isShowing()) {
+            mAddUserDialog.cancel();
+        }
+        mAddUserDialog = new AddUserDialog(mContext);
+        mAddUserDialog.show();
+    }
+
     private void exitGuest(int id) {
         int newId = UserHandle.USER_OWNER;
         if (mLastNonGuestUser != UserHandle.USER_OWNER) {
@@ -534,4 +543,30 @@
             }
         }
     }
+
+    private final class AddUserDialog extends SystemUIDialog implements
+            DialogInterface.OnClickListener {
+
+        public AddUserDialog(Context context) {
+            super(context);
+            setTitle(R.string.user_add_user_title);
+            setMessage(context.getString(R.string.user_add_user_message_short));
+            setButton(DialogInterface.BUTTON_NEGATIVE,
+                    context.getString(android.R.string.cancel), this);
+            setButton(DialogInterface.BUTTON_POSITIVE,
+                    context.getString(android.R.string.ok), this);
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            if (which == BUTTON_NEGATIVE) {
+                cancel();
+            } else {
+                dismiss();
+                int id = mUserManager.createUser(
+                        mContext.getString(R.string.user_new_user_name), 0 /* flags */).id;
+                switchToUserId(id);
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 6c559fb..67ba8d20 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -1547,7 +1547,7 @@
         mStackScrollAlgorithm.notifyChildrenChanged(this);
         ((ExpandableView) child).setOnHeightChangedListener(this);
         generateAddAnimation(child, false /* fromMoreCard */);
-        updateAnimationState(mAnimationsEnabled && mIsExpanded, child);
+        updateAnimationState(child);
     }
 
     public void setAnimationsEnabled(boolean animationsEnabled) {
@@ -1564,6 +1564,11 @@
         }
     }
 
+    private void updateAnimationState(View child) {
+        updateAnimationState(mAnimationsEnabled && mIsExpanded, child);
+    }
+
+
     private void updateAnimationState(boolean running, View child) {
         if (child instanceof ExpandableNotificationRow) {
             ExpandableNotificationRow row = (ExpandableNotificationRow) child;
@@ -1961,6 +1966,7 @@
             mRequestViewResizeAnimationOnLayout = true;
         }
         mStackScrollAlgorithm.onReset(view);
+        updateAnimationState(view);
     }
 
     private void updateScrollPositionOnExpandInBottom(ExpandableView view) {
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 7c4c0e8..e4a1c27 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -40,8 +40,6 @@
     private static final int MAX_ITEMS_IN_BOTTOM_STACK = 3;
     private static final int MAX_ITEMS_IN_TOP_STACK = 3;
 
-    /** When a child is activated, the other cards' alpha fade to this value. */
-    private static final float ACTIVATED_INVERSE_ALPHA = 0.9f;
     public static final float DIMMED_SCALE = 0.95f;
 
     private int mPaddingBetweenElements;
@@ -270,12 +268,8 @@
             childViewState.scale = !mScaleDimmed || !dimmed || isActivatedChild
                     ? 1.0f
                     : DIMMED_SCALE;
-            if (dimmed && activatedChild != null) {
-                if (!isActivatedChild) {
-                    childViewState.alpha *= ACTIVATED_INVERSE_ALPHA;
-                } else {
-                    childViewState.zTranslation += 2.0f * mZDistanceBetweenElements;
-                }
+            if (dimmed && isActivatedChild) {
+                childViewState.zTranslation += 2.0f * mZDistanceBetweenElements;
             }
         }
     }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index f39727a..cce30c7 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -2755,12 +2755,14 @@
                         SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS,
                         mStatusBarColor, mLastTopInset, Gravity.TOP,
                         STATUS_BAR_BACKGROUND_TRANSITION_NAME,
-                        com.android.internal.R.id.statusBarBackground);
+                        com.android.internal.R.id.statusBarBackground,
+                        (getAttributes().flags & FLAG_FULLSCREEN) != 0);
                 mNavigationColorView = updateColorViewInt(mNavigationColorView,
                         SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION,
                         mNavigationBarColor, mLastBottomInset, Gravity.BOTTOM,
                         NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME,
-                        com.android.internal.R.id.navigationBarBackground);
+                        com.android.internal.R.id.navigationBarBackground,
+                        false /* hiddenByWindowFlag */);
             }
             if (insets != null) {
                 insets = insets.consumeStableInsets();
@@ -2769,8 +2771,10 @@
         }
 
         private View updateColorViewInt(View view, int systemUiHideFlag, int translucentFlag,
-                int color, int height, int verticalGravity, String transitionName, int id) {
+                int color, int height, int verticalGravity, String transitionName, int id,
+                boolean hiddenByWindowFlag) {
             boolean show = height > 0 && (mLastSystemUiVisibility & systemUiHideFlag) == 0
+                    && !hiddenByWindowFlag
                     && (getAttributes().flags & translucentFlag) == 0
                     && (color & Color.BLACK) != 0
                     && (getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index ab311c04..16bb00b 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -3533,13 +3533,16 @@
                     pf.bottom = df.bottom = of.bottom = cf.bottom = mOverscanScreenTop
                             + mOverscanScreenHeight;
                 } else if (attrs.type == TYPE_WALLPAPER) {
-                    // The wallpaper also has Real Ultimate Power.
-                    pf.left = df.left = of.left = cf.left = mUnrestrictedScreenLeft;
-                    pf.top = df.top = of.top = cf.top = mUnrestrictedScreenTop;
-                    pf.right = df.right = of.right = cf.right
-                            = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth;
-                    pf.bottom = df.bottom = of.bottom = cf.bottom
-                            = mUnrestrictedScreenTop + mUnrestrictedScreenHeight;
+                    // The wallpaper also has Real Ultimate Power, but we want to tell
+                    // it about the overscan area.
+                    pf.left = df.left = mOverscanScreenLeft;
+                    pf.top = df.top = mOverscanScreenTop;
+                    pf.right = df.right = mOverscanScreenLeft + mOverscanScreenWidth;
+                    pf.bottom = df.bottom = mOverscanScreenTop + mOverscanScreenHeight;
+                    of.left = cf.left = mUnrestrictedScreenLeft;
+                    of.top = cf.top = mUnrestrictedScreenTop;
+                    of.right = cf.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth;
+                    of.bottom = cf.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight;
                 } else if ((fl & FLAG_LAYOUT_IN_OVERSCAN) != 0
                         && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
                         && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
@@ -3653,9 +3656,12 @@
 
         // TYPE_SYSTEM_ERROR is above the NavigationBar so it can't be allowed to extend over it.
         if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && attrs.type != TYPE_SYSTEM_ERROR) {
-            df.left = df.top = of.left = of.top = cf.left = cf.top = vf.left = vf.top = -10000;
-            df.right = df.bottom = of.right = of.bottom = cf.right = cf.bottom
-                    = vf.right = vf.bottom = 10000;
+            df.left = df.top = -10000;
+            df.right = df.bottom = 10000;
+            if (attrs.type != TYPE_WALLPAPER) {
+                of.left = of.top = cf.left = cf.top = vf.left = vf.top = -10000;
+                of.right = of.bottom = cf.right = cf.bottom = vf.right = vf.bottom = 10000;
+            }
         }
 
         if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle()
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index c8718e3..060c8e3 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -106,6 +106,7 @@
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.InputMethodSubtype;
+import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
 import android.widget.ArrayAdapter;
 import android.widget.CompoundButton;
 import android.widget.CompoundButton.OnCheckedChangeListener;
@@ -3455,9 +3456,14 @@
                                 parser.getAttributeValue(null, ATTR_IME_SUBTYPE_EXTRA_VALUE);
                         final boolean isAuxiliary = "1".equals(String.valueOf(
                                 parser.getAttributeValue(null, ATTR_IS_AUXILIARY)));
-                        final InputMethodSubtype subtype =
-                                new InputMethodSubtype(label, icon, imeSubtypeLocale,
-                                        imeSubtypeMode, imeSubtypeExtraValue, isAuxiliary);
+                        final InputMethodSubtype subtype = new InputMethodSubtypeBuilder()
+                                .setSubtypeNameResId(label)
+                                .setSubtypeIconResId(icon)
+                                .setSubtypeLocale(imeSubtypeLocale)
+                                .setSubtypeMode(imeSubtypeMode)
+                                .setSubtypeExtraValue(imeSubtypeExtraValue)
+                                .setIsAuxiliary(isAuxiliary)
+                                .build();
                         tempSubtypesArray.add(subtype);
                     }
                 }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 7624314..37c23bb 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -196,7 +196,7 @@
                     if (VDBG) log("MSG_USER_SWITCHED userId=" + msg.arg1);
                     int numPhones = TelephonyManager.getDefault().getPhoneCount();
                     for (int sub = 0; sub < numPhones; sub++) {
-                        TelephonyRegistry.this.notifyCellLocationUsingSubId(sub,
+                        TelephonyRegistry.this.notifyCellLocationForSubscriber(sub,
                                 mCellLocation[sub]);
                     }
                     break;
@@ -326,7 +326,7 @@
     }
 
     @Override
-    public void listenUsingSubId(long subId, String pkgForDebug, IPhoneStateListener callback,
+    public void listenForSubscriber(long subId, String pkgForDebug, IPhoneStateListener callback,
             int events, boolean notifyNow) {
         listen(pkgForDebug, callback, events, notifyNow, subId, false);
     }
@@ -542,12 +542,12 @@
         broadcastCallStateChanged(state, incomingNumber, mDefaultSubId);
     }
 
-    public void notifyCallStateUsingSubId(long subId, int state, String incomingNumber) {
+    public void notifyCallStateForSubscriber(long subId, int state, String incomingNumber) {
         if (!checkNotifyPermission("notifyCallState()")) {
             return;
         }
         if (VDBG) {
-            log("notifyCallStateUsingSubId: subId=" + subId
+            log("notifyCallStateForSubscriber: subId=" + subId
                 + " state=" + state + " incomingNumber=" + incomingNumber);
         }
         synchronized (mRecords) {
@@ -573,38 +573,38 @@
     }
 
      public void notifyServiceState(ServiceState state) {
-         notifyServiceStateUsingSubId(mDefaultSubId, state);
+         notifyServiceStateForSubscriber(mDefaultSubId, state);
      }
 
-    public void notifyServiceStateUsingSubId(long subId, ServiceState state) {
+    public void notifyServiceStateForSubscriber(long subId, ServiceState state) {
         if (!checkNotifyPermission("notifyServiceState()")){
             return;
         }
         if (subId == SubscriptionManager.DEFAULT_SUB_ID) {
             subId = mDefaultSubId;
-            if (VDBG) log("notifyServiceStateUsingSubId: using mDefaultSubId=" + mDefaultSubId);
+            if (VDBG) log("notifyServiceStateForSubscriber: using mDefaultSubId=" + mDefaultSubId);
         }
         synchronized (mRecords) {
             int phoneId = SubscriptionManager.getPhoneId(subId);
             if (VDBG) {
-                log("notifyServiceStateUsingSubId: subId=" + subId + " phoneId=" + phoneId
+                log("notifyServiceStateForSubscriber: subId=" + subId + " phoneId=" + phoneId
                     + " state=" + state);
             }
             if (validatePhoneId(phoneId)) {
                 mServiceState[phoneId] = state;
-                logServiceStateChanged("notifyServiceStateUsingSubId", subId, phoneId, state);
-                if (VDBG) toStringLogSSC("notifyServiceStateUsingSubId");
+                logServiceStateChanged("notifyServiceStateForSubscriber", subId, phoneId, state);
+                if (VDBG) toStringLogSSC("notifyServiceStateForSubscriber");
 
                 for (Record r : mRecords) {
                     if (VDBG) {
-                        log("notifyServiceStateUsingSubId: r=" + r + " subId=" + subId
+                        log("notifyServiceStateForSubscriber: r=" + r + " subId=" + subId
                                 + " phoneId=" + phoneId + " state=" + state);
                     }
                     if (((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) &&
                         (r.phoneId == phoneId)) {
                         try {
                             if (DBG) {
-                                log("notifyServiceStateUsingSubId: callback.onSSC r=" + r
+                                log("notifyServiceStateForSubscriber: callback.onSSC r=" + r
                                         + " subId=" + subId + " phoneId=" + phoneId
                                         + " state=" + state);
                             }
@@ -615,7 +615,7 @@
                     }
                 }
             } else {
-                log("notifyServiceStateUsingSubId: INVALID phoneId=" + phoneId);
+                log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId);
             }
             handleRemoveListLocked();
         }
@@ -623,33 +623,33 @@
     }
 
     public void notifySignalStrength(SignalStrength signalStrength) {
-        notifySignalStrengthUsingSubId(mDefaultSubId, signalStrength);
+        notifySignalStrengthForSubscriber(mDefaultSubId, signalStrength);
     }
 
-    public void notifySignalStrengthUsingSubId(long subId, SignalStrength signalStrength) {
+    public void notifySignalStrengthForSubscriber(long subId, SignalStrength signalStrength) {
         if (!checkNotifyPermission("notifySignalStrength()")) {
             return;
         }
         if (VDBG) {
-            log("notifySignalStrengthUsingSubId: subId=" + subId
+            log("notifySignalStrengthForSubscriber: subId=" + subId
                 + " signalStrength=" + signalStrength);
-            toStringLogSSC("notifySignalStrengthUsingSubId");
+            toStringLogSSC("notifySignalStrengthForSubscriber");
         }
         synchronized (mRecords) {
             int phoneId = SubscriptionManager.getPhoneId(subId);
             if (validatePhoneId(phoneId)) {
-                if (VDBG) log("notifySignalStrengthUsingSubId: valid phoneId=" + phoneId);
+                if (VDBG) log("notifySignalStrengthForSubscriber: valid phoneId=" + phoneId);
                 mSignalStrength[phoneId] = signalStrength;
                 for (Record r : mRecords) {
                     if (VDBG) {
-                        log("notifySignalStrengthUsingSubId: r=" + r + " subId=" + subId
+                        log("notifySignalStrengthForSubscriber: r=" + r + " subId=" + subId
                                 + " phoneId=" + phoneId + " ss=" + signalStrength);
                     }
                     if (((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) &&
                         (r.phoneId == phoneId)) {
                         try {
                             if (DBG) {
-                                log("notifySignalStrengthUsingSubId: callback.onSsS r=" + r
+                                log("notifySignalStrengthForSubscriber: callback.onSsS r=" + r
                                         + " subId=" + subId + " phoneId=" + phoneId
                                         + " ss=" + signalStrength);
                             }
@@ -664,7 +664,7 @@
                             int gsmSignalStrength = signalStrength.getGsmSignalStrength();
                             int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
                             if (DBG) {
-                                log("notifySignalStrengthUsingSubId: callback.onSS r=" + r
+                                log("notifySignalStrengthForSubscriber: callback.onSS r=" + r
                                         + " subId=" + subId + " phoneId=" + phoneId
                                         + " gsmSS=" + gsmSignalStrength + " ss=" + ss);
                             }
@@ -675,7 +675,7 @@
                     }
                 }
             } else {
-                log("notifySignalStrengthUsingSubId: invalid phoneId=" + phoneId);
+                log("notifySignalStrengthForSubscriber: invalid phoneId=" + phoneId);
             }
             handleRemoveListLocked();
         }
@@ -683,15 +683,15 @@
     }
 
     public void notifyCellInfo(List<CellInfo> cellInfo) {
-         notifyCellInfoUsingSubId(mDefaultSubId, cellInfo);
+         notifyCellInfoForSubscriber(mDefaultSubId, cellInfo);
     }
 
-    public void notifyCellInfoUsingSubId(long subId, List<CellInfo> cellInfo) {
+    public void notifyCellInfoForSubscriber(long subId, List<CellInfo> cellInfo) {
         if (!checkNotifyPermission("notifyCellInfo()")) {
             return;
         }
         if (VDBG) {
-            log("notifyCellInfoUsingSubId: subId=" + subId
+            log("notifyCellInfoForSubscriber: subId=" + subId
                 + " cellInfo=" + cellInfo);
         }
 
@@ -743,15 +743,15 @@
     }
 
     public void notifyMessageWaitingChanged(boolean mwi) {
-        notifyMessageWaitingChangedUsingSubId(mDefaultSubId, mwi);
+        notifyMessageWaitingChangedForSubscriber(mDefaultSubId, mwi);
     }
 
-    public void notifyMessageWaitingChangedUsingSubId(long subId, boolean mwi) {
+    public void notifyMessageWaitingChangedForSubscriber(long subId, boolean mwi) {
         if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
             return;
         }
         if (VDBG) {
-            log("notifyMessageWaitingChangedUsingSubId: subId=" + subId
+            log("notifyMessageWaitingChangedForSubscriber: subId=" + subId
                 + " mwi=" + mwi);
         }
         synchronized (mRecords) {
@@ -774,15 +774,15 @@
     }
 
     public void notifyCallForwardingChanged(boolean cfi) {
-        notifyCallForwardingChangedUsingSubId(mDefaultSubId, cfi);
+        notifyCallForwardingChangedForSubscriber(mDefaultSubId, cfi);
     }
 
-    public void notifyCallForwardingChangedUsingSubId(long subId, boolean cfi) {
+    public void notifyCallForwardingChangedForSubscriber(long subId, boolean cfi) {
         if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
             return;
         }
         if (VDBG) {
-            log("notifyCallForwardingChangedUsingSubId: subId=" + subId
+            log("notifyCallForwardingChangedForSubscriber: subId=" + subId
                 + " cfi=" + cfi);
         }
         synchronized (mRecords) {
@@ -805,10 +805,10 @@
     }
 
     public void notifyDataActivity(int state) {
-        notifyDataActivityUsingSubId(mDefaultSubId, state);
+        notifyDataActivityForSubscriber(mDefaultSubId, state);
     }
 
-    public void notifyDataActivityUsingSubId(long subId, int state) {
+    public void notifyDataActivityForSubscriber(long subId, int state) {
         if (!checkNotifyPermission("notifyDataActivity()" )) {
             return;
         }
@@ -831,12 +831,12 @@
     public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
             String reason, String apn, String apnType, LinkProperties linkProperties,
             NetworkCapabilities networkCapabilities, int networkType, boolean roaming) {
-        notifyDataConnectionUsingSubId(mDefaultSubId, state, isDataConnectivityPossible,
+        notifyDataConnectionForSubscriber(mDefaultSubId, state, isDataConnectivityPossible,
             reason, apn, apnType, linkProperties,
             networkCapabilities, networkType, roaming);
     }
 
-    public void notifyDataConnectionUsingSubId(long subId, int state,
+    public void notifyDataConnectionForSubscriber(long subId, int state,
             boolean isDataConnectivityPossible, String reason, String apn, String apnType,
             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
             int networkType, boolean roaming) {
@@ -844,7 +844,7 @@
             return;
         }
         if (VDBG) {
-            log("notifyDataConnectionUsingSubId: subId=" + subId
+            log("notifyDataConnectionForSubscriber: subId=" + subId
                 + " state=" + state + " isDataConnectivityPossible=" + isDataConnectivityPossible
                 + " reason='" + reason
                 + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType
@@ -921,16 +921,16 @@
     }
 
     public void notifyDataConnectionFailed(String reason, String apnType) {
-         notifyDataConnectionFailedUsingSubId(mDefaultSubId, reason, apnType);
+         notifyDataConnectionFailedForSubscriber(mDefaultSubId, reason, apnType);
     }
 
-    public void notifyDataConnectionFailedUsingSubId(long subId,
+    public void notifyDataConnectionFailedForSubscriber(long subId,
             String reason, String apnType) {
         if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
             return;
         }
         if (VDBG) {
-            log("notifyDataConnectionFailedUsingSubId: subId=" + subId
+            log("notifyDataConnectionFailedForSubscriber: subId=" + subId
                 + " reason=" + reason + " apnType=" + apnType);
         }
         synchronized (mRecords) {
@@ -954,17 +954,17 @@
     }
 
     public void notifyCellLocation(Bundle cellLocation) {
-         notifyCellLocationUsingSubId(mDefaultSubId, cellLocation);
+         notifyCellLocationForSubscriber(mDefaultSubId, cellLocation);
     }
 
-    public void notifyCellLocationUsingSubId(long subId, Bundle cellLocation) {
-        log("notifyCellLocationUsingSubId: subId=" + subId
+    public void notifyCellLocationForSubscriber(long subId, Bundle cellLocation) {
+        log("notifyCellLocationForSubscriber: subId=" + subId
                 + " cellLocation=" + cellLocation);
         if (!checkNotifyPermission("notifyCellLocation()")) {
             return;
         }
         if (VDBG) {
-            log("notifyCellLocationUsingSubId: subId=" + subId
+            log("notifyCellLocationForSubscriber: subId=" + subId
                 + " cellLocation=" + cellLocation);
         }
         synchronized (mRecords) {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 0bdb964..599c3b9 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -308,7 +308,14 @@
             return new ComponentName("!", res.permission != null
                     ? res.permission : "private to package");
         }
+
         ServiceRecord r = res.record;
+
+        if (!mAm.getUserManagerLocked().exists(r.userId)) {
+            Slog.d(TAG, "Trying to start service with non-existent user! " + r.userId);
+            return null;
+        }
+
         NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
                 callingUid, r.packageName, service, service.getFlags(), null, r.userId);
         if (unscheduleServiceRestartLocked(r, callingUid, false)) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 38c6fb3..5cd7c01 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -256,7 +256,7 @@
     private List<HdmiDeviceInfo> mMhlDevices;
 
     @Nullable
-    private HdmiMhlController mMhlController;
+    private HdmiMhlControllerStub mMhlController;
 
     // Last input port before switching to the MHL port. Should switch back to this port
     // when the mobile device sends the request one touch play with off.
@@ -305,7 +305,7 @@
             Slog.i(TAG, "Device does not support HDMI-CEC.");
         }
 
-        mMhlController = HdmiMhlController.create(this);
+        mMhlController = HdmiMhlControllerStub.create(this);
         if (!mMhlController.isReady()) {
             Slog.i(TAG, "Device does not support MHL-control.");
         }
diff --git a/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java b/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java
new file mode 100644
index 0000000..c27cf18
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import android.hardware.hdmi.HdmiPortInfo;
+import android.util.SparseArray;
+
+import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
+
+/**
+ * A handler class for MHL control command. It converts user's command into MHL command and pass it
+ * to MHL HAL layer.
+ * <p>
+ * It can be created only by {@link HdmiMhlControllerStub#create}.
+ */
+final class HdmiMhlControllerStub {
+
+    private static final SparseArray<HdmiMhlLocalDevice> mLocalDevices = new SparseArray<>();
+    private static final HdmiPortInfo[] EMPTY_PORT_INFO = new HdmiPortInfo[0];
+    private static final int INVALID_MHL_VERSION = 0;
+    private static final int NO_SUPPORTED_FEATURES = 0;
+    private static final int INVALID_DEVICE_ROLES = 0;
+
+    // Private constructor. Use HdmiMhlControllerStub.create().
+    private HdmiMhlControllerStub(HdmiControlService service) {
+    }
+
+    // Returns true if MHL controller is initialized and ready to use.
+    boolean isReady() {
+        return false;
+    }
+
+    static HdmiMhlControllerStub create(HdmiControlService service) {
+        return new HdmiMhlControllerStub(service);
+    }
+
+    HdmiPortInfo[] getPortInfos() {
+        return EMPTY_PORT_INFO;
+    }
+
+    /**
+     * Return {@link HdmiMhlLocalDevice} matched with the given port id.
+     *
+     * @return null if has no matched port id
+     */
+    HdmiMhlLocalDevice getLocalDevice(int portId) {
+        return null;
+    }
+
+    /**
+     * Return {@link HdmiMhlLocalDevice} matched with the given device id.
+     *
+     * @return null if has no matched id
+     */
+    HdmiMhlLocalDevice getLocalDeviceById(int deviceId) {
+        return null;
+    }
+
+    SparseArray<HdmiMhlLocalDevice> getAllLocalDevices() {
+        return mLocalDevices;
+    }
+
+    /**
+     * Remove a {@link HdmiMhlLocalDevice} matched with the given port id.
+     *
+     * @return removed {@link HdmiMhlLocalDevice}. Return null if no matched port id.
+     */
+    HdmiMhlLocalDevice removeLocalDevice(int portId) {
+        return null;
+    }
+
+    /**
+     * Add a new {@link HdmiMhlLocalDevice}.
+     *
+     * @return old {@link HdmiMhlLocalDevice} having same port id
+     */
+    HdmiMhlLocalDevice addLocalDevice(HdmiMhlLocalDevice device) {
+        return null;
+    }
+
+    void clearAllLocalDevices() {
+    }
+
+    /**
+     * Send MHL MSC-Subcommand to the device connected to the given port.
+     */
+    void sendSubcommand(int portId, HdmiMhlSubcommand command) {
+    }
+
+    void sendSubcommand(final int portId, final HdmiMhlSubcommand command,
+            SendMessageCallback callback) {
+    }
+
+
+    void sendScratchpadCommand(int portId, int offset, int length, byte[] data) {
+    }
+
+    void setOption(int flag, int value) {
+    }
+
+    /**
+     * Get the MHL version supported by underlying hardware port of the given {@code portId}.
+     * MHL specification version 2.0 returns 0x20, 3.0 will return 0x30 respectively.
+     * The return value is stored in 'version'. Return INVALID_VERSION if MHL hardware layer
+     * is not ready.
+     */
+    int getMhlVersion(int portId) {
+        return INVALID_MHL_VERSION;
+    }
+
+    /**
+     * Get MHL version of a device which is connected to a port of the given {@code portId}.
+     * MHL specification version 2.0 returns 0x20, 3.0 will return 0x30 respectively.
+     * The return value is stored in 'version'.
+     */
+    int getPeerMhlVersion(int portId) {
+        return INVALID_MHL_VERSION;
+    }
+
+    /**
+     * Get the bit flags describing the features supported by the system. Refer to feature support
+     * flag register info in MHL specification.
+     */
+    int getSupportedFeatures(int portId) {
+        return NO_SUPPORTED_FEATURES;
+    }
+
+    /**
+     * Get the bit flags describing the roles which ECBUS device can play. Refer to the
+     * ECBUS_DEV_ROLES Register info MHL3.0 specification
+     */
+    int getEcbusDeviceRoles(int portId) {
+        return INVALID_DEVICE_ROLES;
+    }
+}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index a56f783..c09eff8 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -49,6 +49,7 @@
 import android.database.ContentObserver;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
+import android.media.AudioSystem;
 import android.media.IRingtonePlayer;
 import android.net.Uri;
 import android.os.Binder;
@@ -1945,14 +1946,19 @@
     }
 
     private static AudioAttributes audioAttributesForNotification(Notification n) {
-        if (n.audioAttributes != null
-                && !Notification.AUDIO_ATTRIBUTES_DEFAULT.equals(n.audioAttributes)) {
+        if (n.audioAttributes != null) {
             return n.audioAttributes;
+        } else if (n.audioStreamType >= 0 && n.audioStreamType < AudioSystem.getNumStreamTypes()) {
+            // the stream type is valid, use it
+            return new AudioAttributes.Builder()
+                    .setInternalLegacyStreamType(n.audioStreamType)
+                    .build();
+        } else if (n.audioStreamType == AudioSystem.STREAM_DEFAULT) {
+            return Notification.AUDIO_ATTRIBUTES_DEFAULT;
+        } else {
+            Log.w(TAG, String.format("Invalid stream type: %d", n.audioStreamType));
+            return Notification.AUDIO_ATTRIBUTES_DEFAULT;
         }
-        return new AudioAttributes.Builder()
-                .setLegacyStreamType(n.audioStreamType)
-                .setUsage(AudioAttributes.usageForLegacyStreamType(n.audioStreamType))
-                .build();
     }
 
     void showNextToastLocked() {
@@ -2965,15 +2971,18 @@
      */
     private static final class StatusBarNotificationHolder
             extends IStatusBarNotificationHolder.Stub {
-        private final StatusBarNotification mValue;
+        private StatusBarNotification mValue;
 
         public StatusBarNotificationHolder(StatusBarNotification value) {
             mValue = value;
         }
 
+        /** Get the held value and clear it. This function should only be called once per holder */
         @Override
         public StatusBarNotification get() {
-            return mValue;
+            StatusBarNotification value = mValue;
+            mValue = null;
+            return value;
         }
     }
 }
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 5639dad..41d7fa8f 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -301,8 +301,8 @@
             final int ringerMode = mAudioManager.getRingerMode();
             int newZen = -1;
             if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
-                if (mZenMode != Global.ZEN_MODE_NO_INTERRUPTIONS) {
-                    newZen = Global.ZEN_MODE_NO_INTERRUPTIONS;
+                if (mZenMode == Global.ZEN_MODE_OFF) {
+                    newZen = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
                 }
             } else if ((ringerMode == AudioManager.RINGER_MODE_NORMAL
                     || ringerMode == AudioManager.RINGER_MODE_VIBRATE)
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index b7b1c23..dcc4f8d 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -199,8 +199,7 @@
             mainIntent.setPackage(packageName);
             long ident = Binder.clearCallingIdentity();
             try {
-                List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(mainIntent,
-                        PackageManager.NO_CROSS_PROFILE, // We only want the apps for this user
+                List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(mainIntent, 0 /* flags */,
                         user.getIdentifier());
                 return apps;
             } finally {
@@ -288,8 +287,7 @@
                 // as calling startActivityAsUser ignores the category and just
                 // resolves based on the component if present.
                 List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(launchIntent,
-                        PackageManager.NO_CROSS_PROFILE, // We only want the apps for this user
-                        user.getIdentifier());
+                        0 /* flags */, user.getIdentifier());
                 final int size = apps.size();
                 for (int i = 0; i < size; ++i) {
                     ActivityInfo activityInfo = apps.get(i).activityInfo;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index adca46a..06f550d 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -579,8 +579,7 @@
             try {
                 apk = PackageParser.parseApkLite(file, PackageParser.PARSE_COLLECT_CERTIFICATES);
             } catch (PackageParserException e) {
-                throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
-                        "Failed to parse " + file + ": " + e);
+                throw PackageManagerException.from(e);
             }
 
             if (!stagedSplits.add(apk.splitName)) {
@@ -646,8 +645,7 @@
                 existingBase = PackageParser.parseApkLite(new File(app.getBaseCodePath()),
                         PackageParser.PARSE_COLLECT_CERTIFICATES);
             } catch (PackageParserException e) {
-                throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
-                        "Failed to parse existing package " + app.getCodePath() + ": " + e);
+                throw PackageManagerException.from(e);
             }
 
             assertApkConsistent("Existing base", existingBase);
@@ -699,8 +697,7 @@
         try {
             baseApk = PackageParser.parseApkLite(mResolvedBaseFile, 0);
         } catch (PackageParserException e) {
-            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
-                    "Failed to parse base package " + mResolvedBaseFile + ": " + e);
+            throw PackageManagerException.from(e);
         }
 
         final List<String> splitPaths = new ArrayList<>();
diff --git a/services/core/java/com/android/server/pm/PackageManagerException.java b/services/core/java/com/android/server/pm/PackageManagerException.java
index 0cbdcdc..a41636e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerException.java
+++ b/services/core/java/com/android/server/pm/PackageManagerException.java
@@ -16,6 +16,8 @@
 
 package com.android.server.pm;
 
+import android.content.pm.PackageParser.PackageParserException;
+
 /** {@hide} */
 public class PackageManagerException extends Exception {
     public final int error;
@@ -29,4 +31,9 @@
         super(detailMessage, throwable);
         this.error = error;
     }
+
+    public static PackageManagerException from(PackageParserException e)
+            throws PackageManagerException {
+        throw new PackageManagerException(e.error, e.getMessage(), e.getCause());
+    }
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 7b4270b..d821fc1 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3240,32 +3240,31 @@
         // reader
         synchronized (mPackages) {
             final String pkgName = intent.getPackage();
-            boolean queryCrossProfile = (flags & PackageManager.NO_CROSS_PROFILE) == 0;
             if (pkgName == null) {
                 ResolveInfo resolveInfo = null;
-                if (queryCrossProfile) {
-                    // Check if the intent needs to be forwarded to another user for this package
-                    ArrayList<ResolveInfo> crossProfileResult =
-                            queryIntentActivitiesCrossProfilePackage(
-                                    intent, resolvedType, flags, userId);
-                    if (!crossProfileResult.isEmpty()) {
-                        // Skip the current profile
-                        return crossProfileResult;
-                    }
-                    List<CrossProfileIntentFilter> matchingFilters =
-                            getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
-                    // Check for results that need to skip the current profile.
-                    resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
-                            resolvedType, flags, userId);
-                    if (resolveInfo != null) {
-                        List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
-                        result.add(resolveInfo);
-                        return result;
-                    }
-                    // Check for cross profile results.
-                    resolveInfo = queryCrossProfileIntents(
-                            matchingFilters, intent, resolvedType, flags, userId);
+
+                // Check if the intent needs to be forwarded to another user for this package
+                ArrayList<ResolveInfo> crossProfileResult =
+                        queryIntentActivitiesCrossProfilePackage(
+                                intent, resolvedType, flags, userId);
+                if (!crossProfileResult.isEmpty()) {
+                    // Skip the current profile
+                    return crossProfileResult;
                 }
+                List<CrossProfileIntentFilter> matchingFilters =
+                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
+                // Check for results that need to skip the current profile.
+                resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
+                        resolvedType, flags, userId);
+                if (resolveInfo != null) {
+                    List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
+                    result.add(resolveInfo);
+                    return result;
+                }
+                // Check for cross profile results.
+                resolveInfo = queryCrossProfileIntents(
+                        matchingFilters, intent, resolvedType, flags, userId);
+
                 // Check for results in the current profile.
                 List<ResolveInfo> result = mActivities.queryIntent(
                         intent, resolvedType, flags, userId);
@@ -3277,14 +3276,12 @@
             }
             final PackageParser.Package pkg = mPackages.get(pkgName);
             if (pkg != null) {
-                if (queryCrossProfile) {
-                    ArrayList<ResolveInfo> crossProfileResult =
-                            queryIntentActivitiesCrossProfilePackage(
-                                    intent, resolvedType, flags, userId, pkg, pkgName);
-                    if (!crossProfileResult.isEmpty()) {
-                        // Skip the current profile
-                        return crossProfileResult;
-                    }
+                ArrayList<ResolveInfo> crossProfileResult =
+                        queryIntentActivitiesCrossProfilePackage(
+                                intent, resolvedType, flags, userId, pkg, pkgName);
+                if (!crossProfileResult.isEmpty()) {
+                    // Skip the current profile
+                    return crossProfileResult;
                 }
                 return mActivities.queryIntentForPackage(intent, resolvedType, flags,
                         pkg.activities, userId);
@@ -4165,8 +4162,7 @@
             pp.collectCertificates(pkg, parseFlags);
             pp.collectManifestDigest(pkg);
         } catch (PackageParserException e) {
-            throw new PackageManagerException(e.error, "Failed to collect certificates for "
-                    + pkg.packageName + ": " + e.getMessage());
+            throw PackageManagerException.from(e);
         }
     }
 
@@ -4191,8 +4187,7 @@
         try {
             pkg = pp.parsePackage(scanFile, parseFlags);
         } catch (PackageParserException e) {
-            throw new PackageManagerException(e.error,
-                    "Failed to scan " + scanFile + ": " + e.getMessage());
+            throw PackageManagerException.from(e);
         }
 
         PackageSetting ps = null;
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 4a2cece..d032d29 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -21,7 +21,6 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
-import android.app.ActivityThread;
 import android.app.IStopUserCallback;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -92,6 +91,7 @@
     private static final String ATTR_SERIAL_NO = "serialNumber";
     private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber";
     private static final String ATTR_PARTIAL = "partial";
+    private static final String ATTR_GUEST_TO_REMOVE = "guestToRemove";
     private static final String ATTR_USER_VERSION = "version";
     private static final String ATTR_PROFILE_GROUP_ID = "profileGroupId";
     private static final String TAG_GUEST_RESTRICTIONS = "guestRestrictions";
@@ -228,7 +228,7 @@
                 ArrayList<UserInfo> partials = new ArrayList<UserInfo>();
                 for (int i = 0; i < mUsers.size(); i++) {
                     UserInfo ui = mUsers.valueAt(i);
-                    if (ui.partial && i != 0) {
+                    if ((ui.partial || ui.guestToRemove) && i != 0) {
                         partials.add(ui);
                     }
                 }
@@ -759,6 +759,9 @@
             if (userInfo.partial) {
                 serializer.attribute(null, ATTR_PARTIAL, "true");
             }
+            if (userInfo.guestToRemove) {
+                serializer.attribute(null, ATTR_GUEST_TO_REMOVE, "true");
+            }
             if (userInfo.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
                 serializer.attribute(null, ATTR_PROFILE_GROUP_ID,
                         Integer.toString(userInfo.profileGroupId));
@@ -806,7 +809,7 @@
             serializer.attribute(null, ATTR_NEXT_SERIAL_NO, Integer.toString(mNextSerialNumber));
             serializer.attribute(null, ATTR_USER_VERSION, Integer.toString(mUserVersion));
 
-            serializer.startTag(null,  TAG_GUEST_RESTRICTIONS);
+            serializer.startTag(null, TAG_GUEST_RESTRICTIONS);
             writeRestrictionsLocked(serializer, mGuestRestrictions);
             serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
             for (int i = 0; i < mUsers.size(); i++) {
@@ -855,6 +858,8 @@
         writeBoolean(serializer, restrictions, UserManager.DISALLOW_OUTGOING_CALLS);
         writeBoolean(serializer, restrictions, UserManager.DISALLOW_SMS);
         writeBoolean(serializer, restrictions, UserManager.DISALLOW_CREATE_WINDOWS);
+        writeBoolean(serializer, restrictions, UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
+        writeBoolean(serializer, restrictions, UserManager.DISALLOW_OUTGOING_BEAM);
         serializer.endTag(null, TAG_RESTRICTIONS);
     }
 
@@ -871,6 +876,7 @@
         int profileGroupId = UserInfo.NO_PROFILE_GROUP_ID;
         long lastAttemptTime = 0L;
         boolean partial = false;
+        boolean guestToRemove = false;
         Bundle restrictions = new Bundle();
 
         FileInputStream fis = null;
@@ -918,6 +924,10 @@
                 if ("true".equals(valueString)) {
                     partial = true;
                 }
+                valueString = parser.getAttributeValue(null, ATTR_GUEST_TO_REMOVE);
+                if ("true".equals(valueString)) {
+                    guestToRemove = true;
+                }
 
                 int outerDepth = parser.getDepth();
                 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -942,6 +952,7 @@
             userInfo.creationTime = creationTime;
             userInfo.lastLoggedInTime = lastLoggedInTime;
             userInfo.partial = partial;
+            userInfo.guestToRemove = guestToRemove;
             userInfo.profileGroupId = profileGroupId;
             mUserRestrictions.append(id, restrictions);
             if (salt != 0L) {
@@ -999,6 +1010,8 @@
         readBoolean(parser, restrictions, UserManager.DISALLOW_OUTGOING_CALLS);
         readBoolean(parser, restrictions, UserManager.DISALLOW_SMS);
         readBoolean(parser, restrictions, UserManager.DISALLOW_CREATE_WINDOWS);
+        readBoolean(parser, restrictions, UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
+        readBoolean(parser, restrictions, UserManager.DISALLOW_OUTGOING_BEAM);
     }
 
     private void readBoolean(XmlPullParser parser, Bundle restrictions,
@@ -1119,7 +1132,7 @@
                         return null;
                     }
                     // If we're adding a guest and there already exists one, bail.
-                    if (isGuest && numberOfUsersOfTypeLocked(UserInfo.FLAG_GUEST, true) > 0) {
+                    if (isGuest && findCurrentGuestUserLocked() != null) {
                         return null;
                     }
                     // Limit number of managed profiles that can be created
@@ -1180,6 +1193,23 @@
     }
 
     /**
+     * Find the current guest user. If the Guest user is partial,
+     * then do not include it in the results as it is about to die.
+     * This is different than {@link #numberOfUsersOfTypeLocked(int, boolean)} due to
+     * the special handling of Guests being removed.
+     */
+    private UserInfo findCurrentGuestUserLocked() {
+        final int size = mUsers.size();
+        for (int i = 0; i < size; i++) {
+            final UserInfo user = mUsers.valueAt(i);
+            if (user.isGuest() && !user.guestToRemove && !mRemovingUserIds.get(user.id)) {
+                return user;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Mark this guest user for deletion to allow us to create another guest
      * and switch to that user before actually removing this guest.
      * @param userHandle the userid of the current guest
@@ -1204,14 +1234,15 @@
                 if (!user.isGuest()) {
                     return false;
                 }
-                // Set this to a partially created user, so that the user will be purged
-                // on next startup, in case the runtime stops now before stopping and
-                // removing the user completely.
-                user.partial = true;
+                // We set this to a guest user that is to be removed. This is a temporary state
+                // where we are allowed to add new Guest users, even if this one is still not
+                // removed. This user will still show up in getUserInfo() calls.
+                // If we don't get around to removing this Guest user, it will be purged on next
+                // startup.
+                user.guestToRemove = true;
                 // Mark it as disabled, so that it isn't returned any more when
                 // profiles are queried.
                 user.flags |= UserInfo.FLAG_DISABLED;
-                user.flags &= ~UserInfo.FLAG_GUEST;
                 writeUserLocked(user);
             }
         } finally {
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 48e46db..fefbe0a 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -33,6 +33,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
@@ -48,6 +49,7 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.service.trust.TrustAgentService;
 import android.util.ArraySet;
 import android.util.AttributeSet;
@@ -97,6 +99,7 @@
     private final SparseBooleanArray mUserHasAuthenticatedSinceBoot = new SparseBooleanArray();
     /* package */ final TrustArchive mArchive = new TrustArchive();
     private final Context mContext;
+    private final LockPatternUtils mLockPatternUtils;
 
     private UserManager mUserManager;
 
@@ -104,6 +107,7 @@
         super(context);
         mContext = context;
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        mLockPatternUtils = new LockPatternUtils(context);
     }
 
     @Override
@@ -116,6 +120,7 @@
         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY && !isSafeMode()) {
             mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
             mReceiver.register(mContext);
+            maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_OWNER);
             refreshAgentList(UserHandle.USER_ALL);
         }
     }
@@ -173,12 +178,13 @@
             userInfos = new ArrayList<>();
             userInfos.add(mUserManager.getUserInfo(userId));
         }
-        LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext);
+        LockPatternUtils lockPatternUtils = mLockPatternUtils;
 
         ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
         obsoleteAgents.addAll(mActiveAgents);
 
         for (UserInfo userInfo : userInfos) {
+            if (!userInfo.supportsSwitchTo()) continue;
             if (lockPatternUtils.getKeyguardStoredPasswordQuality(userInfo.id)
                     == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) continue;
             if (!mUserHasAuthenticatedSinceBoot.get(userInfo.id)) continue;
@@ -191,22 +197,11 @@
             if (enabledAgents == null) {
                 continue;
             }
-            List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
-                    PackageManager.GET_META_DATA, userInfo.id);
+            List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
             for (ResolveInfo resolveInfo : resolveInfos) {
-                if (resolveInfo.serviceInfo == null) continue;
-
-                String packageName = resolveInfo.serviceInfo.packageName;
-                if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
-                        != PackageManager.PERMISSION_GRANTED) {
-                    Log.w(TAG, "Skipping agent because package " + packageName
-                            + " does not have permission " + PERMISSION_PROVIDE_AGENT + ".");
-                    continue;
-                }
-
                 ComponentName name = getComponentName(resolveInfo);
-                if (!enabledAgents.contains(name)) continue;
 
+                if (!enabledAgents.contains(name)) continue;
                 if (disableTrustAgents) {
                     List<String> features =
                             dpm.getTrustAgentFeaturesEnabled(null /* admin */, name);
@@ -349,6 +344,54 @@
         return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
     }
 
+    private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
+        if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
+            return;
+        }
+        PackageManager pm = mContext.getPackageManager();
+        List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
+        ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
+        for (ResolveInfo resolveInfo : resolveInfos) {
+            ComponentName componentName = getComponentName(resolveInfo);
+            int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
+            if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+                Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
+                        + "is not a system package.");
+                continue;
+            }
+            discoveredAgents.add(componentName);
+        }
+
+        List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
+        if (previouslyEnabledAgents != null) {
+            discoveredAgents.addAll(previouslyEnabledAgents);
+        }
+        utils.setEnabledTrustAgents(discoveredAgents, userId);
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
+    }
+
+    private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
+        List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
+                0 /* flags */, userId);
+        ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
+        for (ResolveInfo resolveInfo : resolveInfos) {
+            if (resolveInfo.serviceInfo == null) continue;
+            if (resolveInfo.serviceInfo.applicationInfo == null) continue;
+            String packageName = resolveInfo.serviceInfo.packageName;
+            if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
+                    != PackageManager.PERMISSION_GRANTED) {
+                ComponentName name = getComponentName(resolveInfo);
+                Log.w(TAG, "Skipping agent " + name + " because package does not have"
+                        + " permission " + PERMISSION_PROVIDE_AGENT + ".");
+                continue;
+            }
+            allowedAgents.add(resolveInfo);
+        }
+        return allowedAgents;
+    }
+
     // Agent dispatch and aggregation
 
     private boolean aggregateIsTrusted(int userId) {
@@ -421,6 +464,7 @@
             }
         }
         mTrustListeners.add(listener);
+        updateTrustAll();
     }
 
     private void removeListener(ITrustListener listener) {
@@ -623,12 +667,19 @@
 
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
-                    intent.getAction())) {
+            String action = intent.getAction();
+            if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
                 refreshAgentList(getSendingUserId());
                 updateDevicePolicyFeatures();
-            } else if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())) {
+            } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
                 updateUserHasAuthenticated(getSendingUserId());
+            } else if (Intent.ACTION_USER_ADDED.equals(action)) {
+                int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
+                if (userId > 0) {
+                    maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
+                } else {
+                    Log.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
+                }
             }
         }
 
@@ -636,6 +687,7 @@
             IntentFilter filter = new IntentFilter();
             filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
             filter.addAction(Intent.ACTION_USER_PRESENT);
+            filter.addAction(Intent.ACTION_USER_ADDED);
             context.registerReceiverAsUser(this,
                     UserHandle.ALL,
                     filter,
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 802df95..e1ade63 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -42,6 +42,7 @@
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Point;
+import android.graphics.Rect;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Environment;
@@ -206,6 +207,8 @@
         int width = -1;
         int height = -1;
 
+        final Rect padding = new Rect(0, 0, 0, 0);
+
         WallpaperData(int userId) {
             this.userId = userId;
             wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER);
@@ -222,6 +225,7 @@
         IRemoteCallback mReply;
 
         boolean mDimensionsChanged = false;
+        boolean mPaddingChanged = false;
 
         public WallpaperConnection(WallpaperInfo info, WallpaperData wallpaper) {
             mInfo = info;
@@ -283,6 +287,14 @@
                     }
                     mDimensionsChanged = false;
                 }
+                if (mPaddingChanged) {
+                    try {
+                        mEngine.setDisplayPadding(mWallpaper.padding);
+                    } catch (RemoteException e) {
+                        Slog.w(TAG, "Failed to set wallpaper padding", e);
+                    }
+                    mPaddingChanged = false;
+                }
             }
         }
 
@@ -719,6 +731,40 @@
         }
     }
 
+    public void setDisplayPadding(Rect padding) {
+        checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS);
+        synchronized (mLock) {
+            int userId = UserHandle.getCallingUserId();
+            WallpaperData wallpaper = mWallpaperMap.get(userId);
+            if (wallpaper == null) {
+                throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
+            }
+            if (padding.left < 0 || padding.top < 0 || padding.right < 0 || padding.bottom < 0) {
+                throw new IllegalArgumentException("padding must be positive: " + padding);
+            }
+
+            if (!padding.equals(wallpaper.padding)) {
+                wallpaper.padding.set(padding);
+                saveSettingsLocked(wallpaper);
+                if (mCurrentUserId != userId) return; // Don't change the properties now
+                if (wallpaper.connection != null) {
+                    if (wallpaper.connection.mEngine != null) {
+                        try {
+                            wallpaper.connection.mEngine.setDisplayPadding(padding);
+                        } catch (RemoteException e) {
+                        }
+                        notifyCallbacksLocked(wallpaper);
+                    } else if (wallpaper.connection.mService != null) {
+                        // We've attached to the service but the engine hasn't attached back to us
+                        // yet. This means it will be created with the previous dimensions, so we
+                        // need to update it to the new dimensions once it attaches.
+                        wallpaper.connection.mPaddingChanged = true;
+                    }
+                }
+            }
+        }
+    }
+
     public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
             Bundle outParams) {
         synchronized (mLock) {
@@ -1006,7 +1052,7 @@
         try {
             conn.mService.attach(conn, conn.mToken,
                     WindowManager.LayoutParams.TYPE_WALLPAPER, false,
-                    wallpaper.width, wallpaper.height);
+                    wallpaper.width, wallpaper.height, wallpaper.padding);
         } catch (RemoteException e) {
             Slog.w(TAG, "Failed attaching wallpaper; clearing", e);
             if (!wallpaper.wallpaperUpdating) {
@@ -1055,6 +1101,18 @@
             out.startTag(null, "wp");
             out.attribute(null, "width", Integer.toString(wallpaper.width));
             out.attribute(null, "height", Integer.toString(wallpaper.height));
+            if (wallpaper.padding.left != 0) {
+                out.attribute(null, "paddingLeft", Integer.toString(wallpaper.padding.left));
+            }
+            if (wallpaper.padding.top != 0) {
+                out.attribute(null, "paddingTop", Integer.toString(wallpaper.padding.top));
+            }
+            if (wallpaper.padding.right != 0) {
+                out.attribute(null, "paddingRight", Integer.toString(wallpaper.padding.right));
+            }
+            if (wallpaper.padding.bottom != 0) {
+                out.attribute(null, "paddingBottom", Integer.toString(wallpaper.padding.bottom));
+            }
             out.attribute(null, "name", wallpaper.name);
             if (wallpaper.wallpaperComponent != null
                     && !wallpaper.wallpaperComponent.equals(mImageWallpaper)) {
@@ -1091,6 +1149,14 @@
         }
     }
 
+    private int getAttributeInt(XmlPullParser parser, String name, int defValue) {
+        String value = parser.getAttributeValue(null, name);
+        if (value == null) {
+            return defValue;
+        }
+        return Integer.parseInt(value);
+    }
+
     private void loadSettingsLocked(int userId) {
         if (DEBUG) Slog.v(TAG, "loadSettingsLocked");
         
@@ -1121,6 +1187,10 @@
                         wallpaper.width = Integer.parseInt(parser.getAttributeValue(null, "width"));
                         wallpaper.height = Integer.parseInt(parser
                                 .getAttributeValue(null, "height"));
+                        wallpaper.padding.left = getAttributeInt(parser, "paddingLeft", 0);
+                        wallpaper.padding.top = getAttributeInt(parser, "paddingTop", 0);
+                        wallpaper.padding.right = getAttributeInt(parser, "paddingRight", 0);
+                        wallpaper.padding.bottom = getAttributeInt(parser, "paddingBottom", 0);
                         wallpaper.name = parser.getAttributeValue(null, "name");
                         String comp = parser.getAttributeValue(null, "component");
                         wallpaper.nextWallpaperComponent = comp != null
@@ -1167,6 +1237,7 @@
         if (!success) {
             wallpaper.width = -1;
             wallpaper.height = -1;
+            wallpaper.padding.set(0, 0, 0, 0);
             wallpaper.name = "";
         }
 
@@ -1330,13 +1401,12 @@
                 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
                 pw.println(" User " + wallpaper.userId + ":");
                 pw.print("  mWidth=");
-                pw.print(wallpaper.width);
-                pw.print(" mHeight=");
-                pw.println(wallpaper.height);
-                pw.print("  mName=");
-                pw.println(wallpaper.name);
-                pw.print("  mWallpaperComponent=");
-                pw.println(wallpaper.wallpaperComponent);
+                    pw.print(wallpaper.width);
+                    pw.print(" mHeight=");
+                    pw.println(wallpaper.height);
+                pw.print("  mPadding="); pw.println(wallpaper.padding);
+                pw.print("  mName=");  pw.println(wallpaper.name);
+                pw.print("  mWallpaperComponent="); pw.println(wallpaper.wallpaperComponent);
                 if (wallpaper.connection != null) {
                     WallpaperConnection conn = wallpaper.connection;
                     pw.print("  Wallpaper connection ");
diff --git a/services/core/java/com/android/server/wm/CircularDisplayMask.java b/services/core/java/com/android/server/wm/CircularDisplayMask.java
index 64b852b..a7d41fa 100644
--- a/services/core/java/com/android/server/wm/CircularDisplayMask.java
+++ b/services/core/java/com/android/server/wm/CircularDisplayMask.java
@@ -63,8 +63,14 @@
 
         SurfaceControl ctrl = null;
         try {
-            ctrl = new SurfaceControl(session, "CircularDisplayMask",
-                mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
+            if (WindowManagerService.DEBUG_SURFACE_TRACE) {
+                ctrl = new WindowStateAnimator.SurfaceTrace(session, "CircularDisplayMask",
+                        mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT,
+                        SurfaceControl.HIDDEN);
+            } else {
+                ctrl = new SurfaceControl(session, "CircularDisplayMask", mScreenSize.x,
+                        mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
+            }
             ctrl.setLayerStack(display.getLayerStack());
             ctrl.setLayer(zOrder);
             ctrl.setPosition(0, 0);
diff --git a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
new file mode 100644
index 0000000..62f2b48
--- /dev/null
+++ b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.graphics.PorterDuff;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.Slog;
+import android.view.Display;
+import android.view.Surface;
+import android.view.Surface.OutOfResourcesException;
+import android.view.SurfaceControl;
+import android.view.SurfaceSession;
+
+class EmulatorDisplayOverlay {
+    private static final String TAG = "EmulatorDisplayOverlay";
+
+    // Display dimensions
+    private Point mScreenSize;
+
+    private final SurfaceControl mSurfaceControl;
+    private final Surface mSurface = new Surface();
+    private int mLastDW;
+    private int mLastDH;
+    private boolean mDrawNeeded;
+    private Drawable mOverlay;
+    private int mRotation;
+    private boolean mVisible;
+
+    public EmulatorDisplayOverlay(Context context, Display display, SurfaceSession session,
+            int zOrder) {
+        mScreenSize = new Point();
+        display.getSize(mScreenSize);
+
+        SurfaceControl ctrl = null;
+        try {
+            if (WindowManagerService.DEBUG_SURFACE_TRACE) {
+                ctrl = new WindowStateAnimator.SurfaceTrace(session, "EmulatorDisplayOverlay",
+                        mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT,
+                        SurfaceControl.HIDDEN);
+            } else {
+                ctrl = new SurfaceControl(session, "EmulatorDisplayOverlay", mScreenSize.x,
+                        mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
+            }
+            ctrl.setLayerStack(display.getLayerStack());
+            ctrl.setLayer(zOrder);
+            ctrl.setPosition(0, 0);
+            ctrl.show();
+            mSurface.copyFrom(ctrl);
+        } catch (OutOfResourcesException e) {
+        }
+        mSurfaceControl = ctrl;
+        mDrawNeeded = true;
+        mOverlay = context.getDrawable(
+                com.android.internal.R.drawable.emulator_circular_window_overlay);
+    }
+
+    private void drawIfNeeded() {
+        if (!mDrawNeeded || !mVisible) {
+            return;
+        }
+        mDrawNeeded = false;
+
+        Rect dirty = new Rect(0, 0, mScreenSize.x, mScreenSize.y);
+        Canvas c = null;
+        try {
+            c = mSurface.lockCanvas(dirty);
+        } catch (IllegalArgumentException e) {
+        } catch (OutOfResourcesException e) {
+        }
+        if (c == null) {
+            return;
+        }
+        c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.SRC);
+        mSurfaceControl.setPosition(0, 0);
+        mOverlay.setBounds(0, 0, mScreenSize.x, mScreenSize.y);
+        mOverlay.draw(c);
+        mSurface.unlockCanvasAndPost(c);
+    }
+
+    // Note: caller responsible for being inside
+    // Surface.openTransaction() / closeTransaction()
+    public void setVisibility(boolean on) {
+        if (mSurfaceControl == null) {
+            return;
+        }
+        mVisible = on;
+        drawIfNeeded();
+        if (on) {
+            mSurfaceControl.show();
+        } else {
+            mSurfaceControl.hide();
+        }
+    }
+
+    void positionSurface(int dw, int dh, int rotation) {
+        if (mLastDW == dw && mLastDH == dh && mRotation == rotation) {
+            return;
+        }
+        mLastDW = dw;
+        mLastDH = dh;
+        mDrawNeeded = true;
+        mRotation = rotation;
+        drawIfNeeded();
+    }
+
+}
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index f2703ad..d737e7f 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -415,6 +415,18 @@
         mService.wallpaperOffsetsComplete(window);
     }
 
+    public void setWallpaperDisplayOffset(IBinder window, int x, int y) {
+        synchronized(mService.mWindowMap) {
+            long ident = Binder.clearCallingIdentity();
+            try {
+                mService.setWindowWallpaperDisplayOffsetLocked(
+                        mService.windowForClientLocked(this, window, true), x, y);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
+
     public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
             int z, Bundle extras, boolean sync) {
         synchronized(mService.mWindowMap) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 55c6d81..10ab6b5 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -20,6 +20,7 @@
 
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 import android.app.AppOpsManager;
+import android.os.Build;
 import android.util.ArraySet;
 import android.util.TimeUtils;
 import android.view.IWindowId;
@@ -295,6 +296,8 @@
     private static final int SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN =
             View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
 
+    private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular";
+
     final private KeyguardDisableHandler mKeyguardDisableHandler;
 
     final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -441,6 +444,7 @@
     Watermark mWatermark;
     StrictModeFlash mStrictModeFlash;
     CircularDisplayMask mCircularDisplayMask;
+    EmulatorDisplayOverlay mEmulatorDisplayOverlay;
     FocusedStackFrame mFocusedStackFrame;
 
     int mFocusedStackLayer;
@@ -572,6 +576,8 @@
     float mLastWallpaperY = -1;
     float mLastWallpaperXStep = -1;
     float mLastWallpaperYStep = -1;
+    int mLastWallpaperDisplayOffsetX = Integer.MIN_VALUE;
+    int mLastWallpaperDisplayOffsetY = Integer.MIN_VALUE;
     // This is set when we are waiting for a wallpaper to tell us it is done
     // changing its scroll position.
     WindowState mWaitingOnWallpaper;
@@ -879,6 +885,7 @@
         }
 
         showCircularDisplayMaskIfNeeded();
+        showEmulatorDisplayOverlayIfNeeded();
     }
 
     public InputMonitor getInputMonitor() {
@@ -1892,6 +1899,12 @@
                 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
                 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
             }
+            if (mWallpaperTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
+                mLastWallpaperDisplayOffsetX = mWallpaperTarget.mWallpaperDisplayOffsetX;
+            }
+            if (mWallpaperTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
+                mLastWallpaperDisplayOffsetY = mWallpaperTarget.mWallpaperDisplayOffsetY;
+            }
         }
 
         // Start stepping backwards from here, ensuring that our wallpaper windows
@@ -2030,6 +2043,9 @@
         float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
         int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
         int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
+        if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
+            offset += mLastWallpaperDisplayOffsetX;
+        }
         changed = wallpaperWin.mXOffset != offset;
         if (changed) {
             if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
@@ -2046,6 +2062,9 @@
         float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
         int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
         offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
+        if (mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
+            offset += mLastWallpaperDisplayOffsetY;
+        }
         if (wallpaperWin.mYOffset != offset) {
             if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
                     + wallpaperWin + " y: " + offset);
@@ -2130,6 +2149,16 @@
             } else if (changingTarget.mWallpaperY >= 0) {
                 mLastWallpaperY = changingTarget.mWallpaperY;
             }
+            if (target.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
+                mLastWallpaperDisplayOffsetX = target.mWallpaperDisplayOffsetX;
+            } else if (changingTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
+                mLastWallpaperDisplayOffsetX = changingTarget.mWallpaperDisplayOffsetX;
+            }
+            if (target.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
+                mLastWallpaperDisplayOffsetY = target.mWallpaperDisplayOffsetY;
+            } else if (changingTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
+                mLastWallpaperDisplayOffsetY = changingTarget.mWallpaperDisplayOffsetY;
+            }
         }
 
         int curTokenIndex = mWallpaperTokens.size();
@@ -2826,6 +2855,14 @@
         }
     }
 
+    public void setWindowWallpaperDisplayOffsetLocked(WindowState window, int x, int y) {
+        if (window.mWallpaperDisplayOffsetX != x || window.mWallpaperDisplayOffsetY != y)  {
+            window.mWallpaperDisplayOffsetX = x;
+            window.mWallpaperDisplayOffsetY = y;
+            updateWallpaperOffsetLocked(window, true);
+        }
+    }
+
     public Bundle sendWindowWallpaperCommandLocked(WindowState window,
             String action, int x, int y, int z, Bundle extras, boolean sync) {
         if (window == mWallpaperTarget || window == mLowerWallpaperTarget
@@ -5735,7 +5772,16 @@
                 com.android.internal.R.bool.config_windowIsRound)
                 && mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_windowShowCircularMask)) {
-            mH.sendMessage(mH.obtainMessage(H.SHOW_DISPLAY_MASK));
+            mH.sendMessage(mH.obtainMessage(H.SHOW_CIRCULAR_DISPLAY_MASK));
+        }
+    }
+
+    public void showEmulatorDisplayOverlayIfNeeded() {
+        if (mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_windowEnableCircularEmulatorDisplayOverlay)
+                && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false)
+                && Build.HARDWARE.contains("goldfish")) {
+            mH.sendMessage(mH.obtainMessage(H.SHOW_EMULATOR_DISPLAY_OVERLAY));
         }
     }
 
@@ -5743,12 +5789,12 @@
         synchronized(mWindowMap) {
 
             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
-                    ">>> OPEN TRANSACTION showDisplayMask");
+                    ">>> OPEN TRANSACTION showCircularMask");
             SurfaceControl.openTransaction();
             try {
                 // TODO(multi-display): support multiple displays
                 if (mCircularDisplayMask == null) {
-                    int screenOffset = (int) mContext.getResources().getDimensionPixelSize(
+                    int screenOffset = mContext.getResources().getDimensionPixelSize(
                             com.android.internal.R.dimen.circular_display_mask_offset);
 
                     mCircularDisplayMask = new CircularDisplayMask(
@@ -5762,7 +5808,32 @@
             } finally {
                 SurfaceControl.closeTransaction();
                 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
-                        "<<< CLOSE TRANSACTION showDisplayMask");
+                        "<<< CLOSE TRANSACTION showCircularMask");
+            }
+        }
+    }
+
+    public void showEmulatorDisplayOverlay() {
+        synchronized(mWindowMap) {
+
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+                    ">>> OPEN TRANSACTION showEmulatorDisplayOverlay");
+            SurfaceControl.openTransaction();
+            try {
+                if (mEmulatorDisplayOverlay == null) {
+                    mEmulatorDisplayOverlay = new EmulatorDisplayOverlay(
+                            mContext,
+                            getDefaultDisplayContentLocked().getDisplay(),
+                            mFxSession,
+                            mPolicy.windowTypeToLayerLw(
+                                    WindowManager.LayoutParams.TYPE_POINTER)
+                                    * TYPE_LAYER_MULTIPLIER + 10);
+                }
+                mEmulatorDisplayOverlay.setVisibility(true);
+            } finally {
+                SurfaceControl.closeTransaction();
+                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+                        "<<< CLOSE TRANSACTION showEmulatorDisplayOverlay");
             }
         }
     }
@@ -5860,7 +5931,7 @@
     @Override
     public Bitmap screenshotApplications(IBinder appToken, int displayId, int width,
             int height, boolean force565) {
-        if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
+        if (!checkCallingPermission(Manifest.permission.READ_FRAME_BUFFER,
                 "screenshotApplications()")) {
             throw new SecurityException("Requires READ_FRAME_BUFFER permission");
         }
@@ -5880,7 +5951,7 @@
             return null;
         }
 
-        Bitmap rawss = null;
+        Bitmap bm = null;
 
         int maxLayer = 0;
         final Rect frame = new Rect();
@@ -6021,10 +6092,8 @@
 
                 // The screenshot API does not apply the current screen rotation.
                 rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
+
                 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
-                    final int tmp = width;
-                    width = height;
-                    height = tmp;
                     rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
                 }
 
@@ -6050,9 +6119,9 @@
                 if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG,
                         "Taking screenshot while rotating");
 
-                rawss = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer,
-                        inRotation);
-                if (rawss == null) {
+                bm = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer,
+                        inRotation, rot);
+                if (bm == null) {
                     Slog.w(TAG, "Screenshot failure taking screenshot for (" + dw + "x" + dh
                             + ") to layer " + maxLayer);
                     return null;
@@ -6062,17 +6131,6 @@
             break;
         }
 
-        Bitmap bm = Bitmap.createBitmap(width, height, force565 ?
-                Config.RGB_565 : rawss.getConfig());
-        if (DEBUG_SCREENSHOT) {
-            bm.eraseColor(0xFF000000);
-        }
-        Matrix matrix = new Matrix();
-        ScreenRotationAnimation.createRotationMatrix(rot, width, height, matrix);
-        Canvas canvas = new Canvas(bm);
-        canvas.drawBitmap(rawss, matrix, null);
-        canvas.setBitmap(null);
-
         if (DEBUG_SCREENSHOT) {
             // TEST IF IT's ALL BLACK
             int[] buffer = new int[bm.getWidth() * bm.getHeight()];
@@ -6093,9 +6151,12 @@
             }
         }
 
-        rawss.recycle();
-
-        return bm;
+        // Copy the screenshot bitmap to another buffer so that the gralloc backed
+        // bitmap will not have a long lifetime. Gralloc memory can be pinned or
+        // duplicated and might have a higher cost than a skia backed buffer.
+        Bitmap ret = bm.copy(bm.getConfig(),true);
+        bm.recycle();
+        return ret;
     }
 
     /**
@@ -7393,7 +7454,8 @@
 
         public static final int NEW_ANIMATOR_SCALE = 34;
 
-        public static final int SHOW_DISPLAY_MASK = 35;
+        public static final int SHOW_CIRCULAR_DISPLAY_MASK = 35;
+        public static final int SHOW_EMULATOR_DISPLAY_OVERLAY = 36;
 
         @Override
         public void handleMessage(Message msg) {
@@ -7789,11 +7851,16 @@
                     break;
                 }
 
-                case SHOW_DISPLAY_MASK: {
+                case SHOW_CIRCULAR_DISPLAY_MASK: {
                     showCircularMask();
                     break;
                 }
 
+                case SHOW_EMULATOR_DISPLAY_OVERLAY: {
+                    showEmulatorDisplayOverlay();
+                    break;
+                }
+
                 case DO_ANIMATION_CALLBACK: {
                     try {
                         ((IRemoteCallback)msg.obj).sendResult(null);
@@ -9363,6 +9430,9 @@
             if (mCircularDisplayMask != null) {
                 mCircularDisplayMask.positionSurface(defaultDw, defaultDh, mRotation);
             }
+            if (mEmulatorDisplayOverlay != null) {
+                mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh, mRotation);
+            }
 
             boolean focusDisplayed = false;
 
@@ -10889,6 +10959,12 @@
             }
             pw.print("  mLastWallpaperX="); pw.print(mLastWallpaperX);
                     pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
+            if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE
+                    || mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
+                pw.print("  mLastWallpaperDisplayOffsetX="); pw.print(mLastWallpaperDisplayOffsetX);
+                        pw.print(" mLastWallpaperDisplayOffsetY=");
+                        pw.println(mLastWallpaperDisplayOffsetY);
+            }
             if (mInputMethodAnimLayerAdjustment != 0 ||
                     mWallpaperAnimLayerAdjustment != 0) {
                 pw.print("  mInputMethodAnimLayerAdjustment=");
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index e74de38..0baa2be 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -247,6 +247,11 @@
     float mWallpaperXStep = -1;
     float mWallpaperYStep = -1;
 
+    // If a window showing a wallpaper: a raw pixel offset to forcibly apply
+    // to its window; if a wallpaper window: not used.
+    int mWallpaperDisplayOffsetX = Integer.MIN_VALUE;
+    int mWallpaperDisplayOffsetY = Integer.MIN_VALUE;
+
     // Wallpaper windows: pixels offset based on above variables.
     int mXOffset;
     int mYOffset;
@@ -1584,6 +1589,13 @@
             pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
                     pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
         }
+        if (mWallpaperDisplayOffsetX != Integer.MIN_VALUE
+                || mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
+            pw.print(prefix); pw.print("mWallpaperDisplayOffsetX=");
+                    pw.print(mWallpaperDisplayOffsetX);
+                    pw.print(" mWallpaperDisplayOffsetY=");
+                    pw.println(mWallpaperDisplayOffsetY);
+        }
     }
 
     String makeInputChannelName() {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index a871522..dd611ce 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1526,8 +1526,9 @@
     }
 
     void setWallpaperOffset(RectF shownFrame) {
-        final int left = (int) shownFrame.left;
-        final int top = (int) shownFrame.top;
+        final LayoutParams attrs = mWin.getAttrs();
+        final int left = ((int) shownFrame.left) - attrs.surfaceInsets.left;
+        final int top = ((int) shownFrame.top) - attrs.surfaceInsets.top;
         if (mSurfaceX != left || mSurfaceY != top) {
             mSurfaceX = left;
             mSurfaceY = top;
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index 1f377c7..d81cdd9 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -11,7 +11,6 @@
     $(LOCAL_REL_DIR)/com_android_server_connectivity_Vpn.cpp \
     $(LOCAL_REL_DIR)/com_android_server_ConsumerIrService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_hdmi_HdmiCecController.cpp \
-    $(LOCAL_REL_DIR)/com_android_server_hdmi_HdmiMhlController.cpp \
     $(LOCAL_REL_DIR)/com_android_server_input_InputApplicationHandle.cpp \
     $(LOCAL_REL_DIR)/com_android_server_input_InputManagerService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_input_InputWindowHandle.cpp \
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 39b70a8..7b2e408 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -38,7 +38,6 @@
 int register_android_server_location_FlpHardwareProvider(JNIEnv* env);
 int register_android_server_connectivity_Vpn(JNIEnv* env);
 int register_android_server_hdmi_HdmiCecController(JNIEnv* env);
-int register_android_server_hdmi_HdmiMhlController(JNIEnv* env);
 int register_android_server_tv_TvInputHal(JNIEnv* env);
 int register_android_server_PersistentDataBlockService(JNIEnv* env);
 int register_android_server_fingerprint_FingerprintService(JNIEnv* env);
@@ -76,7 +75,6 @@
     register_android_server_ConsumerIrService(env);
     register_android_server_BatteryStatsService(env);
     register_android_server_hdmi_HdmiCecController(env);
-    register_android_server_hdmi_HdmiMhlController(env);
     register_android_server_tv_TvInputHal(env);
     register_android_server_PersistentDataBlockService(env);
     register_android_server_fingerprint_FingerprintService(env);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
index 376230b..ad38b22 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
@@ -67,7 +67,7 @@
     final ModuleProperties moduleProperties;
 
     /** The properties for the DSP module */
-    private final SoundTriggerModule mModule;
+    private SoundTriggerModule mModule;
     private final Object mLock = new Object();
     private final Context mContext;
     private final TelephonyManager mTelephonyManager;
@@ -105,7 +105,6 @@
         } else {
             // TODO: Figure out how to determine which module corresponds to the DSP hardware.
             moduleProperties = modules.get(0);
-            mModule = SoundTrigger.attachModule(moduleProperties.id, this, null);
         }
     }
 
@@ -155,10 +154,17 @@
                 mIsPowerSaveMode = mPowerManager.isPowerSaveMode();
             }
 
-            if (moduleProperties == null || mModule == null) {
+            if (moduleProperties == null) {
                 Slog.w(TAG, "Attempting startRecognition without the capability");
                 return STATUS_ERROR;
             }
+            if (mModule == null) {
+                mModule = SoundTrigger.attachModule(moduleProperties.id, this, null);
+                if (mModule == null) {
+                    Slog.w(TAG, "startRecognition cannot attach to sound trigger module");
+                    return STATUS_ERROR;
+                }
+            }
 
             if (mCurrentSoundModelHandle != INVALID_VALUE
                     && !soundModel.uuid.equals(mCurrentSoundModelUuid)) {
@@ -446,6 +452,10 @@
             Slog.w(TAG, "RemoteException in onError", e);
         } finally {
             internalClearStateLocked();
+            if (mModule != null) {
+                mModule.detach();
+                mModule = null;
+            }
         }
     }
 
diff --git a/telecomm/java/android/telecomm/PhoneAccount.java b/telecomm/java/android/telecomm/PhoneAccount.java
index d3da2ec..f709a86 100644
--- a/telecomm/java/android/telecomm/PhoneAccount.java
+++ b/telecomm/java/android/telecomm/PhoneAccount.java
@@ -246,7 +246,6 @@
      * {@link #getAddress()}. For the majority of {@code PhoneAccount}s this should be registered
      * as {@code null}.  It is used by the system for SIM-based {@code PhoneAccount} registration
      * where {@link android.telephony.TelephonyManager#setLine1NumberForDisplay(String, String)}
-     * or {@link android.telephony.TelephonyManager#setLine1NumberForDisplay(long, String, String)}
      * has been used to alter the callback number.
      * <p>
      *
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 58d30f1..d0f355e 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -265,9 +265,9 @@
      * @return SubInfoRecord, maybe null
      * @hide - to be unhidden
      */
-    public static SubInfoRecord getSubInfoUsingSubId(long subId) {
+    public static SubInfoRecord getSubInfoForSubscriber(long subId) {
         if (!isValidSubId(subId)) {
-            logd("[getSubInfoUsingSubIdx]- invalid subId");
+            logd("[getSubInfoForSubscriberx]- invalid subId");
             return null;
         }
 
@@ -276,7 +276,7 @@
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                subInfo = iSub.getSubInfoUsingSubId(subId);
+                subInfo = iSub.getSubInfoForSubscriber(subId);
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -783,7 +783,7 @@
 
     /** @hide */
     public static SubInfoRecord getDefaultVoiceSubInfo() {
-        return getSubInfoUsingSubId(getDefaultVoiceSubId());
+        return getSubInfoForSubscriber(getDefaultVoiceSubId());
     }
 
     /** @hide */
@@ -826,7 +826,7 @@
 
     /** @hide */
     public static SubInfoRecord getDefaultSmsSubInfo() {
-        return getSubInfoUsingSubId(getDefaultSmsSubId());
+        return getSubInfoForSubscriber(getDefaultSmsSubId());
     }
 
     /** @hide */
@@ -866,7 +866,7 @@
 
     /** @hide */
     public static SubInfoRecord getDefaultDataSubInfo() {
-        return getSubInfoUsingSubId(getDefaultDataSubId());
+        return getSubInfoForSubscriber(getDefaultDataSubId());
     }
 
     /** @hide */
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 38b61ae..d53be4f 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -608,7 +608,7 @@
     public String getDeviceId(int slotId) {
         long[] subId = SubscriptionManager.getSubId(slotId);
         try {
-            return getSubscriberInfo().getDeviceIdUsingSubId(subId[0]);
+            return getSubscriberInfo().getDeviceIdForSubscriber(subId[0]);
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -639,7 +639,7 @@
     public String getImei(int slotId) {
         long[] subId = SubscriptionManager.getSubId(slotId);
         try {
-            return getSubscriberInfo().getImeiUsingSubId(subId[0]);
+            return getSubscriberInfo().getImeiForSubscriber(subId[0]);
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -703,7 +703,7 @@
     /** @hide */
     public void enableLocationUpdates(long subId) {
         try {
-            getITelephony().enableLocationUpdatesUsingSubId(subId);
+            getITelephony().enableLocationUpdatesForSubscriber(subId);
         } catch (RemoteException ex) {
         } catch (NullPointerException ex) {
         }
@@ -725,7 +725,7 @@
     /** @hide */
     public void disableLocationUpdates(long subId) {
         try {
-            getITelephony().disableLocationUpdatesUsingSubId(subId);
+            getITelephony().disableLocationUpdatesForSubscriber(subId);
         } catch (RemoteException ex) {
         } catch (NullPointerException ex) {
         }
@@ -793,7 +793,7 @@
         try{
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.getActivePhoneTypeUsingSubId(subId);
+                return telephony.getActivePhoneTypeForSubscriber(subId);
             } else {
                 // This can happen when the ITelephony interface is not up yet.
                 return getPhoneTypeFromProperty(subId);
@@ -1159,7 +1159,7 @@
        try {
            ITelephony telephony = getITelephony();
            if (telephony != null) {
-               return telephony.getNetworkTypeUsingSubId(subId);
+               return telephony.getNetworkTypeForSubscriber(subId);
            } else {
                // This can happen when the ITelephony interface is not up yet.
                return NETWORK_TYPE_UNKNOWN;
@@ -1213,7 +1213,7 @@
         try{
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.getDataNetworkTypeUsingSubId(subId);
+                return telephony.getDataNetworkTypeForSubscriber(subId);
             } else {
                 // This can happen when the ITelephony interface is not up yet.
                 return NETWORK_TYPE_UNKNOWN;
@@ -1245,7 +1245,7 @@
         try{
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.getVoiceNetworkTypeUsingSubId(subId);
+                return telephony.getVoiceNetworkTypeForSubscriber(subId);
             } else {
                 // This can happen when the ITelephony interface is not up yet.
                 return NETWORK_TYPE_UNKNOWN;
@@ -1572,7 +1572,7 @@
     /** {@hide} */
     public String getSimSerialNumber(long subId) {
         try {
-            return getSubscriberInfo().getIccSerialNumberUsingSubId(subId);
+            return getSubscriberInfo().getIccSerialNumberForSubscriber(subId);
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -1608,7 +1608,7 @@
     /** {@hide} */
     public int getLteOnCdmaMode(long subId) {
         try {
-            return getITelephony().getLteOnCdmaModeUsingSubId(subId);
+            return getITelephony().getLteOnCdmaModeForSubscriber(subId);
         } catch (RemoteException ex) {
             // Assume no ICC card if remote exception which shouldn't happen
             return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
@@ -1648,7 +1648,7 @@
     /** {@hide} */
     public String getSubscriberId(long subId) {
         try {
-            return getSubscriberInfo().getSubscriberIdUsingSubId(subId);
+            return getSubscriberInfo().getSubscriberIdForSubscriber(subId);
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -1687,7 +1687,7 @@
     /** {@hide} */
     public String getGroupIdLevel1(long subId) {
         try {
-            return getSubscriberInfo().getGroupIdLevel1UsingSubId(subId);
+            return getSubscriberInfo().getGroupIdLevel1ForSubscriber(subId);
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -1704,7 +1704,7 @@
      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
     public String getLine1Number() {
-        return getLine1Number(getDefaultSubscription());
+        return getLine1NumberForSubscriber(getDefaultSubscription());
     }
 
     /**
@@ -1717,7 +1717,7 @@
      * @param subId whose phone number for line 1 is returned
      */
     /** {@hide} */
-    public String getLine1Number(long subId) {
+    public String getLine1NumberForSubscriber(long subId) {
         String number = null;
         try {
             number = getITelephony().getLine1NumberForDisplay(subId);
@@ -1728,7 +1728,7 @@
             return number;
         }
         try {
-            return getSubscriberInfo().getLine1NumberUsingSubId(subId);
+            return getSubscriberInfo().getLine1NumberForSubscriber(subId);
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -1751,7 +1751,7 @@
      * @param number The dialing number
      */
     public void setLine1NumberForDisplay(String alphaTag, String number) {
-        setLine1NumberForDisplay(getDefaultSubscription(), alphaTag, number);
+        setLine1NumberForDisplayForSubscriber(getDefaultSubscription(), alphaTag, number);
     }
 
     /**
@@ -1767,10 +1767,11 @@
      * @param subId the subscriber that the alphatag and dialing number belongs to.
      * @param alphaTag alpha-tagging of the dailing nubmer
      * @param number The dialing number
+     * @hide
      */
-    public void setLine1NumberForDisplay(long subId, String alphaTag, String number) {
+    public void setLine1NumberForDisplayForSubscriber(long subId, String alphaTag, String number) {
         try {
-            getITelephony().setLine1NumberForDisplay(subId, alphaTag, number);
+            getITelephony().setLine1NumberForDisplayForSubscriber(subId, alphaTag, number);
         } catch (RemoteException ex) {
         } catch (NullPointerException ex) {
         }
@@ -1786,7 +1787,7 @@
      * nobody seems to call this.
      */
     public String getLine1AlphaTag() {
-        return getLine1AlphaTag(getDefaultSubscription());
+        return getLine1AlphaTagForSubscriber(getDefaultSubscription());
     }
 
     /**
@@ -1800,7 +1801,7 @@
      * nobody seems to call this.
      */
     /** {@hide} */
-    public String getLine1AlphaTag(long subId) {
+    public String getLine1AlphaTagForSubscriber(long subId) {
         String alphaTag = null;
         try {
             alphaTag = getITelephony().getLine1AlphaTagForDisplay(subId);
@@ -1811,7 +1812,7 @@
             return alphaTag;
         }
         try {
-            return getSubscriberInfo().getLine1AlphaTagUsingSubId(subId);
+            return getSubscriberInfo().getLine1AlphaTagForSubscriber(subId);
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -1845,7 +1846,7 @@
     /** {@hide} */
     public String getMsisdn(long subId) {
         try {
-            return getSubscriberInfo().getMsisdnUsingSubId(subId);
+            return getSubscriberInfo().getMsisdnForSubscriber(subId);
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -1875,7 +1876,7 @@
     /** {@hide} */
     public String getVoiceMailNumber(long subId) {
         try {
-            return getSubscriberInfo().getVoiceMailNumberUsingSubId(subId);
+            return getSubscriberInfo().getVoiceMailNumberForSubscriber(subId);
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -1907,7 +1908,7 @@
     /** {@hide} */
     public String getCompleteVoiceMailNumber(long subId) {
         try {
-            return getSubscriberInfo().getCompleteVoiceMailNumberUsingSubId(subId);
+            return getSubscriberInfo().getCompleteVoiceMailNumberForSubscriber(subId);
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -1937,7 +1938,7 @@
     /** {@hide} */
     public int getVoiceMessageCount(long subId) {
         try {
-            return getITelephony().getVoiceMessageCountUsingSubId(subId);
+            return getITelephony().getVoiceMessageCountForSubscriber(subId);
         } catch (RemoteException ex) {
             return 0;
         } catch (NullPointerException ex) {
@@ -1969,7 +1970,7 @@
     /** {@hide} */
     public String getVoiceMailAlphaTag(long subId) {
         try {
-            return getSubscriberInfo().getVoiceMailAlphaTagUsingSubId(subId);
+            return getSubscriberInfo().getVoiceMailAlphaTagForSubscriber(subId);
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -2059,7 +2060,7 @@
     /** {@hide} */
     public int getCallState(long subId) {
         try {
-            return getITelephony().getCallStateUsingSubId(subId);
+            return getITelephony().getCallStateForSubscriber(subId);
         } catch (RemoteException ex) {
             // the phone process is restarting.
             return CALL_STATE_IDLE;
@@ -2181,7 +2182,7 @@
         String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>";
         try {
             Boolean notifyNow = (getITelephony() != null);
-            sRegistry.listenUsingSubId(listener.mSubId, pkgForDebug, listener.callback, events, notifyNow);
+            sRegistry.listenForSubscriber(listener.mSubId, pkgForDebug, listener.callback, events, notifyNow);
         } catch (RemoteException ex) {
             // system process dead
         } catch (NullPointerException ex) {
@@ -2204,7 +2205,7 @@
     /** {@hide} */
     public int getCdmaEriIconIndex(long subId) {
         try {
-            return getITelephony().getCdmaEriIconIndexUsingSubId(subId);
+            return getITelephony().getCdmaEriIconIndexForSubscriber(subId);
         } catch (RemoteException ex) {
             // the phone process is restarting.
             return -1;
@@ -2232,7 +2233,7 @@
     /** {@hide} */
     public int getCdmaEriIconMode(long subId) {
         try {
-            return getITelephony().getCdmaEriIconModeUsingSubId(subId);
+            return getITelephony().getCdmaEriIconModeForSubscriber(subId);
         } catch (RemoteException ex) {
             // the phone process is restarting.
             return -1;
@@ -2257,7 +2258,7 @@
     /** {@hide} */
     public String getCdmaEriText(long subId) {
         try {
-            return getITelephony().getCdmaEriTextUsingSubId(subId);
+            return getITelephony().getCdmaEriTextForSubscriber(subId);
         } catch (RemoteException ex) {
             // the phone process is restarting.
             return null;
@@ -3369,7 +3370,7 @@
      * @hide
      */
     public void enableSimplifiedNetworkSettings(boolean enable) {
-        enableSimplifiedNetworkSettings(getDefaultSubscription(), enable);
+        enableSimplifiedNetworkSettingsForSubscriber(getDefaultSubscription(), enable);
     }
 
     /**
@@ -3384,9 +3385,9 @@
      * @param enable true means enabling the simplified UI.
      * @hide
      */
-    public void enableSimplifiedNetworkSettings(long subId, boolean enable) {
+    public void enableSimplifiedNetworkSettingsForSubscriber(long subId, boolean enable) {
         try {
-            getITelephony().enableSimplifiedNetworkSettings(subId, enable);
+            getITelephony().enableSimplifiedNetworkSettingsForSubscriber(subId, enable);
         } catch (RemoteException ex) {
         } catch (NullPointerException ex) {
         }
@@ -3402,7 +3403,7 @@
      * @hide
      */
     public boolean getSimplifiedNetworkSettingsEnabled() {
-        return getSimplifiedNetworkSettingsEnabled(getDefaultSubscription());
+        return getSimplifiedNetworkSettingsEnabledForSubscriber(getDefaultSubscription());
     }
 
     /**
@@ -3415,9 +3416,9 @@
      * @return true if the simplified UI is enabled.
      * @hide
      */
-    public boolean getSimplifiedNetworkSettingsEnabled(long subId) {
+    public boolean getSimplifiedNetworkSettingsEnabledForSubscriber(long subId) {
         try {
-            return getITelephony().getSimplifiedNetworkSettingsEnabled(subId);
+            return getITelephony().getSimplifiedNetworkSettingsEnabledForSubscriber(subId);
         } catch (RemoteException ex) {
         } catch (NullPointerException ex) {
         }
diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
index 552abaf..c203442 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
@@ -31,12 +31,12 @@
      * Retrieves the unique device ID of a subId for the device, e.g., IMEI
      * for GSM phones.
      */
-    String getDeviceIdUsingSubId(long subId);
+    String getDeviceIdForSubscriber(long subId);
 
     /**
      * Retrieves the IMEI.
      */
-    String getImeiUsingSubId(long subId);
+    String getImeiForSubscriber(long subId);
 
     /**
      * Retrieves the software version number for the device, e.g., IMEI/SV
@@ -52,7 +52,7 @@
     /**
      * Retrieves the unique subscriber ID of a given subId, e.g., IMSI for GSM phones.
      */
-    String getSubscriberIdUsingSubId(long subId);
+    String getSubscriberIdForSubscriber(long subId);
 
     /**
      * Retrieves the Group Identifier Level1 for GSM phones.
@@ -62,7 +62,7 @@
     /**
      * Retrieves the Group Identifier Level1 for GSM phones of a subId.
      */
-    String getGroupIdLevel1UsingSubId(long subId);
+    String getGroupIdLevel1ForSubscriber(long subId);
 
     /**
      * Retrieves the serial number of the ICC, if applicable.
@@ -72,7 +72,7 @@
     /**
      * Retrieves the serial number of a given subId.
      */
-    String getIccSerialNumberUsingSubId(long subId);
+    String getIccSerialNumberForSubscriber(long subId);
 
     /**
      * Retrieves the phone number string for line 1.
@@ -82,7 +82,7 @@
     /**
      * Retrieves the phone number string for line 1 of a subcription.
      */
-    String getLine1NumberUsingSubId(long subId);
+    String getLine1NumberForSubscriber(long subId);
 
 
     /**
@@ -93,7 +93,7 @@
     /**
      * Retrieves the alpha identifier for line 1 of a subId.
      */
-    String getLine1AlphaTagUsingSubId(long subId);
+    String getLine1AlphaTagForSubscriber(long subId);
 
 
     /**
@@ -104,7 +104,7 @@
     /**
      * Retrieves the Msisdn of a subId.
      */
-    String getMsisdnUsingSubId(long subId);
+    String getMsisdnForSubscriber(long subId);
 
     /**
      * Retrieves the voice mail number.
@@ -114,7 +114,7 @@
     /**
      * Retrieves the voice mail number of a given subId.
      */
-    String getVoiceMailNumberUsingSubId(long subId);
+    String getVoiceMailNumberForSubscriber(long subId);
 
     /**
      * Retrieves the complete voice mail number.
@@ -124,7 +124,7 @@
     /**
      * Retrieves the complete voice mail number for particular subId
      */
-    String getCompleteVoiceMailNumberUsingSubId(long subId);
+    String getCompleteVoiceMailNumberForSubscriber(long subId);
 
     /**
      * Retrieves the alpha identifier associated with the voice mail number.
@@ -135,7 +135,7 @@
      * Retrieves the alpha identifier associated with the voice mail number
      * of a subId.
      */
-    String getVoiceMailAlphaTagUsingSubId(long subId);
+    String getVoiceMailAlphaTagForSubscriber(long subId);
 
     /**
      * Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index abbdc4a..32bb8b4 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -47,7 +47,7 @@
      * @param subId the subId id.
      * @return list of SmsRawData of all sms on ICC
      */
-    List<SmsRawData> getAllMessagesFromIccEfUsingSubId(in long subId, String callingPkg);
+    List<SmsRawData> getAllMessagesFromIccEfForSubscriber(in long subId, String callingPkg);
 
     /**
      * Update the specified message on the ICC.
@@ -75,7 +75,7 @@
      * @return success or not
      *
      */
-     boolean updateMessageOnIccEfUsingSubId(in long subId, String callingPkg,
+     boolean updateMessageOnIccEfForSubscriber(in long subId, String callingPkg,
              int messageIndex, int newStatus, in byte[] pdu);
 
     /**
@@ -99,7 +99,7 @@
      * @return success or not
      *
      */
-    boolean copyMessageToIccEfUsingSubId(in long subId, String callingPkg, int status,
+    boolean copyMessageToIccEfForSubscriber(in long subId, String callingPkg, int status,
             in byte[] pdu, in byte[] smsc);
 
     /**
@@ -152,7 +152,7 @@
      *  raw pdu of the status report is in the extended data ("pdu").
      * @param subId the subId id.
      */
-    void sendDataUsingSubId(long subId, String callingPkg, in String destAddr,
+    void sendDataForSubscriber(long subId, String callingPkg, in String destAddr,
             in String scAddr, in int destPort, in byte[] data, in PendingIntent sentIntent,
             in PendingIntent deliveryIntent);
 
@@ -206,7 +206,7 @@
      *  raw pdu of the status report is in the extended data ("pdu").
      * @param subId the subId on which the SMS has to be sent.
      */
-    void sendTextUsingSubId(in long subId, String callingPkg, in String destAddr,
+    void sendTextForSubscriber(in long subId, String callingPkg, in String destAddr,
             in String scAddr, in String text, in PendingIntent sentIntent,
             in PendingIntent deliveryIntent);
 
@@ -283,7 +283,7 @@
      *   extended data ("pdu").
      * @param subId the subId on which the SMS has to be sent.
      */
-    void sendMultipartTextUsingSubId(in long subId, String callingPkg,
+    void sendMultipartTextForSubscriber(in long subId, String callingPkg,
             in String destinationAddress, in String scAddress,
             in List<String> parts, in List<PendingIntent> sentIntents,
             in List<PendingIntent> deliveryIntents);
@@ -315,7 +315,7 @@
      *
      * @see #disableCellBroadcast(int)
      */
-    boolean enableCellBroadcastUsingSubId(in long subId, int messageIdentifier);
+    boolean enableCellBroadcastForSubscriber(in long subId, int messageIdentifier);
 
     /**
      * Disable reception of cell broadcast (SMS-CB) messages with the given
@@ -344,7 +344,7 @@
      *
      * @see #enableCellBroadcast(int)
      */
-    boolean disableCellBroadcastUsingSubId(in long subId, int messageIdentifier);
+    boolean disableCellBroadcastForSubscriber(in long subId, int messageIdentifier);
 
     /*
      * Enable reception of cell broadcast (SMS-CB) messages with the given
@@ -377,7 +377,7 @@
      *
      * @see #disableCellBroadcastRange(int, int)
      */
-    boolean enableCellBroadcastRangeUsingSubId(long subId, int startMessageId, int endMessageId);
+    boolean enableCellBroadcastRangeForSubscriber(long subId, int startMessageId, int endMessageId);
 
     /**
      * Disable reception of cell broadcast (SMS-CB) messages with the given
@@ -410,7 +410,7 @@
      *
      * @see #enableCellBroadcastRange(int, int, int)
      */
-    boolean disableCellBroadcastRangeUsingSubId(long subId, int startMessageId,
+    boolean disableCellBroadcastRangeForSubscriber(long subId, int startMessageId,
             int endMessageId);
 
     /**
@@ -423,7 +423,7 @@
      * Returns the premium SMS send permission for the specified package.
      * Requires system permission.
      */
-    int getPremiumSmsPermissionUsingSubId(long subId, String packageName);
+    int getPremiumSmsPermissionForSubscriber(long subId, String packageName);
 
     /**
      * Set the SMS send permission for the specified package.
@@ -439,7 +439,7 @@
      * Set the SMS send permission for the specified package.
      * Requires system permission.
      */
-    void setPremiumSmsPermissionUsingSubId(long subId, String packageName, int permission);
+    void setPremiumSmsPermissionForSubscriber(long subId, String packageName, int permission);
 
     /**
      * SMS over IMS is supported if IMS is registered and SMS is supported
@@ -459,7 +459,7 @@
      *
      * @see #getImsSmsFormat()
      */
-    boolean isImsSmsSupportedUsingSubId(long subId);
+    boolean isImsSmsSupportedForSubscriber(long subId);
 
     /*
      * get user prefered SMS subId
@@ -489,7 +489,7 @@
      *
      * @see #isImsSmsSupported()
      */
-    String getImsSmsFormatUsingSubId(long subId);
+    String getImsSmsFormatForSubscriber(long subId);
 
     /*
      * Get SMS prompt property,  enabled or not
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 46d0660..b87365e 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -25,7 +25,7 @@
      * @param subId The unique SubInfoRecord index in database
      * @return SubInfoRecord, maybe null
      */
-    SubInfoRecord getSubInfoUsingSubId(long subId);
+    SubInfoRecord getSubInfoForSubscriber(long subId);
 
     /**
      * Get the SubInfoRecord according to an IccId
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 79c72b88..fa9cad4 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -59,7 +59,7 @@
      * @param subId user preferred subId.
      * @return whether it hung up
      */
-    boolean endCallUsingSubId(long subId);
+    boolean endCallForSubscriber(long subId);
 
     /**
      * Answer the currently-ringing call.
@@ -103,7 +103,7 @@
      * @param subId user preferred subId.
      * @return true if the phone state is OFFHOOK.
      */
-    boolean isOffhookUsingSubId(long subId);
+    boolean isOffhookForSubscriber(long subId);
 
     /**
      * Check if an incoming phone call is ringing or call waiting
@@ -112,7 +112,7 @@
      * @param subId user preferred subId.
      * @return true if the phone state is RINGING.
      */
-    boolean isRingingUsingSubId(long subId);
+    boolean isRingingForSubscriber(long subId);
 
     /**
      * Check if an incoming phone call is ringing or call waiting.
@@ -132,7 +132,7 @@
      * @param subId user preferred subId.
      * @return true if the phone state is IDLE.
      */
-    boolean isIdleUsingSubId(long subId);
+    boolean isIdleForSubscriber(long subId);
 
     /**
      * Check to see if the radio is on or not.
@@ -145,7 +145,7 @@
      * @param subId user preferred subId.
      * @return returns true if the radio is on.
      */
-    boolean isRadioOnUsingSubId(long subId);
+    boolean isRadioOnForSubscriber(long subId);
 
     /**
      * Check if the SIM pin lock is enabled.
@@ -167,7 +167,7 @@
      * @param subId user preferred subId.
      * @return whether the operation was a success.
      */
-    boolean supplyPinUsingSubId(long subId, String pin);
+    boolean supplyPinForSubscriber(long subId, String pin);
 
     /**
      * Supply puk to unlock the SIM and set SIM pin to new pin.
@@ -186,7 +186,7 @@
      * @param subId user preferred subId.
      * @return whether the operation was a success.
      */
-    boolean supplyPukUsingSubId(long subId, String puk, String pin);
+    boolean supplyPukForSubscriber(long subId, String puk, String pin);
 
     /**
      * Supply a pin to unlock the SIM.  Blocks until a result is determined.
@@ -204,7 +204,7 @@
      * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code
      *         retValue[1] = number of attempts remaining if known otherwise -1
      */
-    int[] supplyPinReportResultUsingSubId(long subId, String pin);
+    int[] supplyPinReportResultForSubscriber(long subId, String pin);
 
     /**
      * Supply puk to unlock the SIM and set SIM pin to new pin.
@@ -226,7 +226,7 @@
      * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code
      *         retValue[1] = number of attempts remaining if known otherwise -1
      */
-    int[] supplyPukReportResultUsingSubId(long subId, String puk, String pin);
+    int[] supplyPukReportResultForSubscriber(long subId, String puk, String pin);
 
     /**
      * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated
@@ -245,7 +245,7 @@
      * @param subId user preferred subId.
      * @return true if MMI command is executed.
      */
-    boolean handlePinMmiUsingSubId(long subId, String dialString);
+    boolean handlePinMmiForSubscriber(long subId, String dialString);
 
     /**
      * Toggles the radio on or off.
@@ -256,7 +256,7 @@
      * Toggles the radio on or off on particular subId.
      * @param subId user preferred subId.
      */
-    void toggleRadioOnOffUsingSubId(long subId);
+    void toggleRadioOnOffForSubscriber(long subId);
 
     /**
      * Set the radio to on or off
@@ -267,7 +267,7 @@
      * Set the radio to on or off on particular subId.
      * @param subId user preferred subId.
      */
-    boolean setRadioUsingSubId(long subId, boolean turnOn);
+    boolean setRadioForSubscriber(long subId, boolean turnOn);
 
     /**
      * Set the radio to on or off unconditionally
@@ -283,7 +283,7 @@
      * Request to update location information for a subscrition in service state
      * @param subId user preferred subId.
      */
-    void updateServiceLocationUsingSubId(long subId);
+    void updateServiceLocationForSubscriber(long subId);
 
     /**
      * Enable location update notifications.
@@ -294,7 +294,7 @@
      * Enable location update notifications.
      * @param subId user preferred subId.
      */
-    void enableLocationUpdatesUsingSubId(long subId);
+    void enableLocationUpdatesForSubscriber(long subId);
 
     /**
      * Disable location update notifications.
@@ -305,7 +305,7 @@
      * Disable location update notifications.
      * @param subId user preferred subId.
      */
-    void disableLocationUpdatesUsingSubId(long subId);
+    void disableLocationUpdatesForSubscriber(long subId);
 
     /**
      * Allow mobile data connections.
@@ -334,7 +334,7 @@
     /**
      * Returns the call state for a subId.
      */
-     int getCallStateUsingSubId(long subId);
+     int getCallStateForSubscriber(long subId);
 
      int getDataActivity();
      int getDataState();
@@ -352,7 +352,7 @@
      * and TelephonyManager.PHONE_TYPE_GSM if RILConstants.GSM_PHONE
      * @param subId user preferred subId.
      */
-    int getActivePhoneTypeUsingSubId(long subId);
+    int getActivePhoneTypeForSubscriber(long subId);
 
     /**
      * Returns the CDMA ERI icon index to display
@@ -363,7 +363,7 @@
      * Returns the CDMA ERI icon index to display on particular subId.
      * @param subId user preferred subId.
      */
-    int getCdmaEriIconIndexUsingSubId(long subId);
+    int getCdmaEriIconIndexForSubscriber(long subId);
 
     /**
      * Returns the CDMA ERI icon mode,
@@ -378,7 +378,7 @@
      * 1 - FLASHING
      * @param subId user preferred subId.
      */
-    int getCdmaEriIconModeUsingSubId(long subId);
+    int getCdmaEriIconModeForSubscriber(long subId);
 
     /**
      * Returns the CDMA ERI text,
@@ -389,7 +389,7 @@
      * Returns the CDMA ERI text for particular subId,
      * @param subId user preferred subId.
      */
-    String getCdmaEriTextUsingSubId(long subId);
+    String getCdmaEriTextForSubscriber(long subId);
 
     /**
      * Returns true if OTA service provisioning needs to run.
@@ -408,7 +408,7 @@
      * @param subId user preferred subId.
      * Returns the unread count of voicemails
      */
-    int getVoiceMessageCountUsingSubId(long subId);
+    int getVoiceMessageCountForSubscriber(long subId);
 
     /**
       * Returns the network type for data transmission
@@ -420,7 +420,7 @@
      * @param subId user preferred subId.
      * Returns the network type
      */
-    int getNetworkTypeUsingSubId(long subId);
+    int getNetworkTypeForSubscriber(long subId);
 
     /**
       * Returns the network type for data transmission
@@ -432,7 +432,7 @@
       * @param subId user preferred subId.
       * Returns the network type
       */
-    int getDataNetworkTypeUsingSubId(long subId);
+    int getDataNetworkTypeForSubscriber(long subId);
 
     /**
       * Returns the network type for voice
@@ -444,7 +444,7 @@
       * @param subId user preferred subId.
       * Returns the network type
       */
-    int getVoiceNetworkTypeUsingSubId(long subId);
+    int getVoiceNetworkTypeForSubscriber(long subId);
 
     /**
      * Return true if an ICC card is present
@@ -476,7 +476,7 @@
      * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
      * or {@link PHone#LTE_ON_CDMA_TRUE}
      */
-    int getLteOnCdmaModeUsingSubId(long subId);
+    int getLteOnCdmaModeForSubscriber(long subId);
 
     /**
      * Returns the all observed cell information of the device.
@@ -715,7 +715,7 @@
      * @param subId for which the simplified UI should be enabled or disabled.
      * @param enable true means enabling the simplified UI.
      */
-    void enableSimplifiedNetworkSettings(long subId, boolean enable);
+    void enableSimplifiedNetworkSettingsForSubscriber(long subId, boolean enable);
 
     /**
      * Get whether a simplified Mobile Network Settings UI is enabled.
@@ -723,7 +723,7 @@
      * @param subId for which the simplified UI should be enabled or disabled.
      * @return true if the simplified UI is enabled.
      */
-    boolean getSimplifiedNetworkSettingsEnabled(long subId);
+    boolean getSimplifiedNetworkSettingsEnabledForSubscriber(long subId);
 
     /**
      * Set the phone number string and its alphatag for line 1 for display
@@ -735,7 +735,7 @@
      * @param alphaTag alpha-tagging of the dailing nubmer
      * @param number The dialing number
      */
-    void setLine1NumberForDisplay(long subId, String alphaTag, String number);
+    void setLine1NumberForDisplayForSubscriber(long subId, String alphaTag, String number);
 
     /**
      * Returns the displayed dialing number string if it was set previously via
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index fd2d1c7..d776833 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -30,30 +30,30 @@
 
 interface ITelephonyRegistry {
     void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow);
-    void listenUsingSubId(in long subId, String pkg, IPhoneStateListener callback, int events,
+    void listenForSubscriber(in long subId, String pkg, IPhoneStateListener callback, int events,
             boolean notifyNow);
     void notifyCallState(int state, String incomingNumber);
-    void notifyCallStateUsingSubId(in long subId, int state, String incomingNumber);
+    void notifyCallStateForSubscriber(in long subId, int state, String incomingNumber);
     void notifyServiceState(in ServiceState state);
-    void notifyServiceStateUsingSubId(in long subId, in ServiceState state);
+    void notifyServiceStateForSubscriber(in long subId, in ServiceState state);
     void notifySignalStrength(in SignalStrength signalStrength);
-    void notifySignalStrengthUsingSubId(in long subId, in SignalStrength signalStrength);
+    void notifySignalStrengthForSubscriber(in long subId, in SignalStrength signalStrength);
     void notifyMessageWaitingChanged(boolean mwi);
-    void notifyMessageWaitingChangedUsingSubId(in long subId, boolean mwi);
+    void notifyMessageWaitingChangedForSubscriber(in long subId, boolean mwi);
     void notifyCallForwardingChanged(boolean cfi);
-    void notifyCallForwardingChangedUsingSubId(in long subId, boolean cfi);
+    void notifyCallForwardingChangedForSubscriber(in long subId, boolean cfi);
     void notifyDataActivity(int state);
-    void notifyDataActivityUsingSubId(in long subId, int state);
+    void notifyDataActivityForSubscriber(in long subId, int state);
     void notifyDataConnection(int state, boolean isDataConnectivityPossible,
             String reason, String apn, String apnType, in LinkProperties linkProperties,
             in NetworkCapabilities networkCapabilities, int networkType, boolean roaming);
-    void notifyDataConnectionUsingSubId(long subId, int state, boolean isDataConnectivityPossible,
+    void notifyDataConnectionForSubscriber(long subId, int state, boolean isDataConnectivityPossible,
             String reason, String apn, String apnType, in LinkProperties linkProperties,
             in NetworkCapabilities networkCapabilities, int networkType, boolean roaming);
     void notifyDataConnectionFailed(String reason, String apnType);
-    void notifyDataConnectionFailedUsingSubId(long subId, String reason, String apnType);
+    void notifyDataConnectionFailedForSubscriber(long subId, String reason, String apnType);
     void notifyCellLocation(in Bundle cellLocation);
-    void notifyCellLocationUsingSubId(in long subId, in Bundle cellLocation);
+    void notifyCellLocationForSubscriber(in long subId, in Bundle cellLocation);
     void notifyOtaspChanged(in int otaspMode);
     void notifyCellInfo(in List<CellInfo> cellInfo);
     void notifyPreciseCallState(int ringingCallState, int foregroundCallState,
@@ -61,7 +61,7 @@
     void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause);
     void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn,
             String failCause);
-    void notifyCellInfoUsingSubId(in long subId, in List<CellInfo> cellInfo);
+    void notifyCellInfoForSubscriber(in long subId, in List<CellInfo> cellInfo);
     void notifyDataConnectionRealTimeInfo(in DataConnectionRealTimeInfo dcRtInfo);
     void notifyVoLteServiceStateChanged(in VoLteServiceState lteState);
 }
diff --git a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
index 44787e7..6837d22 100644
--- a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
+++ b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
@@ -73,7 +73,7 @@
                     Intent intent = new Intent(ActivityTestMain.this, SpamActivity.class);
                     Bundle options = null;
                     if (fg) {
-                        ActivityOptions opts = ActivityOptions.makeLaunchTaskBehindAnimation();
+                        ActivityOptions opts = ActivityOptions.makeTaskLaunchBehind();
                         options = opts.toBundle();
                     }
                     startActivity(intent, options);
diff --git a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
index 5bf59c7..a2e9117 100644
--- a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
+++ b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
@@ -208,6 +208,12 @@
                 Log.d(TAG, "Found process " + app.processName);
                 return true;
             }
+            for (String relatedPackage : app.pkgList) {
+                if (relatedPackage.equalsIgnoreCase(processName)) {
+                    Log.d(TAG, "Found process " + app.processName);
+                    return true;
+                }
+            }
         }
         Log.d(TAG, "Failed to find process " + processName + " with package name "
                 + packageName);
diff --git a/tests/WallpaperTest/Android.mk b/tests/WallpaperTest/Android.mk
new file mode 100644
index 0000000..b4259cd
--- /dev/null
+++ b/tests/WallpaperTest/Android.mk
@@ -0,0 +1,15 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := WallpaperTest
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
+
diff --git a/tests/WallpaperTest/AndroidManifest.xml b/tests/WallpaperTest/AndroidManifest.xml
new file mode 100644
index 0000000..4c914dd
--- /dev/null
+++ b/tests/WallpaperTest/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.wallpapertest" >
+
+    <uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />
+
+    <application
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name=".MainActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <service
+            android:label="@string/test_wallpaper"
+            android:name=".TestWallpaper"
+            android:permission="android.permission.BIND_WALLPAPER"
+            android:enabled="true">
+            <intent-filter>
+                <action android:name="android.service.wallpaper.WallpaperService" />
+            </intent-filter>
+            <meta-data android:name="android.service.wallpaper"
+                       android:resource="@xml/test_wallpaper" />
+        </service>
+    </application>
+</manifest>
diff --git a/tests/WallpaperTest/res/drawable-hdpi/test_wallpaper_thumb.png b/tests/WallpaperTest/res/drawable-hdpi/test_wallpaper_thumb.png
new file mode 100644
index 0000000..df92eb5
--- /dev/null
+++ b/tests/WallpaperTest/res/drawable-hdpi/test_wallpaper_thumb.png
Binary files differ
diff --git a/tests/WallpaperTest/res/layout/activity_main.xml b/tests/WallpaperTest/res/layout/activity_main.xml
new file mode 100644
index 0000000..d968396
--- /dev/null
+++ b/tests/WallpaperTest/res/layout/activity_main.xml
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/window_background">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/dimens"/>
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="15dp"
+                android:textSize="17sp"
+                android:text="@string/width"/>
+            <EditText
+                android:id="@+id/dimen_width"
+                android:layout_width="60sp"
+                android:layout_height="wrap_content"
+                android:inputType="numberDecimal"/>
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="15dp"
+                android:textSize="17sp"
+                android:text="@string/height"/>
+            <EditText
+                android:id="@+id/dimen_height"
+                android:layout_width="60sp"
+                android:layout_height="wrap_content"
+                android:inputType="numberDecimal"/>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/wallpaper_offset"/>
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="15dp"
+                android:textSize="17sp"
+                android:text="@string/x"/>
+            <EditText
+                android:id="@+id/walloff_x"
+                android:layout_width="60sp"
+                android:layout_height="wrap_content"
+                android:inputType="numberDecimal"/>
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="15dp"
+                android:textSize="17sp"
+                android:text="@string/y"/>
+            <EditText
+                android:id="@+id/walloff_y"
+                android:layout_width="60sp"
+                android:layout_height="wrap_content"
+                android:inputType="numberDecimal"/>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/padding"/>
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical">
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal">
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginLeft="15dp"
+                        android:textSize="17sp"
+                        android:text="@string/left"/>
+                    <EditText
+                        android:id="@+id/padding_left"
+                        android:layout_width="60sp"
+                        android:layout_height="wrap_content"
+                        android:inputType="number"/>
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginLeft="15dp"
+                        android:textSize="17sp"
+                        android:text="@string/right"/>
+                    <EditText
+                        android:id="@+id/padding_right"
+                        android:layout_width="60sp"
+                        android:layout_height="wrap_content"
+                        android:inputType="number"/>
+                </LinearLayout>
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal">
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginLeft="15dp"
+                        android:textSize="17sp"
+                        android:text="@string/top"/>
+                    <EditText
+                        android:id="@+id/padding_top"
+                        android:layout_width="60sp"
+                        android:layout_height="wrap_content"
+                        android:inputType="number"/>
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginLeft="15dp"
+                        android:textSize="17sp"
+                        android:text="@string/bottom"/>
+                    <EditText
+                        android:id="@+id/padding_bottom"
+                        android:layout_width="60sp"
+                        android:layout_height="wrap_content"
+                        android:inputType="number"/>
+                </LinearLayout>
+            </LinearLayout>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/display_offset"/>
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="15dp"
+                android:textSize="17sp"
+                android:text="@string/x"/>
+            <EditText
+                android:id="@+id/dispoff_x"
+                android:layout_width="60sp"
+                android:layout_height="wrap_content"
+                android:inputType="numberSigned"/>
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="15dp"
+                android:textSize="17sp"
+                android:text="@string/y"/>
+            <EditText
+                android:id="@+id/dispoff_y"
+                android:layout_width="60sp"
+                android:layout_height="wrap_content"
+                android:inputType="numberSigned"/>
+        </LinearLayout>
+    </LinearLayout>
+</ScrollView>
diff --git a/tests/WallpaperTest/res/values-v11/styles.xml b/tests/WallpaperTest/res/values-v11/styles.xml
new file mode 100644
index 0000000..95000b2
--- /dev/null
+++ b/tests/WallpaperTest/res/values-v11/styles.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2013 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<resources>
+
+    <!--
+        Base application theme for API 11+. This theme completely replaces
+        AppBaseTheme from res/values/styles.xml on API 11+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Wallpaper">
+        <!-- API 11 theme customizations can go here. -->
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/tests/WallpaperTest/res/values-v21/styles.xml b/tests/WallpaperTest/res/values-v21/styles.xml
new file mode 100644
index 0000000..e42d526
--- /dev/null
+++ b/tests/WallpaperTest/res/values-v21/styles.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2013 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<resources>
+
+    <!--
+        Base application theme for API 21+. This theme completely replaces
+        AppBaseTheme from BOTH res/values/styles.xml and
+        res/values-v11/styles.xml on API 14+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Material.Wallpaper">
+        <!-- API 14 theme customizations can go here. -->
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/tests/WallpaperTest/res/values/colors.xml b/tests/WallpaperTest/res/values/colors.xml
new file mode 100644
index 0000000..8c08249
--- /dev/null
+++ b/tests/WallpaperTest/res/values/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<resources>
+    <color name="window_background">#80000000</color>
+</resources>
\ No newline at end of file
diff --git a/tests/WallpaperTest/res/values/strings.xml b/tests/WallpaperTest/res/values/strings.xml
new file mode 100644
index 0000000..fd21259
--- /dev/null
+++ b/tests/WallpaperTest/res/values/strings.xml
@@ -0,0 +1,42 @@
+<?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>
+    <string name="app_name">Wallpaper Test</string>
+
+    <string name="test_wallpaper">Test Wallpaper</string>
+    <string name="test_wallpaper_author">Google</string>
+    <string name="test_wallpaper_desc">
+        Test wallpaper for use with the wallpaper test app.
+    </string>
+
+    <string name="dimens">Dimens: </string>
+    <string name="width">Width: </string>
+    <string name="height">Height: </string>
+
+    <string name="wallpaper_offset">Wall off: </string>
+    <string name="x">X: </string>
+    <string name="y">Y: </string>
+
+    <string name="padding">Padding: </string>
+    <string name="left">Left: </string>
+    <string name="right">Right: </string>
+    <string name="top">Top: </string>
+    <string name="bottom">Bottom: </string>
+
+    <string name="display_offset">Disp off: </string>
+</resources>
diff --git a/tests/WallpaperTest/res/values/styles.xml b/tests/WallpaperTest/res/values/styles.xml
new file mode 100644
index 0000000..d2b91d6
--- /dev/null
+++ b/tests/WallpaperTest/res/values/styles.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2013 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<resources>
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Wallpaper">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.
+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="AppBaseTheme">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/tests/WallpaperTest/res/xml/test_wallpaper.xml b/tests/WallpaperTest/res/xml/test_wallpaper.xml
new file mode 100644
index 0000000..9f7d714
--- /dev/null
+++ b/tests/WallpaperTest/res/xml/test_wallpaper.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2008, 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.
+ */
+-->
+
+<!-- The attributes in this XML file provide configuration information -->
+<!-- about the polar clock. -->
+
+<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
+    android:author="@string/test_wallpaper_author"
+    android:description="@string/test_wallpaper_desc"
+    android:thumbnail="@drawable/test_wallpaper_thumb" />
diff --git a/tests/WallpaperTest/src/com/example/wallpapertest/MainActivity.java b/tests/WallpaperTest/src/com/example/wallpapertest/MainActivity.java
new file mode 100644
index 0000000..7880f67
--- /dev/null
+++ b/tests/WallpaperTest/src/com/example/wallpapertest/MainActivity.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.wallpapertest;
+
+import android.app.Activity;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+public class MainActivity extends Activity {
+    private static final String TAG = "MainActivity";
+
+    WallpaperManager mWallpaperManager;
+    WindowManager mWindowManager;
+
+    TextView mDimenWidthView;
+    TextView mDimenHeightView;
+
+    TextView mWallOffXView;
+    TextView mWallOffYView;
+
+    TextView mPaddingLeftView;
+    TextView mPaddingRightView;
+    TextView mPaddingTopView;
+    TextView mPaddingBottomView;
+
+    TextView mDispOffXView;
+    TextView mDispOffYView;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        mWallpaperManager = (WallpaperManager)getSystemService(Context.WALLPAPER_SERVICE);
+        mWindowManager = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
+
+        mDimenWidthView = (TextView) findViewById(R.id.dimen_width);
+        mDimenWidthView.addTextChangedListener(mTextWatcher);
+        mDimenHeightView = (TextView) findViewById(R.id.dimen_height);
+        mDimenHeightView.addTextChangedListener(mTextWatcher);
+
+        mWallOffXView = (TextView) findViewById(R.id.walloff_x);
+        mWallOffXView.addTextChangedListener(mTextWatcher);
+        mWallOffYView = (TextView) findViewById(R.id.walloff_y);
+        mWallOffYView.addTextChangedListener(mTextWatcher);
+
+        mPaddingLeftView = (TextView) findViewById(R.id.padding_left);
+        mPaddingLeftView.addTextChangedListener(mTextWatcher);
+        mPaddingRightView = (TextView) findViewById(R.id.padding_right);
+        mPaddingRightView.addTextChangedListener(mTextWatcher);
+        mPaddingTopView = (TextView) findViewById(R.id.padding_top);
+        mPaddingTopView.addTextChangedListener(mTextWatcher);
+        mPaddingBottomView = (TextView) findViewById(R.id.padding_bottom);
+        mPaddingBottomView.addTextChangedListener(mTextWatcher);
+
+        mDispOffXView = (TextView) findViewById(R.id.dispoff_x);
+        mDispOffXView.addTextChangedListener(mTextWatcher);
+        mDispOffYView = (TextView) findViewById(R.id.dispoff_y);
+        mDispOffYView.addTextChangedListener(mTextWatcher);
+
+        updateDimens();
+        updateWallOff();
+        updatePadding();
+        updateDispOff();
+    }
+
+    private int loadPropIntText(TextView view, int baseVal) {
+        String str = view.getText().toString();
+        if (str != null && !TextUtils.isEmpty(str)) {
+            try {
+                float fval = Float.parseFloat(str);
+                return (int)(fval*baseVal);
+            } catch (NumberFormatException e) {
+                Log.i(TAG, "Bad number: " + str, e);
+            }
+        }
+        return baseVal;
+    }
+
+    private float loadFloatText(TextView view) {
+        String str = view.getText().toString();
+        if (str != null && !TextUtils.isEmpty(str)) {
+            try {
+                return Float.parseFloat(str);
+            } catch (NumberFormatException e) {
+                Log.i(TAG, "Bad number: " + str, e);
+            }
+        }
+        return 0;
+    }
+
+    private int loadIntText(TextView view) {
+        String str = view.getText().toString();
+        if (str != null && !TextUtils.isEmpty(str)) {
+            try {
+                return Integer.parseInt(str);
+            } catch (NumberFormatException e) {
+                Log.i(TAG, "Bad number: " + str, e);
+            }
+        }
+        return 0;
+    }
+
+    public void updateDimens() {
+        Point minDims = new Point();
+        Point maxDims = new Point();
+        mWindowManager.getDefaultDisplay().getCurrentSizeRange(minDims, maxDims);
+        mWallpaperManager.suggestDesiredDimensions(
+                loadPropIntText(mDimenWidthView, maxDims.x),
+                loadPropIntText(mDimenHeightView, maxDims.y));
+    }
+
+    public void updateWallOff() {
+        IBinder token = getWindow().getDecorView().getWindowToken();
+        if (token != null) {
+            mWallpaperManager.setWallpaperOffsets(token, loadFloatText(mWallOffXView),
+                    loadFloatText(mWallOffYView));
+        }
+    }
+
+    public void updatePadding() {
+        Rect padding = new Rect();
+        padding.left = loadIntText(mPaddingLeftView);
+        padding.top = loadIntText(mPaddingTopView);
+        padding.right = loadIntText(mPaddingRightView);
+        padding.bottom = loadIntText(mPaddingBottomView);
+        mWallpaperManager.setDisplayPadding(padding);
+    }
+
+    public void updateDispOff() {
+        IBinder token = getWindow().getDecorView().getWindowToken();
+        if (token != null) {
+            mWallpaperManager.setDisplayOffset(token, loadIntText(mDispOffXView),
+                    loadIntText(mDispOffYView));
+        }
+    }
+
+    final TextWatcher mTextWatcher = new TextWatcher() {
+        @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+        }
+
+        @Override public void onTextChanged(CharSequence s, int start, int before, int count) {
+            updateDimens();
+            updateWallOff();
+            updatePadding();
+            updateDispOff();
+        }
+
+        @Override public void afterTextChanged(Editable s) {
+        }
+    };
+}
diff --git a/tests/WallpaperTest/src/com/example/wallpapertest/TestWallpaper.java b/tests/WallpaperTest/src/com/example/wallpapertest/TestWallpaper.java
new file mode 100644
index 0000000..95db6d1
--- /dev/null
+++ b/tests/WallpaperTest/src/com/example/wallpapertest/TestWallpaper.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.wallpapertest;
+
+import android.service.wallpaper.WallpaperService;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.Paint;
+import android.graphics.Color;
+import android.graphics.RectF;
+import android.text.TextPaint;
+import android.view.SurfaceHolder;
+import android.content.res.XmlResourceParser;
+
+import android.os.Handler;
+import android.util.Log;
+
+import android.view.WindowInsets;
+
+public class TestWallpaper extends WallpaperService {
+    private static final String LOG_TAG = "PolarClock";
+    
+    private final Handler mHandler = new Handler();
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+    }
+
+    public Engine onCreateEngine() {
+        return new ClockEngine();
+    }
+
+    class ClockEngine extends Engine {
+        private static final int OUTER_COLOR = 0xffff0000;
+        private static final int INNER_COLOR = 0xff000080;
+        private static final int STABLE_COLOR = 0xa000ff00;
+        private static final int TEXT_COLOR = 0xa0ffffff;
+
+        private final Paint.FontMetrics mTextMetrics = new Paint.FontMetrics();
+
+        private int mPadding;
+
+        private final Rect mMainInsets = new Rect();
+        private final Rect mStableInsets = new Rect();
+        private boolean mRound = false;
+
+        private int mDesiredWidth;
+        private int mDesiredHeight;
+
+        private float mOffsetX;
+        private float mOffsetY;
+        private float mOffsetXStep;
+        private float mOffsetYStep;
+        private int mOffsetXPixels;
+        private int mOffsetYPixels;
+
+        private final Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        private final Paint mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        private final TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
+
+        private final Runnable mDrawClock = new Runnable() {
+            public void run() {
+                drawFrame();
+            }
+        };
+        private boolean mVisible;
+
+        ClockEngine() {
+        }
+
+        @Override
+        public void onCreate(SurfaceHolder surfaceHolder) {
+            super.onCreate(surfaceHolder);
+
+            mDesiredWidth = getDesiredMinimumWidth();
+            mDesiredHeight = getDesiredMinimumHeight();
+
+            Paint paint = mFillPaint;
+            paint.setStyle(Paint.Style.FILL);
+
+            paint = mStrokePaint;
+            paint.setStrokeWidth(3);
+            paint.setStrokeCap(Paint.Cap.ROUND);
+            paint.setStyle(Paint.Style.STROKE);
+
+            TextPaint tpaint = mTextPaint;
+            tpaint.density = getResources().getDisplayMetrics().density;
+            tpaint.setCompatibilityScaling(getResources().getCompatibilityInfo().applicationScale);
+            tpaint.setColor(TEXT_COLOR);
+            tpaint.setTextSize(18 * getResources().getDisplayMetrics().scaledDensity);
+            tpaint.setShadowLayer(4 * getResources().getDisplayMetrics().density, 0, 0, 0xff000000);
+
+            mTextPaint.getFontMetrics(mTextMetrics);
+
+            mPadding = (int)(16 * getResources().getDisplayMetrics().density);
+
+            if (isPreview()) {
+                mOffsetX = 0.5f;
+                mOffsetY = 0.5f;
+            }
+        }
+
+        @Override
+        public void onDestroy() {
+            super.onDestroy();
+            mHandler.removeCallbacks(mDrawClock);
+        }
+
+        @Override
+        public void onVisibilityChanged(boolean visible) {
+            mVisible = visible;
+            if (!visible) {
+                mHandler.removeCallbacks(mDrawClock);
+            }
+            drawFrame();
+        }
+
+        @Override
+        public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+            super.onSurfaceChanged(holder, format, width, height);
+            drawFrame();
+        }
+
+        @Override
+        public void onSurfaceCreated(SurfaceHolder holder) {
+            super.onSurfaceCreated(holder);
+        }
+
+        @Override
+        public void onSurfaceDestroyed(SurfaceHolder holder) {
+            super.onSurfaceDestroyed(holder);
+            mVisible = false;
+            mHandler.removeCallbacks(mDrawClock);
+        }
+
+        @Override
+        public void onApplyWindowInsets(WindowInsets insets) {
+            super.onApplyWindowInsets(insets);
+            mMainInsets.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
+                    insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
+            mStableInsets.set(insets.getStableInsetLeft(), insets.getStableInsetTop(),
+                    insets.getStableInsetRight(), insets.getStableInsetBottom());
+            mRound = insets.isRound();
+            drawFrame();
+        }
+
+        @Override
+        public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) {
+            super.onDesiredSizeChanged(desiredWidth, desiredHeight);
+            mDesiredWidth = desiredWidth;
+            mDesiredHeight = desiredHeight;
+            drawFrame();
+        }
+
+        @Override
+        public void onOffsetsChanged(float xOffset, float yOffset,
+                float xStep, float yStep, int xPixels, int yPixels) {
+            super.onOffsetsChanged(xOffset, yOffset, xStep, yStep, xPixels, yPixels);
+
+            if (isPreview()) return;
+
+            mOffsetX = xOffset;
+            mOffsetY = yOffset;
+            mOffsetXStep = xStep;
+            mOffsetYStep = yStep;
+            mOffsetXPixels = xPixels;
+            mOffsetYPixels = yPixels;
+
+            drawFrame();
+        }
+
+        void drawFrame() {
+            final SurfaceHolder holder = getSurfaceHolder();
+            final Rect frame = holder.getSurfaceFrame();
+            final int width = frame.width();
+            final int height = frame.height();
+
+            Canvas c = null;
+            try {
+                c = holder.lockCanvas();
+                if (c != null) {
+                    final Paint paint = mFillPaint;
+
+                    paint.setColor(OUTER_COLOR);
+                    c.drawRect(0, 0, width, height, paint);
+
+                    paint.setColor(INNER_COLOR);
+                    c.drawRect(0+mMainInsets.left, 0+mMainInsets.top,
+                            width-mMainInsets.right, height-mMainInsets.bottom, paint);
+
+                    mStrokePaint.setColor(STABLE_COLOR);
+                    c.drawRect(0 + mStableInsets.left, 0 + mStableInsets.top,
+                            width - mStableInsets.right, height - mStableInsets.bottom,
+                            mStrokePaint);
+
+                    final int ascdesc = (int)(-mTextMetrics.ascent + mTextMetrics.descent);
+                    final int linegap = (int)(-mTextMetrics.ascent + mTextMetrics.descent
+                            + mTextMetrics.leading);
+
+                    int x = mStableInsets.left + mPadding;
+                    int y = height - mStableInsets.bottom - mPadding - ascdesc;
+                    c.drawText("Surface Size: " + width + " x " + height,
+                            x, y, mTextPaint);
+                    y -= linegap;
+                    c.drawText("Desired Size: " + mDesiredWidth + " x " + mDesiredHeight,
+                            x, y, mTextPaint);
+                    y -= linegap;
+                    c.drawText("Cur Offset Raw: " + mOffsetX + ", " + mOffsetY,
+                            x, y, mTextPaint);
+                    y -= linegap;
+                    c.drawText("Cur Offset Step: " + mOffsetXStep + ", " + mOffsetYStep,
+                            x, y, mTextPaint);
+                    y -= linegap;
+                    c.drawText("Cur Offset Pixels: " + mOffsetXPixels + ", " + mOffsetYPixels,
+                            x, y, mTextPaint);
+                    y -= linegap;
+                    c.drawText("Stable Insets: (" + mStableInsets.left + ", " + mStableInsets.top
+                            + ") - (" + mStableInsets.right + ", " + mStableInsets.bottom + ")",
+                            x, y, mTextPaint);
+                    y -= linegap;
+                    c.drawText("System Insets: (" + mMainInsets.left + ", " + mMainInsets.top
+                            + ") - (" + mMainInsets.right + ", " + mMainInsets.bottom + ")",
+                            x, y, mTextPaint);
+
+                }
+            } finally {
+                if (c != null) holder.unlockCanvasAndPost(c);
+            }
+        }
+    }
+}
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index b3c364b..8341de6 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -2574,8 +2574,12 @@
                 continue;
             }
             const size_t N = t->getOrderedConfigs().size();
-            sp<AaptSymbols> typeSymbols;
-            typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos());
+            sp<AaptSymbols> typeSymbols =
+                    outSymbols->addNestedSymbol(String8(t->getName()), t->getPos());
+            if (typeSymbols == NULL) {
+                return UNKNOWN_ERROR;
+            }
+
             for (size_t ci=0; ci<N; ci++) {
                 sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
                 if (c == NULL) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
index 130500a..0ed6ab1 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
@@ -174,6 +174,11 @@
     }
 
     @Override
+    public void setWallpaperDisplayOffset(IBinder windowToken, int x, int y) {
+        // pass for now.
+    }
+
+    @Override
     public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
             int z, Bundle extras, boolean sync) {
         // pass for now.
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 65c00bd..aaa2f98 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -76,6 +76,8 @@
     public static final int REASON_INVALID_LISTENER = -2;
     /** Invalid request */
     public static final int REASON_INVALID_REQUEST = -3;
+    /** Invalid request */
+    public static final int REASON_NOT_AUTHORIZED = -4;
 
     /** @hide */
     public static final String GET_AVAILABLE_CHANNELS_EXTRA = "Channels";