Merge "Add ic_dialog_alert_material to symbols" into mnc-dev
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index bac668a..8b74a1e 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -557,7 +557,7 @@
                 if (mIsForcedVisibility) {
                     mView.setTransitionAlpha(0);
                 } else {
-                    mView.setTransitionVisibility(mFinalVisibility);
+                    mView.setVisibility(mFinalVisibility);
                 }
             }
         }
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index cf6a018..f89ee91 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -244,15 +244,6 @@
 
     final CursorAnchorInfoNotifier mCursorAnchorInfoNotifier = new CursorAnchorInfoNotifier();
 
-    private final Runnable mHideFloatingToolbar = new Runnable() {
-        @Override
-        public void run() {
-            if (mTextActionMode != null) {
-                mTextActionMode.hide(ActionMode.DEFAULT_HIDE_DURATION);
-            }
-        }
-    };
-
     private final Runnable mShowFloatingToolbar = new Runnable() {
         @Override
         public void run() {
@@ -389,7 +380,6 @@
             mTextView.removeCallbacks(mInsertionActionModeRunnable);
         }
 
-        mTextView.removeCallbacks(mHideFloatingToolbar);
         mTextView.removeCallbacks(mShowFloatingToolbar);
 
         destroyDisplayListsData();
@@ -1248,14 +1238,12 @@
     private void hideFloatingToolbar() {
         if (mTextActionMode != null) {
             mTextView.removeCallbacks(mShowFloatingToolbar);
-            // Delay the "hide" a little bit just in case a "show" will happen almost immediately.
-            mTextView.postDelayed(mHideFloatingToolbar, 100);
+            mTextActionMode.hide(ActionMode.DEFAULT_HIDE_DURATION);
         }
     }
 
     private void showFloatingToolbar() {
         if (mTextActionMode != null) {
-            mTextView.removeCallbacks(mHideFloatingToolbar);
             // Delay "show" so it doesn't interfere with click confirmations
             // or double-clicks that could "dismiss" the floating toolbar.
             int delay = ViewConfiguration.getDoubleTapTimeout();
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index 661dce1..99c12776 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -48,12 +48,14 @@
     private final Runnable mMovingOff = new Runnable() {
         public void run() {
             mFloatingToolbarVisibilityHelper.setMoving(false);
+            mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
         }
     };
 
     private final Runnable mHideOff = new Runnable() {
         public void run() {
             mFloatingToolbarVisibilityHelper.setHideRequested(false);
+            mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
         }
     };
 
@@ -87,6 +89,7 @@
                     }
                 });
         mFloatingToolbarVisibilityHelper = new FloatingToolbarVisibilityHelper(mFloatingToolbar);
+        mFloatingToolbarVisibilityHelper.activate();
     }
 
     @Override
@@ -108,8 +111,7 @@
     public void invalidate() {
         checkToolbarInitialized();
         mCallback.onPrepareActionMode(this, mMenu);
-        mFloatingToolbar.updateLayout();
-        invalidateContentRect();
+        invalidateContentRect();  // Will re-layout and show the toolbar if necessary.
     }
 
     @Override
@@ -131,44 +133,43 @@
 
         mContentRectOnWindow.set(mContentRect);
         mContentRectOnWindow.offset(mViewPosition[0], mViewPosition[1]);
-        // Make sure that content rect is not out of the view's visible bounds.
-        mContentRectOnWindow.set(
-                Math.max(mContentRectOnWindow.left, mViewRect.left),
-                Math.max(mContentRectOnWindow.top, mViewRect.top),
-                Math.min(mContentRectOnWindow.right, mViewRect.right),
-                Math.min(mContentRectOnWindow.bottom, mViewRect.bottom));
-
-        if (!mContentRectOnWindow.equals(mPreviousContentRectOnWindow)) {
-            if (!mPreviousContentRectOnWindow.isEmpty()) {
-                notifyContentRectMoving();
-            }
-            mFloatingToolbar.setContentRect(mContentRectOnWindow);
-            mFloatingToolbar.updateLayout();
-        }
-        mPreviousContentRectOnWindow.set(mContentRectOnWindow);
 
         if (isContentRectWithinBounds()) {
             mFloatingToolbarVisibilityHelper.setOutOfBounds(false);
+            // Make sure that content rect is not out of the view's visible bounds.
+            mContentRectOnWindow.set(
+                    Math.max(mContentRectOnWindow.left, mViewRect.left),
+                    Math.max(mContentRectOnWindow.top, mViewRect.top),
+                    Math.min(mContentRectOnWindow.right, mViewRect.right),
+                    Math.min(mContentRectOnWindow.bottom, mViewRect.bottom));
+
+            if (!mContentRectOnWindow.equals(mPreviousContentRectOnWindow)) {
+                // Content rect is moving.
+                mOriginatingView.removeCallbacks(mMovingOff);
+                mFloatingToolbarVisibilityHelper.setMoving(true);
+                mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY);
+
+                mFloatingToolbar.setContentRect(mContentRectOnWindow);
+                mFloatingToolbar.updateLayout();
+            }
         } else {
             mFloatingToolbarVisibilityHelper.setOutOfBounds(true);
+            mContentRectOnWindow.setEmpty();
         }
