Merge "Fix issue #6381224: Initial emulator boot fails and shows a blank black screen." into jb-dev
diff --git a/api/16.txt b/api/16.txt
index 70c4032..bc97e81 100644
--- a/api/16.txt
+++ b/api/16.txt
@@ -676,6 +676,7 @@
     field public static final int measureAllChildren = 16843018; // 0x101010a
     field public static final int measureWithLargestChild = 16843476; // 0x10102d4
     field public static final int mediaRouteButtonStyle = 16843693; // 0x10103ad
+    field public static final int mediaRouteTypes = 16843694; // 0x10103ae
     field public static final int menuCategory = 16843230; // 0x10101de
     field public static final int mimeType = 16842790; // 0x1010026
     field public static final int minDate = 16843583; // 0x101033f
@@ -3688,6 +3689,8 @@
     ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet);
     ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet, int);
     method public int getRouteTypes();
+    method public void onAttachedToWindow();
+    method public void onDetachedFromWindow();
     method public void setExtendedSettingsClickListener(android.view.View.OnClickListener);
     method public void setRouteTypes(int);
     method public void showDialog();
@@ -3759,6 +3762,7 @@
   public static class Notification.BigPictureStyle extends android.app.Notification.Style {
     ctor public Notification.BigPictureStyle();
     ctor public Notification.BigPictureStyle(android.app.Notification.Builder);
+    method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.Bitmap);
     method public android.app.Notification.BigPictureStyle bigPicture(android.graphics.Bitmap);
     method public android.app.Notification build();
     method public android.app.Notification.BigPictureStyle setBigContentTitle(java.lang.CharSequence);
@@ -5827,7 +5831,6 @@
     field public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; // 0x8000
     field public static final int FLAG_ACTIVITY_CLEAR_TOP = 67108864; // 0x4000000
     field public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 524288; // 0x80000
-    field public static final int FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS = 8192; // 0x2000
     field public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 8388608; // 0x800000
     field public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; // 0x2000000
     field public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; // 0x100000
@@ -11537,6 +11540,7 @@
     method public abstract void onRouteSelected(android.media.MediaRouter, int, android.media.MediaRouter.RouteInfo);
     method public abstract void onRouteUngrouped(android.media.MediaRouter, android.media.MediaRouter.RouteInfo, android.media.MediaRouter.RouteGroup);
     method public abstract void onRouteUnselected(android.media.MediaRouter, int, android.media.MediaRouter.RouteInfo);
+    method public abstract void onRouteVolumeChanged(android.media.MediaRouter, android.media.MediaRouter.RouteInfo);
   }
 
   public static class MediaRouter.RouteCategory {
@@ -11564,10 +11568,21 @@
     method public android.graphics.drawable.Drawable getIconDrawable();
     method public java.lang.CharSequence getName();
     method public java.lang.CharSequence getName(android.content.Context);
+    method public int getPlaybackStream();
+    method public int getPlaybackType();
     method public java.lang.CharSequence getStatus();
     method public int getSupportedTypes();
     method public java.lang.Object getTag();
+    method public int getVolume();
+    method public int getVolumeHandling();
+    method public int getVolumeMax();
+    method public void requestSetVolume(int);
+    method public void requestUpdateVolume(int);
     method public void setTag(java.lang.Object);
+    field public static final int PLAYBACK_TYPE_LOCAL = 0; // 0x0
+    field public static final int PLAYBACK_TYPE_REMOTE = 1; // 0x1
+    field public static final int PLAYBACK_VOLUME_FIXED = 0; // 0x0
+    field public static final int PLAYBACK_VOLUME_VARIABLE = 1; // 0x1
   }
 
   public static class MediaRouter.SimpleCallback extends android.media.MediaRouter.Callback {
@@ -11579,15 +11594,29 @@
     method public void onRouteSelected(android.media.MediaRouter, int, android.media.MediaRouter.RouteInfo);
     method public void onRouteUngrouped(android.media.MediaRouter, android.media.MediaRouter.RouteInfo, android.media.MediaRouter.RouteGroup);
     method public void onRouteUnselected(android.media.MediaRouter, int, android.media.MediaRouter.RouteInfo);
+    method public void onRouteVolumeChanged(android.media.MediaRouter, android.media.MediaRouter.RouteInfo);
   }
 
   public static class MediaRouter.UserRouteInfo extends android.media.MediaRouter.RouteInfo {
+    method public android.media.RemoteControlClient getRemoteControlClient();
     method public void setIconDrawable(android.graphics.drawable.Drawable);
     method public void setIconResource(int);
     method public void setName(java.lang.CharSequence);
     method public void setName(int);
+    method public void setPlaybackStream(int);
+    method public void setPlaybackType(int);
     method public void setRemoteControlClient(android.media.RemoteControlClient);
     method public void setStatus(java.lang.CharSequence);
+    method public void setVolume(int);
+    method public void setVolumeCallback(android.media.MediaRouter.VolumeCallback);
+    method public void setVolumeHandling(int);
+    method public void setVolumeMax(int);
+  }
+
+  public static abstract class MediaRouter.VolumeCallback {
+    ctor public MediaRouter.VolumeCallback();
+    method public abstract void onVolumeSetRequest(android.media.MediaRouter.RouteInfo, int);
+    method public abstract void onVolumeUpdateRequest(android.media.MediaRouter.RouteInfo, int);
   }
 
   public class MediaScannerConnection implements android.content.ServiceConnection {
@@ -22816,10 +22845,18 @@
   public abstract class ActionProvider {
     ctor public ActionProvider(android.content.Context);
     method public boolean hasSubMenu();
+    method public boolean isVisible();
     method public abstract deprecated android.view.View onCreateActionView();
     method public android.view.View onCreateActionView(android.view.MenuItem);
     method public boolean onPerformDefaultAction();
     method public void onPrepareSubMenu(android.view.SubMenu);
+    method public boolean overridesItemVisibility();
+    method public void refreshVisibility();
+    method public void setVisibilityListener(android.view.ActionProvider.VisibilityListener);
+  }
+
+  public static abstract interface ActionProvider.VisibilityListener {
+    method public abstract void onActionProviderVisibilityChanged(boolean);
   }
 
   public final class Choreographer {
@@ -28146,8 +28183,11 @@
     method public void setString(int, java.lang.String, java.lang.String);
     method public void setTextColor(int, int);
     method public void setTextViewCompoundDrawables(int, int, int, int, int);
+    method public void setTextViewCompoundDrawablesRelative(int, int, int, int, int);
     method public void setTextViewText(int, java.lang.CharSequence);
+    method public void setTextViewTextSize(int, int, float);
     method public void setUri(int, java.lang.String, android.net.Uri);
+    method public void setViewPadding(int, int, int, int, int);
     method public void setViewVisibility(int, int);
     method public void showNext(int);
     method public void showPrevious(int);
diff --git a/api/current.txt b/api/current.txt
index f5cced9..bc97e81 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3689,6 +3689,8 @@
     ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet);
     ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet, int);
     method public int getRouteTypes();
+    method public void onAttachedToWindow();
+    method public void onDetachedFromWindow();
     method public void setExtendedSettingsClickListener(android.view.View.OnClickListener);
     method public void setRouteTypes(int);
     method public void showDialog();
@@ -5829,7 +5831,6 @@
     field public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; // 0x8000
     field public static final int FLAG_ACTIVITY_CLEAR_TOP = 67108864; // 0x4000000
     field public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 524288; // 0x80000
-    field public static final int FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS = 8192; // 0x2000
     field public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 8388608; // 0x800000
     field public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; // 0x2000000
     field public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; // 0x100000
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 2ed93f4..e12fa19 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1617,6 +1617,16 @@
             return true;
         }
 
