Merge "ActivityChooser view not handling its removal and relayout properly." into jb-dev
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
index c643137..bdcb2af 100644
--- a/core/java/android/animation/LayoutTransition.java
+++ b/core/java/android/animation/LayoutTransition.java
@@ -1208,6 +1208,9 @@
      * affect CHANGE_APPEARING or CHANGE_DISAPPEARING animations.
      */
     private void addChild(ViewGroup parent, View child, boolean changesLayout) {
+        if (parent.getWindowVisibility() != View.VISIBLE) {
+            return;
+        }
         if ((mTransitionTypes & FLAG_APPEARING) == FLAG_APPEARING) {
             // Want disappearing animations to finish up before proceeding
             cancel(DISAPPEARING);
@@ -1243,6 +1246,9 @@
      * @hide
      */
     public void layoutChange(ViewGroup parent) {
+        if (parent.getWindowVisibility() != View.VISIBLE) {
+            return;
+        }
         if ((mTransitionTypes & FLAG_CHANGING) == FLAG_CHANGING  && !isRunning()) {
             // This method is called for all calls to layout() in the container, including
             // those caused by add/remove/hide/show events, which will already have set up
@@ -1301,6 +1307,9 @@
      * affect CHANGE_APPEARING or CHANGE_DISAPPEARING animations.
      */
     private void removeChild(ViewGroup parent, View child, boolean changesLayout) {
+        if (parent.getWindowVisibility() != View.VISIBLE) {
+            return;
+        }
         if ((mTransitionTypes & FLAG_DISAPPEARING) == FLAG_DISAPPEARING) {
             // Want appearing animations to finish up before proceeding
             cancel(APPEARING);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 618f1f8..3ced82b 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1689,6 +1689,8 @@
      */
     public static class BigPictureStyle extends Style {
         private Bitmap mPicture;
+        private Bitmap mBigLargeIcon;
+        private boolean mBigLargeIconSet = false;
 
         public BigPictureStyle() {
         }
@@ -1719,6 +1721,16 @@
             return this;
         }
 
+        /**
+         * @hide
+         * Override the large icon when the big notification is shown.
+         */
+        public BigPictureStyle bigLargeIcon(Bitmap b) {
+            mBigLargeIconSet = true;
+            mBigLargeIcon = b;
+            return this;
+        }
+
         private RemoteViews makeBigContentView() {
             RemoteViews contentView = getStandardView(R.layout.notification_template_big_picture);
 
@@ -1731,6 +1743,9 @@
         public Notification build() {
             checkBuilder();
             Notification wip = mBuilder.buildUnstyled();
+            if (mBigLargeIconSet ) {
+                mBuilder.mLargeIcon = mBigLargeIcon;
+            }
             wip.bigContentView = makeBigContentView();
             return wip;
         }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a74a0ef..20eef11 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12725,6 +12725,7 @@
         if (!initialized) {
             a.initialize(mRight - mLeft, mBottom - mTop, parent.getWidth(), parent.getHeight());
             a.initializeInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop);
+            if (mAttachInfo != null) a.setListenerHandler(mAttachInfo.mHandler);
             onAnimationStart();
         }
 
@@ -12738,6 +12739,7 @@
         } else {
             invalidationTransform = parent.mChildTransformation;
         }
+
         if (more) {
             if (!a.willChangeBounds()) {
                 if ((flags & (parent.FLAG_OPTIMIZE_INVALIDATE | parent.FLAG_ANIMATION_DONE)) ==
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 421109f..a243c73 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3154,8 +3154,12 @@
     }
 
     /**
-     * Adds a child view. If no layout parameters are already set on the child, the
-     * default parameters for this ViewGroup are set on the child.
+     * <p>Adds a child view. If no layout parameters are already set on the child, the
+     * default parameters for this ViewGroup are set on the child.</p>
+     * 
+     * <p><strong>Note:</strong> do not invoke this method from
+     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
      *
      * @param child the child view to add
      *
@@ -3168,6 +3172,10 @@
     /**
      * Adds a child view. If no layout parameters are already set on the child, the
      * default parameters for this ViewGroup are set on the child.
+     * 
+     * <p><strong>Note:</strong> do not invoke this method from
+     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
      *
      * @param child the child view to add
      * @param index the position at which to add the child
@@ -3189,6 +3197,10 @@
      * Adds a child view with this ViewGroup's default layout parameters and the
      * specified width and height.
      *
+     * <p><strong>Note:</strong> do not invoke this method from
+     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
+     *
      * @param child the child view to add
      */
     public void addView(View child, int width, int height) {
@@ -3201,6 +3213,10 @@
     /**
      * Adds a child view with the specified layout parameters.
      *
+     * <p><strong>Note:</strong> do not invoke this method from
+     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
+     *
      * @param child the child view to add
      * @param params the layout parameters to set on the child
      */
@@ -3211,6 +3227,10 @@
     /**
      * Adds a child view with the specified layout parameters.
      *
+     * <p><strong>Note:</strong> do not invoke this method from
+     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
+     *
      * @param child the child view to add
      * @param index the position at which to add the child
      * @param params the layout parameters to set on the child
@@ -3528,6 +3548,10 @@
 
     /**
      * {@inheritDoc}
+     * 
+     * <p><strong>Note:</strong> do not invoke this method from
+     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
      */
     public void removeView(View view) {
         removeViewInternal(view);
@@ -3539,6 +3563,10 @@
      * Removes a view during layout. This is useful if in your onLayout() method,
      * you need to remove more views.
      *
+     * <p><strong>Note:</strong> do not invoke this method from
+     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
+     * 
      * @param view the view to remove from the group
      */
     public void removeViewInLayout(View view) {
@@ -3549,6 +3577,10 @@
      * Removes a range of views during layout. This is useful if in your onLayout() method,
      * you need to remove more views.
      *
+     * <p><strong>Note:</strong> do not invoke this method from
+     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
+     *
      * @param start the index of the first view to remove from the group
      * @param count the number of views to remove from the group
      */
@@ -3559,6 +3591,10 @@
     /**
      * Removes the view at the specified position in the group.
      *
+     * <p><strong>Note:</strong> do not invoke this method from
+     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
+     * 
      * @param index the position in the group of the view to remove
      */
     public void removeViewAt(int index) {
@@ -3570,6 +3606,10 @@
     /**
      * Removes the specified range of views from the group.
      *
+     * <p><strong>Note:</strong> do not invoke this method from
+     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
+     *
      * @param start the first position in the group of the range of views to remove
      * @param count the number of views to remove
      */
@@ -3715,6 +3755,10 @@
     /**
      * Call this method to remove all child views from the
      * ViewGroup.
+     * 
+     * <p><strong>Note:</strong> do not invoke this method from
+     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
      */
     public void removeAllViews() {
         removeAllViewsInLayout();
@@ -3730,6 +3774,10 @@
      * that can currently fit inside the object on screen. Do not call
      * this method unless you are extending ViewGroup and understand the
      * view measuring and layout pipeline.
+     *
+     * <p><strong>Note:</strong> do not invoke this method from
+     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
      */
     public void removeAllViewsInLayout() {
         final int count = mChildrenCount;
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index d92ebcd..85d77cb 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.RectF;
+import android.os.Handler;
 import android.os.SystemProperties;
 import android.util.AttributeSet;
 import android.util.TypedValue;
@@ -207,6 +208,11 @@
 
     private final CloseGuard guard = CloseGuard.get();
 
+    private Handler mListenerHandler;
+    private Runnable mOnStart;
+    private Runnable mOnRepeat;
+    private Runnable mOnEnd;
+
     /**
      * Creates a new animation with a duration of 0ms, the default interpolator, with
      * fillBefore set to true and fillAfter set to false
@@ -275,6 +281,7 @@
         mRepeated = 0;
         mMore = true;
         mOneMoreTime = true;
+        mListenerHandler = null;
     }
 
     /**
@@ -290,7 +297,7 @@
      */
     public void cancel() {
         if (mStarted && !mEnded) {
-            if (mListener != null) mListener.onAnimationEnd(this);
+            fireAnimationEnd();
             mEnded = true;
             guard.close();
         }
@@ -306,7 +313,7 @@
         if (mStarted && !mEnded) {
             mEnded = true;
             guard.close();
-            if (mListener != null) mListener.onAnimationEnd(this);
+            fireAnimationEnd();
         }
     }
 
@@ -341,6 +348,38 @@
     }
 
     /**
+     * Sets the handler used to invoke listeners.
+     * 
+     * @hide
+     */
+    public void setListenerHandler(Handler handler) {
+        if (mListenerHandler == null) {
+            mOnStart = new Runnable() {
+                public void run() {
+                    if (mListener != null) {
+                        mListener.onAnimationStart(Animation.this);
+                    }
+                }
+            };
+            mOnRepeat = new Runnable() {
+                public void run() {
+                    if (mListener != null) {
+                        mListener.onAnimationRepeat(Animation.this);
+                    }
+                }
+            };
+            mOnEnd = new Runnable() {
+                public void run() {
+                    if (mListener != null) {
+                        mListener.onAnimationEnd(Animation.this);
+                    }
+                }
+            };
+        }
+        mListenerHandler = handler;
+    }
+
+    /**
      * Sets the acceleration curve for this animation. The interpolator is loaded as
      * a resource from the specified context.
      *
@@ -792,7 +831,6 @@
      * @return True if the animation is still running
      */
     public boolean getTransformation(long currentTime, Transformation outTransformation) {
-
         if (mStartTime == -1) {
             mStartTime = currentTime;
         }
@@ -815,9 +853,7 @@
 
         if ((normalizedTime >= 0.0f || mFillBefore) && (normalizedTime <= 1.0f || mFillAfter)) {
             if (!mStarted) {
-                if (mListener != null) {
-                    mListener.onAnimationStart(this);
-                }
+                fireAnimationStart();
                 mStarted = true;
                 if (USE_CLOSEGUARD) {
                     guard.open("cancel or detach or getTransformation");
@@ -839,9 +875,7 @@
                 if (!mEnded) {
                     mEnded = true;
                     guard.close();
-                    if (mListener != null) {
-                        mListener.onAnimationEnd(this);
-                    }
+                    fireAnimationEnd();
                 }
             } else {
                 if (mRepeatCount > 0) {
@@ -855,9 +889,7 @@
                 mStartTime = -1;
                 mMore = true;
 
-                if (mListener != null) {
-                    mListener.onAnimationRepeat(this);
-                }
+                fireAnimationRepeat();
             }
         }
 
@@ -868,7 +900,28 @@
 
         return mMore;
     }
-    
+
+    private void fireAnimationStart() {
+        if (mListener != null) {
+            if (mListenerHandler == null) mListener.onAnimationStart(this);
+            else mListenerHandler.postAtFrontOfQueue(mOnStart);
+        }
+    }
+
+    private void fireAnimationRepeat() {
+        if (mListener != null) {
+            if (mListenerHandler == null) mListener.onAnimationRepeat(this);
+            else mListenerHandler.postAtFrontOfQueue(mOnRepeat);
+        }
+    }
+
+    private void fireAnimationEnd() {
+        if (mListener != null) {
+            if (mListenerHandler == null) mListener.onAnimationEnd(this);
+            else mListenerHandler.postAtFrontOfQueue(mOnEnd);
+        }
+    }
+
     /**
      * Gets the transformation to apply at a specified point in time. Implementations of this
      * method should always replace the specified Transformation or document they are doing
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 58dd82e..9f8771c 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -7872,7 +7872,7 @@
         nativeSetTextSelection(mNativeClass, data.mSelectTextPtr);
 
         if ((data.mSelectionReason == TextSelectionData.REASON_ACCESSIBILITY_INJECTOR)
-                || (!mSelectingText
+                || (!mSelectingText && data.mStart != data.mEnd
                         && data.mSelectionReason != TextSelectionData.REASON_SELECT_WORD)) {
             selectionDone();
             mShowTextSelectionExtra = true;
diff --git a/core/res/res/layout/notification_template_big_picture.xml b/core/res/res/layout/notification_template_big_picture.xml
index 9b896a4..077616e 100644
--- a/core/res/res/layout/notification_template_big_picture.xml
+++ b/core/res/res/layout/notification_template_big_picture.xml
@@ -38,8 +38,25 @@
         android:scaleType="fitXY"
         android:src="@drawable/title_bar_shadow"
         />
-    <include layout="@layout/notification_template_base" 
+    <include layout="@layout/notification_template_base"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         />
+  <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="208dp"
+        android:layout_marginLeft="64dp"
+        android:layout_gravity="bottom"
+        android:background="#CC111111"
+        >
+        <include
+            layout="@layout/notification_action_list"
+            android:id="@+id/actions"
+            android:layout_marginLeft="8dp"
+            android:layout_gravity="bottom"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            />
+    </FrameLayout>
 </FrameLayout>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index f1f67eb..a143feb 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -785,6 +785,7 @@
   <java-symbol type="string" name="serviceNotProvisioned" />
   <java-symbol type="string" name="serviceRegistered" />
   <java-symbol type="string" name="setup_autofill" />
+  <java-symbol type="string" name="share" />
   <java-symbol type="string" name="shareactionprovider_share_with" />
   <java-symbol type="string" name="shareactionprovider_share_with_application" />
   <java-symbol type="string" name="short_format_month" />
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_menu_share.png b/packages/SystemUI/res/drawable-hdpi/ic_menu_share.png
new file mode 100644
index 0000000..11ab480
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_menu_share.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_menu_share.png b/packages/SystemUI/res/drawable-mdpi/ic_menu_share.png
new file mode 100644
index 0000000..30e69bb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_menu_share.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_menu_share.png b/packages/SystemUI/res/drawable-xhdpi/ic_menu_share.png
new file mode 100644
index 0000000..af3e112
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_menu_share.png
Binary files differ
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index b1611d1..0b362d1 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -59,7 +59,7 @@
     <dimen name="notification_max_height">256dp</dimen>
 
     <!-- Height of a small notification in the status bar plus glow, padding, etc -->
-    <dimen name="notification_row_min_height">72dp</dimen>
+    <dimen name="notification_row_min_height">70dp</dimen>
 
     <!-- Height of a large notification in the status bar plus glow, padding, etc -->
     <dimen name="notification_row_max_height">260dp</dimen>
@@ -74,7 +74,7 @@
     <dimen name="status_bar_icon_padding">0dp</dimen>
 
     <!-- half the distance between notifications in the panel -->
-    <dimen name="notification_divider_height">4dp</dimen>
+    <dimen name="notification_divider_height">3dp</dimen>
 
     <!-- Notification drawer tuning parameters (phone UI) -->
     <!-- Initial velocity of the shade when expanding on its own -->
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 9a76c14..8795154 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -22,6 +22,7 @@
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.app.Notification;
+import android.app.Notification.BigPictureStyle;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.content.ContentResolver;
@@ -31,9 +32,13 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Matrix;
+import android.graphics.Paint;
 import android.graphics.PixelFormat;
 import android.graphics.PointF;
+import android.graphics.RectF;
 import android.media.MediaActionSound;
 import android.net.Uri;
 import android.os.AsyncTask;
@@ -85,6 +90,7 @@
     private String mImageFileName;
     private String mImageFilePath;
     private long mImageTime;
+    private BigPictureStyle mNotificationStyle;
 
     // WORKAROUND: We want the same notification across screenshots that we update so that we don't
     // spam a user's notification drawer.  However, we only show the ticker for the saving state
@@ -109,16 +115,22 @@
         // Create the large notification icon
         int imageWidth = data.image.getWidth();
         int imageHeight = data.image.getHeight();
-        int iconWidth = data.iconSize;
-        int iconHeight = data.iconSize;
-        if (imageWidth > imageHeight) {
-            iconWidth = (int) (((float) iconHeight / imageHeight) * imageWidth);
-        } else {
-            iconHeight = (int) (((float) iconWidth / imageWidth) * imageHeight);
-        }
-        Bitmap rawIcon = Bitmap.createScaledBitmap(data.image, iconWidth, iconHeight, true);
-        Bitmap croppedIcon = Bitmap.createBitmap(rawIcon, (iconWidth - data.iconSize) / 2,
-                (iconHeight - data.iconSize) / 2, data.iconSize, data.iconSize);
+        int iconSize = data.iconSize;
+
+        final int shortSide = imageWidth < imageHeight ? imageWidth : imageHeight;
+        Bitmap preview = Bitmap.createBitmap(shortSide, shortSide, data.image.getConfig());
+        Canvas c = new Canvas(preview);
+        Paint paint = new Paint();
+        ColorMatrix desat = new ColorMatrix();
+        desat.setSaturation(0.25f);
+        paint.setColorFilter(new ColorMatrixColorFilter(desat));
+        Matrix matrix = new Matrix();
+        matrix.postTranslate((shortSide - imageWidth) / 2,
+                            (shortSide - imageHeight) / 2);
+        c.drawBitmap(data.image, matrix, paint);
+        c.drawColor(0x40FFFFFF);
+
+        Bitmap croppedIcon = Bitmap.createScaledBitmap(preview, iconSize, iconSize, true);
 
         // Show the intermediate notification
         mTickerAddSpace = !mTickerAddSpace;
@@ -131,7 +143,12 @@
             .setContentText(r.getString(R.string.screenshot_saving_text))
             .setSmallIcon(R.drawable.stat_notify_image)
             .setWhen(System.currentTimeMillis());
-        Notification n = mNotificationBuilder.getNotification();
+
+        mNotificationStyle = new Notification.BigPictureStyle()
+            .bigPicture(preview);
+        mNotificationBuilder.setStyle(mNotificationStyle);
+
+        Notification n = mNotificationBuilder.build();
         n.flags |= Notification.FLAG_NO_CLEAR;
         mNotificationManager.notify(nId, n);
 
@@ -139,6 +156,8 @@
         // on small devices, the large icon is not shown) so defer showing the large icon until
         // we compose the final post-save notification below.
         mNotificationBuilder.setLargeIcon(croppedIcon);
+        // But we still don't set it for the expanded view, allowing the smallIcon to show here.
+        mNotificationStyle.bigLargeIcon(null);
     }
 
     @Override
@@ -151,6 +170,7 @@
 
         Context context = params[0].context;
         Bitmap image = params[0].image;
+        Resources r = context.getResources();
 
         try {
             // Save the screenshot to the MediaStore
@@ -165,6 +185,14 @@
             values.put(MediaStore.Images.ImageColumns.MIME_TYPE, "image/png");
             Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
 
+            Intent sharingIntent = new Intent(Intent.ACTION_SEND);
+            sharingIntent.setType("image/png");
+            sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
+            sharingIntent.setFlags(Intent.FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS);
+            mNotificationBuilder.addAction(R.drawable.ic_menu_share,
+                     r.getString(com.android.internal.R.string.share),
+                     PendingIntent.getActivity(context, 0, sharingIntent, 0));
+
             OutputStream out = resolver.openOutputStream(uri);
             image.compress(Bitmap.CompressFormat.PNG, 100, out);
             out.flush();
@@ -207,7 +235,7 @@
                 .setWhen(System.currentTimeMillis())
                 .setAutoCancel(true);
 
-            Notification n = mNotificationBuilder.getNotification();
+            Notification n = mNotificationBuilder.build();
             n.flags &= ~Notification.FLAG_NO_CLEAR;
             mNotificationManager.notify(mNotificationId, n);
         }
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 5e2f494..039efbd 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -191,8 +191,11 @@
             @Override
             public void onSomePackagesChanged() {
                 synchronized (mLock) {
-                    populateAccessibilityServiceListLocked();
-                    manageServicesLocked();
+                    // We will update when the automation service dies.
+                    if (mUiAutomationService == null) {
+                        populateAccessibilityServiceListLocked();
+                        manageServicesLocked();
+                    }
                 }
             }
 
@@ -242,11 +245,14 @@
             public void onReceive(Context context, Intent intent) {
                 if (intent.getAction() == Intent.ACTION_BOOT_COMPLETED) {
                     synchronized (mLock) {
-                        populateAccessibilityServiceListLocked();
-                        handleAccessibilityEnabledSettingChangedLocked();
-                        handleTouchExplorationEnabledSettingChangedLocked();
-                        updateInputFilterLocked();
-                        sendStateToClientsLocked();
+                        // We will update when the automation service dies.
+                        if (mUiAutomationService == null) {
+                            populateAccessibilityServiceListLocked();
+                            handleAccessibilityEnabledSettingChangedLocked();
+                            handleTouchExplorationEnabledSettingChangedLocked();
+                            updateInputFilterLocked();
+                            sendStateToClientsLocked();
+                        }
                     }
 
                     return;
@@ -294,9 +300,12 @@
                 public void onChange(boolean selfChange) {
                     super.onChange(selfChange);
                     synchronized (mLock) {
-                        handleAccessibilityEnabledSettingChangedLocked();
-                        updateInputFilterLocked();
-                        sendStateToClientsLocked();
+                        // We will update when the automation service dies.
+                        if (mUiAutomationService == null) {
+                            handleAccessibilityEnabledSettingChangedLocked();
+                            updateInputFilterLocked();
+                            sendStateToClientsLocked();
+                        }
                     }
                 }
             });
@@ -309,9 +318,12 @@
                     public void onChange(boolean selfChange) {
                         super.onChange(selfChange);
                         synchronized (mLock) {
-                            handleTouchExplorationEnabledSettingChangedLocked();
-                            updateInputFilterLocked();
-                            sendStateToClientsLocked();
+                            // We will update when the automation service dies.
+                            if (mUiAutomationService == null) {
+                                handleTouchExplorationEnabledSettingChangedLocked();
+                                updateInputFilterLocked();
+                                sendStateToClientsLocked();
+                            }
                         }
                     }
                 });
@@ -324,7 +336,10 @@
                 public void onChange(boolean selfChange) {
                     super.onChange(selfChange);
                     synchronized (mLock) {
-                        manageServicesLocked();
+                        // We will update when the automation service dies.
+                        if (mUiAutomationService == null) {
+                            manageServicesLocked();
+                        }
                     }
                 }
             });
@@ -747,10 +762,6 @@
      * Manages services by starting enabled ones and stopping disabled ones.
      */
     private void manageServicesLocked() {
-        // While the UI automation service is running it takes over.
-        if (mUiAutomationService != null) {
-            return;
-        }
         populateEnabledServicesLocked(mEnabledServices);
         final int enabledInstalledServicesCount = updateServicesStateLocked(mInstalledServices,
                 mEnabledServices);
@@ -926,8 +937,13 @@
 
     private void tryEnableTouchExploration(final Service service) {
         if (!mIsTouchExplorationEnabled && service.mRequestTouchExplorationMode) {
-            mMainHandler.obtainMessage(MSG_SHOW_ENABLE_TOUCH_EXPLORATION_DIALOG,
-                    service).sendToTarget();
+            if (!service.mIsAutomation) {
+                mMainHandler.obtainMessage(MSG_SHOW_ENABLE_TOUCH_EXPLORATION_DIALOG,
+                        service).sendToTarget();
+            } else {
+                Settings.Secure.putInt(mContext.getContentResolver(),
+                        Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1);
+            }
         }
     }
 
@@ -1479,10 +1495,15 @@
                 // the state based on values in the settings database.
                 if (mIsAutomation) {
                     mUiAutomationService = null;
+
                     handleAccessibilityEnabledSettingChangedLocked();
+                    sendStateToClientsLocked();
+
                     handleTouchExplorationEnabledSettingChangedLocked();
                     updateInputFilterLocked();
-                    sendStateToClientsLocked();
+
+                    populateAccessibilityServiceListLocked();
+                    manageServicesLocked();
                 }
             }
         }