+        mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
+
+        mPreviousContentRectOnWindow.set(mContentRectOnWindow);
     }
 
     private boolean isContentRectWithinBounds() {
-       mScreenRect.set(
-           0,
-           0,
-           mContext.getResources().getDisplayMetrics().widthPixels,
-           mContext.getResources().getDisplayMetrics().heightPixels);
+        mScreenRect.set(
+            0,
+            0,
+            mContext.getResources().getDisplayMetrics().widthPixels,
+            mContext.getResources().getDisplayMetrics().heightPixels);
 
-       return Rect.intersects(mContentRectOnWindow, mScreenRect)
-           && Rect.intersects(mContentRectOnWindow, mViewRect);
-    }
-
-    private void notifyContentRectMoving() {
-        mOriginatingView.removeCallbacks(mMovingOff);
-        mFloatingToolbarVisibilityHelper.setMoving(true);
-        mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY);
+        return Rect.intersects(mContentRectOnWindow, mScreenRect)
+            && Rect.intersects(mContentRectOnWindow, mViewRect);
     }
 
     @Override
@@ -184,6 +185,7 @@
             mHideOff.run();
         } else {
             mFloatingToolbarVisibilityHelper.setHideRequested(true);
+            mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
             mOriginatingView.postDelayed(mHideOff, duration);
         }
     }
@@ -221,7 +223,7 @@
     }
 
     /**
-     * @throws IlllegalStateException
+     * @throws IllegalStateException
      */
     private void checkToolbarInitialized() {
         Preconditions.checkState(mFloatingToolbar != null);
@@ -229,13 +231,14 @@
     }
 
     private void reset() {
+        mFloatingToolbarVisibilityHelper.deactivate();
         mOriginatingView.removeCallbacks(mMovingOff);
         mOriginatingView.removeCallbacks(mHideOff);
     }
 
 
     /**
-     * A helper that shows/hides the floating toolbar depending on certain states.
+     * A helper for showing/hiding the floating toolbar depending on certain states.
      */
     private static final class FloatingToolbarVisibilityHelper {
 
@@ -245,29 +248,45 @@
         private boolean mMoving;
         private boolean mOutOfBounds;
 
+        private boolean mActive;
+
         public FloatingToolbarVisibilityHelper(FloatingToolbar toolbar) {
             mToolbar = Preconditions.checkNotNull(toolbar);
         }
 
+        public void activate() {
+            mHideRequested = false;
+            mMoving = false;
+            mOutOfBounds = false;
+
+            mActive = true;
+        }
+
+        public void deactivate() {
+            mActive = false;
+            mToolbar.dismiss();
+        }
+
         public void setHideRequested(boolean hide) {
             mHideRequested = hide;
-            updateToolbarVisibility();
         }
 
         public void setMoving(boolean moving) {
             mMoving = moving;
-            updateToolbarVisibility();
         }
 
         public void setOutOfBounds(boolean outOfBounds) {
             mOutOfBounds = outOfBounds;
-            updateToolbarVisibility();
         }
 
-        private void updateToolbarVisibility() {
+        public void updateToolbarVisibility() {
+            if (!mActive) {
+                return;
+            }
+
             if (mHideRequested || mMoving || mOutOfBounds) {
                 mToolbar.hide();
-            } else if (mToolbar.isHidden()) {
+            } else {
                 mToolbar.show();
             }
         }
diff --git a/core/jni/android_util_Log.cpp b/core/jni/android_util_Log.cpp
index 9a80f1d..2b1067b 100644
--- a/core/jni/android_util_Log.cpp
+++ b/core/jni/android_util_Log.cpp
@@ -41,32 +41,8 @@
 };
 static levels_t levels;
 
-static int toLevel(const char* value)
-{
-    switch (value[0]) {
-        case 'V': return levels.verbose;
-        case 'D': return levels.debug;
-        case 'I': return levels.info;
-        case 'W': return levels.warn;
-        case 'E': return levels.error;
-        case 'A': return levels.assert;
-        case 'S': return -1; // SUPPRESS
-    }
-    return levels.info;
-}
-
 static jboolean isLoggable(const char* tag, jint level) {
-    String8 key;
-    key.append(LOG_NAMESPACE);
-    key.append(tag);
-
-    char buf[PROPERTY_VALUE_MAX];
-    if (property_get(key.string(), buf, "") <= 0) {
-        buf[0] = '\0';
-    }
-
-    int logLevel = toLevel(buf);
-    return logLevel >= 0 && level >= logLevel;
+    return __android_log_is_loggable(level, tag, ANDROID_LOG_INFO);
 }
 
 static jboolean android_util_Log_isLoggable(JNIEnv* env, jobject clazz, jstring tag, jint level)
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e9b9767..b262442 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -31,7 +31,6 @@
 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
-import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
@@ -10338,11 +10337,12 @@
     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
-            if (mRunningVoice == null) {
+            boolean wasRunningVoice = mRunningVoice != null;
+            mRunningVoice = session;
+            if (!wasRunningVoice) {
                 mVoiceWakeLock.acquire();
                 updateSleepIfNeededLocked();
             }
-            mRunningVoice = session;
         }
     }
 