+        case IS_INTENT_SENDER_AN_ACTIVITY_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IIntentSender r = IIntentSender.Stub.asInterface(
+                data.readStrongBinder());
+            boolean res = isIntentSenderAnActivity(r);
+            reply.writeNoException();
+            reply.writeInt(res ? 1 : 0);
+            return true;
+        }
+
         case UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             Configuration config = Configuration.CREATOR.createFromParcel(data);
@@ -3753,6 +3763,19 @@
         return res;
     }
 
+    public boolean isIntentSenderAnActivity(IIntentSender sender) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(sender.asBinder());
+        mRemote.transact(IS_INTENT_SENDER_AN_ACTIVITY_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean res = reply.readInt() != 0;
+        data.recycle();
+        reply.recycle();
+        return res;
+    }
+
     public void updatePersistentConfiguration(Configuration values) throws RemoteException
     {
         Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 609a047..031e39b 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -338,6 +338,8 @@
 
     public boolean isIntentSenderTargetedToPackage(IIntentSender sender) throws RemoteException;
 
+    public boolean isIntentSenderAnActivity(IIntentSender sender) throws RemoteException;
+
     public void updatePersistentConfiguration(Configuration values) throws RemoteException;
 
     public long[] getProcessPss(int[] pids) throws RemoteException;
@@ -603,4 +605,5 @@
     int FINISH_ACTIVITY_AFFINITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+148;
     int GET_LAUNCHED_FROM_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+149;
     int UNSTABLE_PROVIDER_DIED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+150;
+    int IS_INTENT_SENDER_AN_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+151;
 }
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index aa366b6..8adc8a2 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -631,6 +631,20 @@
     }
 
     /**
+     * @hide
+     * Check whether this PendingIntent will launch an Activity.
+     */
+    public boolean isActivity() {
+        try {
+            return ActivityManagerNative.getDefault()
+                .isIntentSenderAnActivity(mTarget);
+        } catch (RemoteException e) {
+            // Should never happen.
+            return false;
+        }
+    }
+
+    /**
      * Comparison operator on two PendingIntent objects, such that true
      * is returned then they both represent the same operation from the
      * same package.  This allows you to use {@link #getActivity},
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 3aa5181..810e790 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -323,7 +323,7 @@
      * 
      * <p>
      * The total Bitmap memory used by the RemoteViews object cannot exceed that required to
-     * fill the screen once, ie. (screen width x screen height x 4) bytes.
+     * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes.
      *
      * @param appWidgetIds     The AppWidget instances for which to set the RemoteViews.
      * @param views         The RemoteViews object to show.
@@ -391,7 +391,7 @@
      *
      * <p>
      * The total Bitmap memory used by the RemoteViews object cannot exceed that required to
-     * fill the screen once, ie. (screen width x screen height x 4) bytes.
+     * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes.
      *
      * @param appWidgetId      The AppWidget instance for which to set the RemoteViews.
      * @param views         The RemoteViews object to show.
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 76dfac4..3fdf451 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3105,17 +3105,6 @@
      */
     public static final int FLAG_ACTIVITY_TASK_ON_HOME = 0X00004000;
     /**
-     * If set in an Intent passed to {@link Context#startActivity Context.startActivity()},
-     * upon starting the activity the system will also clear any system dialogs that
-     * are currently shown.  This is intended primarily for any actions that are
-     * associated with buttons in a notification: tapping on the button to launch
-     * the activity needs to also dismiss the notification window (which is one
-     * of the system dialogs); setting this flag on the Intent associated with that
-     * action will ensure that and other system dialogs are dismissed so that the
-     * user arrives in the new activity.
-     */
-    public static final int FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS = 0X00002000;
-    /**
      * If set, when sending a broadcast only registered receivers will be
      * called -- no BroadcastReceiver components will be launched.
      */
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index beb87cd..e29000d 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -125,7 +125,10 @@
      * setting on click extras and setting on click pending intents. The former is enabled,
      * and the latter disabled when this flag is true.
      */
