merge in lmp-release history after reset to 4dc1f927d49c3999c5079f72fc09f364b29505d6
diff --git a/api/current.txt b/api/current.txt
index 993ada1..a1f2acf 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1062,6 +1062,7 @@
     field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d
     field public static final int restrictedAccountType = 16843733; // 0x10103d5
     field public static final int restrictionType = 16843923; // 0x1010493
+    field public static final int resumeWhilePausing = 16843955; // 0x10104b3
     field public static final int reversible = 16843851; // 0x101044b
     field public static final int right = 16843183; // 0x10101af
     field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
@@ -8411,6 +8412,7 @@
     field public static final int FLAG_MULTIPROCESS = 1; // 0x1
     field public static final int FLAG_NO_HISTORY = 128; // 0x80
     field public static final int FLAG_RELINQUISH_TASK_IDENTITY = 4096; // 0x1000
+    field public static final int FLAG_RESUME_WHILE_PAUSING = 16384; // 0x4000
     field public static final int FLAG_SINGLE_USER = 1073741824; // 0x40000000
     field public static final int FLAG_STATE_NOT_NEEDED = 16; // 0x10
     field public static final int LAUNCH_MULTIPLE = 0; // 0x0
@@ -27426,11 +27428,12 @@
     ctor public TextToSpeech(android.content.Context, android.speech.tts.TextToSpeech.OnInitListener);
     ctor public TextToSpeech(android.content.Context, android.speech.tts.TextToSpeech.OnInitListener, java.lang.String);
     method public int addEarcon(java.lang.String, java.lang.String, int);
-    method public int addEarcon(java.lang.String, java.lang.String);
+    method public deprecated int addEarcon(java.lang.String, java.lang.String);
+    method public int addEarcon(java.lang.String, java.io.File);
     method public int addSpeech(java.lang.String, java.lang.String, int);
     method public int addSpeech(java.lang.CharSequence, java.lang.String, int);
     method public int addSpeech(java.lang.String, java.lang.String);
-    method public int addSpeech(java.lang.CharSequence, java.lang.String);
+    method public int addSpeech(java.lang.CharSequence, java.io.File);
     method public deprecated boolean areDefaultsEnforced();
     method public java.util.Set<java.util.Locale> getAvailableLanguages();
     method public java.lang.String getDefaultEngine();
@@ -27444,7 +27447,7 @@
     method public java.util.Set<android.speech.tts.Voice> getVoices();
     method public int isLanguageAvailable(java.util.Locale);
     method public boolean isSpeaking();
-    method public int playEarcon(java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>, java.lang.String);
+    method public int playEarcon(java.lang.String, int, android.os.Bundle, java.lang.String);
     method public deprecated int playEarcon(java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>);
     method public int playSilence(long, int, java.util.HashMap<java.lang.String, java.lang.String>, java.lang.String);
     method public deprecated int playSilence(long, int, java.util.HashMap<java.lang.String, java.lang.String>);
@@ -27457,10 +27460,10 @@
     method public int setSpeechRate(float);
     method public int setVoice(android.speech.tts.Voice);
     method public void shutdown();
-    method public int speak(java.lang.CharSequence, int, java.util.HashMap<java.lang.String, java.lang.String>, java.lang.String);
+    method public int speak(java.lang.CharSequence, int, android.os.Bundle, java.lang.String);
     method public deprecated int speak(java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>);
     method public int stop();
-    method public int synthesizeToFile(java.lang.CharSequence, java.util.HashMap<java.lang.String, java.lang.String>, java.lang.String, java.lang.String);
+    method public int synthesizeToFile(java.lang.CharSequence, android.os.Bundle, java.io.File, java.lang.String);
     method public deprecated int synthesizeToFile(java.lang.String, java.util.HashMap<java.lang.String, java.lang.String>, java.lang.String);
     field public static final java.lang.String ACTION_TTS_QUEUE_PROCESSING_COMPLETED = "android.speech.tts.TTS_QUEUE_PROCESSING_COMPLETED";
     field public static final int ERROR = -1; // 0xffffffff
@@ -27533,15 +27536,15 @@
 
   public abstract class TextToSpeechService extends android.app.Service {
     ctor public TextToSpeechService();
-    method protected int isValidVoiceName(java.lang.String);
     method public android.os.IBinder onBind(android.content.Intent);
     method protected java.lang.String onGetDefaultVoiceNameFor(java.lang.String, java.lang.String, java.lang.String);
     method protected java.util.Set<java.lang.String> onGetFeaturesForLanguage(java.lang.String, java.lang.String, java.lang.String);
     method protected abstract java.lang.String[] onGetLanguage();
-    method protected java.util.List<android.speech.tts.Voice> onGetVoices();
+    method public java.util.List<android.speech.tts.Voice> onGetVoices();
     method protected abstract int onIsLanguageAvailable(java.lang.String, java.lang.String, java.lang.String);
+    method public int onIsValidVoiceName(java.lang.String);
     method protected abstract int onLoadLanguage(java.lang.String, java.lang.String, java.lang.String);
-    method protected int onLoadVoice(java.lang.String);
+    method public int onLoadVoice(java.lang.String);
     method protected abstract void onStop();
     method protected abstract void onSynthesizeText(android.speech.tts.SynthesisRequest, android.speech.tts.SynthesisCallback);
   }
@@ -27562,7 +27565,7 @@
     method public java.util.Locale getLocale();
     method public java.lang.String getName();
     method public int getQuality();
-    method public boolean getRequiresNetworkConnection();
+    method public boolean isNetworkConnectionRequired();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int LATENCY_HIGH = 400; // 0x190
     field public static final int LATENCY_LOW = 200; // 0xc8
@@ -35897,8 +35900,8 @@
   public final class CursorAnchorInfo implements android.os.Parcelable {
     ctor public CursorAnchorInfo(android.os.Parcel);
     method public int describeContents();
-    method public android.graphics.RectF getCharacterRect(int);
-    method public int getCharacterRectFlags(int);
+    method public android.graphics.RectF getCharacterBounds(int);
+    method public int getCharacterBoundsFlags(int);
     method public java.lang.CharSequence getComposingText();
     method public int getComposingTextStart();
     method public float getInsertionMarkerBaseline();
@@ -35913,11 +35916,12 @@
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int FLAG_HAS_INVISIBLE_REGION = 2; // 0x2
     field public static final int FLAG_HAS_VISIBLE_REGION = 1; // 0x1
+    field public static final int FLAG_IS_RTL = 4; // 0x4
   }
 
   public static final class CursorAnchorInfo.Builder {
     ctor public CursorAnchorInfo.Builder();
-    method public android.view.inputmethod.CursorAnchorInfo.Builder addCharacterRect(int, float, float, float, float, int);
+    method public android.view.inputmethod.CursorAnchorInfo.Builder addCharacterBounds(int, float, float, float, float, int);
     method public android.view.inputmethod.CursorAnchorInfo build();
     method public void reset();
     method public android.view.inputmethod.CursorAnchorInfo.Builder setComposingText(int, java.lang.CharSequence);
@@ -37560,6 +37564,7 @@
     method public android.widget.CalendarView getCalendarView();
     method public boolean getCalendarViewShown();
     method public int getDayOfMonth();
+    method public int getFirstDayOfWeek();
     method public long getMaxDate();
     method public long getMinDate();
     method public int getMonth();
@@ -37567,6 +37572,7 @@
     method public int getYear();
     method public void init(int, int, int, android.widget.DatePicker.OnDateChangedListener);
     method public void setCalendarViewShown(boolean);
+    method public void setFirstDayOfWeek(int);
     method public void setMaxDate(long);
     method public void setMinDate(long);
     method public void setSpinnersShown(boolean);
diff --git a/api/removed.txt b/api/removed.txt
index a272cf4..3c16276 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -1,11 +1,3 @@
-package android {
-
-  public static final class R.attr {
-    field public static final int __removed1 = 16843955; // 0x10104b3
-  }
-
-}
-
 package android.media {
 
   public class AudioFormat {
@@ -53,6 +45,8 @@
   }
 
   public final class CursorAnchorInfo implements android.os.Parcelable {
+    method public android.graphics.RectF getCharacterRect(int);
+    method public int getCharacterRectFlags(int);
     method public boolean isInsertionMarkerClipped();
     field public static final int CHARACTER_RECT_TYPE_FULLY_VISIBLE = 1; // 0x1
     field public static final int CHARACTER_RECT_TYPE_INVISIBLE = 3; // 0x3
@@ -63,6 +57,7 @@
   }
 
   public static final class CursorAnchorInfo.Builder {
+    method public android.view.inputmethod.CursorAnchorInfo.Builder addCharacterRect(int, float, float, float, float, int);
     method public android.view.inputmethod.CursorAnchorInfo.Builder setInsertionMarkerLocation(float, float, float, float, boolean);
   }
 
@@ -78,11 +73,3 @@
 
 }
 
-package com.android.internal {
-
-  public static final class R.attr {
-    field public static final int __removed1 = 16843955; // 0x10104b3
-  }
-
-}
-
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 3e03893..9486a72 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2656,17 +2656,24 @@
 
         /**
          * Start an activity in this task.  Brings the task to the foreground.  If this task
-         * is not currently active (that is, its id < 0), then the activity being started
-         * needs to be started as a new task and the Intent's ComponentName must match the
-         * base ComponenentName of the recent task entry.  Otherwise, the activity being
-         * started must <b>not</b> be launched as a new task -- not through explicit intent
-         * flags nor implicitly as the singleTask or singleInstance launch modes.
+         * is not currently active (that is, its id < 0), then a new activity for the given
+         * Intent will be launched as the root of the task and the task brought to the
+         * foreground.  Otherwise, if this task is currently active and the Intent does not specify
+         * an activity to launch in a new task, then a new activity for the given Intent will
+         * be launched on top of the task and the task brought to the foreground.  If this
+         * task is currently active and the Intent specifies {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+         * or would otherwise be launched in to a new task, then the activity not launched but
+         * this task be brought to the foreground and a new intent delivered to the top
+         * activity if appropriate.
          *
-         * <p>See {@link Activity#startActivity(android.content.Intent, android.os.Bundle)
-         * Activity.startActivity} for more information.</p>
+         * <p>In other words, you generally want to use an Intent here that does not specify
+         * {@link Intent#FLAG_ACTIVITY_NEW_TASK} or {@link Intent#FLAG_ACTIVITY_NEW_DOCUMENT},
+         * and let the system do the right thing.</p>
          *
          * @param intent The Intent describing the new activity to be launched on the task.
          * @param options Optional launch options.
+         *
+         * @see Activity#startActivity(android.content.Intent, android.os.Bundle)
          */
         public void startActivity(Context context, Intent intent, Bundle options) {
             ActivityThread thread = ActivityThread.currentActivityThread();
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 1f7e450..394b183 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -509,8 +509,7 @@
         case ACTIVITY_PAUSED_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
-            PersistableBundle persistentState = data.readPersistableBundle();
-            activityPaused(token, persistentState);
+            activityPaused(token);
             reply.writeNoException();
             return true;
         }
@@ -2829,13 +2828,12 @@
         data.recycle();
         reply.recycle();
     }
-    public void activityPaused(IBinder token, PersistableBundle persistentState) throws RemoteException
+    public void activityPaused(IBinder token) throws RemoteException
     {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(token);
-        data.writePersistableBundle(persistentState);
         mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 9dd4605..ffffb6c 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -84,13 +84,13 @@
      * Initial width of the animation.
      * @hide
      */
-    public static final String KEY_ANIM_START_WIDTH = "android:animStartWidth";
+    public static final String KEY_ANIM_WIDTH = "android:animWidth";
 
     /**
      * Initial height of the animation.
      * @hide
      */
-    public static final String KEY_ANIM_START_HEIGHT = "android:animStartHeight";
+    public static final String KEY_ANIM_HEIGHT = "android:animHeight";
 
     /**
      * Callback for when animation is started.
@@ -140,8 +140,8 @@
     private Bitmap mThumbnail;
     private int mStartX;
     private int mStartY;
-    private int mStartWidth;
-    private int mStartHeight;
+    private int mWidth;
+    private int mHeight;
     private IRemoteCallback mAnimationStartedListener;
     private ResultReceiver mTransitionReceiver;
     private boolean mIsReturning;
@@ -238,13 +238,13 @@
      * defines the coordinate space for <var>startX</var> and <var>startY</var>.
      * @param startX The x starting location of the new activity, relative to <var>source</var>.
      * @param startY The y starting location of the activity, relative to <var>source</var>.
-     * @param startWidth The initial width of the new activity.
-     * @param startHeight The initial height of the new activity.
+     * @param width The initial width of the new activity.
+     * @param height The initial height of the new activity.
      * @return Returns a new ActivityOptions object that you can use to
      * supply these options as the options Bundle when starting an activity.
      */
     public static ActivityOptions makeScaleUpAnimation(View source,
-            int startX, int startY, int startWidth, int startHeight) {
+            int startX, int startY, int width, int height) {
         ActivityOptions opts = new ActivityOptions();
         opts.mPackageName = source.getContext().getPackageName();
         opts.mAnimationType = ANIM_SCALE_UP;
@@ -252,8 +252,8 @@
         source.getLocationOnScreen(pts);
         opts.mStartX = pts[0] + startX;
         opts.mStartY = pts[1] + startY;
-        opts.mStartWidth = startWidth;
-        opts.mStartHeight = startHeight;
+        opts.mWidth = width;
+        opts.mHeight = height;
         return opts;
     }
 
@@ -359,9 +359,10 @@
      * @hide
      */
     public static ActivityOptions makeThumbnailAspectScaleUpAnimation(View source,
-            Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
-        return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY, listener,
-                true);
+            Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight,
+            OnAnimationStartedListener listener) {
+        return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY,
+                targetWidth, targetHeight, listener, true);
     }
 
     /**
@@ -382,13 +383,15 @@
      * @hide
      */
     public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source,
-            Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
-        return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY, listener,
-                false);
+            Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight,
+            OnAnimationStartedListener listener) {
+        return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY,
+                targetWidth, targetHeight, listener, false);
     }
 
     private static ActivityOptions makeAspectScaledThumbnailAnimation(View source, Bitmap thumbnail,
-            int startX, int startY, OnAnimationStartedListener listener, boolean scaleUp) {
+            int startX, int startY, int targetWidth, int targetHeight,
+            OnAnimationStartedListener listener, boolean scaleUp) {
         ActivityOptions opts = new ActivityOptions();
         opts.mPackageName = source.getContext().getPackageName();
         opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_ASPECT_SCALE_UP :
@@ -398,6 +401,8 @@
         source.getLocationOnScreen(pts);
         opts.mStartX = pts[0] + startX;
         opts.mStartY = pts[1] + startY;
+        opts.mWidth = targetWidth;
+        opts.mHeight = targetHeight;
         opts.setOnAnimationStartedListener(source.getHandler(), listener);
         return opts;
     }
@@ -543,8 +548,8 @@
             case ANIM_SCALE_UP:
                 mStartX = opts.getInt(KEY_ANIM_START_X, 0);
                 mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