@@ -18595,29 +18595,24 @@
             return;
         }
         boolean isInteraction;
-        if (!mSleeping) {
-            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+        // To avoid some abuse patterns, we are going to be careful about what we consider
+        // to be an app interaction.  Being the top activity doesn't count while the display
+        // is sleeping, nor do short foreground services.
+        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
+            isInteraction = true;
             app.fgInteractionTime = 0;
-        } else {
-            // If the display is off, we are going to be more restrictive about what we consider
-            // to be an app interaction.  Being the top activity doesn't count, nor do generally
-            // foreground services.
-            if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
-                isInteraction = true;
-                app.fgInteractionTime = 0;
-            } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
-                final long now = SystemClock.elapsedRealtime();
-                if (app.fgInteractionTime == 0) {
-                    app.fgInteractionTime = now;
-                    isInteraction = false;
-                } else {
-                    isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
-                }
+        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
+            final long now = SystemClock.elapsedRealtime();
+            if (app.fgInteractionTime == 0) {
+                app.fgInteractionTime = now;
+                isInteraction = false;
             } else {
-                isInteraction = app.curProcState
-                        <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
-                app.fgInteractionTime = 0;
+                isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
             }
+        } else {
+            isInteraction = app.curProcState
+                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+            app.fgInteractionTime = 0;
         }
         if (isInteraction && !app.reportedInteraction) {
             String[] packages = app.getPackageList();
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index b0fca95..fafe44a 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -853,7 +853,38 @@
         PackageMonitor mPackageMonitor = new PackageMonitor() {
             @Override
             public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
-                return super.onHandleForceStop(intent, packages, uid, doit);
+                if (DEBUG) Slog.d(TAG, "onHandleForceStop uid=" + uid + " doit=" + doit);
+
+                int userHandle = UserHandle.getUserId(uid);
+                ComponentName curInteractor = getCurInteractor(userHandle);
+                ComponentName curRecognizer = getCurRecognizer(userHandle);
+                boolean hit = false;
+                for (String pkg : packages) {
+                    if (curInteractor != null && pkg.equals(curInteractor.getPackageName())) {
+                        hit = true;
+                        break;
+                    } else if (curRecognizer != null
+                            && pkg.equals(curRecognizer.getPackageName())) {
+                        hit = true;
+                        break;
+                    }
+                }
+                if (hit && doit) {
+                    // The user is force stopping our current interactor/recognizer.
+                    // Clear the current settings and restore default state.
+                    synchronized (VoiceInteractionManagerService.this) {
+                        mSoundTriggerHelper.stopAllRecognitions();
+                        if (mImpl != null) {
+                            mImpl.shutdownLocked();
+                            mImpl = null;
+                        }
+                        setCurInteractor(null, userHandle);
+                        setCurRecognizer(null, userHandle);
+                        initForUser(userHandle);
+                        switchImplementationIfNeededLocked(true);
+                    }
+                }
+                return hit;
             }
 
             @Override
@@ -865,51 +896,53 @@
                 int userHandle = getChangingUserId();
                 if (DEBUG) Slog.d(TAG, "onSomePackagesChanged user=" + userHandle);
 
-                ComponentName curInteractor = getCurInteractor(userHandle);
-                ComponentName curRecognizer = getCurRecognizer(userHandle);
-                if (curRecognizer == null) {
-                    // Could a new recognizer appear when we don't have one pre-installed?
-                    if (anyPackagesAppearing()) {
-                        curRecognizer = findAvailRecognizer(null, userHandle);
-                        if (curRecognizer != null) {
-                            setCurRecognizer(curRecognizer, userHandle);
+                synchronized (VoiceInteractionManagerService.this) {
+                    ComponentName curInteractor = getCurInteractor(userHandle);
+                    ComponentName curRecognizer = getCurRecognizer(userHandle);
+                    if (curRecognizer == null) {
+                        // Could a new recognizer appear when we don't have one pre-installed?
+                        if (anyPackagesAppearing()) {
+                            curRecognizer = findAvailRecognizer(null, userHandle);
+                            if (curRecognizer != null) {
+                                setCurRecognizer(curRecognizer, userHandle);
+                            }
                         }
-                    }
-                    return;
-                }
-
-                if (curInteractor != null) {
-                    int change = isPackageDisappearing(curInteractor.getPackageName());
-                    if (change == PACKAGE_PERMANENT_CHANGE) {
-                        // The currently set interactor is permanently gone; fall back to
-                        // the default config.
-                        setCurInteractor(null, userHandle);
-                        setCurRecognizer(null, userHandle);
-                        initForUser(userHandle);
                         return;
                     }
 
-                    change = isPackageAppearing(curInteractor.getPackageName());
-                    if (change != PACKAGE_UNCHANGED) {
-                        // If current interactor is now appearing, for any reason, then
-                        // restart our connection with it.
-                        if (mImpl != null && curInteractor.getPackageName().equals(
-                                mImpl.mComponent.getPackageName())) {
-                            switchImplementationIfNeededLocked(true);
+                    if (curInteractor != null) {
+                        int change = isPackageDisappearing(curInteractor.getPackageName());
+                        if (change == PACKAGE_PERMANENT_CHANGE) {
+                            // The currently set interactor is permanently gone; fall back to
+                            // the default config.
+                            setCurInteractor(null, userHandle);
+                            setCurRecognizer(null, userHandle);
+                            initForUser(userHandle);
+                            return;
                         }
+
+                        change = isPackageAppearing(curInteractor.getPackageName());
+                        if (change != PACKAGE_UNCHANGED) {
+                            // If current interactor is now appearing, for any reason, then
+                            // restart our connection with it.
+                            if (mImpl != null && curInteractor.getPackageName().equals(
+                                    mImpl.mComponent.getPackageName())) {
+                                switchImplementationIfNeededLocked(true);
+                            }
+                        }
+                        return;
                     }
-                    return;
-                }
 
-                // There is no interactor, so just deal with a simple recognizer.
-                int change = isPackageDisappearing(curRecognizer.getPackageName());
-                if (change == PACKAGE_PERMANENT_CHANGE
-                        || change == PACKAGE_TEMPORARY_CHANGE) {
-                    setCurRecognizer(findAvailRecognizer(null, userHandle), userHandle);
+                    // There is no interactor, so just deal with a simple recognizer.
+                    int change = isPackageDisappearing(curRecognizer.getPackageName());
+                    if (change == PACKAGE_PERMANENT_CHANGE
+                            || change == PACKAGE_TEMPORARY_CHANGE) {
+                        setCurRecognizer(findAvailRecognizer(null, userHandle), userHandle);
 
-                } else if (isPackageModified(curRecognizer.getPackageName())) {
-                    setCurRecognizer(findAvailRecognizer(curRecognizer.getPackageName(),
-                            userHandle), userHandle);
+                    } else if (isPackageModified(curRecognizer.getPackageName())) {
+                        setCurRecognizer(findAvailRecognizer(curRecognizer.getPackageName(),
+                                userHandle), userHandle);
+                    }
                 }
             }
         };