-     private boolean mIsWidgetCollectionChild = false;
+    private boolean mIsWidgetCollectionChild = false;
+
+    private static final OnClickHandler DEFAULT_ON_CLICK_HANDLER = new OnClickHandler();
+    private OnClickHandler mOnClickHandler = DEFAULT_ON_CLICK_HANDLER;
 
     /**
      * This annotation indicates that a subclass of View is alllowed to be used
@@ -149,29 +152,9 @@
         }
     }
 
-    /**
-     * Base class for all actions that can be performed on an 
-     * inflated view.
-     *
-     *  SUBCLASSES MUST BE IMMUTABLE SO CLONE WORKS!!!!!
-     */
-    private abstract static class Action implements Parcelable {
-        public abstract void apply(View root, ViewGroup rootParent) throws ActionException;
-
-        public int describeContents() {
-            return 0;
-        }
-
-        /**
-         * Overridden by each class to report on it's own memory usage
-         */
-        public void updateMemoryUsageEstimate(MemoryUsageCounter counter) {
-            // We currently only calculate Bitmap memory usage, so by default, don't do anything
-            // here
-            return;
-        }
-
-        protected boolean startIntentSafely(View view, PendingIntent pendingIntent,
+    /** @hide */
+    public static class OnClickHandler {
+        public boolean onClickHandler(View view, PendingIntent pendingIntent,
                 Intent fillInIntent) {
             try {
                 // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
@@ -193,6 +176,30 @@
             }
             return true;
         }
+    }
+
+    /**
+     * Base class for all actions that can be performed on an
+     * inflated view.
+     *
+     *  SUBCLASSES MUST BE IMMUTABLE SO CLONE WORKS!!!!!
+     */
+    private abstract static class Action implements Parcelable {
+        public abstract void apply(RemoteViews owner, View root,
+                ViewGroup rootParent) throws ActionException;
+
+        public int describeContents() {
+            return 0;
+        }
+
+        /**
+         * Overridden by each class to report on it's own memory usage
+         */
+        public void updateMemoryUsageEstimate(MemoryUsageCounter counter) {
+            // We currently only calculate Bitmap memory usage, so by default, don't do anything
+            // here
+            return;
+        }
 
         public void setBitmapCache(BitmapCache bitmapCache) {
             // Do nothing
@@ -222,7 +229,7 @@
         }
 
         @Override
-        public void apply(View root, ViewGroup rootParent) {
+        public void apply(RemoteViews owner, View root, ViewGroup rootParent) {
             final View view = root.findViewById(viewId);
             if (!(view instanceof AdapterView<?>)) return;
 
@@ -253,7 +260,7 @@
         }
 
         @Override
-        public void apply(View root, ViewGroup rootParent) {
+        public void apply(RemoteViews owner, View root, ViewGroup rootParent) {
             final View target = root.findViewById(viewId);
             if (target == null) return;
 
@@ -265,6 +272,7 @@
             if (target == root) {
                 target.setTagInternal(com.android.internal.R.id.fillInIntent, fillInIntent);
             } else if (target != null && fillInIntent != null) {
+                final OnClickHandler clicker = owner.mOnClickHandler;
                 OnClickListener listener = new OnClickListener() {
                     public void onClick(View v) {
                         // Insure that this view is a child of an AdapterView
@@ -302,7 +310,7 @@
                         rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f);
 
                         fillInIntent.setSourceBounds(rect);
-                        startIntentSafely(v, pendingIntent, fillInIntent);
+                        clicker.onClickHandler(v, pendingIntent, fillInIntent);
                     }
 
                 };
@@ -334,13 +342,14 @@
         }
 
         @Override
-        public void apply(View root, ViewGroup rootParent) {
+        public void apply(RemoteViews owner, View root, ViewGroup rootParent) {
             final View target = root.findViewById(viewId);
             if (target == null) return;
 
             // If the view isn't an AdapterView, setting a PendingIntent template doesn't make sense
             if (target instanceof AdapterView<?>) {
                 AdapterView<?> av = (AdapterView<?>) target;
+                final OnClickHandler clicker = owner.mOnClickHandler;
                 // The PendingIntent template is stored in the view's tag.
                 OnItemClickListener listener = new OnItemClickListener() {
                     public void onItemClick(AdapterView<?> parent, View view,
@@ -380,7 +389,7 @@
 
                             final Intent intent = new Intent();
                             intent.setSourceBounds(rect);
-                            startIntentSafely(view, pendingIntentTemplate, fillInIntent);
+                            clicker.onClickHandler(view, pendingIntentTemplate, fillInIntent);
                         }
                     }
                 };
@@ -417,7 +426,7 @@
         }
 
         @Override
-        public void apply(View root, ViewGroup rootParent) {
+        public void apply(RemoteViews owner, View root, ViewGroup rootParent) {
             final View target = root.findViewById(viewId);
             if (target == null) return;
 
@@ -485,7 +494,7 @@
         }
 
         @Override
-        public void apply(View root, ViewGroup rootParent) {
+        public void apply(RemoteViews owner, View root, ViewGroup rootParent) {
             final View target = root.findViewById(viewId);
             if (target == null) return;
 
@@ -506,6 +515,7 @@
 
             if (target != null) {
                 // If the pendingIntent is null, we clear the onClickListener
+                final OnClickHandler clicker = owner.mOnClickHandler;
                 OnClickListener listener = null;
                 if (pendingIntent != null) {
                     listener = new OnClickListener() {
@@ -525,7 +535,7 @@
     
                             final Intent intent = new Intent();
                             intent.setSourceBounds(rect);
-                            startIntentSafely(v, pendingIntent, intent);
+                            clicker.onClickHandler(v, pendingIntent, intent);
                         }
                     };
                 }
@@ -592,7 +602,7 @@
         }
         
         @Override
-        public void apply(View root, ViewGroup rootParent) {
+        public void apply(RemoteViews owner, View root, ViewGroup rootParent) {
             final View target = root.findViewById(viewId);
             if (target == null) return;
             
@@ -652,7 +662,7 @@
         }
 
         @Override
-        public void apply(View root, ViewGroup rootParent) {
+        public void apply(RemoteViews owner, View root, ViewGroup rootParent) {
             final View view = root.findViewById(viewId);
             if (view == null) return;
 
@@ -776,10 +786,11 @@
         }
 
         @Override
-        public void apply(View root, ViewGroup rootParent) throws ActionException {
+        public void apply(RemoteViews owner, View root,
+                ViewGroup rootParent) throws ActionException {
             ReflectionAction ra = new ReflectionAction(viewId, methodName, ReflectionAction.BITMAP,
                     bitmap);
-            ra.apply(root, rootParent);
+            ra.apply(owner, root, rootParent);
         }
 
         @Override
@@ -995,7 +1006,7 @@
         }
 
         @Override
-        public void apply(View root, ViewGroup rootParent) {
+        public void apply(RemoteViews owner, View root, ViewGroup rootParent) {
             final View view = root.findViewById(viewId);
             if (view == null) return;
 
@@ -1097,13 +1108,13 @@
         }
 
         @Override
-        public void apply(View root, ViewGroup rootParent) {
+        public void apply(RemoteViews owner, View root, ViewGroup rootParent) {
             final Context context = root.getContext();
             final ViewGroup target = (ViewGroup) root.findViewById(viewId);
             if (target == null) return;
             if (nestedViews != null) {
                 // Inflate nested views and add as children
-                target.addView(nestedViews.apply(context, target));
+                target.addView(nestedViews.apply(owner, context, target));
             } else {
                 // Clear all children when nested views omitted
                 target.removeAllViews();
@@ -1164,7 +1175,7 @@
         }
 
         @Override
-        public void apply(View root, ViewGroup rootParent) {
+        public void apply(RemoteViews owner, View root, ViewGroup rootParent) {
             final Context context = root.getContext();
             final TextView target = (TextView) root.findViewById(viewId);
             if (target == null) return;
@@ -1206,7 +1217,7 @@
         }
 
         @Override
-        public void apply(View root, ViewGroup rootParent) {
+        public void apply(RemoteViews owner, View root, ViewGroup rootParent) {
             final Context context = root.getContext();
             final TextView target = (TextView) root.findViewById(viewId);
             if (target == null) return;
@@ -1250,7 +1261,7 @@
         }
 
         @Override
-        public void apply(View root, ViewGroup rootParent) {
+        public void apply(RemoteViews owner, View root, ViewGroup rootParent) {
             final Context context = root.getContext();
             final View target = root.findViewById(viewId);
             if (target == null) return;
@@ -2088,6 +2099,11 @@
         return this;
     }
 
+    /** @hide */
+    public void setOnClickHandler(OnClickHandler handler) {
+        mOnClickHandler = handler;
+    }
+
     /**
      * Inflates the view hierarchy represented by this object and applies
      * all of the actions.
@@ -2100,6 +2116,10 @@
      * @return The inflated view hierarchy
      */
     public View apply(Context context, ViewGroup parent) {
+        return apply(this, context, parent);
+    }
+
+    View apply(RemoteViews owner, Context context, ViewGroup parent) {
         RemoteViews rvToApply = getRemoteViewsToApply(context);
 
         View result;
@@ -2114,7 +2134,7 @@
 
         result = inflater.inflate(rvToApply.getLayoutId(), parent, false);
 
-        rvToApply.performApply(result, parent);
+        rvToApply.performApply(owner, result, parent);
 
         return result;
     }
@@ -2141,15 +2161,15 @@
         }
 
         prepareContext(context);
-        rvToApply.performApply(v, (ViewGroup) v.getParent());
+        rvToApply.performApply(this, v, (ViewGroup) v.getParent());
     }
 
-    private void performApply(View v, ViewGroup parent) {
+    private void performApply(RemoteViews owner, View v, ViewGroup parent) {
         if (mActions != null) {
             final int count = mActions.size();
             for (int i = 0; i < count; i++) {
                 Action a = mActions.get(i);
-                a.apply(v, parent);
+                a.apply(owner, v, parent);
             }
         }
     }
diff --git a/docs/html/shareables/training/CustomView.zip b/docs/html/shareables/training/CustomView.zip
index f8c1c7a..d7ae8a2 100644
--- a/docs/html/shareables/training/CustomView.zip
+++ b/docs/html/shareables/training/CustomView.zip
Binary files differ
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 2debd57..fcb676d 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -159,6 +159,22 @@
 
     /**
      * Instantiate a decoder supporting input data of the given mime type.
+     *
+     * The following is a partial list of defined mime types and their semantics:
+     * <ul>
+     * <li>"video/x-vnd.on2.vp8" - VPX video (i.e. video in .webm)
+     * <li>"video/avc" - H.264/AVC video
+     * <li>"video/mp4v-es" - MPEG4 video
+     * <li>"video/3gpp" - H.263 video
+     * <li>"audio/3gpp" - AMR narrowband audio
+     * <li>"audio/amr-wb" - AMR wideband audio
+     * <li>"audio/mpeg" - MPEG1/2 audio layer III
+     * <li>"audio/mp4a-latm" - AAC audio
+     * <li>"audio/vorbis" - vorbis audio
+     * <li>"audio/g711-alaw" - G.711 alaw audio
+     * <li>"audio/g711-mlaw" - G.711 ulaw audio
+     * </ul>
+     *
      * @param type The mime type of the input data.
      */
     public static MediaCodec createDecoderByType(String type) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index b0939de..2594167 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -63,7 +63,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 78;
+    private static final int DATABASE_VERSION = 79;
 
     private Context mContext;
 
@@ -1054,6 +1054,23 @@
             upgradeVersion = 78;
         }
 
+        if (upgradeVersion == 78) {
+            // The JavaScript based screen-reader URL changes in JellyBean.
+            db.beginTransaction();
+            SQLiteStatement stmt = null;
+            try {
+                stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)"
+                        + " VALUES(?,?);");
+                loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
+                        R.string.def_accessibility_screen_reader_url);
+                db.setTransactionSuccessful();
+            } finally {
+                db.endTransaction();
+                if (stmt != null) stmt.close();
+            }
+            upgradeVersion = 79;
+        }
+
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index c09e4c4..9448bbf 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -190,8 +190,7 @@
             sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
 
             Intent chooserIntent = Intent.createChooser(sharingIntent, null);
-            chooserIntent.addFlags(Intent.FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS
-                    | Intent.FLAG_ACTIVITY_CLEAR_TASK 
+            chooserIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK 
                     | Intent.FLAG_ACTIVITY_NEW_TASK);
 
             mNotificationBuilder.addAction(R.drawable.ic_menu_share,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index a3ec6c3..04cff96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -65,6 +65,7 @@
 import com.android.systemui.recent.RecentTasksLoader;
 import com.android.systemui.recent.TaskDescription;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.NotificationData.Entry;
 import com.android.systemui.statusbar.policy.NotificationRowLayout;
 import com.android.systemui.statusbar.tablet.StatusBarPanel;
 
@@ -154,6 +155,35 @@
         }
     };
 
+    private RemoteViews.OnClickHandler mOnClickHandler = new RemoteViews.OnClickHandler() {
+        @Override
+        public boolean onClickHandler(View view, PendingIntent pendingIntent, Intent fillInIntent) {
+            final boolean isActivity = pendingIntent.isActivity();
+            if (isActivity) {
+                try {
+                    // The intent we are sending is for the application, which
+                    // won't have permission to immediately start an activity after
+                    // the user switches to home.  We know it is safe to do at this
+                    // point, so make sure new activity switches are now allowed.
+                    ActivityManagerNative.getDefault().resumeAppSwitches();
+                    // Also, notifications can be launched from the lock screen,
+                    // so dismiss the lock screen when the activity starts.
+                    ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+                } catch (RemoteException e) {
+                }
+            }
+
+            boolean handled = super.onClickHandler(view, pendingIntent, fillInIntent);
+
+            if (isActivity && handled) {
+                // close the shade if it was open
+                animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE);
+                visibilityChanged(false);
+            }
+            return handled;
+        }
+    };
+
     public void start() {
         mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
                 .getDefaultDisplay();
@@ -547,8 +577,10 @@
         View expandedLarge = null;
         Exception exception = null;
         try {
+            oneU.setOnClickHandler(mOnClickHandler);
             expandedOneU = oneU.apply(mContext, adaptive);
             if (large != null) {
+                large.setOnClickHandler(mOnClickHandler);
                 expandedLarge = large.apply(mContext, adaptive);
             }
         }
@@ -904,4 +936,21 @@
             }
         }
     }
+
+    // Q: What kinds of notifications should show during setup?
+    // A: Almost none! Only things coming from the system (package is "android") that also
+    // have special "kind" tags marking them as relevant for setup (see below).
+    protected boolean showNotificationEvenIfUnprovisioned(StatusBarNotification sbn) {
+        if ("android".equals(sbn.pkg)) {
+            if (sbn.notification.kind != null) {
+                for (String aKind : sbn.notification.kind) {
+                    // IME switcher, created by InputMethodManagerService
+                    if ("android.system.imeswitcher".equals(aKind)) return true;
+                    // OTA availability & errors, created by SystemUpdateService
+                    if ("android.system.update".equals(aKind)) return true;
+                }
+            }
+        }
+        return false;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 3c19ad2..eff6061 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -821,23 +821,6 @@
             R.integer.config_show_search_delay);
     }
 
-    // Q: What kinds of notifications should show during setup?
-    // A: Almost none! Only things coming from the system (package is "android") that also 
-    // have special "kind" tags marking them as relevant for setup (see below).
-    private boolean showNotificationEvenIfUnprovisioned(StatusBarNotification sbn) {
-        if ("android".equals(sbn.pkg)) {
-            if (sbn.notification.kind != null) {
-                for (String aKind : sbn.notification.kind) {
-                    // IME switcher, created by InputMethodManagerService
-                    if ("android.system.imeswitcher".equals(aKind)) return true;
-                    // OTA availability & errors, created by SystemUpdateService
-                    if ("android.system.update".equals(aKind)) return true;
-                }
-            }
-        }
-        return false;
-    }
-
     private void loadNotificationShade() {
         if (mPile == null) return;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index af0f9d3..fdbfb65 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -217,7 +217,7 @@
     */
 
     public void onClick(View v) {
-        if (v == mTitleArea) {
+        if (mSettingsButton.isEnabled() && v == mTitleArea) {
             swapPanels();
         }
     }
@@ -280,7 +280,7 @@
 
     public void updatePanelModeButtons() {
         final boolean settingsVisible = (mSettingsView != null);
-        mSettingsButton.setVisibility(!settingsVisible ? View.VISIBLE : View.GONE);
+        mSettingsButton.setVisibility(!settingsVisible && mSettingsButton.isEnabled() ? View.VISIBLE : View.GONE);
         mNotificationButton.setVisibility(settingsVisible ? View.VISIBLE : View.GONE);
     }
 
@@ -421,5 +421,12 @@
                 super.onTouchEvent(ev);
         return handled;
     }
+
+    public void setSettingsEnabled(boolean settingsEnabled) {
+        if (mSettingsButton != null) {
+            mSettingsButton.setEnabled(settingsEnabled);
+            mSettingsButton.setVisibility(settingsEnabled ? View.VISIBLE : View.GONE);
+        }
+    }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanelTitle.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanelTitle.java
index 00cf3c5..d180ab9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanelTitle.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanelTitle.java
@@ -32,7 +32,7 @@
 public class NotificationPanelTitle extends RelativeLayout implements View.OnClickListener {
     private NotificationPanel mPanel;
     private ArrayList<View> buttons;
-    private View mNotificationsButton;
+    private View mSettingsButton;
 
     public NotificationPanelTitle(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -47,7 +47,7 @@
     @Override
     public void onFinishInflate() {
         super.onFinishInflate();
-        buttons.add(findViewById(R.id.settings_button));
+        buttons.add(mSettingsButton = findViewById(R.id.settings_button));
         buttons.add(findViewById(R.id.notification_button));
     }
 
@@ -63,6 +63,8 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent e) {
+        if (!mSettingsButton.isEnabled())
+            return false;
         switch (e.getAction()) {
             case MotionEvent.ACTION_DOWN:
                 setPressed(true);
@@ -88,7 +90,7 @@
 
     @Override
     public void onClick(View v) {
-        if (v == this) {
+        if (mSettingsButton.isEnabled() && v == this) {
             mPanel.swapPanels();
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 9b46af8..29d8c98 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -1235,7 +1235,7 @@
     @Override
     protected void setAreThereNotifications() {
         if (mNotificationPanel != null) {
-            mNotificationPanel.setClearable(mNotificationData.hasClearableItems());
+            mNotificationPanel.setClearable(isDeviceProvisioned() && mNotificationData.hasClearableItems());
         }
     }
 
@@ -1533,10 +1533,13 @@
         if (mInputMethodSwitchButton.getVisibility() != View.GONE) maxNotificationIconsCount --;
         if (mCompatModeButton.getVisibility()        != View.GONE) maxNotificationIconsCount --;
 
+        final boolean provisioned = isDeviceProvisioned();
+        // If the device hasn't been through Setup, we only show system notifications
         for (int i=0; toShow.size()< maxNotificationIconsCount; i++) {
             if (i >= N) break;
             Entry ent = mNotificationData.get(N-i-1);
-            if (ent.notification.score >= HIDE_ICONS_BELOW_SCORE) {
+            if ((provisioned && ent.notification.score >= HIDE_ICONS_BELOW_SCORE)
+                    || showNotificationEvenIfUnprovisioned(ent.notification)) {
                 toShow.add(ent.icon);
             }
         }
@@ -1567,9 +1570,13 @@
 
         ArrayList<View> toShow = new ArrayList<View>();
 
+        final boolean provisioned = isDeviceProvisioned();
+        // If the device hasn't been through Setup, we only show system notifications
         for (int i=0; i<N; i++) {
-            View row = mNotificationData.get(N-i-1).row;
-            toShow.add(row);
+            Entry ent = mNotificationData.get(N-i-1);
+            if (provisioned || showNotificationEvenIfUnprovisioned(ent.notification)) {
+                toShow.add(ent.row);
+            }
         }
 
         ArrayList<View> toRemove = new ArrayList<View>();
@@ -1588,11 +1595,12 @@
             View v = toShow.get(i);
             if (v.getParent() == null) {
                 // the notification panel has the most important things at the bottom
-                mPile.addView(v, N-1-i);
+                mPile.addView(v, Math.min(toShow.size()-1-i, mPile.getChildCount()));
             }
         }
 
-        mNotificationPanel.setNotificationCount(N);
+        mNotificationPanel.setNotificationCount(toShow.size());
+        mNotificationPanel.setSettingsEnabled(isDeviceProvisioned());
     }
 
     @Override
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 6b24da3..25da642 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -65,7 +65,6 @@
 import com.android.internal.widget.PointerLocationView;
 
 import android.service.dreams.IDreamManager;
-import android.speech.RecognizerIntent;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
@@ -160,6 +159,7 @@
     static final boolean localLOGV = false;
     static final boolean DEBUG_LAYOUT = false;
     static final boolean DEBUG_INPUT = false;
+    static final boolean DEBUG_STARTING_WINDOW = false;
     static final boolean SHOW_STARTING_ANIMATIONS = true;
     static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
 
@@ -1470,8 +1470,9 @@
 
         try {
             Context context = mContext;
-            //Log.i(TAG, "addStartingWindow " + packageName + ": nonLocalizedLabel="
-            //        + nonLocalizedLabel + " theme=" + Integer.toHexString(theme));
+            if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "addStartingWindow " + packageName
+                    + ": nonLocalizedLabel=" + nonLocalizedLabel + " theme="
+                    + Integer.toHexString(theme));
             if (theme != context.getThemeResId() || labelRes != 0) {
                 try {
                     context = context.createPackageContext(packageName, 0);
@@ -1538,7 +1539,7 @@
                 return null;
             }
 
-            if (localLOGV) Log.v(
+            if (DEBUG_STARTING_WINDOW) Slog.d(
                 TAG, "Adding starting window for " + packageName
                 + " / " + appToken + ": "
                 + (view.getParent() != null ? view : null));
@@ -1563,11 +1564,11 @@
 
     /** {@inheritDoc} */
     public void removeStartingWindow(IBinder appToken, View window) {
-        // RuntimeException e = new RuntimeException();
-        // Log.i(TAG, "remove " + appToken + " " + window, e);
-
-        if (localLOGV) Log.v(
-            TAG, "Removing starting window for " + appToken + ": " + window);
+        if (DEBUG_STARTING_WINDOW) {
+            RuntimeException e = new RuntimeException("here");
+            e.fillInStackTrace();
+            Log.v(TAG, "Removing starting window for " + appToken + ": " + window, e);
+        }
 
         if (window != null) {
             WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index eaecd4c..9dd4a91 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -229,7 +229,7 @@
             Slog.i(TAG, "Window Manager");
             wm = WindowManagerService.main(context, power,
                     factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
-                    !firstBoot);
+                    !firstBoot, onlyCore);
             ServiceManager.addService(Context.WINDOW_SERVICE, wm);
             inputManager = wm.getInputManagerService();
             ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 63455ee..f482552 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3577,8 +3577,7 @@
         
         for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
-            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0
-                    && (r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS) == 0) {
+            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
                 r.stack.finishActivityLocked(r, i,
                         Activity.RESULT_CANCELED, null, "close-sys");
             }
@@ -4573,6 +4572,21 @@
         return false;
     }
 
+    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
+        if (!(pendingResult instanceof PendingIntentRecord)) {
+            return false;
+        }
+        try {
+            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
+            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
+                return true;
+            }
+            return false;
+        } catch (ClassCastException e) {
+        }
+        return false;
+    }
+
     public void setProcessLimit(int max) {
         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
                 "setProcessLimit()");
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index be39711..b276494 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -2564,10 +2564,6 @@
             mDismissKeyguardOnNextActivity = false;
             mService.mWindowManager.dismissKeyguard();
         }
-        if (err >= ActivityManager.START_SUCCESS &&
-                (launchFlags&Intent.FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS) != 0) {
-            mService.closeSystemDialogsLocked(Process.myUid(), "launch");
-        }
         return err;
     }
   
diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java
index 1953ad7..13e8bc5 100644
--- a/services/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/java/com/android/server/wm/AppWindowAnimator.java
@@ -35,6 +35,10 @@
     // AppWindowToken animations.
     int animLayerAdjustment;
 
+    // Propagated from AppWindowToken.allDrawn, to determine when
+    // the state changes.
+    boolean allDrawn;
+
     // Special surface for thumbnail animation.
     Surface thumbnail;
     int thumbnailTransactionSeq;
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index bf35154..6ecbb8e 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -241,12 +241,18 @@
             pw.print(prefix); pw.print("paused="); pw.println(paused);
         }
         if (numInterestingWindows != 0 || numDrawnWindows != 0
-                || inPendingTransaction || allDrawn) {
+                || allDrawn || mAppAnimator.allDrawn) {
             pw.print(prefix); pw.print("numInterestingWindows=");
                     pw.print(numInterestingWindows);
                     pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
                     pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
-                    pw.print(" allDrawn="); pw.println(allDrawn);
+                    pw.print(" allDrawn="); pw.print(allDrawn);
+                    pw.print(" (animator="); pw.print(mAppAnimator.allDrawn);
+                    pw.println(")");
+        }
+        if (inPendingTransaction) {
+            pw.print(prefix); pw.print("inPendingTransaction=");
+                    pw.println(inPendingTransaction);
         }
         if (startingData != null || removed || firstWindowDrawn) {
             pw.print(prefix); pw.print("startingData="); pw.print(startingData);
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 758b6e7..fdd8aab 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -38,7 +38,6 @@
     ArrayList<WindowStateAnimator> mWinAnimators = new ArrayList<WindowStateAnimator>();
 
     boolean mAnimating;
-    boolean mTokenMayBeDrawn;
     boolean mForceHiding;
     WindowState mWindowAnimationBackground;
     int mWindowAnimationBackgroundColor;
@@ -57,7 +56,7 @@
 
     /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
      * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
-    private int mTransactionSequence;
+    private int mAnimTransactionSequence;
 
     /** The one and only screen rotation if one is happening */
     ScreenRotationAnimation mScreenRotationAnimation = null;
@@ -194,7 +193,7 @@
     }
 
     private void updateWindowsAndWallpaperLocked() {
-        ++mTransactionSequence;
+        ++mAnimTransactionSequence;
 
         ArrayList<WindowStateAnimator> unForceHiding = null;
         boolean wallpaperInUnForceHiding = false;
@@ -332,59 +331,22 @@
             }
 
             final AppWindowToken atoken = win.mAppToken;
-            if (atoken != null && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
-                if (atoken.lastTransactionSequence != mTransactionSequence) {
-                    atoken.lastTransactionSequence = mTransactionSequence;
-                    atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
-                    atoken.startingDisplayed = false;
-                }
-                if ((win.isOnScreen() || winAnimator.mAttrType
-                        == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
-                        && !win.mExiting && !win.mDestroying) {
-                    if (WindowManagerService.DEBUG_VISIBILITY ||
-                            WindowManagerService.DEBUG_ORIENTATION) {
-                        Slog.v(TAG, "Eval win " + win + ": isDrawn=" + win.isDrawnLw()
-                                + ", isAnimating=" + winAnimator.isAnimating());
-                        if (!win.isDrawnLw()) {
-                            Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurface
-                                    + " pv=" + win.mPolicyVisibility
-                                    + " mDrawState=" + winAnimator.mDrawState
-                                    + " ah=" + win.mAttachedHidden
-                                    + " th=" + atoken.hiddenRequested
-                                    + " a=" + winAnimator.mAnimating);
+            if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) {
+                if (atoken == null || atoken.allDrawn) {
+                    if (winAnimator.performShowLocked()) {
+                        mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
+                        if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+                            mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5",
+                                mPendingLayoutChanges);
                         }
                     }
-                    if (win != atoken.startingWindow) {
-                        if (!atoken.mAppAnimator.freezingScreen || !win.mAppFreezing) {
-                            atoken.numInterestingWindows++;
-                            if (win.isDrawnLw()) {
-                                atoken.numDrawnWindows++;
-                                if (WindowManagerService.DEBUG_VISIBILITY ||
-                                        WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
-                                        "tokenMayBeDrawn: " + atoken
-                                        + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
-                                        + " mAppFreezing=" + win.mAppFreezing);
-                                mTokenMayBeDrawn = true;
-                            }
-                        }
-                    } else if (win.isDrawnLw()) {
-                        atoken.startingDisplayed = true;
-                    }
-                }
-            } else if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) {
-                if (winAnimator.performShowLocked()) {
-                    mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
-                    if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
-                        mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5",
-                            mPendingLayoutChanges);
-                    }
                 }
             }
             final AppWindowAnimator appAnimator =
                     atoken == null ? null : atoken.mAppAnimator;
             if (appAnimator != null && appAnimator.thumbnail != null) {
-                if (appAnimator.thumbnailTransactionSeq != mTransactionSequence) {
-                    appAnimator.thumbnailTransactionSeq = mTransactionSequence;
+                if (appAnimator.thumbnailTransactionSeq != mAnimTransactionSequence) {
+                    appAnimator.thumbnailTransactionSeq = mAnimTransactionSequence;
                     appAnimator.thumbnailLayer = 0;
                 }
                 if (appAnimator.thumbnailLayer < winAnimator.mAnimLayer) {
@@ -414,39 +376,32 @@
         final int NT = appTokens.size();
         for (int i=0; i<NT; i++) {
             AppWindowToken wtoken = appTokens.get(i);
-            if (wtoken.mAppAnimator.freezingScreen) {
-                int numInteresting = wtoken.numInterestingWindows;
-                if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
-                    if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
-                            "allDrawn: " + wtoken
-                            + " interesting=" + numInteresting
-                            + " drawn=" + wtoken.numDrawnWindows);
-                    wtoken.mAppAnimator.showAllWindowsLocked();
-                    mService.unsetAppFreezingScreenLocked(wtoken, false, true);
-                    if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG,
-                            "Setting mOrientationChangeComplete=true because wtoken "
-                            + wtoken + " numInteresting=" + numInteresting
-                            + " numDrawn=" + wtoken.numDrawnWindows);
-                    // This will set mOrientationChangeComplete and cause a pass through layout.
-                    mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-                }
-            } else if (!wtoken.allDrawn) {
-                int numInteresting = wtoken.numInterestingWindows;
-                if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
-                    if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
-                            "allDrawn: " + wtoken
-                            + " interesting=" + numInteresting
-                            + " drawn=" + wtoken.numDrawnWindows);
-                    wtoken.allDrawn = true;
-                    mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
-                    if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
-                        mService.debugLayoutRepeats("testTokenMayBeDrawnLocked",
-                            mPendingLayoutChanges);
-                    }
+            final boolean allDrawn = wtoken.allDrawn;
+            if (allDrawn != wtoken.mAppAnimator.allDrawn) {
+                wtoken.mAppAnimator.allDrawn = allDrawn;
+                if (allDrawn) {
+                    // The token has now changed state to having all
+                    // windows shown...  what to do, what to do?
+                    if (wtoken.mAppAnimator.freezingScreen) {
+                        wtoken.mAppAnimator.showAllWindowsLocked();
+                        mService.unsetAppFreezingScreenLocked(wtoken, false, true);
+                        if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG,
+                                "Setting mOrientationChangeComplete=true because wtoken "
+                                + wtoken + " numInteresting=" + wtoken.numInterestingWindows
+                                + " numDrawn=" + wtoken.numDrawnWindows);
+                        // This will set mOrientationChangeComplete and cause a pass through layout.
+                        mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+                    } else {
+                        mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
+                        if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+                            mService.debugLayoutRepeats("testTokenMayBeDrawnLocked",
+                                mPendingLayoutChanges);
+                        }
 
-                    // We can now show all of the drawn windows!
-                    if (!mService.mOpeningApps.contains(wtoken)) {
-                        mAnimating |= wtoken.mAppAnimator.showAllWindowsLocked();
+                        // We can now show all of the drawn windows!
+                        if (!mService.mOpeningApps.contains(wtoken)) {
+                            mAnimating |= wtoken.mAppAnimator.showAllWindowsLocked();
+                        }
                     }
                 }
             }
@@ -454,7 +409,6 @@
     }
 
     private void performAnimationsLocked() {
-        mTokenMayBeDrawn = false;
         mForceHiding = false;
         mDetachedWallpaper = null;
         mWindowAnimationBackground = null;
@@ -465,9 +419,7 @@
             mPendingActions |= WALLPAPER_ACTION_PENDING;
         }
 
-        if (mTokenMayBeDrawn) {
-            testTokenMayBeDrawnLocked();
-        }
+        testTokenMayBeDrawnLocked();
     }
 
     synchronized void animate() {
@@ -584,18 +536,23 @@
     }
 
     public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
-        if (mWindowDetachedWallpaper != null) {
-            pw.print("  mWindowDetachedWallpaper="); pw.println(mWindowDetachedWallpaper);
-        }
-        if (mWindowAnimationBackgroundSurface != null) {
-            pw.println("  mWindowAnimationBackgroundSurface:");
-            mWindowAnimationBackgroundSurface.printTo("    ", pw);
-        }
-        if (mDimAnimator != null) {
-            pw.println("  mDimAnimator:");
-            mDimAnimator.printTo("    ", pw);
-        } else {
-            pw.println( "  no DimAnimator ");
+        if (dumpAll) {
+            if (mWindowDetachedWallpaper != null) {
+                pw.print(prefix); pw.print("mWindowDetachedWallpaper=");
+                        pw.println(mWindowDetachedWallpaper);
+            }
+            pw.print(prefix); pw.print("mAnimTransactionSequence=");
+                    pw.println(mAnimTransactionSequence);
+            if (mWindowAnimationBackgroundSurface != null) {
+                pw.print(prefix); pw.print("mWindowAnimationBackgroundSurface:");
+                        mWindowAnimationBackgroundSurface.printTo(prefix + "  ", pw);
+            }
+            if (mDimAnimator != null) {
+                pw.print(prefix); pw.print("mDimAnimator:");
+                mDimAnimator.printTo(prefix + "  ", pw);
+            } else {
+                pw.print(prefix); pw.print("no DimAnimator ");
+            }
         }
     }
 
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 73bfe8e..c850bd2 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -96,6 +96,7 @@
 import android.util.EventLog;
 import android.util.FloatMath;
 import android.util.Log;
+import android.util.LogPrinter;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseIntArray;
@@ -642,6 +643,10 @@
     }
     LayoutFields mInnerFields = new LayoutFields();
 
+    /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
+     * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
+    private int mTransactionSequence;
+
     /** Only do a maximum of 6 repeated layouts. After that quit */
     private int mLayoutRepeatCount;
 
@@ -758,9 +763,15 @@
     // The desired scaling factor for compatible apps.
     float mCompatibleScreenScale;
 
+    // If true, only the core apps and services are being launched because the device
+    // is in a special boot mode, such as being encrypted or waiting for a decryption password.
+    // For example, when this flag is true, there will be no wallpaper service.
+    final boolean mOnlyCore;
+
     public static WindowManagerService main(Context context,
-            PowerManagerService pm, boolean haveInputMethods, boolean allowBootMsgs) {
-        WMThread thr = new WMThread(context, pm, haveInputMethods, allowBootMsgs);
+            PowerManagerService pm, boolean haveInputMethods, boolean allowBootMsgs,
+            boolean onlyCore) {
+        WMThread thr = new WMThread(context, pm, haveInputMethods, allowBootMsgs, onlyCore);
         thr.start();
 
         synchronized (thr) {
@@ -781,21 +792,25 @@
         private final PowerManagerService mPM;
         private final boolean mHaveInputMethods;
         private final boolean mAllowBootMessages;
+        private final boolean mOnlyCore;
 
         public WMThread(Context context, PowerManagerService pm,
-                boolean haveInputMethods, boolean allowBootMsgs) {
+                boolean haveInputMethods, boolean allowBootMsgs, boolean onlyCore) {
             super("WindowManager");
             mContext = context;
             mPM = pm;
             mHaveInputMethods = haveInputMethods;
             mAllowBootMessages = allowBootMsgs;
+            mOnlyCore = onlyCore;
         }
 
         @Override
         public void run() {
             Looper.prepare();
+            //Looper.myLooper().setMessageLogging(new LogPrinter(
+            //        android.util.Log.DEBUG, TAG, android.util.Log.LOG_ID_SYSTEM));
             WindowManagerService s = new WindowManagerService(mContext, mPM,
-                    mHaveInputMethods, mAllowBootMessages);
+                    mHaveInputMethods, mAllowBootMessages, mOnlyCore);
             android.os.Process.setThreadPriority(
                     android.os.Process.THREAD_PRIORITY_DISPLAY);
             android.os.Process.setCanSelfBackground(false);
@@ -858,10 +873,11 @@
     }
 
     private WindowManagerService(Context context, PowerManagerService pm,
-            boolean haveInputMethods, boolean showBootMsgs) {
+            boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
         mContext = context;
         mHaveInputMethods = haveInputMethods;
         mAllowBootMessages = showBootMsgs;
+        mOnlyCore = onlyCore;
         mLimitedAlphaCompositing = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_sf_limitedAlpha);
         mHeadless = "1".equals(SystemProperties.get(SYSTEM_HEADLESS, "0"));
@@ -3573,7 +3589,7 @@
 
     public void setAppGroupId(IBinder token, int groupId) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
-                "setAppStartingIcon()")) {
+                "setAppGroupId()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
@@ -3996,7 +4012,7 @@
             CharSequence nonLocalizedLabel, int labelRes, int icon,
             int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
-                "setAppStartingIcon()")) {
+                "setAppStartingWindow()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
@@ -4052,12 +4068,13 @@
                         startingWindow.mToken = wtoken;
                         startingWindow.mRootToken = wtoken;
                         startingWindow.mAppToken = wtoken;
-                        if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
-                                "Removing starting window: " + startingWindow);
+                        if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
+                            Slog.v(TAG, "Removing starting window: " + startingWindow);
+                        }
                         mWindows.remove(startingWindow);
                         mWindowsChanged = true;