-                mStartWidth = opts.getInt(KEY_ANIM_START_WIDTH, 0);
-                mStartHeight = opts.getInt(KEY_ANIM_START_HEIGHT, 0);
+                mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
+                mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0);
                 break;
 
             case ANIM_THUMBNAIL_SCALE_UP:
@@ -554,6 +559,8 @@
                 mThumbnail = (Bitmap) opts.getParcelable(KEY_ANIM_THUMBNAIL);
                 mStartX = opts.getInt(KEY_ANIM_START_X, 0);
                 mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
+                mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
+                mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0);
                 mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
                         opts.getBinder(KEY_ANIM_START_LISTENER));
                 break;
@@ -605,13 +612,13 @@
     }
 
     /** @hide */
-    public int getStartWidth() {
-        return mStartWidth;
+    public int getWidth() {
+        return mWidth;
     }
 
     /** @hide */
-    public int getStartHeight() {
-        return mStartHeight;
+    public int getHeight() {
+        return mHeight;
     }
 
     /** @hide */
@@ -690,8 +697,8 @@
             case ANIM_SCALE_UP:
                 mStartX = otherOptions.mStartX;
                 mStartY = otherOptions.mStartY;
-                mStartWidth = otherOptions.mStartWidth;
-                mStartHeight = otherOptions.mStartHeight;
+                mWidth = otherOptions.mWidth;
+                mHeight = otherOptions.mHeight;
                 if (mAnimationStartedListener != null) {
                     try {
                         mAnimationStartedListener.sendResult(null);
@@ -707,6 +714,8 @@
                 mThumbnail = otherOptions.mThumbnail;
                 mStartX = otherOptions.mStartX;
                 mStartY = otherOptions.mStartY;
+                mWidth = otherOptions.mWidth;
+                mHeight = otherOptions.mHeight;
                 if (mAnimationStartedListener != null) {
                     try {
                         mAnimationStartedListener.sendResult(null);
@@ -755,8 +764,8 @@
             case ANIM_SCALE_UP:
                 b.putInt(KEY_ANIM_START_X, mStartX);
                 b.putInt(KEY_ANIM_START_Y, mStartY);
-                b.putInt(KEY_ANIM_START_WIDTH, mStartWidth);
-                b.putInt(KEY_ANIM_START_HEIGHT, mStartHeight);
+                b.putInt(KEY_ANIM_WIDTH, mWidth);
+                b.putInt(KEY_ANIM_HEIGHT, mHeight);
                 break;
             case ANIM_THUMBNAIL_SCALE_UP:
             case ANIM_THUMBNAIL_SCALE_DOWN:
@@ -765,6 +774,8 @@
                 b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail);
                 b.putInt(KEY_ANIM_START_X, mStartX);
                 b.putInt(KEY_ANIM_START_Y, mStartY);
+                b.putInt(KEY_ANIM_WIDTH, mWidth);
+                b.putInt(KEY_ANIM_HEIGHT, mHeight);
                 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
                         != null ? mAnimationStartedListener.asBinder() : null);
                 break;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 4f2a3bc5..3a39900 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -563,11 +563,11 @@
         }
 
         public final void schedulePauseActivity(IBinder token, boolean finished,
-                boolean userLeaving, int configChanges) {
+                boolean userLeaving, int configChanges, boolean dontReport) {
             sendMessage(
                     finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                     token,
-                    (userLeaving ? 1 : 0),
+                    (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
                     configChanges);
         }
 
@@ -1283,13 +1283,15 @@
                 } break;
                 case PAUSE_ACTIVITY:
                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
-                    handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
+                    handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,
+                            (msg.arg1&2) != 0);
                     maybeSnapshot();
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
                 case PAUSE_ACTIVITY_FINISHING:
                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
-                    handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
+                    handlePauseActivity((IBinder)msg.obj, true, (msg.arg1&1) != 0, msg.arg2,
+                            (msg.arg1&1) != 0);
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
                 case STOP_ACTIVITY_SHOW:
@@ -3142,7 +3144,7 @@
     }
 
     private void handlePauseActivity(IBinder token, boolean finished,
-            boolean userLeaving, int configChanges) {
+            boolean userLeaving, int configChanges, boolean dontReport) {
         ActivityClientRecord r = mActivities.get(token);
         if (r != null) {
             //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
@@ -3159,9 +3161,11 @@
             }
 
             // Tell the activity manager we have paused.
-            try {
-                ActivityManagerNative.getDefault().activityPaused(token, r.persistentState);
-            } catch (RemoteException ex) {
+            if (!dontReport) {
+                try {
+                    ActivityManagerNative.getDefault().activityPaused(token);
+                } catch (RemoteException ex) {
+                }
             }
             mSomeActivitiesChanged = true;
         }
@@ -4283,6 +4287,8 @@
             AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
         }
 
+        Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
+
         /*
          * Before spawning a new process, reset the time zone to be the system time zone.
          * This needs to be done because the system time zone could have changed after the
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 9cd6d49..404268c 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1693,7 +1693,7 @@
         if (dr == null) {
             dr = itemInfo.loadDefaultIcon(this);
         }
-        return getUserBadgedDrawableForDensity(dr, new UserHandle(mContext.getUserId()), null, 0);
+        return getUserBadgedIcon(dr, new UserHandle(mContext.getUserId()));
     }
 
     private Drawable getBadgedDrawable(Drawable drawable, Drawable badgeDrawable,
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 63e8707..0123e16 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -78,7 +78,8 @@
             boolean finished = data.readInt() != 0;
             boolean userLeaving = data.readInt() != 0;
             int configChanges = data.readInt();
-            schedulePauseActivity(b, finished, userLeaving, configChanges);
+            boolean dontReport = data.readInt() != 0;
+            schedulePauseActivity(b, finished, userLeaving, configChanges, dontReport);
             return true;
         }
 
@@ -689,13 +690,14 @@
     }
     
     public final void schedulePauseActivity(IBinder token, boolean finished,
-            boolean userLeaving, int configChanges) throws RemoteException {
+            boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
         data.writeInt(finished ? 1 : 0);
         data.writeInt(userLeaving ? 1 :0);
         data.writeInt(configChanges);
+        data.writeInt(dontReport ? 1 : 0);
         mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 99428e8..9483680 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -111,7 +111,7 @@
     public void activityResumed(IBinder token) throws RemoteException;
     public void activityIdle(IBinder token, Configuration config,
             boolean stopProfiling) throws RemoteException;
-    public void activityPaused(IBinder token, PersistableBundle persistentState) throws RemoteException;
+    public void activityPaused(IBinder token) throws RemoteException;
     public void activityStopped(IBinder token, Bundle state,
             PersistableBundle persistentState, CharSequence description) throws RemoteException;
     public void activitySlept(IBinder token) throws RemoteException;
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index a7546d9..f53075c 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -49,7 +49,7 @@
  */
 public interface IApplicationThread extends IInterface {
     void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
-            int configChanges) throws RemoteException;
+            int configChanges, boolean dontReport) throws RemoteException;
     void scheduleStopActivity(IBinder token, boolean showWindow,
             int configChanges) throws RemoteException;
     void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index dbf49c5..8d3126d 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -255,16 +255,22 @@
      * Bit in {@link #flags}: If set, a task rooted at this activity will have its
      * baseIntent replaced by the activity immediately above this. Each activity may further
      * relinquish its identity to the activity above it using this flag. Set from the
-     * android.R.attr#relinquishTaskIdentity attribute.
+     * {@link android.R.attr#relinquishTaskIdentity} attribute.
      */
     public static final int FLAG_RELINQUISH_TASK_IDENTITY = 0x1000;
     /**
      * Bit in {@link #flags} indicating that tasks started with this activity are to be
      * removed from the recent list of tasks when the last activity in the task is finished.
-     * {@link android.R.attr#autoRemoveFromRecents}
+     * Corresponds to {@link android.R.attr#autoRemoveFromRecents}
      */
     public static final int FLAG_AUTO_REMOVE_FROM_RECENTS = 0x2000;
     /**
+     * Bit in {@link #flags} indicating that this activity can start is creation/resume
+     * while the previous activity is still pausing.  Corresponds to
+     * {@link android.R.attr#resumeWhilePausing}
+     */
+    public static final int FLAG_RESUME_WHILE_PAUSING = 0x4000;
+    /**
      * @hide Bit in {@link #flags}: If set, this component will only be seen
      * by the primary user.  Only works with broadcast receivers.  Set from the
      * android.R.attr#primaryUserOnly attribute.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 6d40dcf..e0fd532e 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3110,6 +3110,12 @@
                     false)) {
                 a.info.flags |= ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
             }
+
+            if (sa.getBoolean(
+                    com.android.internal.R.styleable.AndroidManifestActivity_resumeWhilePausing,
+                    false)) {
+                a.info.flags |= ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
+            }
         } else {
             a.info.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
             a.info.configChanges = 0;
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
index 7a49eb5c..7390e2b 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.java
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -480,7 +480,7 @@
             int capturePreambleMs = in.readInt();
             boolean triggerInData = in.readByte() == 1;
             AudioFormat captureFormat = null;
-            if (triggerInData) {
+            if (in.readByte() == 1) {
                 int sampleRate = in.readInt();
                 int encoding = in.readInt();
                 int channelMask = in.readInt();
@@ -508,7 +508,8 @@
             dest.writeInt(captureSession);
             dest.writeInt(captureDelayMs);
             dest.writeInt(capturePreambleMs);
-            if (triggerInData && (captureFormat != null)) {
+            dest.writeByte((byte) (triggerInData ? 1 : 0));
+            if (captureFormat != null) {
                 dest.writeByte((byte)1);
                 dest.writeInt(captureFormat.getSampleRate());
                 dest.writeInt(captureFormat.getEncoding());
diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java
index 1a5811c..b6b70cc 100644
--- a/core/java/android/os/Message.java
+++ b/core/java/android/os/Message.java
@@ -113,6 +113,8 @@
 
     private static final int MAX_POOL_SIZE = 50;
 
+    private static boolean gCheckRecycle = true;
+
     /**
      * Return a new Message instance from the global pool. Allows us to
      * avoid allocating new objects in many cases.
@@ -256,6 +258,13 @@
         return m;
     }
 
+    /** @hide */
+    public static void updateCheckRecycle(int targetSdkVersion) {
+        if (targetSdkVersion < Build.VERSION_CODES.L) {
+            gCheckRecycle = false;
+        }
+    }
+
     /**
      * Return a Message instance to the global pool.
      * <p>
@@ -266,8 +275,11 @@
      */
     public void recycle() {
         if (isInUse()) {
-            throw new IllegalStateException("This message cannot be recycled because it "
-                    + "is still in use.");
+            if (gCheckRecycle) {
+                throw new IllegalStateException("This message cannot be recycled because it "
+                        + "is still in use.");
+            }
+            return;
         }
         recycleUnchecked();
     }
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 7245975..a4b6e92 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -578,7 +578,7 @@
          *
          * @deprecated Starting from API level 20, to select network synthesis, call
          * ({@link TextToSpeech#getVoices()}, find a suitable network voice
-         * ({@link Voice#getRequiresNetworkConnection()}) and pass it
+         * ({@link Voice#isNetworkConnectionRequired()}) and pass it
          * to {@link TextToSpeech#setVoice(Voice)}).
          */
         @Deprecated
@@ -596,7 +596,7 @@
 
          * @deprecated Starting from API level 20, to select embedded synthesis, call
          * ({@link TextToSpeech#getVoices()}, find a suitable embedded voice
-         * ({@link Voice#getRequiresNetworkConnection()}) and pass it
+         * ({@link Voice#isNetworkConnectionRequired()}) and pass it
          * to {@link TextToSpeech#setVoice(Voice)}).
          */
         @Deprecated
@@ -957,20 +957,18 @@
      *
      * @param text
      *            The string of text. Example: <code>"south_south_east"</code>
-     * @param filename
-     *            The full path to the sound file (for example:
-     *            "/sdcard/mysounds/hello.wav")
+     * @param file
+     *            File object pointing to the sound file.
      *
      * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
      */
-    public int addSpeech(CharSequence text, String filename) {
+    public int addSpeech(CharSequence text, File file) {
         synchronized (mStartLock) {
-            mUtterances.put(text, Uri.parse(filename));
+            mUtterances.put(text, Uri.fromFile(file));
             return SUCCESS;
         }
     }
 
-
     /**
      * Adds a mapping between a string of text and a sound resource in a
      * package. Use this to add custom earcons.
@@ -1017,7 +1015,11 @@
      *            "/sdcard/mysounds/tick.wav")
      *
      * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
+     *
+     * @deprecated As of API level 20, replaced by
+     *         {@link #addEarcon(String, File)}.
      */
+    @Deprecated
     public int addEarcon(String earcon, String filename) {
         synchronized(mStartLock) {
             mEarcons.put(earcon, Uri.parse(filename));
@@ -1025,6 +1027,27 @@
         }
     }
 
+    /**
+     * Adds a mapping between a string of text and a sound file.
+     * Use this to add custom earcons.
+     *
+     * @see #playEarcon(String, int, HashMap)
+     *
+     * @param earcon
+     *            The name of the earcon.
+     *            Example: <code>"[tick]"</code>
+     * @param file
+     *            File object pointing to the sound file.
+     *
+     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
+     */
+    public int addEarcon(String earcon, File file) {
+        synchronized(mStartLock) {
+            mEarcons.put(earcon, Uri.fromFile(file));
+            return SUCCESS;
+        }
+    }
+
     private Uri makeResourceUri(String packageName, int resourceId) {
         return new Uri.Builder()
                 .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
@@ -1061,7 +1084,7 @@
      */
     public int speak(final CharSequence text,
                      final int queueMode,
-                     final HashMap<String, String> params,
+                     final Bundle params,
                      final String utteranceId) {
         return runAction(new Action<Integer>() {
             @Override
@@ -1103,11 +1126,11 @@
      *
      * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the speak operation.
      * @deprecated As of API level 20, replaced by
-     *         {@link #speak(CharSequence, int, HashMap, String)}.
+     *         {@link #speak(CharSequence, int, Bundle, String)}.
      */
     @Deprecated
     public int speak(final String text, final int queueMode, final HashMap<String, String> params) {
-        return speak(text, queueMode, params,
+        return speak(text, queueMode, convertParamsHashMaptoBundle(params),
                      params == null ? null : params.get(Engine.KEY_PARAM_UTTERANCE_ID));
     }
 
@@ -1135,7 +1158,7 @@
      * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the playEarcon operation.
      */
     public int playEarcon(final String earcon, final int queueMode,
-            final HashMap<String, String> params, final String utteranceId) {
+            final Bundle params, final String utteranceId) {
         return runAction(new Action<Integer>() {
             @Override
             public Integer run(ITextToSpeechService service) throws RemoteException {
@@ -1173,12 +1196,12 @@
      *
      * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the playEarcon operation.
      * @deprecated As of API level 20, replaced by
-     *         {@link #playEarcon(String, int, HashMap, String)}.
+     *         {@link #playEarcon(String, int, Bundle, String)}.
      */
     @Deprecated
     public int playEarcon(final String earcon, final int queueMode,
             final HashMap<String, String> params) {
-        return playEarcon(earcon, queueMode, params,
+        return playEarcon(earcon, queueMode, convertParamsHashMaptoBundle(params),
                           params == null ? null : params.get(Engine.KEY_PARAM_UTTERANCE_ID));
     }
 
@@ -1757,22 +1780,20 @@
      *            must be prefixed by the name of the engine they are intended for. For example
      *            the keys "com.svox.pico_foo" and "com.svox.pico:bar" will be passed to the
      *            engine named "com.svox.pico" if it is being used.
-     * @param filename Absolute file filename to write the generated audio data to.It should be
-     *            something like "/sdcard/myappsounds/mysound.wav".
+     * @param file File to write the generated audio data to.
      * @param utteranceId An unique identifier for this request.
      * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the synthesizeToFile operation.
      */
-    public int synthesizeToFile(final CharSequence text, final HashMap<String, String> params,
-            final String filename, final String utteranceId) {
+    public int synthesizeToFile(final CharSequence text, final Bundle params,
+            final File file, final String utteranceId) {
         return runAction(new Action<Integer>() {
             @Override
             public Integer run(ITextToSpeechService service) throws RemoteException {
                 ParcelFileDescriptor fileDescriptor;
                 int returnValue;
                 try {
-                    File file = new File(filename);
                     if(file.exists() && !file.canWrite()) {
-                        Log.e(TAG, "Can't write to " + filename);
+                        Log.e(TAG, "Can't write to " + file);
                         return ERROR;
                     }
                     fileDescriptor = ParcelFileDescriptor.open(file,
@@ -1784,10 +1805,10 @@
                     fileDescriptor.close();
                     return returnValue;
                 } catch (FileNotFoundException e) {
-                    Log.e(TAG, "Opening file " + filename + " failed", e);
+                    Log.e(TAG, "Opening file " + file + " failed", e);
                     return ERROR;
                 } catch (IOException e) {
-                    Log.e(TAG, "Closing file " + filename + " failed", e);
+                    Log.e(TAG, "Closing file " + file + " failed", e);
                     return ERROR;
                 }
             }
@@ -1817,16 +1838,18 @@
      *
      * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the synthesizeToFile operation.
      * @deprecated As of API level 20, replaced by
-     *         {@link #synthesizeToFile(CharSequence, HashMap, String, String)}.
+     *         {@link #synthesizeToFile(CharSequence, Bundle, File, String)}.
      */
+    @Deprecated
     public int synthesizeToFile(final String text, final HashMap<String, String> params,
             final String filename) {
-        return synthesizeToFile(text, params, filename, params.get(Engine.KEY_PARAM_UTTERANCE_ID));
+        return synthesizeToFile(text, convertParamsHashMaptoBundle(params),
+                new File(filename), params.get(Engine.KEY_PARAM_UTTERANCE_ID));
     }
 
-    private Bundle getParams(HashMap<String, String> params) {
+    private Bundle convertParamsHashMaptoBundle(HashMap<String, String> params) {
         if (params != null && !params.isEmpty()) {
-            Bundle bundle = new Bundle(mParams);
+            Bundle bundle = new Bundle();
             copyIntParam(bundle, params, Engine.KEY_PARAM_STREAM);
             copyIntParam(bundle, params, Engine.KEY_PARAM_SESSION_ID);
             copyStringParam(bundle, params, Engine.KEY_PARAM_UTTERANCE_ID);
@@ -1852,11 +1875,85 @@
             }
 
             return bundle;
+        }
+        return null;
+    }
+
+    private Bundle getParams(Bundle params) {
+        if (params != null && !params.isEmpty()) {
+            Bundle bundle = new Bundle(mParams);
+            bundle.putAll(params);
+
+            verifyIntegerBundleParam(bundle, Engine.KEY_PARAM_STREAM);
+            verifyIntegerBundleParam(bundle, Engine.KEY_PARAM_SESSION_ID);
+            verifyStringBundleParam(bundle, Engine.KEY_PARAM_UTTERANCE_ID);
+            verifyFloatBundleParam(bundle, Engine.KEY_PARAM_VOLUME);
+            verifyFloatBundleParam(bundle, Engine.KEY_PARAM_PAN);
+
+            // Copy feature strings defined by the framework.
+            verifyBooleanBundleParam(bundle, Engine.KEY_FEATURE_NETWORK_SYNTHESIS);
+            verifyBooleanBundleParam(bundle, Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS);
+            verifyIntegerBundleParam(bundle, Engine.KEY_FEATURE_NETWORK_TIMEOUT_MS);
+            verifyIntegerBundleParam(bundle, Engine.KEY_FEATURE_NETWORK_RETRIES_COUNT);
+
+            return bundle;
         } else {
             return mParams;
         }
     }
 
+    private static boolean verifyIntegerBundleParam(Bundle bundle, String key) {
+        if (bundle.containsKey(key)) {
+            if (!(bundle.get(key) instanceof Integer ||
+                    bundle.get(key) instanceof Long)) {
+                bundle.remove(key);
+                Log.w(TAG, "Synthesis request paramter " + key + " containst value "
+                        + " with invalid type. Should be an Integer or a Long");
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static boolean verifyStringBundleParam(Bundle bundle, String key) {
+        if (bundle.containsKey(key)) {
+            if (!(bundle.get(key) instanceof String)) {
+                bundle.remove(key);
+                Log.w(TAG, "Synthesis request paramter " + key + " containst value "
+                        + " with invalid type. Should be a String");
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static boolean verifyBooleanBundleParam(Bundle bundle, String key) {
+        if (bundle.containsKey(key)) {
+            if (!(bundle.get(key) instanceof Boolean ||
+                    bundle.get(key) instanceof String)) {
+                bundle.remove(key);
+                Log.w(TAG, "Synthesis request paramter " + key + " containst value "
+                        + " with invalid type. Should be a Boolean or String");
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    private static boolean verifyFloatBundleParam(Bundle bundle, String key) {
+        if (bundle.containsKey(key)) {
+            if (!(bundle.get(key) instanceof Float ||
+                    bundle.get(key) instanceof Double)) {
+                bundle.remove(key);
+                Log.w(TAG, "Synthesis request paramter " + key + " containst value "
+                        + " with invalid type. Should be a Float or a Double");
+                return false;
+            }
+        }
+        return true;
+    }
+
     private void copyStringParam(Bundle bundle, HashMap<String, String> params, String key) {
         String value = params.get(key);
         if (value != null) {
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 4fea109..d00a433 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -84,7 +84,7 @@
  * the following methods:
  * <ul>
  * <li>{@link #onGetVoices()}</li>
- * <li>{@link #isValidVoiceName(String)}</li>
+ * <li>{@link #onIsValidVoiceName(String)}</li>
  * <li>{@link #onLoadVoice(String)}</li>
  * <li>{@link #onGetDefaultVoiceNameFor(String, String, String)}</li>
  * </ul>
@@ -278,7 +278,7 @@
      *
      * @return A list of voices supported.
      */
-    protected List<Voice> onGetVoices() {
+    public List<Voice> onGetVoices() {
         // Enumerate all locales and check if they are available
         ArrayList<Voice> voices = new ArrayList<Voice>();
         for (Locale locale : Locale.getAvailableLocales()) {
@@ -335,7 +335,7 @@
         }
         Locale properLocale = TtsEngines.normalizeTTSLocale(iso3Locale);
         String voiceName = properLocale.toLanguageTag();
-        if (isValidVoiceName(voiceName) == TextToSpeech.SUCCESS) {
+        if (onIsValidVoiceName(voiceName) == TextToSpeech.SUCCESS) {
             return voiceName;
         } else {
             return null;
@@ -357,7 +357,7 @@
      * @param voiceName Name of the voice.
      * @return {@link TextToSpeech#ERROR} or {@link TextToSpeech#SUCCESS}.
      */
-    protected int onLoadVoice(String voiceName) {
+    public int onLoadVoice(String voiceName) {
         Locale locale = Locale.forLanguageTag(voiceName);
         if (locale == null) {
             return TextToSpeech.ERROR;
@@ -388,7 +388,7 @@
      * @param voiceName Name of the voice.
      * @return {@link TextToSpeech#ERROR} or {@link TextToSpeech#SUCCESS}.
      */
-    protected int isValidVoiceName(String voiceName) {
+    public int onIsValidVoiceName(String voiceName) {
         Locale locale = Locale.forLanguageTag(voiceName);
         if (locale == null) {
             return TextToSpeech.ERROR;
@@ -1275,7 +1275,7 @@
             if (!checkNonNull(voiceName)) {
                 return TextToSpeech.ERROR;
             }
-            int retVal = isValidVoiceName(voiceName);
+            int retVal = onIsValidVoiceName(voiceName);
 
             if (retVal == TextToSpeech.SUCCESS) {
                 SpeechItem item = new LoadVoiceItem(caller, Binder.getCallingUid(),
diff --git a/core/java/android/speech/tts/Voice.java b/core/java/android/speech/tts/Voice.java
index a97141c..a1fa51d 100644
--- a/core/java/android/speech/tts/Voice.java
+++ b/core/java/android/speech/tts/Voice.java
@@ -162,7 +162,7 @@
     /**
      * @return Does the Voice require a network connection to work.
      */
-    public boolean getRequiresNetworkConnection() {
+    public boolean isNetworkConnectionRequired() {
         return mRequiresNetworkConnection;
     }
 
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 5d6d998..6aa86c7 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -94,7 +94,8 @@
     void overridePendingAppTransitionThumb(in Bitmap srcThumb, int startX, int startY,
             IRemoteCallback startedCallback, boolean scaleUp);
     void overridePendingAppTransitionAspectScaledThumb(in Bitmap srcThumb, int startX,
-            int startY, IRemoteCallback startedCallback, boolean scaleUp);
+            int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
+            boolean scaleUp);
     void executeAppTransition();
     void setAppStartingWindow(IBinder token, String pkg, int theme,
             in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
diff --git a/core/java/android/view/inputmethod/CursorAnchorInfo.java b/core/java/android/view/inputmethod/CursorAnchorInfo.java
index fe0f5b9..600fffe 100644
--- a/core/java/android/view/inputmethod/CursorAnchorInfo.java
+++ b/core/java/android/view/inputmethod/CursorAnchorInfo.java
@@ -35,9 +35,21 @@
  * actually inserted.</p>
  */
 public final class CursorAnchorInfo implements Parcelable {
+    /**
+     * The index of the first character of the selected text (inclusive). {@code -1} when there is
+     * no text selection.
+     */
     private final int mSelectionStart;
+    /**
+     * The index of the first character of the selected text (exclusive). {@code -1} when there is
+     * no text selection.
+     */
     private final int mSelectionEnd;
 
+    /**
+     * The index of the first character of the composing text (inclusive). {@code -1} when there is
+     * no composing text.
+     */
     private final int mComposingTextStart;
     /**
      * The text, tracked as a composing region.
@@ -82,7 +94,7 @@
      * Java chars, in the local coordinates that will be transformed with the transformation matrix
      * when rendered on the screen.
      */
-    private final SparseRectFArray mCharacterRects;
+    private final SparseRectFArray mCharacterBoundsArray;
 
     /**
      * Transformation matrix that is applied to any positional information of this class to
@@ -91,18 +103,24 @@
     private final Matrix mMatrix;
 
     /**
-     * Flag for {@link #getInsertionMarkerFlags()} and {@link #getCharacterRectFlags(int)}: the
+     * Flag for {@link #getInsertionMarkerFlags()} and {@link #getCharacterBoundsFlags(int)}: the
      * insertion marker or character bounds have at least one visible region.
      */
     public static final int FLAG_HAS_VISIBLE_REGION = 0x01;
 
     /**
-     * Flag for {@link #getInsertionMarkerFlags()} and {@link #getCharacterRectFlags(int)}: the
+     * Flag for {@link #getInsertionMarkerFlags()} and {@link #getCharacterBoundsFlags(int)}: the
      * insertion marker or character bounds have at least one invisible (clipped) region.
      */
     public static final int FLAG_HAS_INVISIBLE_REGION = 0x02;
 
     /**
+     * Flag for {@link #getInsertionMarkerFlags()} and {@link #getCharacterBoundsFlags(int)}: the
+     * insertion marker or character bounds is placed at right-to-left (RTL) character.
+     */
+    public static final int FLAG_IS_RTL = 0x04;
+
+    /**
      * @removed
      */
     public static final int CHARACTER_RECT_TYPE_MASK = 0x0f;
@@ -144,7 +162,7 @@
         mInsertionMarkerTop = source.readFloat();
         mInsertionMarkerBaseline = source.readFloat();
         mInsertionMarkerBottom = source.readFloat();
-        mCharacterRects = source.readParcelable(SparseRectFArray.class.getClassLoader());
+        mCharacterBoundsArray = source.readParcelable(SparseRectFArray.class.getClassLoader());
         mMatrix = new Matrix();
         mMatrix.setValues(source.createFloatArray());
     }
@@ -166,7 +184,7 @@
         dest.writeFloat(mInsertionMarkerTop);
         dest.writeFloat(mInsertionMarkerBaseline);
         dest.writeFloat(mInsertionMarkerBottom);
-        dest.writeParcelable(mCharacterRects, flags);
+        dest.writeParcelable(mCharacterBoundsArray, flags);
         final float[] matrixArray = new float[9];
         mMatrix.getValues(matrixArray);
         dest.writeFloatArray(matrixArray);
@@ -174,7 +192,6 @@
 
     @Override
     public int hashCode(){
-        // TODO: Improve the hash function.
         final float floatHash = mInsertionMarkerHorizontal + mInsertionMarkerTop
                 + mInsertionMarkerBaseline + mInsertionMarkerBottom;
         int hash = floatHash > 0 ? (int) floatHash : (int)(-floatHash);
@@ -185,7 +202,7 @@
         hash *= 31;
         hash += Objects.hashCode(mComposingText);
         hash *= 31;
-        hash += Objects.hashCode(mCharacterRects);
+        hash += Objects.hashCode(mCharacterBoundsArray);
         hash *= 31;
         hash += Objects.hashCode(mMatrix);
         return hash;
@@ -231,7 +248,7 @@
                 || !areSameFloatImpl(mInsertionMarkerBottom, that.mInsertionMarkerBottom)) {
             return false;
         }
-        if (!Objects.equals(mCharacterRects, that.mCharacterRects)) {
+        if (!Objects.equals(mCharacterBoundsArray, that.mCharacterBoundsArray)) {
             return false;
         }
         if (!Objects.equals(mMatrix, that.mMatrix)) {
@@ -250,7 +267,7 @@
                 + " mInsertionMarkerTop=" + mInsertionMarkerTop
                 + " mInsertionMarkerBaseline=" + mInsertionMarkerBaseline
                 + " mInsertionMarkerBottom=" + mInsertionMarkerBottom
-                + " mCharacterRects=" + Objects.toString(mCharacterRects)
+                + " mCharacterBoundsArray=" + Objects.toString(mCharacterBoundsArray)
                 + " mMatrix=" + Objects.toString(mMatrix)
                 + "}";
     }
@@ -259,6 +276,19 @@
      * Builder for {@link CursorAnchorInfo}. This class is not designed to be thread-safe.
      */
     public static final class Builder {
+        private int mSelectionStart = -1;
+        private int mSelectionEnd = -1;
+        private int mComposingTextStart = -1;
+        private CharSequence mComposingText = null;
+        private float mInsertionMarkerHorizontal = Float.NaN;
+        private float mInsertionMarkerTop = Float.NaN;
+        private float mInsertionMarkerBaseline = Float.NaN;
+        private float mInsertionMarkerBottom = Float.NaN;
+        private int mInsertionMarkerFlags = 0;
+        private SparseRectFArrayBuilder mCharacterBoundsArrayBuilder = null;
+        private final Matrix mMatrix = new Matrix(Matrix.IDENTITY_MATRIX);
+        private boolean mMatrixInitialized = false;
+
         /**
          * Sets the text range of the selection. Calling this can be skipped if there is no
          * selection.
@@ -268,8 +298,6 @@
             mSelectionEnd = newEnd;
             return this;
         }
-        private int mSelectionStart = -1;
-        private int mSelectionEnd = -1;
 
         /**
          * Sets the text range of the composing text. Calling this can be skipped if there is
@@ -288,8 +316,6 @@
             }
             return this;
         }
-        private int mComposingTextStart = -1;
-        private CharSequence mComposingText = null;
 
         /**
          * @removed
@@ -335,11 +361,33 @@
             mInsertionMarkerFlags = flags;
             return this;
         }
-        private float mInsertionMarkerHorizontal = Float.NaN;
-        private float mInsertionMarkerTop = Float.NaN;
-        private float mInsertionMarkerBaseline = Float.NaN;
-        private float mInsertionMarkerBottom = Float.NaN;
-        private int mInsertionMarkerFlags = 0;
+
+        /**
+         * Adds the bounding box of the character specified with the index.
+         *
+         * @param index index of the character in Java chars units. Must be specified in
+         * ascending order across successive calls.
+         * @param left x coordinate of the left edge of the character in local coordinates.
+         * @param top y coordinate of the top edge of the character in local coordinates.
+         * @param right x coordinate of the right edge of the character in local coordinates.
+         * @param bottom y coordinate of the bottom edge of the character in local coordinates.
+         * @param flags flags for this character bounds. See {@link #FLAG_HAS_VISIBLE_REGION},
+         * {@link #FLAG_HAS_INVISIBLE_REGION} and {@link #FLAG_IS_RTL}. These flags must be
+         * specified when necessary.
+         * @throws IllegalArgumentException If the index is a negative value, or not greater than
+         * all of the previously called indices.
+         */
+        public Builder addCharacterBounds(final int index, final float left, final float top,
+                final float right, final float bottom, final int flags) {
+            if (index < 0) {
+                throw new IllegalArgumentException("index must not be a negative integer.");
+            }
+            if (mCharacterBoundsArrayBuilder == null) {
+                mCharacterBoundsArrayBuilder = new SparseRectFArrayBuilder();
+            }
+            mCharacterBoundsArrayBuilder.append(index, left, top, right, bottom, flags);
+            return this;
+        }
 
         /**
          * Adds the bounding box of the character specified with the index.
@@ -358,21 +406,25 @@
          * example.
          * @throws IllegalArgumentException If the index is a negative value, or not greater than
          * all of the previously called indices.
+         * @removed
          */
         public Builder addCharacterRect(final int index, final float leadingEdgeX,
                 final float leadingEdgeY, final float trailingEdgeX, final float trailingEdgeY,
                 final int flags) {
-            if (index < 0) {
-                throw new IllegalArgumentException("index must not be a negative integer.");
+            final int newFlags;
+            final float left;
+            final float right;
+            if (leadingEdgeX <= trailingEdgeX) {
+                newFlags = flags;
+                left = leadingEdgeX;
+                right = trailingEdgeX;
+            } else {
+                newFlags = flags | FLAG_IS_RTL;
+                left = trailingEdgeX;
+                right = leadingEdgeX;
             }
-            if (mCharacterRectBuilder == null) {
-                mCharacterRectBuilder = new SparseRectFArrayBuilder();
-            }
-            mCharacterRectBuilder.append(index, leadingEdgeX, leadingEdgeY, trailingEdgeX,
-                    trailingEdgeY, flags);
-            return this;
+            return addCharacterBounds(index, left, leadingEdgeY, right, trailingEdgeY, newFlags);
         }
-        private SparseRectFArrayBuilder mCharacterRectBuilder = null;
 
         /**
          * Sets the matrix that transforms local coordinates into screen coordinates.
@@ -384,8 +436,6 @@
             mMatrixInitialized = true;
             return this;
         }
-        private final Matrix mMatrix = new Matrix(Matrix.IDENTITY_MATRIX);
-        private boolean mMatrixInitialized = false;
 
         /**
          * @return {@link CursorAnchorInfo} using parameters in this {@link Builder}.
@@ -394,13 +444,15 @@
          */
         public CursorAnchorInfo build() {
             if (!mMatrixInitialized) {
-                // Coordinate transformation matrix is mandatory when positional parameters are
-                // specified.
-                if ((mCharacterRectBuilder != null && !mCharacterRectBuilder.isEmpty()) ||
-                        !Float.isNaN(mInsertionMarkerHorizontal) ||
-                        !Float.isNaN(mInsertionMarkerTop) ||
-                        !Float.isNaN(mInsertionMarkerBaseline) ||
-                        !Float.isNaN(mInsertionMarkerBottom)) {
+                // Coordinate transformation matrix is mandatory when at least one positional
+                // parameter is specified.
+                final boolean hasCharacterBounds = (mCharacterBoundsArrayBuilder != null
+                        && !mCharacterBoundsArrayBuilder.isEmpty());
+                if (hasCharacterBounds
+                        || !Float.isNaN(mInsertionMarkerHorizontal)
+                        || !Float.isNaN(mInsertionMarkerTop)
+                        || !Float.isNaN(mInsertionMarkerBaseline)
+                        || !Float.isNaN(mInsertionMarkerBottom)) {
                     throw new IllegalArgumentException("Coordinate transformation matrix is " +
                             "required when positional parameters are specified.");
                 }
@@ -424,8 +476,8 @@
             mInsertionMarkerBottom = Float.NaN;
             mMatrix.set(Matrix.IDENTITY_MATRIX);
             mMatrixInitialized = false;
-            if (mCharacterRectBuilder != null) {
-                mCharacterRectBuilder.reset();
+            if (mCharacterBoundsArrayBuilder != null) {
+                mCharacterBoundsArrayBuilder.reset();
             }
         }
     }
@@ -440,8 +492,8 @@
         mInsertionMarkerTop = builder.mInsertionMarkerTop;
         mInsertionMarkerBaseline = builder.mInsertionMarkerBaseline;
         mInsertionMarkerBottom = builder.mInsertionMarkerBottom;
-        mCharacterRects = builder.mCharacterRectBuilder != null ?
-                builder.mCharacterRectBuilder.build() : null;
+        mCharacterBoundsArray = builder.mCharacterBoundsArrayBuilder != null ?
+                builder.mCharacterBoundsArrayBuilder.build() : null;
         mMatrix = new Matrix(builder.mMatrix);
     }
 
@@ -539,6 +591,19 @@
     /**
      * Returns a new instance of {@link RectF} that indicates the location of the character
      * specified with the index.
+     * @param index index of the character in a Java chars.
+     * @return the character bounds in local coordinates as a new instance of {@link RectF}.
+     */
+    public RectF getCharacterBounds(final int index) {
+        if (mCharacterBoundsArray == null) {
+            return null;
+        }
+        return mCharacterBoundsArray.get(index);
+    }
+
+    /**
+     * Returns a new instance of {@link RectF} that indicates the location of the character
+     * specified with the index.
      * <p>
      * Note that coordinates are not necessarily contiguous or even monotonous, especially when
      * RTL text and LTR text are mixed.
@@ -549,28 +614,32 @@
      * the location. Note that the {@code left} field can be greater than the {@code right} field
      * if the character is in RTL text. Returns {@code null} if no location information is
      * available.
+     * @removed
      */
-    // TODO: Prepare a document about the expected behavior for surrogate pairs, combining
-    // characters, and non-graphical chars.
     public RectF getCharacterRect(final int index) {
-        if (mCharacterRects == null) {
-            return null;
+        return getCharacterBounds(index);
+    }
+
+    /**
+     * Returns the flags associated with the character bounds specified with the index.
+     * @param index index of the character in a Java chars.
+     * @return {@code 0} if no flag is specified.
+     */
+    public int getCharacterBoundsFlags(final int index) {
+        if (mCharacterBoundsArray == null) {
+            return 0;
         }
-        return mCharacterRects.get(index);
+        return mCharacterBoundsArray.getFlags(index, 0);
     }
 
     /**
      * Returns the flags associated with the character rect specified with the index.
      * @param index index of the character in a Java chars.
      * @return {@code 0} if no flag is specified.
+     * @removed
      */
-    // TODO: Prepare a document about the expected behavior for surrogate pairs, combining
-    // characters, and non-graphical chars.
     public int getCharacterRectFlags(final int index) {
-        if (mCharacterRects == null) {
-            return 0;
-        }
-        return mCharacterRects.getFlags(index, 0);
+        return getCharacterBoundsFlags(index);
     }
 
     /**
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 2729bd0..d77f0b2 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -125,6 +125,7 @@
         final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker,
                 defStyleAttr, defStyleRes);
         final int mode = a.getInt(R.styleable.DatePicker_datePickerMode, MODE_SPINNER);
+        final int firstDayOfWeek = a.getInt(R.styleable.DatePicker_firstDayOfWeek, 0);
         a.recycle();
 
         switch (mode) {
@@ -136,6 +137,10 @@
                 mDelegate = createSpinnerUIDelegate(context, attrs, defStyleAttr, defStyleRes);
                 break;
         }
+
+        if (firstDayOfWeek != 0) {
+            setFirstDayOfWeek(firstDayOfWeek);
+        }
     }
 
     private DatePickerDelegate createSpinnerUIDelegate(Context context, AttributeSet attrs,
@@ -300,6 +305,47 @@
     }
 
     /**
+     * Sets the first day of week.
+     *
+     * @param firstDayOfWeek The first day of the week conforming to the
+     *            {@link CalendarView} APIs.
+     * @see Calendar#SUNDAY
+     * @see Calendar#MONDAY
+     * @see Calendar#TUESDAY
+     * @see Calendar#WEDNESDAY
+     * @see Calendar#THURSDAY
+     * @see Calendar#FRIDAY
+     * @see Calendar#SATURDAY
+     *
+     * @attr ref android.R.styleable#DatePicker_firstDayOfWeek
+     */
+    public void setFirstDayOfWeek(int firstDayOfWeek) {
+        if (firstDayOfWeek < Calendar.SUNDAY || firstDayOfWeek > Calendar.SATURDAY) {
+            throw new IllegalArgumentException("firstDayOfWeek must be between 1 and 7");
+        }
+        mDelegate.setFirstDayOfWeek(firstDayOfWeek);
+    }
+
+    /**
+     * Gets the first day of week.
+     *
+     * @return The first day of the week conforming to the {@link CalendarView}
+     *         APIs.
+     * @see Calendar#SUNDAY
+     * @see Calendar#MONDAY
+     * @see Calendar#TUESDAY
+     * @see Calendar#WEDNESDAY
+     * @see Calendar#THURSDAY
+     * @see Calendar#FRIDAY
+     * @see Calendar#SATURDAY
+     *
+     * @attr ref android.R.styleable#DatePicker_firstDayOfWeek
+     */
+    public int getFirstDayOfWeek() {
+        return mDelegate.getFirstDayOfWeek();
+    }
+
+    /**
      * Gets whether the {@link CalendarView} is shown.
      *
      * @return True if the calendar view is shown.
@@ -315,7 +361,7 @@
      * @return The calendar view.
      * @see #getCalendarViewShown()
      */
-    public CalendarView getCalendarView () {
+    public CalendarView getCalendarView() {
         return mDelegate.getCalendarView();
     }
 
@@ -382,6 +428,9 @@
         int getMonth();
         int getDayOfMonth();
 
+        void setFirstDayOfWeek(int firstDayOfWeek);
+        int getFirstDayOfWeek();
+
         void setMinDate(long minDate);
         Calendar getMinDate();
 
@@ -699,6 +748,16 @@
         }
 
         @Override
+        public void setFirstDayOfWeek(int firstDayOfWeek) {
+            mCalendarView.setFirstDayOfWeek(firstDayOfWeek);
+        }
+
+        @Override
+        public int getFirstDayOfWeek() {
+            return mCalendarView.getFirstDayOfWeek();
+        }
+
+        @Override
         public void setMinDate(long minDate) {
             mTempDate.setTimeInMillis(minDate);
             if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index eed49bf..b962962 100644
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -49,6 +49,7 @@
  */
 class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate implements
         View.OnClickListener, DatePickerController {
+    private static final int USE_LOCALE = 0;
 
     private static final int UNINITIALIZED = -1;
     private static final int MONTH_AND_DAY_VIEW = 0;
@@ -99,6 +100,8 @@
     private Calendar mMinDate;
     private Calendar mMaxDate;
 
+    private int mFirstDayOfWeek = USE_LOCALE;
+
     private HashSet<OnDateChangedListener> mListeners = new HashSet<OnDateChangedListener>();
 
     public DatePickerCalendarDelegate(DatePicker delegator, Context context, AttributeSet attrs,
@@ -438,7 +441,15 @@
     }
 
     @Override
+    public void setFirstDayOfWeek(int firstDayOfWeek) {
+        mFirstDayOfWeek = firstDayOfWeek;
+    }
+
+    @Override
     public int getFirstDayOfWeek() {
+        if (mFirstDayOfWeek != USE_LOCALE) {
+            return mFirstDayOfWeek;
+        }
         return mCurrentDate.getFirstDayOfWeek();
     }
 
diff --git a/core/java/android/widget/DatePickerController.java b/core/java/android/widget/DatePickerController.java
index 6a074da..059709d 100644
--- a/core/java/android/widget/DatePickerController.java
+++ b/core/java/android/widget/DatePickerController.java
@@ -35,6 +35,7 @@
 
     Calendar getSelectedDay();
 
+    void setFirstDayOfWeek(int firstDayOfWeek);
     int getFirstDayOfWeek();
 
     int getMinYear();
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 22138d0..3f168e8 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3060,47 +3060,69 @@
                     final CharSequence composingText = text.subSequence(composingTextStart,
                             composingTextEnd);
                     builder.setComposingText(composingTextStart, composingText);
-                }
-                // TODO: Optimize this loop by caching the result.
-                for (int offset = composingTextStart; offset < composingTextEnd; offset++) {
-                    if (offset < 0) {
-                        continue;
+
+                    final int minLine = layout.getLineForOffset(composingTextStart);
+                    final int maxLine = layout.getLineForOffset(composingTextEnd - 1);
+                    for (int line = minLine; line <= maxLine; ++line) {
+                        final int lineStart = layout.getLineStart(line);
+                        final int lineEnd = layout.getLineEnd(line);
+                        final int offsetStart = Math.max(lineStart, composingTextStart);
+                        final int offsetEnd = Math.min(lineEnd, composingTextEnd);
+                        final boolean ltrLine =
+                                layout.getParagraphDirection(line) == Layout.DIR_LEFT_TO_RIGHT;
+                        final float[] widths = new float[offsetEnd - offsetStart];
+                        layout.getPaint().getTextWidths(text, offsetStart, offsetEnd, widths);
+                        final float top = layout.getLineTop(line);
+                        final float bottom = layout.getLineBottom(line);
+                        for (int offset = offsetStart; offset < offsetEnd; ++offset) {
+                            final float charWidth = widths[offset - offsetStart];
+                            final boolean isRtl = layout.isRtlCharAt(offset);
+                            final float primary = layout.getPrimaryHorizontal(offset);
+                            final float secondary = layout.getSecondaryHorizontal(offset);
+                            // TODO: This doesn't work perfectly for text with custom styles and
+                            // TAB chars.
+                            final float left;
+                            final float right;
+                            if (ltrLine) {
+                                if (isRtl) {
+                                    left = secondary - charWidth;
+                                    right = secondary;
+                                } else {
+                                    left = primary;
+                                    right = primary + charWidth;
+                                }
+                            } else {
+                                if (!isRtl) {
+                                    left = secondary;
+                                    right = secondary + charWidth;
+                                } else {
+                                    left = primary - charWidth;
+                                    right = primary;
+                                }
+                            }
+                            // TODO: Check top-right and bottom-left as well.
+                            final float localLeft = left + viewportToContentHorizontalOffset;
+                            final float localRight = right + viewportToContentHorizontalOffset;
+                            final float localTop = top + viewportToContentVerticalOffset;
+                            final float localBottom = bottom + viewportToContentVerticalOffset;
+                            final boolean isTopLeftVisible = isPositionVisible(localLeft, localTop);
+                            final boolean isBottomRightVisible =
+                                    isPositionVisible(localRight, localBottom);
+                            int characterBoundsFlags = 0;
+                            if (isTopLeftVisible || isBottomRightVisible) {
+                                characterBoundsFlags |= CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
+                            }
+                            if (!isTopLeftVisible || !isTopLeftVisible) {
+                                characterBoundsFlags |= CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION;
+                            }
+                            if (isRtl) {
+                                characterBoundsFlags |= CursorAnchorInfo.FLAG_IS_RTL;
+                            }
+                            // Here offset is the index in Java chars.
+                            builder.addCharacterBounds(offset, localLeft, localTop, localRight,
+                                    localBottom, characterBoundsFlags);
+                        }
                     }
-                    final boolean isRtl = layout.isRtlCharAt(offset);
-                    final int line = layout.getLineForOffset(offset);
-                    final int nextCharIndex = offset + 1;
-                    final float localLeadingEdgeX = layout.getPrimaryHorizontal(offset);
-                    final float localTrailingEdgeX;
-                    if (nextCharIndex != layout.getLineEnd(line)) {
-                        localTrailingEdgeX = layout.getPrimaryHorizontal(nextCharIndex);
-                    } else if (isRtl) {
-                        localTrailingEdgeX = layout.getLineLeft(line);
-                    } else {
-                        localTrailingEdgeX = layout.getLineRight(line);
-                    }
-                    final float leadingEdgeX = localLeadingEdgeX
-                            + viewportToContentHorizontalOffset;
-                    final float trailingEdgeX = localTrailingEdgeX
-                            + viewportToContentHorizontalOffset;
-                    final float top = layout.getLineTop(line) + viewportToContentVerticalOffset;
-                    final float bottom = layout.getLineBottom(line)
-                            + viewportToContentVerticalOffset;
-                    // TODO: Check right-top and left-bottom as well.
-                    final boolean isLeadingEdgeTopVisible = isPositionVisible(leadingEdgeX, top);
-                    final boolean isTrailingEdgeBottomVisible =
-                            isPositionVisible(trailingEdgeX, bottom);
-                    int characterRectFlags = 0;
-                    if (isLeadingEdgeTopVisible || isTrailingEdgeBottomVisible) {
-                        characterRectFlags |= CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
-                    }
-                    if (!isLeadingEdgeTopVisible || !isTrailingEdgeBottomVisible) {
-                        characterRectFlags |= CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION;
-                    }
-                    // Here offset is the index in Java chars.
-                    // TODO: We must have a well-defined specification. For example, how
-                    // surrogate pairs and composition letters are handled must be documented.
-                    builder.addCharacterRect(offset, leadingEdgeX, top, trailingEdgeX, bottom,
-                            characterRectFlags);
                 }
             }
 
@@ -3127,6 +3149,9 @@
                 if (!isTopVisible || !isBottomVisible) {
                     insertionMarkerFlags |= CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION;
                 }
+                if (layout.isRtlCharAt(offset)) {
+                    insertionMarkerFlags |= CursorAnchorInfo.FLAG_IS_RTL;
+                }
                 builder.setInsertionMarkerLocation(insertionMarkerX, insertionMarkerTop,
                         insertionMarkerBaseline, insertionMarkerBottom, insertionMarkerFlags);
             }
diff --git a/core/jni/android_hardware_SoundTrigger.cpp b/core/jni/android_hardware_SoundTrigger.cpp
index f0d7a35..7b33bc2 100644
--- a/core/jni/android_hardware_SoundTrigger.cpp
+++ b/core/jni/android_hardware_SoundTrigger.cpp
@@ -211,7 +211,7 @@
     }
 
     jobject jAudioFormat = NULL;
-    if (event->trigger_in_data) {
+    if (event->trigger_in_data || event->capture_available) {
         jAudioFormat = env->NewObject(gAudioFormatClass,
                                     gAudioFormatCstor,
                                     audioFormatFromNative(event->audio_config.format),
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d1cc1fd..cf4064f 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4341,6 +4341,8 @@
         <attr name="minDate" format="string" />
         <!-- The maximal date shown by this calendar view in mm/dd/yyyy format. -->
         <attr name="maxDate" format="string" />
+        <!-- The first day of week according to {@link java.util.Calendar}. -->
+        <attr name="firstDayOfWeek" />
         <!-- @hide The layout of the date picker. -->
         <attr name="internalLayout" format="reference"  />
         <!-- @hide The layout of the legacy DatePicker. -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index e905a3a..10c2518e 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -939,7 +939,7 @@
          {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK
          Intent.FLAG_ACTIVITY_MULTIPLE_TASK}. If the value of
          documentLaunchModes is <code>never</code> then any use of
-.........{@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT
+         {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT
          Intent.FLAG_ACTIVITY_NEW_DOCUMENT} to launch this activity will be ignored. -->
     <attr name="documentLaunchMode">
         <!-- The default mode, which will create a new task only when
@@ -994,6 +994,15 @@
          TaskDescription to change labels, colors and icons in the recent task list. -->
     <attr name="relinquishTaskIdentity" format="boolean" />
 
+    <!-- Indicate that it is okay for this activity be resumed while the previous
+         activity is in the process of pausing, without waiting for the previous pause
+         to complete.  Use this with caution: your activity can not acquire any exclusive
+         resources (such as opening the camera or recording audio) when it launches, or it
+         may conflict with the previous activity and fail.
+
+         <p>The default value of this attribute is <code>false</code>. -->
+    <attr name="resumeWhilePausing" format="boolean" />
+
     <!-- The <code>manifest</code> tag is the root of an
          <code>AndroidManifest.xml</code> file,
          describing the contents of an Android package (.apk) file.  One
@@ -1678,6 +1687,7 @@
         <attr name="maxRecents" />
         <attr name="autoRemoveFromRecents" />
         <attr name="relinquishTaskIdentity" />
+        <attr name="resumeWhilePausing" />
     </declare-styleable>
     
     <!-- The <code>activity-alias</code> tag declares a new
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index a4c3474..5b047f7 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2266,7 +2266,7 @@
   <public type="attr" name="windowReenterTransition" />
   <public type="attr" name="windowSharedElementReturnTransition" />
   <public type="attr" name="windowSharedElementReenterTransition" />
-  <public type="attr" name="__removed1" />
+  <public type="attr" name="resumeWhilePausing" />
   <public type="attr" name="datePickerMode"/>
   <public type="attr" name="timePickerMode"/>
   <public type="attr" name="inset" />
diff --git a/core/tests/inputmethodtests/run_core_inputmethod_test.sh b/core/tests/inputmethodtests/run_core_inputmethod_test.sh
index ed8b7f7..a11e49b 100755
--- a/core/tests/inputmethodtests/run_core_inputmethod_test.sh
+++ b/core/tests/inputmethodtests/run_core_inputmethod_test.sh
@@ -15,7 +15,7 @@
 
 if [[ $rebuild == true ]]; then
   make -j4 FrameworksCoreInputMethodTests
-  TESTAPP=${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreInputMethodTests.apk
+  TESTAPP=${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreInputMethodTests/FrameworksCoreInputMethodTests.apk
   COMMAND="adb install -r $TESTAPP"
   echo $COMMAND
   $COMMAND
diff --git a/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java b/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
index cc4a7c4..b6a03d9 100644
--- a/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
+++ b/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
@@ -26,14 +26,12 @@
 
 import java.util.Objects;
 
-import static android.view.inputmethod.CursorAnchorInfo.CHARACTER_RECT_TYPE_FULLY_VISIBLE;
-import static android.view.inputmethod.CursorAnchorInfo.CHARACTER_RECT_TYPE_INVISIBLE;
-import static android.view.inputmethod.CursorAnchorInfo.CHARACTER_RECT_TYPE_NOT_FEASIBLE;
-import static android.view.inputmethod.CursorAnchorInfo.CHARACTER_RECT_TYPE_PARTIALLY_VISIBLE;
-import static android.view.inputmethod.CursorAnchorInfo.CHARACTER_RECT_TYPE_UNSPECIFIED;
+import static android.view.inputmethod.CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION;
+import static android.view.inputmethod.CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
+import static android.view.inputmethod.CursorAnchorInfo.FLAG_IS_RTL;
 
 public class CursorAnchorInfoTest extends InstrumentationTestCase {
-    private static final RectF[] MANY_RECTS = new RectF[] {
+    private static final RectF[] MANY_BOUNDS = new RectF[] {
             new RectF(101.0f, 201.0f, 301.0f, 401.0f),
             new RectF(102.0f, 202.0f, 302.0f, 402.0f),
             new RectF(103.0f, 203.0f, 303.0f, 403.0f),
@@ -55,25 +53,25 @@
             new RectF(119.0f, 219.0f, 319.0f, 419.0f),
     };
     private static final int[] MANY_FLAGS_ARRAY = new int[] {
-        CHARACTER_RECT_TYPE_FULLY_VISIBLE,
-        CHARACTER_RECT_TYPE_INVISIBLE,
-        CHARACTER_RECT_TYPE_PARTIALLY_VISIBLE,
-        CHARACTER_RECT_TYPE_FULLY_VISIBLE,
-        CHARACTER_RECT_TYPE_FULLY_VISIBLE,
-        CHARACTER_RECT_TYPE_FULLY_VISIBLE,
-        CHARACTER_RECT_TYPE_NOT_FEASIBLE,
-        CHARACTER_RECT_TYPE_FULLY_VISIBLE,
-        CHARACTER_RECT_TYPE_FULLY_VISIBLE,
-        CHARACTER_RECT_TYPE_FULLY_VISIBLE,
-        CHARACTER_RECT_TYPE_FULLY_VISIBLE,
-        CHARACTER_RECT_TYPE_FULLY_VISIBLE,
-        CHARACTER_RECT_TYPE_FULLY_VISIBLE,
-        CHARACTER_RECT_TYPE_FULLY_VISIBLE,
-        CHARACTER_RECT_TYPE_FULLY_VISIBLE,
-        CHARACTER_RECT_TYPE_FULLY_VISIBLE,
-        CHARACTER_RECT_TYPE_FULLY_VISIBLE,
-        CHARACTER_RECT_TYPE_NOT_FEASIBLE,
-        CHARACTER_RECT_TYPE_NOT_FEASIBLE,
+        FLAG_HAS_INVISIBLE_REGION,
+        FLAG_HAS_INVISIBLE_REGION | FLAG_HAS_VISIBLE_REGION,
+        FLAG_HAS_VISIBLE_REGION,
+        FLAG_HAS_VISIBLE_REGION,
+        FLAG_HAS_VISIBLE_REGION,
+        FLAG_HAS_VISIBLE_REGION,
+        FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
+        FLAG_HAS_INVISIBLE_REGION | FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
+        FLAG_HAS_INVISIBLE_REGION | FLAG_IS_RTL,
+        FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
+        FLAG_HAS_VISIBLE_REGION,
+        FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
+        FLAG_HAS_VISIBLE_REGION,
+        FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
+        FLAG_HAS_VISIBLE_REGION,
+        FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
+        FLAG_HAS_VISIBLE_REGION,
+        FLAG_HAS_INVISIBLE_REGION,
+        FLAG_HAS_INVISIBLE_REGION | FLAG_IS_RTL,
     };
 
     @SmallTest
@@ -82,11 +80,13 @@
         final int SELECTION_END = 40;
         final int COMPOSING_TEXT_START = 32;
         final String COMPOSING_TEXT = "test";
-        final boolean INSERTION_MARKER_CLIPPED = true;
+        final int INSERTION_MARKER_FLAGS =
+                FLAG_HAS_VISIBLE_REGION | FLAG_HAS_INVISIBLE_REGION | FLAG_IS_RTL;
         final float INSERTION_MARKER_HORIZONTAL = 10.5f;
         final float INSERTION_MARKER_TOP = 100.1f;
         final float INSERTION_MARKER_BASELINE = 110.4f;
         final float INSERTION_MARKER_BOTOM = 111.0f;
+
         Matrix TRANSFORM_MATRIX = new Matrix(Matrix.IDENTITY_MATRIX);
         TRANSFORM_MATRIX.setScale(10.0f, 20.0f);
 
@@ -94,13 +94,13 @@
         builder.setSelectionRange(SELECTION_START, SELECTION_END)
                 .setComposingText(COMPOSING_TEXT_START, COMPOSING_TEXT)
                 .setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP,
-                        INSERTION_MARKER_BASELINE, INSERTION_MARKER_BOTOM,
-                        INSERTION_MARKER_CLIPPED)
+                        INSERTION_MARKER_BASELINE, INSERTION_MARKER_BOTOM, INSERTION_MARKER_FLAGS)
                 .setMatrix(TRANSFORM_MATRIX);
-        for (int i = 0; i < MANY_RECTS.length; i++) {
-            final RectF rect = MANY_RECTS[i];
+        for (int i = 0; i < MANY_BOUNDS.length; i++) {
+            final RectF bounds = MANY_BOUNDS[i];
             final int flags = MANY_FLAGS_ARRAY[i];
-            builder.addCharacterRect(i, rect.left, rect.top, rect.right, rect.bottom, flags);
+            builder.addCharacterBounds(i, bounds.left, bounds.top, bounds.right, bounds.bottom,
+                    flags);
         }
 
         final CursorAnchorInfo info = builder.build();
@@ -108,26 +108,24 @@
         assertEquals(SELECTION_END, info.getSelectionEnd());
         assertEquals(COMPOSING_TEXT_START, info.getComposingTextStart());
         assertTrue(TextUtils.equals(COMPOSING_TEXT, info.getComposingText()));
-        assertTrue(info.isInsertionMarkerClipped());
+        assertEquals(INSERTION_MARKER_FLAGS, info.getInsertionMarkerFlags());
         assertEquals(INSERTION_MARKER_HORIZONTAL, info.getInsertionMarkerHorizontal());
         assertEquals(INSERTION_MARKER_TOP, info.getInsertionMarkerTop());
         assertEquals(INSERTION_MARKER_BASELINE, info.getInsertionMarkerBaseline());
         assertEquals(INSERTION_MARKER_BOTOM, info.getInsertionMarkerBottom());
         assertEquals(TRANSFORM_MATRIX, info.getMatrix());
-        for (int i = 0; i < MANY_RECTS.length; i++) {
-            final RectF expectedRect = MANY_RECTS[i];
-            assertEquals(expectedRect, info.getCharacterRect(i));
+        for (int i = 0; i < MANY_BOUNDS.length; i++) {
+            final RectF expectedBounds = MANY_BOUNDS[i];
+            assertEquals(expectedBounds, info.getCharacterRect(i));
         }
         assertNull(info.getCharacterRect(-1));
-        assertNull(info.getCharacterRect(MANY_RECTS.length + 1));
+        assertNull(info.getCharacterRect(MANY_BOUNDS.length + 1));
         for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) {
             final int expectedFlags = MANY_FLAGS_ARRAY[i];
             assertEquals(expectedFlags, info.getCharacterRectFlags(i));
         }
-        assertEquals(CHARACTER_RECT_TYPE_UNSPECIFIED,
-                info.getCharacterRectFlags(-1));
-        assertEquals(CHARACTER_RECT_TYPE_UNSPECIFIED,
-                info.getCharacterRectFlags(MANY_RECTS.length + 1));
+        assertEquals(0, info.getCharacterRectFlags(-1));
+        assertEquals(0, info.getCharacterRectFlags(MANY_BOUNDS.length + 1));
 
         // Make sure that the builder can reproduce the same object.
         final CursorAnchorInfo info2 = builder.build();
@@ -135,25 +133,24 @@
         assertEquals(SELECTION_END, info2.getSelectionEnd());
         assertEquals(COMPOSING_TEXT_START, info2.getComposingTextStart());
         assertTrue(TextUtils.equals(COMPOSING_TEXT, info2.getComposingText()));
-        assertTrue(info2.isInsertionMarkerClipped());
+        assertEquals(INSERTION_MARKER_FLAGS, info2.getInsertionMarkerFlags());
         assertEquals(INSERTION_MARKER_HORIZONTAL, info2.getInsertionMarkerHorizontal());
         assertEquals(INSERTION_MARKER_TOP, info2.getInsertionMarkerTop());
         assertEquals(INSERTION_MARKER_BASELINE, info2.getInsertionMarkerBaseline());
         assertEquals(INSERTION_MARKER_BOTOM, info2.getInsertionMarkerBottom());
         assertEquals(TRANSFORM_MATRIX, info2.getMatrix());
-        for (int i = 0; i < MANY_RECTS.length; i++) {
-            final RectF expectedRect = MANY_RECTS[i];
-            assertEquals(expectedRect, info2.getCharacterRect(i));
+        for (int i = 0; i < MANY_BOUNDS.length; i++) {
+            final RectF expectedBounds = MANY_BOUNDS[i];
+            assertEquals(expectedBounds, info2.getCharacterRect(i));
         }
         assertNull(info2.getCharacterRect(-1));
-        assertNull(info2.getCharacterRect(MANY_RECTS.length + 1));
+        assertNull(info2.getCharacterRect(MANY_BOUNDS.length + 1));
         for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) {
             final int expectedFlags = MANY_FLAGS_ARRAY[i];
             assertEquals(expectedFlags, info2.getCharacterRectFlags(i));
         }
-        assertEquals(CHARACTER_RECT_TYPE_UNSPECIFIED, info2.getCharacterRectFlags(-1));
-        assertEquals(CHARACTER_RECT_TYPE_UNSPECIFIED,
-                info2.getCharacterRectFlags(MANY_RECTS.length + 1));
+        assertEquals(0, info2.getCharacterRectFlags(-1));
+        assertEquals(0, info2.getCharacterRectFlags(MANY_BOUNDS.length + 1));
         assertEquals(info, info2);
         assertEquals(info.hashCode(), info2.hashCode());
 
@@ -163,25 +160,24 @@
         assertEquals(SELECTION_END, info3.getSelectionEnd());
         assertEquals(COMPOSING_TEXT_START, info3.getComposingTextStart());
         assertTrue(TextUtils.equals(COMPOSING_TEXT, info3.getComposingText()));
-        assertTrue(info3.isInsertionMarkerClipped());
+        assertEquals(INSERTION_MARKER_FLAGS, info3.getInsertionMarkerFlags());
         assertEquals(INSERTION_MARKER_HORIZONTAL, info3.getInsertionMarkerHorizontal());
         assertEquals(INSERTION_MARKER_TOP, info3.getInsertionMarkerTop());
         assertEquals(INSERTION_MARKER_BASELINE, info3.getInsertionMarkerBaseline());
         assertEquals(INSERTION_MARKER_BOTOM, info3.getInsertionMarkerBottom());
         assertEquals(TRANSFORM_MATRIX, info3.getMatrix());
-        for (int i = 0; i < MANY_RECTS.length; i++) {
-            final RectF expectedRect = MANY_RECTS[i];
-            assertEquals(expectedRect, info3.getCharacterRect(i));
+        for (int i = 0; i < MANY_BOUNDS.length; i++) {
+            final RectF expectedBounds = MANY_BOUNDS[i];
+            assertEquals(expectedBounds, info3.getCharacterRect(i));
         }
         assertNull(info3.getCharacterRect(-1));
-        assertNull(info3.getCharacterRect(MANY_RECTS.length + 1));
+        assertNull(info3.getCharacterRect(MANY_BOUNDS.length + 1));
         for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) {
             final int expectedFlags = MANY_FLAGS_ARRAY[i];
             assertEquals(expectedFlags, info3.getCharacterRectFlags(i));
         }
-        assertEquals(CHARACTER_RECT_TYPE_UNSPECIFIED, info3.getCharacterRectFlags(-1));
-        assertEquals(CHARACTER_RECT_TYPE_UNSPECIFIED,
-                info3.getCharacterRectFlags(MANY_RECTS.length + 1));
+        assertEquals(0, info3.getCharacterRectFlags(-1));
+        assertEquals(0, info3.getCharacterRectFlags(MANY_BOUNDS.length + 1));
         assertEquals(info.hashCode(), info3.hashCode());
 
         builder.reset();
@@ -190,7 +186,7 @@
         assertEquals(-1, uninitializedInfo.getSelectionEnd());
         assertEquals(-1, uninitializedInfo.getComposingTextStart());
         assertNull(uninitializedInfo.getComposingText());
-        assertFalse(uninitializedInfo.isInsertionMarkerClipped());
+        assertEquals(0, uninitializedInfo.getInsertionMarkerFlags());
         assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerHorizontal());
         assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerTop());
         assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBaseline());
@@ -218,7 +214,7 @@
         final int SELECTION_END1 = 7;
         final String COMPOSING_TEXT1 = "0123456789";
         final int COMPOSING_TEXT_START1 = 0;
-        final boolean INSERTION_MARKER_CLIPPED1 = true;
+        final int INSERTION_MARKER_FLAGS1 = FLAG_HAS_VISIBLE_REGION;
         final float INSERTION_MARKER_HORIZONTAL1 = 10.5f;
         final float INSERTION_MARKER_TOP1 = 100.1f;
         final float INSERTION_MARKER_BASELINE1 = 110.4f;
@@ -227,7 +223,8 @@
         final int SELECTION_END2 = 8;
         final String COMPOSING_TEXT2 = "9876543210";
         final int COMPOSING_TEXT_START2 = 3;
-        final boolean INSERTION_MARKER_CLIPPED2 = false;
+        final int INSERTION_MARKER_FLAGS2 =
+                FLAG_HAS_VISIBLE_REGION | FLAG_HAS_INVISIBLE_REGION | FLAG_IS_RTL;
         final float INSERTION_MARKER_HORIZONTAL2 = 14.5f;
         final float INSERTION_MARKER_TOP2 = 200.1f;
         final float INSERTION_MARKER_BASELINE2 = 210.4f;
@@ -265,10 +262,10 @@
         assertEquals(
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         Float.NaN, Float.NaN, Float.NaN, Float.NaN,
-                        INSERTION_MARKER_CLIPPED1).build(),
+                        INSERTION_MARKER_FLAGS1).build(),
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         Float.NaN, Float.NaN, Float.NaN, Float.NaN,
-                        INSERTION_MARKER_CLIPPED1).build());
+                        INSERTION_MARKER_FLAGS1).build());
 
         // Check Matrix.
         assertEquals(
@@ -290,74 +287,74 @@
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
                         INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
-                        INSERTION_MARKER_CLIPPED1).build(),
+                        INSERTION_MARKER_FLAGS1).build(),
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
                         INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
-                        INSERTION_MARKER_CLIPPED1).build());
+                        INSERTION_MARKER_FLAGS1).build());
         assertNotEquals(
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         Float.NaN, INSERTION_MARKER_TOP1,
                         INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
-                        INSERTION_MARKER_CLIPPED1).build(),
+                        INSERTION_MARKER_FLAGS1).build(),
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
                         INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
-                        INSERTION_MARKER_CLIPPED1).build());
+                        INSERTION_MARKER_FLAGS1).build());
         assertNotEquals(
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
                         INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
-                        INSERTION_MARKER_CLIPPED1).build(),
+                        INSERTION_MARKER_FLAGS1).build(),
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         INSERTION_MARKER_HORIZONTAL2, INSERTION_MARKER_TOP1,
                         INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
-                        INSERTION_MARKER_CLIPPED1).build());
+                        INSERTION_MARKER_FLAGS1).build());
         assertNotEquals(
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
                         INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
-                        INSERTION_MARKER_CLIPPED1).build(),
+                        INSERTION_MARKER_FLAGS1).build(),
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP2,
                         INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
-                        INSERTION_MARKER_CLIPPED1).build());
+                        INSERTION_MARKER_FLAGS1).build());
         assertNotEquals(
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
                         INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
-                        INSERTION_MARKER_CLIPPED1).build(),
+                        INSERTION_MARKER_FLAGS1).build(),
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
                         INSERTION_MARKER_BASELINE2, INSERTION_MARKER_BOTOM1,
-                        INSERTION_MARKER_CLIPPED1).build());
+                        INSERTION_MARKER_FLAGS1).build());
         assertNotEquals(
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
                         INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
-                        INSERTION_MARKER_CLIPPED1).build(),
+                        INSERTION_MARKER_FLAGS1).build(),
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         INSERTION_MARKER_HORIZONTAL2, INSERTION_MARKER_TOP1,
                         INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
-                        INSERTION_MARKER_CLIPPED1).build());
+                        INSERTION_MARKER_FLAGS1).build());
         assertNotEquals(
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
                         INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
-                        INSERTION_MARKER_CLIPPED1).build(),
+                        INSERTION_MARKER_FLAGS1).build(),
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
                         INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM2,
-                        INSERTION_MARKER_CLIPPED1).build());
+                        INSERTION_MARKER_FLAGS1).build());
         assertNotEquals(
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
                         INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
-                        INSERTION_MARKER_CLIPPED1).build(),
+                        INSERTION_MARKER_FLAGS1).build(),
                 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
                         INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
                         INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
-                        INSERTION_MARKER_CLIPPED2).build());
+                        INSERTION_MARKER_FLAGS2).build());
     }
 
     @SmallTest
@@ -394,7 +391,7 @@
         final int SELECTION_END = 40;
         final int COMPOSING_TEXT_START = 32;
         final String COMPOSING_TEXT = "test";
-        final boolean INSERTION_MARKER_CLIPPED = true;
+        final int INSERTION_MARKER_FLAGS = FLAG_HAS_VISIBLE_REGION;
         final float INSERTION_MARKER_HORIZONTAL = 10.5f;
         final float INSERTION_MARKER_TOP = 100.1f;
         final float INSERTION_MARKER_BASELINE = 110.4f;
@@ -416,7 +413,7 @@
             }
 
             builder.setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP,
-                    INSERTION_MARKER_BASELINE, INSERTION_MARKER_BOTOM, INSERTION_MARKER_CLIPPED);
+                    INSERTION_MARKER_BASELINE, INSERTION_MARKER_BOTOM, INSERTION_MARKER_FLAGS);
             try {
                 // Coordinate transformation matrix is required if no positional information is
                 // specified.
@@ -438,19 +435,10 @@
     }
 
     @SmallTest
-    public void testBuilderAddCharacterRect() throws Exception {
+    public void testBuilderAddCharacterBounds() throws Exception {
         // A negative index should be rejected.
         try {
-            new Builder().addCharacterRect(-1, 0.0f, 0.0f, 0.0f, 0.0f,
-                    CHARACTER_RECT_TYPE_FULLY_VISIBLE);
-            assertTrue(false);
-        } catch (IllegalArgumentException ex) {
-        }
-
-        // CHARACTER_RECT_TYPE_UNSPECIFIED is not allowed.
-        try {
-            new Builder().addCharacterRect(0, 0.0f, 0.0f, 0.0f, 0.0f,
-                    CHARACTER_RECT_TYPE_UNSPECIFIED);
+            new Builder().addCharacterBounds(-1, 0.0f, 0.0f, 0.0f, 0.0f, FLAG_HAS_VISIBLE_REGION);
             assertTrue(false);
         } catch (IllegalArgumentException ex) {
         }
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 72a6f88..317d472 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -389,8 +389,11 @@
         }
 
         /**
-         * Informs the application that video is available and the playback of the TV stream has
-         * been started.
+         * Informs the application that the video is now available for watching. This is primarily
+         * used to signal the application to unblock the screen. The TV input service must call this
+         * method as soon as the content rendered onto its surface gets ready for viewing.
+         *
+         * @see #notifyVideoUnavailable
          */
         public void notifyVideoAvailable() {
             runOnMainThread(new Runnable() {
@@ -407,16 +410,18 @@
         }
 
         /**
-         * Informs the application that video is not available, so the TV input cannot continue
-         * playing the TV stream.
+         * Informs the application that the video became unavailable for some reason. This is
+         * primarily used to signal the application to block the screen not to show any intermittent
+         * video artifacts.
          *
-         * @param reason The reason that the TV input stopped the playback:
-         * <ul>
-         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_UNKNOWN}
-         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_TUNING}
-         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL}
-         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_BUFFERING}
-         * </ul>
+         * @param reason The reason why the video became unavailable:
+         *            <ul>
+         *            <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_UNKNOWN}
+         *            <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_TUNING}
+         *            <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL}
+         *            <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_BUFFERING}
+         *            </ul>
+         * @see #notifyVideoAvailable
          */
         public void notifyVideoUnavailable(final int reason) {
             if (reason < TvInputManager.VIDEO_UNAVAILABLE_REASON_START
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index d4ebb01..b94a258 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -176,6 +176,7 @@
                 android:theme="@style/RecentsStyle"
                 android:excludeFromRecents="true"
                 android:launchMode="singleInstance"
+                android:resumeWhilePausing="true"
                 android:exported="true">
           <intent-filter>
             <action android:name="com.android.systemui.TOGGLE_RECENTS" />
@@ -196,6 +197,8 @@
                   android:label="@string/accessibility_desc_recent_apps"
                   android:launchMode="singleInstance"
                   android:excludeFromRecents="true"
+                  android:stateNotNeeded="true"
+                  android:resumeWhilePausing="true"
                   android:theme="@style/RecentsTheme">
             <intent-filter>
                 <action android:name="com.android.systemui.recents.TOGGLE_RECENTS" />
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 5399a39..0e189792 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -137,7 +137,7 @@
     <!-- The min animation duration for animating the task in when transitioning from home. -->
     <integer name="recents_animate_task_enter_from_home_duration">275</integer>
     <!-- The animation stagger to apply to each task animation when transitioning from home. -->
-    <integer name="recents_animate_task_enter_from_home_delay">150</integer>
+    <integer name="recents_animate_task_enter_from_home_delay">10</integer>
     <!-- The short duration when animating in/out the lock to app button. -->
     <integer name="recents_animate_lock_to_app_button_short_duration">150</integer>
     <!-- The long duration when animating in/out the lock to app button. -->
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
index b7434fd..34430d9 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
@@ -203,8 +203,7 @@
         Drawable icon = getFullResIcon(td.resolveInfo, pm);
         if (td.userId != UserHandle.myUserId()) {
             // Need to badge the icon
-            icon = mContext.getPackageManager().getUserBadgedDrawableForDensity(icon,
-                    new UserHandle(td.userId), null, 0);
+            icon = mContext.getPackageManager().getUserBadgedIcon(icon, new UserHandle(td.userId));
         }
         if (DEBUG) Log.v(TAG, "Loaded bitmap for task "
                 + td + ": " + thumbnail);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index 2d114c0..5fa9fa4 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -16,10 +16,12 @@
 
 package com.android.systemui.recents;
 
+import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -385,9 +387,9 @@
                 toTask);
         if (toTransform != null && toTask.key != null) {
             Rect toTaskRect = toTransform.rect;
-
-            // XXX: Reduce the memory usage the to the task bar height
-            Bitmap thumbnail = Bitmap.createBitmap(toTaskRect.width(), toTaskRect.height(),
+            int toHeaderWidth = (int) (mHeaderBar.getMeasuredWidth() * toTransform.scale);
+            int toHeaderHeight = (int) (mHeaderBar.getMeasuredHeight() * toTransform.scale);
+            Bitmap thumbnail = Bitmap.createBitmap(toHeaderWidth, toHeaderHeight,
                     Bitmap.Config.ARGB_8888);
             if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) {
                 thumbnail.eraseColor(0xFFff0000);
@@ -401,7 +403,8 @@
 
             mStartAnimationTriggered = false;
             return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mStatusBarView,
-                    thumbnail, toTaskRect.left, toTaskRect.top, this);
+                    thumbnail, toTaskRect.left, toTaskRect.top, toTaskRect.width(),
+                    toTaskRect.height(), this);
         }
 
         // If both the screenshot and thumbnail fails, then just fall back to the default transition
@@ -562,11 +565,34 @@
     public void onAnimationStarted() {
         // Notify recents to start the enter animation
         if (!mStartAnimationTriggered) {
+            // There can be a race condition between the start animation callback and
+            // the start of the new activity (where we register the receiver that listens
+            // to this broadcast, so we add our own receiver and if that gets called, then
+            // we know the activity has not yet started and we can retry sending the broadcast.
+            BroadcastReceiver fallbackReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    if (getResultCode() == Activity.RESULT_OK) {
+                        mStartAnimationTriggered = true;
+                        return;
+                    }
+
+                    // Schedule for the broadcast to be sent again after some time
+                    mHandler.postDelayed(new Runnable() {
+                        @Override
+                        public void run() {
+                            onAnimationStarted();
+                        }
+                    }, 75);
+                }
+            };
+
+            // 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);
-            mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
-            mStartAnimationTriggered = true;
+            mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
+                    fallbackReceiver, null, Activity.RESULT_CANCELED, null, null);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index ec7799a..8f92027 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -146,6 +146,9 @@
                 ReferenceCountedTrigger t = new ReferenceCountedTrigger(context, null, null, null);
                 mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(t));
                 onEnterAnimationTriggered();
+                // Notify the fallback receiver that we have successfully got the broadcast
+                // See AlternateRecentsComponent.onAnimationStarted()
+                setResultCode(Activity.RESULT_OK);
             }
         }
     };
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 07a42bd..887cbac 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -356,7 +356,7 @@
      */
     public Drawable getBadgedIcon(Drawable icon, int userId) {
         if (userId != UserHandle.myUserId()) {
-            icon = mPm.getUserBadgedDrawableForDensity(icon, new UserHandle(userId), null, 0);
+            icon = mPm.getUserBadgedIcon(icon, new UserHandle(userId));
         }
         return icon;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 0c6e7b6..1bfb41f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -413,10 +413,8 @@
         final SystemServicesProxy ssp =
                 RecentsTaskLoader.getInstance().getSystemServicesProxy();
         ActivityOptions opts = null;
-        int thumbnailWidth = transform.rect.width();
-        int thumbnailHeight = transform.rect.height();
-        if (task.thumbnail != null && thumbnailWidth > 0 && thumbnailHeight > 0 &&
-                task.thumbnail.getWidth() > 0 && task.thumbnail.getHeight() > 0) {
+        if (task.thumbnail != null && task.thumbnail.getWidth() > 0 &&
+                task.thumbnail.getHeight() > 0) {
             Bitmap b;
             if (tv != null) {
                 // Disable any focused state before we draw the header
@@ -424,7 +422,11 @@
                     tv.unsetFocusedTask();
                 }
 
-                b = Bitmap.createBitmap(thumbnailWidth, thumbnailHeight, Bitmap.Config.ARGB_8888);
+                float scale = tv.getScaleX();
+                int fromHeaderWidth = (int) (tv.mHeaderView.getMeasuredWidth() * scale);
+                int fromHeaderHeight = (int) (tv.mHeaderView.getMeasuredHeight() * scale);
+                b = Bitmap.createBitmap(fromHeaderWidth, fromHeaderHeight,
+                        Bitmap.Config.ARGB_8888);
                 if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) {
                     b.eraseColor(0xFFff0000);
                 } else {
@@ -435,7 +437,7 @@
                 }
             } else {
                 // Notify the system to skip the thumbnail layer by using an ALPHA_8 bitmap
-                b = Bitmap.createBitmap(thumbnailWidth, thumbnailHeight, Bitmap.Config.ALPHA_8);
+                b = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
             }
             ActivityOptions.OnAnimationStartedListener animStartedListener = null;
             if (lockToTask) {
@@ -456,7 +458,8 @@
                 };
             }
             opts = ActivityOptions.makeThumbnailAspectScaleUpAnimation(sourceView,
-                    b, offsetX, offsetY, animStartedListener);
+                    b, offsetX, offsetY, transform.rect.width(), transform.rect.height(),
+                    animStartedListener);
         }
 
         final ActivityOptions launchOpts = opts;
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 eecc170..49aa52b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -839,25 +839,28 @@
 
     @Override
      public void onClick(final View v) {
-        // We purposely post the handler delayed to allow for the touch feedback to draw
         final TaskView tv = this;
-        postDelayed(new Runnable() {
-            @Override
-            public void run() {
-                if (Constants.DebugFlags.App.EnableTaskFiltering && v == mHeaderView.mApplicationIcon) {
-                    mCb.onTaskViewAppIconClicked(tv);
-                } else if (v == mHeaderView.mDismissButton) {
-                    dismissTask();
-                } else {
-                    if (v == mActionButtonView) {
-                        // Reset the translation of the action button before we animate it out
-                        mActionButtonView.setTranslationZ(0f);
+        final boolean delayViewClick = (v != this);
+        if (delayViewClick) {
+            // We purposely post the handler delayed to allow for the touch feedback to draw
+            postDelayed(new Runnable() {
+                @Override
+                public void run() {
+                    if (Constants.DebugFlags.App.EnableTaskFiltering && v == mHeaderView.mApplicationIcon) {
+                        mCb.onTaskViewAppIconClicked(tv);
+                    } else if (v == mHeaderView.mDismissButton) {
+                        dismissTask();
                     }
-                    mCb.onTaskViewClicked(tv, tv.getTask(),
-                            (v == mFooterView || v == mActionButtonView));
                 }
+            }, 125);
+        } else {
+            if (v == mActionButtonView) {
+                // Reset the translation of the action button before we animate it out
+                mActionButtonView.setTranslationZ(0f);
             }
-        }, 125);
+            mCb.onTaskViewClicked(tv, tv.getTask(),
+                    (v == mFooterView || v == mActionButtonView));
+        }
     }
 
     /**** View.OnLongClickListener Implementation ****/
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6ddad41..1397ea4 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -6278,12 +6278,12 @@
     }
 
     @Override
-    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
+    public final void activityPaused(IBinder token) {
         final long origId = Binder.clearCallingIdentity();
         synchronized(this) {
             ActivityStack stack = ActivityRecord.getStackLocked(token);
             if (stack != null) {
-                stack.activityPausedLocked(token, false, persistentState);
+                stack.activityPausedLocked(token, false);
             }
         }
         Binder.restoreCallingIdentity(origId);
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 77b4cc9..e043f03 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -698,12 +698,12 @@
                 case ActivityOptions.ANIM_SCALE_UP:
                     service.mWindowManager.overridePendingAppTransitionScaleUp(
                             pendingOptions.getStartX(), pendingOptions.getStartY(),
-                            pendingOptions.getStartWidth(), pendingOptions.getStartHeight());
+                            pendingOptions.getWidth(), pendingOptions.getHeight());
                     if (intent.getSourceBounds() == null) {
                         intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
                                 pendingOptions.getStartY(),
-                                pendingOptions.getStartX()+pendingOptions.getStartWidth(),
-                                pendingOptions.getStartY()+pendingOptions.getStartHeight()));
+                                pendingOptions.getStartX()+pendingOptions.getWidth(),
+                                pendingOptions.getStartY()+pendingOptions.getHeight()));
                     }
                     break;
                 case ActivityOptions.ANIM_THUMBNAIL_SCALE_UP:
@@ -728,15 +728,14 @@
                     service.mWindowManager.overridePendingAppTransitionAspectScaledThumb(
                             pendingOptions.getThumbnail(),
                             pendingOptions.getStartX(), pendingOptions.getStartY(),
+                            pendingOptions.getWidth(), pendingOptions.getHeight(),
                             pendingOptions.getOnAnimationStartListener(),
                             (animationType == ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_UP));
                     if (intent.getSourceBounds() == null) {
                         intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
                                 pendingOptions.getStartY(),
-                                pendingOptions.getStartX()
-                                        + pendingOptions.getThumbnail().getWidth(),
-                                pendingOptions.getStartY()
-                                        + pendingOptions.getThumbnail().getHeight()));
+                                pendingOptions.getStartX() + pendingOptions.getWidth(),
+                                pendingOptions.getStartY() + pendingOptions.getHeight()));
                     }
                     break;
                 default:
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 81c379a..6168546 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -284,7 +284,7 @@
                         if (r.app != null) {
                             mService.logAppTooSlow(r.app, r.pauseTime, "pausing " + r);
                         }
-                        activityPausedLocked(r.appToken, true, r.persistentState);
+                        activityPausedLocked(r.appToken, true);
                     }
                 } break;
                 case LAUNCH_TICK_MSG: {
@@ -712,7 +712,7 @@
             // Still have something resumed; can't sleep until it is paused.
             if (DEBUG_PAUSE) Slog.v(TAG, "Sleep needs to pause " + mResumedActivity);
             if (DEBUG_USER_LEAVING) Slog.v(TAG, "Sleep => pause with userLeaving=false");
-            startPausingLocked(false, true);
+            startPausingLocked(false, true, false, false);
             return true;
         }
         if (mPausingActivity != null) {
@@ -790,22 +790,38 @@
         return null;
     }
 
-    final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
+    /**
+     * Start pausing the currently resumed activity.  It is an error to call this if there
+     * is already an activity being paused or there is no resumed activity.
+     *
+     * @param userLeaving True if this should result in an onUserLeaving to the current activity.
+     * @param uiSleeping True if this is happening with the user interface going to sleep (the
+     * screen turning off).
+     * @param resuming True if this is being called as part of resuming the top activity, so
+     * we shouldn't try to instigate a resume here.
+     * @param dontWait True if the caller does not want to wait for the pause to complete.  If
+     * set to true, we will immediately complete the pause here before returning.
+     * @return Returns true if an activity now is in the PAUSING state, and we are waiting for
+     * it to tell us when it is done.
+     */
+    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
+            boolean dontWait) {
         if (mPausingActivity != null) {
-            Slog.e(TAG, "Trying to pause when pause is already pending for "
-                  + mPausingActivity, new RuntimeException("here").fillInStackTrace());
+            Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity);
+            completePauseLocked(false);
         }
         ActivityRecord prev = mResumedActivity;
         if (prev == null) {
-            Slog.e(TAG, "Trying to pause when nothing is resumed",
-                    new RuntimeException("here").fillInStackTrace());
-            mStackSupervisor.resumeTopActivitiesLocked();
-            return;
+            if (!resuming) {
+                Slog.wtf(TAG, "Trying to pause when nothing is resumed");
+                mStackSupervisor.resumeTopActivitiesLocked();
+            }
+            return false;
         }
 
         if (mActivityContainer.mParentActivity == null) {
             // Top level stack, not a child. Look for child stacks.
-            mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping);
+            mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait);
         }
 
         if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSING: " + prev);
@@ -834,7 +850,7 @@
                         prev.shortComponentName);
                 mService.updateUsageStats(prev, false);
                 prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
-                        userLeaving, prev.configChangeFlags);
+                        userLeaving, prev.configChangeFlags, dontWait);
             } catch (Exception e) {
                 // Ignore exception, if process died other code will cleanup.
                 Slog.w(TAG, "Exception thrown during pause", e);
@@ -865,39 +881,46 @@
                 if (DEBUG_PAUSE) Slog.v(TAG, "Key dispatch not paused for screen off");
             }
 
-            // Schedule a pause timeout in case the app doesn't respond.
-            // We don't give it much time because this directly impacts the
-            // responsiveness seen by the user.
-            Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
-            msg.obj = prev;
-            prev.pauseTime = SystemClock.uptimeMillis();
-            mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
-            if (DEBUG_PAUSE) Slog.v(TAG, "Waiting for pause to complete...");
+            if (dontWait) {
+                // If the caller said they don't want to wait for the pause, then complete
+                // the pause now.
+                completePauseLocked(false);
+                return false;
+
+            } else {
+                // Schedule a pause timeout in case the app doesn't respond.
+                // We don't give it much time because this directly impacts the
+                // responsiveness seen by the user.
+                Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
+                msg.obj = prev;
+                prev.pauseTime = SystemClock.uptimeMillis();
+                mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
+                if (DEBUG_PAUSE) Slog.v(TAG, "Waiting for pause to complete...");
+                return true;
+            }
+
         } else {
             // This activity failed to schedule the
             // pause, so just treat it as being paused now.
             if (DEBUG_PAUSE) Slog.v(TAG, "Activity not running, resuming next.");
-            mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
+            if (!resuming) {
+                mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
+            }
+            return false;
         }
     }
 
-    final void activityPausedLocked(IBinder token, boolean timeout,
-            PersistableBundle persistentState) {
+    final void activityPausedLocked(IBinder token, boolean timeout) {
         if (DEBUG_PAUSE) Slog.v(
             TAG, "Activity paused: token=" + token + ", timeout=" + timeout);
 
         final ActivityRecord r = isInStackLocked(token);
         if (r != null) {
             mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
-            if (persistentState != null) {
-                r.persistentState = persistentState;
-                mService.notifyTaskPersisterLocked(r.task, false);
-            }
             if (mPausingActivity == r) {
                 if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r
                         + (timeout ? " (due to timeout)" : " (pause complete)"));
-                r.state = ActivityState.PAUSED;
-                completePauseLocked();
+                completePauseLocked(true);
             } else {
                 EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
                         r.userId, System.identityHashCode(r), r.shortComponentName,
@@ -948,11 +971,12 @@
         }
     }
 
-    private void completePauseLocked() {
+    private void completePauseLocked(boolean resumeNext) {
         ActivityRecord prev = mPausingActivity;
         if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev);
 
         if (prev != null) {
+            prev.state = ActivityState.PAUSED;
             if (prev.finishing) {
                 if (DEBUG_PAUSE) Slog.v(TAG, "Executing finish of activity: " + prev);
                 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
@@ -995,19 +1019,21 @@
             mPausingActivity = null;
         }
 
-        final ActivityStack topStack = mStackSupervisor.getFocusedStack();
-        if (!mService.isSleepingOrShuttingDown()) {
-            mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
-        } else {
-            mStackSupervisor.checkReadyForSleepLocked();
-            ActivityRecord top = topStack.topRunningActivityLocked(null);
-            if (top == null || (prev != null && top != prev)) {
-                // If there are no more activities available to run,
-                // do resume anyway to start something.  Also if the top
-                // activity on the stack is not the just paused activity,
-                // we need to go ahead and resume it to ensure we complete
-                // an in-flight app switch.
-                mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
+        if (resumeNext) {
+            final ActivityStack topStack = mStackSupervisor.getFocusedStack();
+            if (!mService.isSleepingOrShuttingDown()) {
+                mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
+            } else {
+                mStackSupervisor.checkReadyForSleepLocked();
+                ActivityRecord top = topStack.topRunningActivityLocked(null);
+                if (top == null || (prev != null && top != prev)) {
+                    // If there are no more activities available to run,
+                    // do resume anyway to start something.  Also if the top
+                    // activity on the stack is not the just paused activity,
+                    // we need to go ahead and resume it to ensure we complete
+                    // an in-flight app switch.
+                    mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
+                }
             }
         }
 
@@ -1607,10 +1633,10 @@
 
         // We need to start pausing the current activity so the top one
         // can be resumed...
-        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving);
+        boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
+        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
         if (mResumedActivity != null) {
-            pausing = true;
-            startPausingLocked(userLeaving, false);
+            pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
             if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
         }
         if (pausing) {
@@ -2720,7 +2746,7 @@
             if (mPausingActivity == null) {
                 if (DEBUG_PAUSE) Slog.v(TAG, "Finish needs to pause: " + r);
                 if (DEBUG_USER_LEAVING) Slog.v(TAG, "finish() => pause with userLeaving=false");
-                startPausingLocked(false, false);
+                startPausingLocked(false, false, false, false);
             }
 
             if (endTask) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 780efa1..f821daf 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -592,7 +592,7 @@
      * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
      * @return true if any activity was paused as a result of this call.
      */
-    boolean pauseBackStacks(boolean userLeaving) {
+    boolean pauseBackStacks(boolean userLeaving, boolean resuming, boolean dontWait) {
         boolean someActivityPaused = false;
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
@@ -601,8 +601,8 @@
                 if (!isFrontStack(stack) && stack.mResumedActivity != null) {
                     if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
                             " mResumedActivity=" + stack.mResumedActivity);
-                    stack.startPausingLocked(userLeaving, false);
-                    someActivityPaused = true;
+                    someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
+                            dontWait);
                 }
             }
         }
@@ -631,7 +631,8 @@
         return pausing;
     }
 
-    void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) {
+    void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping,
+            boolean resuming, boolean dontWait) {
         // TODO: Put all stacks in supervisor and iterate through them instead.
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
@@ -639,7 +640,7 @@
                 final ActivityStack stack = stacks.get(stackNdx);
                 if (stack.mResumedActivity != null &&
                         stack.mActivityContainer.mParentActivity == parent) {
-                    stack.startPausingLocked(userLeaving, uiSleeping);
+                    stack.startPausingLocked(userLeaving, uiSleeping, resuming, dontWait);
                 }
             }
         }
@@ -1640,57 +1641,8 @@
             }
         }
 
-        if (sourceRecord == null) {
-            // This activity is not being started from another...  in this
-            // case we -always- start a new task.
-            if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) {
-                Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
-                        "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
-                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
-            }
-        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
-            // The original activity who is starting us is running as a single
-            // instance...  this new activity it is starting must go on its
-            // own task.
-            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
-        } else if (launchSingleInstance || launchSingleTask) {
-            // The activity being started is a single instance...  it always
-            // gets launched into its own task.
-            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
-        }
-
-        ActivityInfo newTaskInfo = null;
-        Intent newTaskIntent = null;
-        ActivityStack sourceStack;
-        if (sourceRecord != null) {
-            if (sourceRecord.finishing) {
-                // If the source is finishing, we can't further count it as our source.  This
-                // is because the task it is associated with may now be empty and on its way out,
-                // so we don't want to blindly throw it in to that task.  Instead we will take
-                // the NEW_TASK flow and try to find a task for it. But save the task information
-                // so it can be used when creating the new task.
-                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
-                    Slog.w(TAG, "startActivity called from finishing " + sourceRecord
-                            + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
-                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
-                    newTaskInfo = sourceRecord.info;
-                    newTaskIntent = sourceRecord.task.intent;
-                }
-                sourceRecord = null;
-                sourceStack = null;
-            } else {
-                sourceStack = sourceRecord.task.stack;
-            }
-        } else {
-            sourceStack = null;
-        }
-
         boolean addingToTask = false;
-        boolean movedHome = false;
         TaskRecord reuseTask = null;
-        ActivityStack targetStack;
-
-        intent.setFlags(launchFlags);
 
         // If the caller is not coming from another activity, but has given us an
         // explicit task into which they would like us to launch the new activity,
@@ -1746,6 +1698,58 @@
             inTask = null;
         }
 
+        if (inTask == null) {
+            if (sourceRecord == null) {
+                // This activity is not being started from another...  in this
+                // case we -always- start a new task.
+                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) {
+                    Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
+                            "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
+                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
+                }
+            } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
+                // The original activity who is starting us is running as a single
+                // instance...  this new activity it is starting must go on its
+                // own task.
+                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
+            } else if (launchSingleInstance || launchSingleTask) {
+                // The activity being started is a single instance...  it always
+                // gets launched into its own task.
+                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
+            }
+        }
+
+        ActivityInfo newTaskInfo = null;
+        Intent newTaskIntent = null;
+        ActivityStack sourceStack;
+        if (sourceRecord != null) {
+            if (sourceRecord.finishing) {
+                // If the source is finishing, we can't further count it as our source.  This
+                // is because the task it is associated with may now be empty and on its way out,
+                // so we don't want to blindly throw it in to that task.  Instead we will take
+                // the NEW_TASK flow and try to find a task for it. But save the task information
+                // so it can be used when creating the new task.
+                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
+                    Slog.w(TAG, "startActivity called from finishing " + sourceRecord
+                            + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
+                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
+                    newTaskInfo = sourceRecord.info;
+                    newTaskIntent = sourceRecord.task.intent;
+                }
+                sourceRecord = null;
+                sourceStack = null;
+            } else {
+                sourceStack = sourceRecord.task.stack;
+            }
+        } else {
+            sourceStack = null;
+        }
+
+        boolean movedHome = false;
+        ActivityStack targetStack;
+
+        intent.setFlags(launchFlags);
+
         // We may want to try to place the new activity in to an existing task.  We always
         // do this if the target activity is singleTask or singleInstance; we will also do
         // this if NEW_TASK has been requested, and there is not an additional qualifier telling
@@ -3840,7 +3844,7 @@
                 mContainerState = CONTAINER_STATE_NO_SURFACE;
                 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
                 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
-                    mStack.startPausingLocked(false, true);
+                    mStack.startPausingLocked(false, true, false, false);
                 }
             }
 
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index aabb8f7..bfc7659 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -569,9 +569,9 @@
             int appWidth, int appHeight, int orientation, int transit, Rect containingFrame,
             Rect contentInsets, boolean isFullScreen) {
         Animation a;
-        final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
+        final int thumbWidthI = mNextAppTransitionStartWidth;
         final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
-        final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
+        final int thumbHeightI = mNextAppTransitionStartHeight;
         final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
 
         // Used for the ENTER_SCALE_UP and EXIT_SCALE_DOWN transitions
@@ -993,7 +993,7 @@
     }
 
     void overridePendingAppTransitionAspectScaledThumb(Bitmap srcThumb, int startX, int startY,
-            IRemoteCallback startedCallback, boolean scaleUp) {
+            int targetWidth, int targetHeight, IRemoteCallback startedCallback, boolean scaleUp) {
         if (isTransitionSet()) {
             mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
                     : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
@@ -1002,6 +1002,8 @@
             mNextAppTransitionScaleUp = scaleUp;
             mNextAppTransitionStartX = startX;
             mNextAppTransitionStartY = startY;
+            mNextAppTransitionStartWidth = targetWidth;
+            mNextAppTransitionStartHeight = targetHeight;
             postAnimationCallback();
             mNextAppTransitionCallback = startedCallback;
         } else {
@@ -1138,6 +1140,10 @@
                         pw.print(mNextAppTransitionStartX);
                         pw.print(" mNextAppTransitionStartY=");
                         pw.println(mNextAppTransitionStartY);
+                        pw.print(" mNextAppTransitionStartWidth=");
+                        pw.print(mNextAppTransitionStartWidth);
+                        pw.print(" mNextAppTransitionStartHeight=");
+                        pw.println(mNextAppTransitionStartHeight);
                 pw.print("  mNextAppTransitionScaleUp="); pw.println(mNextAppTransitionScaleUp);
                 break;
         }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a1afe29..55c6d81 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4031,10 +4031,11 @@
 
     @Override
     public void overridePendingAppTransitionAspectScaledThumb(Bitmap srcThumb, int startX,
-            int startY, IRemoteCallback startedCallback, boolean scaleUp) {
+            int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
+            boolean scaleUp) {
         synchronized(mWindowMap) {
             mAppTransition.overridePendingAppTransitionAspectScaledThumb(srcThumb, startX,
-                    startY, startedCallback, scaleUp);
+                    startY, targetWidth, targetHeight, startedCallback, scaleUp);
         }
     }
 