-                        if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing starting " + startingWindow
-                                + " from " + ttoken);
+                        if (DEBUG_ADD_REMOVE) Slog.v(TAG,
+                                "Removing starting " + startingWindow + " from " + ttoken);
                         ttoken.windows.remove(startingWindow);
                         ttoken.allAppWindows.remove(startingWindow);
                         addWindowToListInOrderLocked(startingWindow, true);
@@ -4144,6 +4161,8 @@
             // show a starting window -- the current effect (a full-screen
             // opaque starting window that fades away to the real contents
             // when it is ready) does not work for this.
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Checking theme of starting window: 0x"
+                    + Integer.toHexString(theme));
             if (theme != 0) {
                 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
                         com.android.internal.R.styleable.Window);
@@ -4152,6 +4171,15 @@
                     // pretend like we didn't see that.
                     return;
                 }
+                if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Translucent="
+                        + ent.array.getBoolean(
+                                com.android.internal.R.styleable.Window_windowIsTranslucent, false)
+                        + " Floating="
+                        + ent.array.getBoolean(
+                                com.android.internal.R.styleable.Window_windowIsFloating, false)
+                        + " ShowWallpaper="
+                        + ent.array.getBoolean(
+                                com.android.internal.R.styleable.Window_windowShowWallpaper, false));
                 if (ent.array.getBoolean(
                         com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
                     return;
@@ -4175,6 +4203,7 @@
                 }
             }
 
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
             mStartingIconInTransition = true;
             wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
                     labelRes, icon, windowFlags);
@@ -4182,6 +4211,7 @@
             // Note: we really want to do sendMessageAtFrontOfQueue() because we
             // want to process the message ASAP, before any other queued
             // messages.
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
             mH.sendMessageAtFrontOfQueue(m);
         }
     }
@@ -5191,7 +5221,8 @@
                 Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
                         + " mForceDisplayEnabled=" + mForceDisplayEnabled
                         + " mShowingBootMessages=" + mShowingBootMessages
-                        + " mSystemBooted=" + mSystemBooted, here);
+                        + " mSystemBooted=" + mSystemBooted
+                        + " mOnlyCore=" + mOnlyCore, here);
             }
             if (mDisplayEnabled) {
                 return;
@@ -5209,7 +5240,8 @@
                 // wallpaper, don't bother waiting for it
                 boolean haveWallpaper = false;
                 boolean wallpaperEnabled = mContext.getResources().getBoolean(
-                        com.android.internal.R.bool.config_enableWallpaperService);
+                        com.android.internal.R.bool.config_enableWallpaperService)
+                        && !mOnlyCore;
                 boolean haveKeyguard = true;
                 final int N = mWindows.size();
                 for (int i=0; i<N; i++) {
@@ -5285,6 +5317,9 @@
             } catch (RemoteException ex) {
                 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
             }