@@ -4303,20 +4304,28 @@
     }
 
     public void setAppFullscreen(IBinder token, boolean toOpaque) {
-        AppWindowToken atoken = findAppWindowToken(token);
-        if (atoken != null) {
-            atoken.appFullscreen = toOpaque;
-            setWindowOpaque(token, toOpaque);
-            requestTraversal();
+        synchronized (mWindowMap) {
+            AppWindowToken atoken = findAppWindowToken(token);
+            if (atoken != null) {
+                atoken.appFullscreen = toOpaque;
+                setWindowOpaqueLocked(token, toOpaque);
+                requestTraversalLocked();
+            }
         }
     }
 
     public void setWindowOpaque(IBinder token, boolean isOpaque) {
+        synchronized (mWindowMap) {
+            setWindowOpaqueLocked(token, isOpaque);
+        }
+    }
+
+    public void setWindowOpaqueLocked(IBinder token, boolean isOpaque) {
         AppWindowToken wtoken = findAppWindowToken(token);
         if (wtoken != null) {
             WindowState win = wtoken.findMainWindow();
             if (win != null) {
-                win.mWinAnimator.setOpaque(isOpaque);
+                win.mWinAnimator.setOpaqueLocked(isOpaque);
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 3d4be12..a871522 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1556,11 +1556,11 @@
         }
     }
 
-    void setOpaque(boolean isOpaque) {
+    void setOpaqueLocked(boolean isOpaque) {
         if (mSurfaceControl == null) {
             return;
         }
-        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setOpaque");
+        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setOpaqueLocked");
         SurfaceControl.openTransaction();
         try {
             if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "isOpaque=" + isOpaque,
@@ -1568,7 +1568,7 @@
             mSurfaceControl.setOpaque(isOpaque);
         } finally {
             SurfaceControl.closeTransaction();
-            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setOpaque");
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setOpaqueLocked");
         }
     }
 
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 e03b9c8..44787e7 100644
--- a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
+++ b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
@@ -30,7 +30,6 @@
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.graphics.BitmapFactory;
-import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -391,6 +390,17 @@
     }
 
     @Override
+    protected void onPause() {
+        super.onPause();
+        Log.i(TAG, "I'm such a slooow poor loser");
+        try {
+            Thread.sleep(500);
+        } catch (InterruptedException e) {
+        }
+        Log.i(TAG, "See?");
+    }
+
+    @Override
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
         if (mOverrideConfig != null) {
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 2604e97..c403ce6 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -222,7 +222,8 @@
 
     @Override
     public void overridePendingAppTransitionAspectScaledThumb(Bitmap srcThumb, int startX,
-            int startY, IRemoteCallback startedCallback, boolean scaleUp) {
+            int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
+            boolean scaleUp) {
         // TODO Auto-generated method stub
     }