+
+            // Enable input dispatch.
+            mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled);
         }
 
         mPolicy.enableScreenAfterBoot();
@@ -6636,7 +6671,8 @@
     // -------------------------------------------------------------
     
     final InputMonitor mInputMonitor = new InputMonitor(this);
-    
+    private boolean mEventDispatchingEnabled;
+
     public void pauseKeyDispatching(IBinder _token) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "pauseKeyDispatching()")) {
@@ -6672,7 +6708,10 @@
         }
 
         synchronized (mWindowMap) {
-            mInputMonitor.setEventDispatchingLw(enabled);
+            mEventDispatchingEnabled = enabled;
+            if (mDisplayEnabled) {
+                mInputMonitor.setEventDispatchingLw(enabled);
+            }
             sendScreenStatusToClientsLocked();
         }
     }
@@ -8444,6 +8483,26 @@
         }
     }
 
+    private void updateAllDrawnLocked() {
+        // See if any windows have been drawn, so they (and others
+        // associated with them) can now be shown.
+        final ArrayList<AppWindowToken> appTokens = mAnimatingAppTokens;
+        final int NT = appTokens.size();
+        for (int i=0; i<NT; i++) {
+            AppWindowToken wtoken = appTokens.get(i);
+            if (!wtoken.allDrawn) {
+                int numInteresting = wtoken.numInterestingWindows;
+                if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
+                    if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
+                            "allDrawn: " + wtoken
+                            + " interesting=" + numInteresting
+                            + " drawn=" + wtoken.numDrawnWindows);
+                    wtoken.allDrawn = true;
+                }
+            }
+        }
+    }
+
     // "Something has changed!  Let's make it correct now."
     private final void performLayoutAndPlaceSurfacesLockedInner(
             boolean recoveringMemory) {
@@ -8483,6 +8542,7 @@
         mInnerFields.mHoldScreen = null;
         mInnerFields.mScreenBrightness = -1;
         mInnerFields.mButtonBrightness = -1;
+        mTransactionSequence++;
 
         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
                 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
@@ -8560,6 +8620,7 @@
             mInnerFields.mSyswin = false;
 
             boolean focusDisplayed = false;
+            boolean updateAllDrawn = false;
             final int N = mWindows.size();
             for (i=N-1; i>=0; i--) {
                 WindowState w = mWindows.get(i);
@@ -8616,6 +8677,53 @@
                     }
 
                     winAnimator.setSurfaceBoundaries(recoveringMemory);
+
+                    final AppWindowToken atoken = w.mAppToken;
+                    if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
+                        Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen="
+                            + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
+                            + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
+                    }
+                    if (atoken != null && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
+                        if (atoken.lastTransactionSequence != mTransactionSequence) {
+                            atoken.lastTransactionSequence = mTransactionSequence;
+                            atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
+                            atoken.startingDisplayed = false;
+                        }
+                        if ((w.isOnScreen() || winAnimator.mAttrType
+                                == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
+                                && !w.mExiting && !w.mDestroying) {
+                            if (WindowManagerService.DEBUG_VISIBILITY ||
+                                    WindowManagerService.DEBUG_ORIENTATION) {
+                                Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
+                                        + ", isAnimating=" + winAnimator.isAnimating());
+                                if (!w.isDrawnLw()) {
+                                    Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurface
+                                            + " pv=" + w.mPolicyVisibility
+                                            + " mDrawState=" + winAnimator.mDrawState
+                                            + " ah=" + w.mAttachedHidden
+                                            + " th=" + atoken.hiddenRequested
+                                            + " a=" + winAnimator.mAnimating);
+                                }
+                            }
+                            if (w != atoken.startingWindow) {
+                                if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
+                                    atoken.numInterestingWindows++;
+                                    if (w.isDrawnLw()) {
+                                        atoken.numDrawnWindows++;
+                                        if (WindowManagerService.DEBUG_VISIBILITY ||
+                                                WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
+                                                "tokenMayBeDrawn: " + atoken
+                                                + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
+                                                + " mAppFreezing=" + w.mAppFreezing);
+                                        updateAllDrawn = true;
+                                    }
+                                }
+                            } else if (w.isDrawnLw()) {
+                                atoken.startingDisplayed = true;
+                            }
+                        }
+                    }
                 }
 
                 if (someoneLosingFocus && w == mCurrentFocus && w.isDisplayedLw()) {
@@ -8625,6 +8733,10 @@
                 updateResizingWindows(w);
             }
 
+            if (updateAllDrawn) {
+                updateAllDrawnLocked();
+            }
+
             if (focusDisplayed) {
                 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
             }
@@ -9753,7 +9865,8 @@
             }
             pw.print("  mSystemBooted="); pw.print(mSystemBooted);
                     pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
-            pw.print("  mLayoutNeeded="); pw.println(mLayoutNeeded);
+            pw.print("  mLayoutNeeded="); pw.print(mLayoutNeeded);
+                    pw.print("mTransactionSequence="); pw.println(mTransactionSequence);
             pw.print("  mDisplayFrozen="); pw.print(mDisplayFrozen);
                     pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
                     pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
@@ -9814,6 +9927,8 @@
             }
             pw.print("  mStartingIconInTransition="); pw.print(mStartingIconInTransition);
                     pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
+            pw.println("  Window Animator:");
+            mAnimator.dump(pw, "    ", dumpAll);
         }
     }
 
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 109161a..03e52fe 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -120,6 +120,16 @@
     static final int READY_TO_SHOW = 3;
     /** Set when the window has been shown in the screen the first time. */
     static final int HAS_DRAWN = 4;
+    static String drawStateToString(int state) {
+        switch (state) {
+            case NO_SURFACE: return "NO_SURFACE";
+            case DRAW_PENDING: return "DRAW_PENDING";
+            case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING";
+            case READY_TO_SHOW: return "READY_TO_SHOW";
+            case HAS_DRAWN: return "HAS_DRAWN";
+            default: return Integer.toString(state);
+        }
+    }
     int mDrawState;
 
     /** Was this window last hidden? */
@@ -399,10 +409,19 @@
     }
 
     boolean finishDrawingLocked() {
+        if (DEBUG_STARTING_WINDOW &&
+                mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
+            Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
+                    + drawStateToString(mDrawState));
+        }
         if (mDrawState == DRAW_PENDING) {
             if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
                 Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + this + " in "
                         + mSurface);
+            if (DEBUG_STARTING_WINDOW &&
+                    mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
+                Slog.v(TAG, "Draw state now committed in " + mWin);
+            }
             mDrawState = COMMIT_DRAW_PENDING;
             return true;
         }
@@ -411,11 +430,17 @@
 
     // This must be called while inside a transaction.
     boolean commitFinishDrawingLocked(long currentTime) {
+        if (DEBUG_STARTING_WINDOW &&
+                mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
+            Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
+                    + drawStateToString(mDrawState));
+        }
         if (mDrawState != COMMIT_DRAW_PENDING) {
             return false;
         }
-        if (DEBUG_SURFACE_TRACE || DEBUG_ANIM)
+        if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) {
             Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurface);
+        }
         mDrawState = READY_TO_SHOW;
         final boolean starting = mWin.mAttrs.type == TYPE_APPLICATION_STARTING;
         final AppWindowToken atoken = mWin.mAppToken;
@@ -1214,7 +1239,8 @@
 
     // This must be called while inside a transaction.
     boolean performShowLocked() {
-        if (DEBUG_VISIBILITY) {
+        if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW &&
+                mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) {
             RuntimeException e = null;
             if (!WindowManagerService.HIDE_STACK_CRAWLS) {
                 e = new RuntimeException();
@@ -1223,12 +1249,7 @@
             Slog.v(TAG, "performShow on " + this
                     + ": mDrawState=" + mDrawState + " readyForDisplay="
                     + mWin.isReadyForDisplayIgnoringKeyguard()
-                    + " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING), e);
-        }
-        if (mDrawState == READY_TO_SHOW && mWin.isReadyForDisplayIgnoringKeyguard()) {
-            if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
-                WindowManagerService.logSurface(mWin, "SHOW (performShowLocked)", null);
-            if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
+                    + " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING)
                     + " during animation: policyVis=" + mWin.mPolicyVisibility
                     + " attHidden=" + mWin.mAttachedHidden
                     + " tok.hiddenRequested="
@@ -1237,7 +1258,24 @@
                     + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
                     + " animating=" + mAnimating
                     + " tok animating="
-                    + (mWin.mAppToken != null ? mWin.mAppToken.mAppAnimator.animating : false));
+                    + (mWin.mAppToken != null ? mWin.mAppToken.mAppAnimator.animating : false), e);
+        }
+        if (mDrawState == READY_TO_SHOW && mWin.isReadyForDisplayIgnoringKeyguard()) {
+            if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
+                WindowManagerService.logSurface(mWin, "SHOW (performShowLocked)", null);
+            if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW &&
+                    mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) {
+                Slog.v(TAG, "Showing " + this
+                        + " during animation: policyVis=" + mWin.mPolicyVisibility
+                        + " attHidden=" + mWin.mAttachedHidden
+                        + " tok.hiddenRequested="
+                        + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false)
+                        + " tok.hidden="
+                        + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
+                        + " animating=" + mAnimating
+                        + " tok animating="
+                        + (mWin.mAppToken != null ? mWin.mAppToken.mAppAnimator.animating : false));
+            }
 
             mService.enableScreenIfNeededLocked();
 
@@ -1425,7 +1463,8 @@
         if (mSurface != null) {
             if (dumpAll) {
                 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
-                pw.print(prefix); pw.print("mDrawState="); pw.print(mDrawState);
+                pw.print(prefix); pw.print("mDrawState=");
+                pw.print(drawStateToString(mDrawState));
                 pw.print(" mLastHidden="); pw.println(mLastHidden);
             }
             pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);