Merge "Survey says: NIET!" into jb-dev
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 17b1962..92b6f72 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1360,6 +1360,13 @@
         public int lastTrimLevel;
 
         /**
+         * Constant for {@link #importance}: this is a persistent process.
+         * Only used when reporting to process observers.
+         * @hide
+         */
+        public static final int IMPORTANCE_PERSISTENT = 50;
+
+        /**
          * Constant for {@link #importance}: this process is running the
          * foreground UI.
          */
diff --git a/core/java/android/app/IProcessObserver.aidl b/core/java/android/app/IProcessObserver.aidl
index 2094294..e587912 100644
--- a/core/java/android/app/IProcessObserver.aidl
+++ b/core/java/android/app/IProcessObserver.aidl
@@ -20,6 +20,7 @@
 oneway interface IProcessObserver {
 
     void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities);
+    void onImportanceChanged(int pid, int uid, int importance);
     void onProcessDied(int pid, int uid);
 
 }
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 6dc31dd..bd86a8d 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -62,6 +62,8 @@
 
     private final int mMyProcessId;
 
+    private final ArrayList<View> mTempArrayList = new ArrayList<View>();
+
     public AccessibilityInteractionController(ViewRootImpl viewRootImpl) {
         Looper looper =  viewRootImpl.mHandler.getLooper();
         mMyLooperThreadId = looper.getThread().getId();
@@ -313,7 +315,7 @@
                     infos = provider.findAccessibilityNodeInfosByText(text,
                             virtualDescendantId);
                 } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED) {
-                    ArrayList<View> foundViews = mViewRootImpl.mAttachInfo.mTempArrayList;
+                    ArrayList<View> foundViews = mTempArrayList;
                     foundViews.clear();
                     root.findViewsWithText(foundViews, text, View.FIND_VIEWS_WITH_TEXT
                             | View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index da666b5..a42e156 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -62,6 +62,13 @@
     public static final int STATUS_INVOKE = 0x2;
 
     /**
+     * Indicates that the display list performed GL drawing operations.
+     *
+     * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)
+     */
+    public static final int STATUS_DREW = 0x4;
+
+    /**
      * Starts recording the display list. All operations performed on the
      * returned canvas are recorded and stored in this display list.
      * 
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index f986d15..7e86ea3 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -457,9 +457,11 @@
      * @param functor The native functor to insert in the execution queue.
      *
      * @see HardwareCanvas#callDrawGLFunction(int)
-     * @see #detachFunctor(int) 
+     * @see #detachFunctor(int)
+     *
+     * @return true if the functor was attached successfully
      */
-    abstract void attachFunctor(View.AttachInfo attachInfo, int functor);
+    abstract boolean attachFunctor(View.AttachInfo attachInfo, int functor);
 
     /**
      * Initializes the hardware renderer for the specified surface and setup the
@@ -1102,6 +1104,7 @@
 
                     onPreDraw(dirty);
 
+                    int status = DisplayList.STATUS_DONE;
                     int saveCount = canvas.save();
                     callbacks.onHardwarePreDraw(canvas);
 
@@ -1135,7 +1138,7 @@
                                 drawDisplayListStartTime = System.nanoTime();
                             }
 
-                            int status = canvas.drawDisplayList(displayList, mRedrawClip,
+                            status = canvas.drawDisplayList(displayList, mRedrawClip,
                                     DisplayList.FLAG_CLIP_CHILDREN);
 
                             if (mProfileEnabled) {
@@ -1171,22 +1174,25 @@
                     onPostDraw();
 
                     attachInfo.mIgnoreDirtyState = false;
+                    
+                    if ((status & DisplayList.STATUS_DREW) == DisplayList.STATUS_DREW) {
 
-                    long eglSwapBuffersStartTime = 0;
-                    if (mProfileEnabled) {
-                        eglSwapBuffersStartTime = System.nanoTime();
+                        long eglSwapBuffersStartTime = 0;
+                        if (mProfileEnabled) {
+                            eglSwapBuffersStartTime = System.nanoTime();
+                        }
+    
+                        sEgl.eglSwapBuffers(sEglDisplay, mEglSurface);
+    
+                        if (mProfileEnabled) {
+                            long now = System.nanoTime();
+                            float total = (now - eglSwapBuffersStartTime) * 0.000001f;
+                            mProfileData[mProfileCurrentFrame + 2] = total;
+                        }
+    
+                        checkEglErrors();
                     }
 
-                    sEgl.eglSwapBuffers(sEglDisplay, mEglSurface);
-
-                    if (mProfileEnabled) {
-                        long now = System.nanoTime();
-                        float total = (now - eglSwapBuffersStartTime) * 0.000001f;
-                        mProfileData[mProfileCurrentFrame + 2] = total;
-                    }
-
-                    checkEglErrors();
-
                     return dirty == null;
                 }
             }
@@ -1227,11 +1233,13 @@
         }
 
         @Override
-        void attachFunctor(View.AttachInfo attachInfo, int functor) {
+        boolean attachFunctor(View.AttachInfo attachInfo, int functor) {
             if (mCanvas != null) {
                 mCanvas.attachFunctor(functor);
                 scheduleFunctors(attachInfo);
+                return true;
             }
+            return false;
         }
 
         /**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 551b6cc..3138692 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -670,10 +670,11 @@
         }
     }
 
-    public void attachFunctor(int functor) {
+    public boolean attachFunctor(int functor) {
         if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
-            mAttachInfo.mHardwareRenderer.attachFunctor(mAttachInfo, functor);
+            return mAttachInfo.mHardwareRenderer.attachFunctor(mAttachInfo, functor);
         }
+        return false;
     }
 
     public void detachFunctor(int functor) {
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 65fd59a..d1da53b 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -7827,15 +7827,18 @@
         mSendScrollEvent = true;
 
         int functor = 0;
+        boolean forceInval = isPictureAfterFirstLayout;
         ViewRootImpl viewRoot = mWebView.getViewRootImpl();
         if (mWebView.isHardwareAccelerated() && viewRoot != null) {
             functor = nativeGetDrawGLFunction(mNativeClass);
             if (functor != 0) {
-                viewRoot.attachFunctor(functor);
+                // force an invalidate if functor attach not successful
+                forceInval |= !viewRoot.attachFunctor(functor);
             }
         }
 
         if (functor == 0
+                || forceInval
                 || mWebView.getLayerType() != View.LAYER_TYPE_NONE) {
             // invalidate the screen so that the next repaint will show new content
             // TODO: partial invalidate
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index dae9c6a..edffb5e9 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -57,7 +57,6 @@
 import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.view.ViewParent;
-import android.view.ViewRootImpl;
 import android.view.ViewTreeObserver;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -1331,43 +1330,42 @@
 
     @Override
     public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
-        if ((focusableMode & FOCUSABLES_ACCESSIBILITY) == FOCUSABLES_ACCESSIBILITY
-                && (direction == ACCESSIBILITY_FOCUS_FORWARD
-                        || direction == ACCESSIBILITY_FOCUS_BACKWARD)) {
-            if (canTakeAccessibilityFocusFromHover()) {
-                views.add(this);
+        if ((focusableMode & FOCUSABLES_ACCESSIBILITY) == FOCUSABLES_ACCESSIBILITY) {
+            switch(direction) {
+                case ACCESSIBILITY_FOCUS_BACKWARD: {
+                    View focusable = (getChildCount() > 0) ? getChildAt(getChildCount() - 1) : this;
+                    if (focusable.canTakeAccessibilityFocusFromHover()) {
+                        views.add(focusable);
+                    }
+                } return;
+                case ACCESSIBILITY_FOCUS_FORWARD: {
+                    if (canTakeAccessibilityFocusFromHover()) {
+                        views.add(this);
+                    }
+                } return;
             }
-        } else {
             super.addFocusables(views, direction, focusableMode);
         }
     }
 
     @Override
     public View focusSearch(int direction) {
-        return focusSearch(null, direction);
+        return focusSearch(this, direction);
     }
 
     @Override
     public View focusSearch(View focused, int direction) {
         switch (direction) {
             case ACCESSIBILITY_FOCUS_FORWARD: {
-                ViewRootImpl viewRootImpl = getViewRootImpl();
-                if (viewRootImpl == null) {
-                    return null;
-                }
-                View currentFocus = viewRootImpl.getAccessibilityFocusedHost();
-                if (currentFocus == null) {
-                    return super.focusSearch(this, direction);
-                }
-                // If we have the focus try giving it to the first child.
-                if (currentFocus == this) {
+                // If we are the focused view try giving it to the first child.
+                if (focused == this) {
                     if (getChildCount() > 0) {
                         return getChildAt(0);
                     }
                     return super.focusSearch(this, direction);
                 }
-                // Find the item that has accessibility focus.
-                final int currentPosition = getPositionForView(currentFocus);
+                // Find the item that has the focused view.
+                final int currentPosition = getPositionForView(focused);
                 if (currentPosition < 0 || currentPosition >= getCount()) {
                     return super.focusSearch(this, direction);
                 }
@@ -1376,9 +1374,9 @@
                 if (currentItem instanceof ViewGroup) {
                     ViewGroup currentItemGroup = (ViewGroup) currentItem;
                     View nextFocus = FocusFinder.getInstance().findNextFocus(currentItemGroup,
-                                currentFocus, direction);
+                                focused, direction);
                     if (nextFocus != null && nextFocus != currentItemGroup
-                            && nextFocus != currentFocus) {
+                            && nextFocus != focused) {
                         return nextFocus;
                     }
                 }
@@ -1386,50 +1384,54 @@
                 final int nextPosition = currentPosition - getFirstVisiblePosition() + 1;
                 if (nextPosition < getChildCount()) {
                     return getChildAt(nextPosition);
-                } else {
-                    return super.focusSearch(this, direction);
                 }
+                // No next item start searching from the list.
+                return super.focusSearch(this, direction);
             }
             case ACCESSIBILITY_FOCUS_BACKWARD: {
-                ViewRootImpl viewRootImpl = getViewRootImpl();
-                if (viewRootImpl == null) {
-                    return null;
-                }
-                View currentFocus = viewRootImpl.getAccessibilityFocusedHost();
-                if (currentFocus == null) {
-                    return super.focusSearch(this, direction);
-                }
-                // If we have the focus do a generic search.
-                if (currentFocus == this) {
-                    final int lastChildIndex = getChildCount() - 1;
-                    if (lastChildIndex >= 0) {
-                        return getChildAt(lastChildIndex);
+                // If we are the focused search from the view that is
+                // as closer to the bottom as possible.
+                if (focused == this) {
+                    final int childCount = getChildCount();
+                    if (childCount > 0) {
+                        return super.focusSearch(getChildAt(childCount - 1), direction);
                     }
                     return super.focusSearch(this, direction);
                 }
-                // Find the item that has accessibility focus.
-                final int currentPosition = getPositionForView(currentFocus);
+                // Find the item that has the focused view.
+                final int currentPosition = getPositionForView(focused);
                 if (currentPosition < 0 || currentPosition >= getCount()) {
                     return super.focusSearch(this, direction);
                 }
-                // Try to advance focus in the current item.
+
                 View currentItem = getChildAt(currentPosition - getFirstVisiblePosition());
+
+                // If a list item is the focused view we try to find a view
+                // in the previous item since in reverse the item contents
+                // get accessibility focus before the item itself.
+                if (currentItem == focused) {
+                    // This list gets accessibility focus after the last first item.
+                    final int previoustPosition = currentPosition - getFirstVisiblePosition() - 1;
+                    if (previoustPosition < 0) {
+                        return this;
+                    }
+                    currentItem = getChildAt(previoustPosition);
+                    focused = null;
+                }
+
+                // Search for into the item.
                 if (currentItem instanceof ViewGroup) {
                     ViewGroup currentItemGroup = (ViewGroup) currentItem;
                     View nextFocus = FocusFinder.getInstance().findNextFocus(currentItemGroup,
-                                currentFocus, direction);
+                                focused, direction);
                     if (nextFocus != null && nextFocus != currentItemGroup
-                            && nextFocus != currentFocus) {
+                            && nextFocus != focused) {
                         return nextFocus;
                     }
                 }
-                // Try to move focus to the previous item.
-                final int nextPosition = currentPosition - getFirstVisiblePosition() - 1;
-                if (nextPosition >= 0) {
-                    return getChildAt(nextPosition);
-                } else {
-                    return super.focusSearch(this, direction);
-                }
+
+                // If not item content wants focus we give it to the item.
+                return currentItem;
             }
         }
         return super.focusSearch(focused, direction);
diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp
index d80bfb3..89058a7 100644
--- a/core/jni/android_view_DisplayEventReceiver.cpp
+++ b/core/jni/android_view_DisplayEventReceiver.cpp
@@ -42,12 +42,13 @@
 } gDisplayEventReceiverClassInfo;
 
 
-class NativeDisplayEventReceiver : public RefBase {
+class NativeDisplayEventReceiver : public LooperCallback {
 public:
     NativeDisplayEventReceiver(JNIEnv* env,
             jobject receiverObj, const sp<MessageQueue>& messageQueue);
 
     status_t initialize();
+    void dispose();
     status_t scheduleVsync();
 
 protected:
@@ -59,7 +60,7 @@
     DisplayEventReceiver mReceiver;
     bool mWaitingForVsync;
 
-    static int handleReceiveCallback(int receiveFd, int events, void* data);
+    virtual int handleEvent(int receiveFd, int events, void* data);
     bool readLastVsyncMessage(nsecs_t* outTimestamp, uint32_t* outCount);
 };
 
@@ -72,12 +73,6 @@
 }
 
 NativeDisplayEventReceiver::~NativeDisplayEventReceiver() {
-    ALOGV("receiver %p ~ Disposing display event receiver.", this);
-
-    if (!mReceiver.initCheck()) {
-        mMessageQueue->getLooper()->removeFd(mReceiver.getFd());
-    }
-
     JNIEnv* env = AndroidRuntime::getJNIEnv();
     env->DeleteGlobalRef(mReceiverObjGlobal);
 }
@@ -90,13 +85,21 @@
     }
 
     int rc = mMessageQueue->getLooper()->addFd(mReceiver.getFd(), 0, ALOOPER_EVENT_INPUT,
-            handleReceiveCallback, this);
+            this, NULL);
     if (rc < 0) {
         return UNKNOWN_ERROR;
     }
     return OK;
 }
 
+void NativeDisplayEventReceiver::dispose() {
+    ALOGV("receiver %p ~ Disposing display event receiver.", this);
+
+    if (!mReceiver.initCheck()) {
+        mMessageQueue->getLooper()->removeFd(mReceiver.getFd());
+    }
+}
+
 status_t NativeDisplayEventReceiver::scheduleVsync() {
     if (!mWaitingForVsync) {
         ALOGV("receiver %p ~ Scheduling vsync.", this);
@@ -117,9 +120,7 @@
     return OK;
 }
 
-int NativeDisplayEventReceiver::handleReceiveCallback(int receiveFd, int events, void* data) {
-    sp<NativeDisplayEventReceiver> r = static_cast<NativeDisplayEventReceiver*>(data);
-
+int NativeDisplayEventReceiver::handleEvent(int receiveFd, int events, void* data) {
     if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
         ALOGE("Display event receiver pipe was closed or an error occurred.  "
                 "events=0x%x", events);
@@ -135,23 +136,23 @@
     // Drain all pending events, keep the last vsync.
     nsecs_t vsyncTimestamp;
     uint32_t vsyncCount;
-    if (!r->readLastVsyncMessage(&vsyncTimestamp, &vsyncCount)) {
-        ALOGV("receiver %p ~ Woke up but there was no vsync pulse!", data);
+    if (!readLastVsyncMessage(&vsyncTimestamp, &vsyncCount)) {
+        ALOGV("receiver %p ~ Woke up but there was no vsync pulse!", this);
         return 1; // keep the callback, did not obtain a vsync pulse
     }
 
     ALOGV("receiver %p ~ Vsync pulse: timestamp=%lld, count=%d",
-            data, vsyncTimestamp, vsyncCount);
-    r->mWaitingForVsync = false;
+            this, vsyncTimestamp, vsyncCount);
+    mWaitingForVsync = false;
 
     JNIEnv* env = AndroidRuntime::getJNIEnv();
 
-    ALOGV("receiver %p ~ Invoking vsync handler.", data);
-    env->CallVoidMethod(r->mReceiverObjGlobal,
+    ALOGV("receiver %p ~ Invoking vsync handler.", this);
+    env->CallVoidMethod(mReceiverObjGlobal,
             gDisplayEventReceiverClassInfo.dispatchVsync, vsyncTimestamp, vsyncCount);
-    ALOGV("receiver %p ~ Returned from vsync handler.", data);
+    ALOGV("receiver %p ~ Returned from vsync handler.", this);
 
-    r->mMessageQueue->raiseAndClearException(env, "dispatchVsync");
+    mMessageQueue->raiseAndClearException(env, "dispatchVsync");
     return 1; // keep the callback
 }
 
@@ -201,6 +202,7 @@
 static void nativeDispose(JNIEnv* env, jclass clazz, jint receiverPtr) {
     sp<NativeDisplayEventReceiver> receiver =
             reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr);
+    receiver->dispose();
     receiver->decStrong(gDisplayEventReceiverClassInfo.clazz); // drop reference held by the object
 }
 
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index 08e08b9..9501cf2 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -44,13 +44,14 @@
 } gInputEventReceiverClassInfo;
 
 
-class NativeInputEventReceiver : public RefBase {
+class NativeInputEventReceiver : public LooperCallback {
 public:
     NativeInputEventReceiver(JNIEnv* env,
             jobject receiverObj, const sp<InputChannel>& inputChannel,
             const sp<MessageQueue>& messageQueue);
 
     status_t initialize();
+    void dispose();
     status_t finishInputEvent(uint32_t seq, bool handled);
     status_t consumeEvents(JNIEnv* env, bool consumeBatches, nsecs_t frameTime);
 
@@ -68,7 +69,7 @@
         return mInputConsumer.getChannel()->getName().string();
     }
 
-    static int handleReceiveCallback(int receiveFd, int events, void* data);
+    virtual int handleEvent(int receiveFd, int events, void* data);
 };
 
 
@@ -84,23 +85,24 @@
 }
 
 NativeInputEventReceiver::~NativeInputEventReceiver() {
-#if DEBUG_DISPATCH_CYCLE
-    ALOGD("channel '%s' ~ Disposing input event receiver.", getInputChannelName());
-#endif
-
-    mMessageQueue->getLooper()->removeFd(mInputConsumer.getChannel()->getFd());
-
     JNIEnv* env = AndroidRuntime::getJNIEnv();
     env->DeleteGlobalRef(mReceiverObjGlobal);
 }
 
 status_t NativeInputEventReceiver::initialize() {
     int receiveFd = mInputConsumer.getChannel()->getFd();
-    mMessageQueue->getLooper()->addFd(
-            receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
+    mMessageQueue->getLooper()->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, this, NULL);
     return OK;
 }
 
+void NativeInputEventReceiver::dispose() {
+#if DEBUG_DISPATCH_CYCLE
+    ALOGD("channel '%s' ~ Disposing input event receiver.", getInputChannelName());
+#endif
+
+    mMessageQueue->getLooper()->removeFd(mInputConsumer.getChannel()->getFd());
+}
+
 status_t NativeInputEventReceiver::finishInputEvent(uint32_t seq, bool handled) {
 #if DEBUG_DISPATCH_CYCLE
     ALOGD("channel '%s' ~ Finished input event.", getInputChannelName());
@@ -114,24 +116,22 @@
     return status;
 }
 
-int NativeInputEventReceiver::handleReceiveCallback(int receiveFd, int events, void* data) {
-    sp<NativeInputEventReceiver> r = static_cast<NativeInputEventReceiver*>(data);
-
+int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {
     if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
         ALOGE("channel '%s' ~ Publisher closed input channel or an error occurred.  "
-                "events=0x%x", r->getInputChannelName(), events);
+                "events=0x%x", getInputChannelName(), events);
         return 0; // remove the callback
     }
 
     if (!(events & ALOOPER_EVENT_INPUT)) {
         ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event.  "
-                "events=0x%x", r->getInputChannelName(), events);
+                "events=0x%x", getInputChannelName(), events);
         return 1;
     }
 
     JNIEnv* env = AndroidRuntime::getJNIEnv();
-    status_t status = r->consumeEvents(env, false /*consumeBatches*/, -1);
-    r->mMessageQueue->raiseAndClearException(env, "handleReceiveCallback");
+    status_t status = consumeEvents(env, false /*consumeBatches*/, -1);
+    mMessageQueue->raiseAndClearException(env, "handleReceiveCallback");
     return status == OK || status == NO_MEMORY ? 1 : 0;
 }
 
@@ -256,6 +256,7 @@
 static void nativeDispose(JNIEnv* env, jclass clazz, jint receiverPtr) {
     sp<NativeInputEventReceiver> receiver =
             reinterpret_cast<NativeInputEventReceiver*>(receiverPtr);
+    receiver->dispose();
     receiver->decStrong(gInputEventReceiverClassInfo.clazz); // drop reference held by the object
 }
 
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index ca5d5f6..62c1723 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -855,12 +855,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"Выдаліць запыт"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Адправіць запыт"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Галасавы пошук"</string>
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Уключыць функцыю Explore by Touch?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"Служба доступу <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> запытвае ўключэнне функцыі Explore by Touch. Калі функцыя Explore by Touch будзе ўключаная, вы зможаце пачуць або ўбачыць апісанні таго, што знаходзіцца пад вашым пальцам, або выконваць жэсты для ўзаемадзеяння з планшэтам."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"Служба доступу <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> запытвае ўключэнне функцыі Explore by Touch. Калі функцыя Explore by Touch будзе ўключаная, вы зможаце пачуць або ўбачыць апісанні таго, што знаходзіцца пад вашым пальцам, або выконваць жэсты для ўзаемадзеяння з тэлефонам."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 месяц таму"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Раней, чым 1 месяц таму"</string>
   <plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
     <string name="configure_input_methods" msgid="9091652157722495116">"Наладзіць метады ўводу"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Фізічная клавіятура"</string>
     <string name="hardware" msgid="7517821086888990278">"Апар. ср."</string>
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Выбраць раскладку клавіятуры"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Націсніце, каб выбраць раскладку клавіятуры."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГДЕЁЖЗІЙКЛМНОПРСТУЎФХЦЧШ\'ЫЬЭЮЯ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"кандыдат."</u></string>
@@ -1323,6 +1318,5 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Запусцiць браўзер?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Прыняць выклік?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Заўсёды"</string>
-    <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Толькі адзін раз"</string>
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 98c7ac5..e33bda8 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -855,12 +855,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"Smazat dotaz"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Odeslat dotaz"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Hlasové vyhledávání"</string>
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Povolit funkci Prozkoumání dotykem?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"Služba <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> požaduje povolení funkce Prozkoumání dotykem. Pokud je funkce Prozkoumání dotykem zapnuta, můžete slyšet nebo vidět popisy objektů pod vaším prstem nebo ovládat tablet gesty."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"Služba <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> požaduje povolení funkce Prozkoumání dotykem. Pokud je funkce Prozkoumání dotykem zapnuta, můžete slyšet nebo vidět popisy objektů pod vaším prstem nebo ovládat telefon gesty."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"před 1 měsícem"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Déle než před 1 měsícem"</string>
   <plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
     <string name="configure_input_methods" msgid="9091652157722495116">"Nastavit metody zadávání"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fyzická klávesnice"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Výběr rozložení klávesnice"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Dotykem vyberte rozložení klávesnice."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string>
@@ -1323,5 +1318,5 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Spustit prohlížeč?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Přijmout hovor?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Vždy"</string>
-    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Jen jednou"</string>
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Pouze jednou"</string>
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index a326e2d..b76da67 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -855,12 +855,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"Anfrage löschen"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Anfrage senden"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Sprachsuche"</string>
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"\"Tippen &amp; Entdecken\" aktivieren?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> fordert die Aktivierung von \"Tippen &amp; Entdecken\". Wenn \"Tippen &amp; Entdecken\" aktiviert ist, können Sie Beschreibungen dessen hören oder sehen, was sich unter ihren Fingern befindet, oder Gesten ausführen, um mit dem Tablet zu interagieren."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> fordert die Aktivierung von \"Tippen &amp; Entdecken\". Wenn \"Tippen &amp; Entdecken\" aktiviert ist, können Sie Beschreibungen dessen hören oder sehen, was sich unter ihren Fingern befindet, oder Gesten ausführen, um mit dem Telefon zu interagieren."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"Vor 1 Monat"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Vor mehr als 1 Monat"</string>
   <plurals name="num_seconds_ago">
@@ -1009,7 +1006,7 @@
     <string name="smv_application" msgid="3307209192155442829">"Die App <xliff:g id="APPLICATION">%1$s</xliff:g> (Prozess <xliff:g id="PROCESS">%2$s</xliff:g>) hat gegen ihre selbsterzwungene StrictMode-Richtlinie verstoßen."</string>
     <string name="smv_process" msgid="5120397012047462446">"Der Prozess <xliff:g id="PROCESS">%1$s</xliff:g> hat gegen seine selbsterzwungene StrictMode-Richtlinie verstoßen."</string>
     <string name="android_upgrading_title" msgid="1584192285441405746">"Android wird aktualisiert..."</string>
-    <string name="android_upgrading_apk" msgid="7904042682111526169">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> von <xliff:g id="NUMBER_1">%2$d</xliff:g> wird optimiert."</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> von <xliff:g id="NUMBER_1">%2$d</xliff:g> wird optimiert..."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Apps werden gestartet."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Start wird abgeschlossen..."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> läuft"</string>
@@ -1127,10 +1124,8 @@
     <string name="configure_input_methods" msgid="9091652157722495116">"Eingabemethoden einrichten"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Physische Tastatur"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Tastaturlayout auswählen"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Zum Auswählen eines Tastaturlayouts berühren"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"Kandidaten"</u></string>
@@ -1323,6 +1318,5 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Anruf annehmen?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Immer"</string>
-    <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Nur einmal"</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index e53e3bc..043ee30 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -662,7 +662,7 @@
     <string name="phoneTypeWorkPager" msgid="649938731231157056">"Busca del trabajo"</string>
     <string name="phoneTypeAssistant" msgid="5596772636128562884">"Asistente"</string>
     <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
-    <string name="eventTypeCustom" msgid="7837586198458073404">"Personalizados"</string>
+    <string name="eventTypeCustom" msgid="7837586198458073404">"Personalizado"</string>
     <string name="eventTypeBirthday" msgid="2813379844211390740">"Cumpleaños"</string>
     <string name="eventTypeAnniversary" msgid="3876779744518284000">"Aniversario"</string>
     <string name="eventTypeOther" msgid="7388178939010143077">"Otros"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 1ec3a3e..d3d8e4f 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -855,12 +855,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"Tyhjennä kysely"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Lähetä kysely"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Puhehaku"</string>
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Otetaanko Tutki koskettamalla käyttöön?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> haluaa ottaa Tutki koskettamalla -ominaisuuden käyttöön. Kun Tutki koskettamalla on käytössä, näet tai kuulet kuvauksen sormen alla olevista kohteista ja voit käyttää tablet-laitetta sormieleiden avulla."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> haluaa ottaa Tutustu koskettamalla -ominaisuuden käyttöön. Kun Tutustu koskettamalla on käytössä, näet tai kuulet kuvauksen sormen alla olevista kohteista ja voit käyttää puhelinta sormieleiden avulla."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"kuukausi sitten"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Yli kuukausi sitten"</string>
   <plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
     <string name="configure_input_methods" msgid="9091652157722495116">"Määritä syöttötavat"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fyysinen näppäimistö"</string>
     <string name="hardware" msgid="7517821086888990278">"Laitteisto"</string>
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Valitse näppäimistöasettelu"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Kosketa ja valitse näppäimistöasettelu."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidaatit"</u></string>
@@ -1323,6 +1318,5 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Käynnistetäänkö selain?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Vastataanko puheluun?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Aina"</string>
-    <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Vain kerran"</string>
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index d7cb12c..0d96e6d 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -855,12 +855,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"Effacer la requête"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Envoyer la requête"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Recherche vocale"</string>
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Activer \"Explorer au toucher\" ?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> souhaite activer la fonctionnalité \"Explorer au toucher\". Lorsque celle-ci est activée, vous pouvez entendre ou voir les descriptions des éléments que vous sélectionnez, ou bien interagir avec la tablette en effectuant certains gestes."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> souhaite activer la fonctionnalité \"Explorer au toucher\". Lorsque celle-ci est activée, vous pouvez entendre ou voir les descriptions des éléments que vous sélectionnez, ou bien interagir avec le téléphone en effectuant certains gestes."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"Il y a 1 mois"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Il y a plus d\'un mois"</string>
   <plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
     <string name="configure_input_methods" msgid="9091652157722495116">"Configurer les modes de saisie"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Clavier physique"</string>
     <string name="hardware" msgid="7517821086888990278">"Matériel"</string>
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Sélectionnez la disposition du clavier"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Appuyez ici pour sélectionner une disposition de clavier."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
@@ -1323,6 +1318,5 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Lancer le navigateur ?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Prendre l\'appel ?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Toujours"</string>
-    <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Une seule fois"</string>
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 2a83a16..b0fd087 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -855,12 +855,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"क्‍वेरी साफ़ करें"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"क्वेरी सबमिट करें"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"ध्वनि खोज"</string>
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"स्‍पर्श के द्वारा अन्‍वेषण करें सक्षम करें?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्‍पर्श के द्वारा अन्‍वेषण करें सक्षम करना चाहती है. स्‍पर्श के द्वारा अन्‍वेष करें चालू होने पर, आप अपनी अंगुली के नीचे क्या है उसका विवरण सुन सकते हैं या देख सकते हैं या टेबलेट से संवाद करने के लिए जेस्‍चर निष्‍पादित कर सकते हैं."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्‍पर्श के द्वारा अन्‍वेषण करें सक्षम करना चाहती है. स्‍पर्श के द्वारा अन्‍वेष करें चालू होने पर, आप अपनी अंगुली के नीचे क्या है उसका विवरण सुन सकते हैं या देख सकते हैं या फ़ोन से संवाद करने के लिए जेस्‍चर निष्‍पादित कर सकते हैं."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 माह पहले"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 माह से पहले"</string>
   <plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
     <string name="configure_input_methods" msgid="9091652157722495116">"इनपुट पद्धतियां सेट करें"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"भौतिक कीबोर्ड"</string>
     <string name="hardware" msgid="7517821086888990278">"हार्डवेयर"</string>
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"कीबोर्ड लेआउट का चयन करें"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"कीबोर्ड लेआउट का चयन करने के लिए स्‍पर्श करें."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"उम्‍मीदवार"</u></string>
@@ -1323,6 +1318,5 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ब्राउज़र लॉन्च करें?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"कॉल स्वीकार करें?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"हमेशा"</string>
-    <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"केवल एक बार"</string>
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index d8bd15f..edb0032 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -855,12 +855,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"Izbriši upit"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Pošalji upit"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Glasovno pretraživanje"</string>
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Omogućiti Istraživanje dodirom?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"Usluga <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> želi omogućiti značajku Istraživanje dodirom. Kad je značajka Istraživanje dodirom uključena, možete čuti ili vidjeti opise onoga što je pod vašim prstom ili izvršiti pokrete za interakciju s tabletnim računalom."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"Usluga <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> želi omogućiti značajku Istraživanje dodirom. Kad je značajka Istraživanje dodirom uključena, možete čuti ili vidjeti opise onoga što je pod vašim prstom ili izvršiti pokrete za interakciju s telefonom."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"Prije 1 mjesec"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Prije 1 mjesec"</string>
   <plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
     <string name="configure_input_methods" msgid="9091652157722495116">"Postavljanje načina unosa"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fizička tipkovnica"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardver"</string>
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Odaberite izgled tipkovnice"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Dodirnite za odabir izgleda tipkovnice."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string>
@@ -1323,6 +1318,5 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Pokrenuti preglednik?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Prihvatiti poziv?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Uvijek"</string>
-    <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Samo jednom"</string>
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 188f6d7..8334d44 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -855,12 +855,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"Lekérdezés törlése"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Lekérdezés küldése"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Hangalapú keresés"</string>
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Aktiválja a Felfedezés érintésselt?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> aktiválni szeretné a Felfedezés érintéssel funkciót. Amikor be van kapcsolva a Felfedezés érintéssel, akkor hallhatja vagy láthatja annak leírását, ami az ujja alatt van, illetve végrehajthat kézmozdulatokat a táblagép kezeléséhez."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> aktiválni szeretné a Felfedezés érintéssel funkciót. Amikor be van kapcsolva a Felfedezés érintéssel, akkor hallhatja vagy láthatja annak leírását, ami az ujja alatt van, illetve végrehajthat kézmozdulatokat a telefon kezeléséhez."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 hónapja"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Több mint 1 hónapja"</string>
   <plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
     <string name="configure_input_methods" msgid="9091652157722495116">"Beviteli módok beállítása"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fizikai billentyűzet"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardver"</string>
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Válasszon billentyűzetkiosztást"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Érintse meg az egyik billentyűzetkiosztás kiválasztásához."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"jelöltek"</u></string>
@@ -1323,6 +1318,5 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Böngésző indítása?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Fogadja a hívást?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Mindig"</string>
-    <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Csak egyszer"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 604e163..2220454 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -855,12 +855,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"検索キーワードを削除"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"検索キーワードを送信"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"音声検索"</string>
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"タッチガイドをONにしますか?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>がタッチガイドをONにしようとしています。タッチガイドをONにすると、指の位置にあるアイテムの説明を読み上げたり表示したりできます。また、タブレットを通常とは違うジェスチャーで操作できます。"</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>がタッチガイドをONにしようとしています。タッチガイドをONにすると、指の位置にあるアイテムの説明を読み上げたり表示したりできます。また、携帯端末を通常とは違うジェスチャーで操作できます。"</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"1か月前"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1か月前"</string>
   <plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
     <string name="configure_input_methods" msgid="9091652157722495116">"入力方法をセットアップ"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"物理キーボード"</string>
     <string name="hardware" msgid="7517821086888990278">"ハードウェア"</string>
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"キーボードレイアウトの選択"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"タップしてキーボードレイアウトを選択してください。"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"候補"</u></string>
@@ -1323,6 +1318,5 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ブラウザを起動しますか?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"通話を受けますか?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"常時"</string>
-    <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"1回のみ"</string>
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 6ed825f..c7e818d 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -855,12 +855,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"Slett søket"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Send inn spørsmål"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Talesøk"</string>
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Aktivere Utforsk ved å trykke?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ber om aktivering av Utforsk ved å trykke. Når Utforsk ved å trykke er slått på, kan du høre og se beskrivelser av det som er under fingrene dine. Du kan også utføre handlinger på nettbrettet ved hjelp av bevegelser."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ber om aktivering av Utforsk ved å trykke. Når Utforsk ved å trykke er slått på, kan du høre eller se beskrivelser av det som er under fingrene dine. Du kan også utføre handlinger på nettbrettet ved hjelp av bevegelser."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"For én måned siden"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"For over en måned siden"</string>
   <plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
     <string name="configure_input_methods" msgid="9091652157722495116">"Konfigurer inndatametoder"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fysisk tastatur"</string>
     <string name="hardware" msgid="7517821086888990278">"Maskinvare"</string>
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Velg tastaturoppsett"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Trykk for å velge et tastaturoppsett"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
     <string name="candidates_style" msgid="4333913089637062257">"TAG_FONT"<u>"kandidater"</u>"CLOSE_FONT"</string>
@@ -1323,6 +1318,5 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Vil du starte nettleseren?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Vil du besvare anropet?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Alltid"</string>
-    <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Bare én gang"</string>
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b92c38c..857e655 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -855,12 +855,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"Zoekopdracht wissen"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Zoekopdracht verzenden"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Spraakgestuurd zoeken"</string>
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"\'Verkennen via aanraking\' aan?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wil \'Verkennen via aanraking\' inschakelen. Wanneer \'Verkennen via aanraking\' is ingeschakeld, kunt u beschrijvingen beluisteren of bekijken van wat er onder uw vinger staat of aanraakbewerkingen uitvoeren op de tablet."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wil \'Verkennen via aanraking\' inschakelen. Wanneer \'Verkennen via aanraking\' is ingeschakeld, kunt u beschrijvingen beluisteren of bekijken van wat er onder uw vinger staat of aanraakbewerkingen uitvoeren op de telefoon."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 maand geleden"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Meer dan 1 maand geleden"</string>
   <plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
     <string name="configure_input_methods" msgid="9091652157722495116">"Invoermethoden instellen"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fysiek toetsenbord"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Toetsenbordindeling selecteren"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Tik om een ​​toetsenbordindeling te selecteren."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidaten"</u></string>
@@ -1323,6 +1318,5 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Oproep accepteren?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Altijd"</string>
-    <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Eén keer"</string>
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 6c5ea32..fdce9ea 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -855,12 +855,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"Jasný dopyt"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Odoslať dopyt"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Hlasové vyhľadávanie"</string>
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Povoliť Preskúmanie dotykom?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"Služba <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> požaduje povolenie funkcie Preskúmanie dotykom. Ak je funkcia Explore by Touch zapnutá, môžete počuť alebo vidieť popisy objektov pod vaším prstom alebo ovládať tablet gestami."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"Služba <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> požaduje povolenie funkcie Preskúmanie dotykom. Ak je funkcia Explore by Touch zapnutá, môžete počuť alebo vidieť popisy objektov pod vaším prstom alebo ovládať telefón gestami."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"pred 1 mesiacom"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Viac ako pred 1 mesiacom"</string>
   <plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
     <string name="configure_input_methods" msgid="9091652157722495116">"Nastavenie metód vstupu"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fyzická klávesnica"</string>
     <string name="hardware" msgid="7517821086888990278">"Hardvér"</string>
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Zvoľte rozloženie klávesnice"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Dotykom zvoľte rozloženie klávesnice."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁÄBCČDĎDZDŽEÉFGHCHIÍJKLĽMNŇOÓÔPRŔSŠTŤUÚVWXYÝZŽ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string>
@@ -1323,6 +1318,5 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Spustiť prehliadač?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Prijať hovor?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Vždy"</string>
-    <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Len raz"</string>
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 049c1d8..b3929e2 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -855,12 +855,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"Izbris poizvedbe"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Pošlji poizvedbo"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Glasovno iskanje"</string>
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Vklop raziskovanja z dotikom?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"Storitev <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> želi omogočiti raziskovanje z dotikom. Ko je raziskovanje z dotikom vklopljeno, lahko slišite ali vidite opise tega, kar je pod vašim prstom, ali izvajate poteze za interakcijo s tabličnim računalnikom."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"Storitev <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> želi omogočiti raziskovanje z dotikom. Ko je raziskovanje z dotikom vklopljeno, lahko slišite ali vidite opise tega, kar je pod vašim prstom, ali izvajate poteze za interakcijo s telefonom."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"Pred 1 mesecem"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Pred več kot 1 mesecem"</string>
   <plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
     <string name="configure_input_methods" msgid="9091652157722495116">"Nastavi načine vnosa"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fizična tipkovnica"</string>
     <string name="hardware" msgid="7517821086888990278">"Strojna oprema"</string>
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Izberite razporeditev tipkovnice"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Dotaknite se, da izberete razporeditev tipkovnice"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string>
@@ -1323,6 +1318,5 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Ali želite odpreti brskalnik?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Ali želite sprejeti klic?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Vedno"</string>
-    <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Samo tokrat"</string>
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index fa7da01..5438262 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -855,12 +855,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"Обриши упит"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Пошаљи упит"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Гласовна претрага"</string>
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Желите да омог. Истражив. додиром?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> жели да омогући Истраживање додиром. Када је Истраживање додиром укључено, можете да чујете или видите описе ставке на коју сте ставили прст или да комуницирате са таблетом помоћу покрета."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> жели да омогући Истраживање додиром. Када је Истраживање додиром укључено, можете да чујете или видите описе ставке на коју сте ставили прст или да комуницирате са телефоном помоћу покрета."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"Пре месец дана"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Пре месец дана"</string>
   <plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
     <string name="configure_input_methods" msgid="9091652157722495116">"Подеси методе уноса"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Физичка тастатура"</string>
     <string name="hardware" msgid="7517821086888990278">"Хардвер"</string>
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Избор распореда тастатуре"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Додирните да бисте изабрали распоред тастатуре."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
@@ -1323,6 +1318,5 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Желите ли да покренете прегледач?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Желите ли да прихватите позив?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Увек"</string>
-    <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Само једном"</string>
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index f2430c2..2beeb39 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -855,12 +855,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"Sorguyu temizle"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Sorguyu gönder"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Sesli arama"</string>
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Dokunarak Keşfet etkinleştirilsin mi?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> Dokunarak Keşfet özelliğini etkinleştirmek istiyor. Dokunarak Keşfet açık olduğunda, parmağınızın altındaki öğelere ait açıklamaları duyabilir veya görebilir ya da tabletle etkileşimde bulunmak için ilgili hareketleri yapabilirsiniz."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>, Dokunarak Keşfet özelliğini etkinleştirmek istiyor. Dokunarak Keşfet açık olduğunda parmağınızın altındaki öğelere ait açıklamaları duyabilir veya görebilir ya da telefonla etkileşimde bulunmak için ilgili hareketleri yapabilirsiniz."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 ay önce"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 ay önce"</string>
   <plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
     <string name="configure_input_methods" msgid="9091652157722495116">"Giriş yöntemlerini ayarla"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Fiziksel klavye"</string>
     <string name="hardware" msgid="7517821086888990278">"Donanım"</string>
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Bir klavye düzeni seç"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Bir klavye düzeni seçmek için dokunun."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"adaylar"</u></string>
@@ -1323,6 +1318,5 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Tarayıcı Başlatılsın mı?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Çağrı kabul edilsin mi?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Her zaman"</string>
-    <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Yalnızca bir defa"</string>
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 2c6a4ed..3df0de5 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -855,12 +855,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"清除查詢"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"提交查詢"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"語音搜尋"</string>
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"啟用輕觸探索?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> 需要啟用「輕觸探索」。開啟這項功能時,系統會在您的手指時顯示或朗讀說明,您也可以執行手勢來與平板電腦互動。"</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> 需要啟用「輕觸探索」。開啟這項功能時,系統會在您的手指輕觸螢幕上的物件時顯示或朗讀說明,您也可以執行手勢來與手機互動。"</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 個月以前"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 個月前"</string>
   <plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
     <string name="configure_input_methods" msgid="9091652157722495116">"設定輸入法"</string>
     <string name="use_physical_keyboard" msgid="6203112478095117625">"實體鍵盤"</string>
     <string name="hardware" msgid="7517821086888990278">"硬體"</string>
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"選取鍵盤配置"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"輕觸即可選取鍵盤配置。"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"待選項目"</u></string>
@@ -1323,6 +1318,5 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"啟動「瀏覽器」嗎?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"接聽電話嗎?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"一律採用"</string>
-    <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"僅限一次"</string>
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4c28a82..4cac3ec 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2505,7 +2505,7 @@
 
     <!-- Title for a warning message about the interaction model changes after allowing an accessibility
          service to put the device into explore by touch mode, displayed as a dialog message when
-         the user selects to enables the service. (default). [CHAR LIMIT=35] -->
+         the user selects to enables the service. (default). [CHAR LIMIT=45] -->
     <string name="enable_explore_by_touch_warning_title">Enable Explore by Touch?</string>
     <!-- Summary for a warning message about the interaction model changes after allowing an accessibility
          service to put the device into explore by touch mode, displayed as a dialog message when
diff --git a/include/private/hwui/DrawGlInfo.h b/include/private/hwui/DrawGlInfo.h
index e33823e..fc810be 100644
--- a/include/private/hwui/DrawGlInfo.h
+++ b/include/private/hwui/DrawGlInfo.h
@@ -72,7 +72,14 @@
         // The functor needs to be invoked again but will
         // not redraw. Only the functor is invoked again
         // (unless another functor requests a redraw.)
-        kStatusInvoke = 0x2
+        kStatusInvoke = 0x2,
+        // DisplayList actually issued GL drawing commands.
+        // This is used to signal the HardwareRenderer that the
+        // buffers should be flipped - otherwise, there were no
+        // changes to the buffer, so no need to flip. Some hardware
+        // has issues with stale buffer contents when no GL
+        // commands are issued.
+        kStatusDrew = 0x4
     };
 }; // struct DrawGlInfo
 
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 546925e..88d2209 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -833,7 +833,7 @@
  * purposes of logging display list info for a given view.
  */
 status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) {
-    status_t drawGlStatus = 0;
+    status_t drawGlStatus = DrawGlInfo::kStatusDone;
     TextContainer text;
     mReader.rewind();
 
@@ -859,7 +859,7 @@
         DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
         renderer.restoreToCount(restoreTo);
         renderer.endMark();
-        return false;
+        return drawGlStatus;
     }
 
     DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
@@ -1002,7 +1002,7 @@
                 }
                 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
                         layer, x, y, paint);
-                renderer.drawLayer(layer, x, y, paint);
+                drawGlStatus |= renderer.drawLayer(layer, x, y, paint);
             }
             break;
             case DrawBitmap: {
@@ -1015,7 +1015,7 @@
                 }
                 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
                         bitmap, x, y, paint);
-                renderer.drawBitmap(bitmap, x, y, paint);
+                drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
             }
             break;
             case DrawBitmapMatrix: {
@@ -1024,7 +1024,7 @@
                 SkPaint* paint = getPaint(renderer);
                 DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
                         bitmap, matrix, paint);
-                renderer.drawBitmap(bitmap, matrix, paint);
+                drawGlStatus |= renderer.drawBitmap(bitmap, matrix, paint);
             }
             break;
             case DrawBitmapRect: {
@@ -1041,7 +1041,7 @@
                 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
                         (char*) indent, OP_NAMES[op], bitmap,
                         f1, f2, f3, f4, f5, f6, f7, f8,paint);
-                renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
+                drawGlStatus |= renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
             }
             break;
             case DrawBitmapData: {
@@ -1051,7 +1051,7 @@
                 SkPaint* paint = getPaint(renderer);
                 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
                         bitmap, x, y, paint);
-                renderer.drawBitmap(bitmap, x, y, paint);
+                drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
             }
             break;
             case DrawBitmapMesh: {
@@ -1067,7 +1067,8 @@
                 SkPaint* paint = getPaint(renderer);
 
                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, paint);
+                drawGlStatus |= renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices,
+                        colors, paint);
             }
             break;
             case DrawPatch: {
@@ -1091,15 +1092,15 @@
                 SkPaint* paint = getPaint(renderer);
 
                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount,
-                        numColors, left, top, right, bottom, paint);
+                drawGlStatus |= renderer.drawPatch(bitmap, xDivs, yDivs, colors,
+                        xDivsCount, yDivsCount, numColors, left, top, right, bottom, paint);
             }
             break;
             case DrawColor: {
                 int32_t color = getInt();
                 int32_t xferMode = getInt();
                 DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
-                renderer.drawColor(color, (SkXfermode::Mode) xferMode);
+                drawGlStatus |= renderer.drawColor(color, (SkXfermode::Mode) xferMode);
             }
             break;
             case DrawRect: {
@@ -1110,7 +1111,7 @@
                 SkPaint* paint = getPaint(renderer);
                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
                         f1, f2, f3, f4, paint);
-                renderer.drawRect(f1, f2, f3, f4, paint);
+                drawGlStatus |= renderer.drawRect(f1, f2, f3, f4, paint);
             }
             break;
             case DrawRoundRect: {
@@ -1123,7 +1124,7 @@
                 SkPaint* paint = getPaint(renderer);
                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
                         (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
-                renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
+                drawGlStatus |= renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
             }
             break;
             case DrawCircle: {
@@ -1133,7 +1134,7 @@
                 SkPaint* paint = getPaint(renderer);
                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p",
                         (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
-                renderer.drawCircle(f1, f2, f3, paint);
+                drawGlStatus |= renderer.drawCircle(f1, f2, f3, paint);
             }
             break;
             case DrawOval: {
@@ -1144,7 +1145,7 @@
                 SkPaint* paint = getPaint(renderer);
                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
                         (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
-                renderer.drawOval(f1, f2, f3, f4, paint);
+                drawGlStatus |= renderer.drawOval(f1, f2, f3, f4, paint);
             }
             break;
             case DrawArc: {
@@ -1158,14 +1159,14 @@
                 SkPaint* paint = getPaint(renderer);
                 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
                         (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
-                renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
+                drawGlStatus |= renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
             }
             break;
             case DrawPath: {
                 SkPath* path = getPath();
                 SkPaint* paint = getPaint(renderer);
                 DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
-                renderer.drawPath(path, paint);
+                drawGlStatus |= renderer.drawPath(path, paint);
             }
             break;
             case DrawLines: {
@@ -1173,7 +1174,7 @@
                 float* points = getFloats(count);
                 SkPaint* paint = getPaint(renderer);
                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                renderer.drawLines(points, count, paint);
+                drawGlStatus |= renderer.drawLines(points, count, paint);
             }
             break;
             case DrawPoints: {
@@ -1181,7 +1182,7 @@
                 float* points = getFloats(count);
                 SkPaint* paint = getPaint(renderer);
                 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                renderer.drawPoints(points, count, paint);
+                drawGlStatus |= renderer.drawPoints(points, count, paint);
             }
             break;
             case DrawText: {
@@ -1193,7 +1194,8 @@
                 float length = getFloat();
                 DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent,
                         OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length);
-                renderer.drawText(text.text(), text.length(), count, x, y, paint, length);
+                drawGlStatus |= renderer.drawText(text.text(), text.length(), count, x, y,
+                        paint, length);
             }
             break;
             case DrawTextOnPath: {
@@ -1205,7 +1207,7 @@
                 SkPaint* paint = getPaint(renderer);
                 DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
                     text.text(), text.length(), count, paint);
-                renderer.drawTextOnPath(text.text(), text.length(), count, path,
+                drawGlStatus |= renderer.drawTextOnPath(text.text(), text.length(), count, path,
                         hOffset, vOffset, paint);
             }
             break;
@@ -1217,7 +1219,8 @@
                 SkPaint* paint = getPaint(renderer);
                 DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent,
                         OP_NAMES[op], text.text(), text.length(), count, paint);
-                renderer.drawPosText(text.text(), text.length(), count, positions, paint);
+                drawGlStatus |= renderer.drawPosText(text.text(), text.length(), count,
+                        positions, paint);
             }
             break;
             case ResetShader: {
@@ -1490,23 +1493,25 @@
     return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
+status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
     addOp(DisplayList::DrawLayer);
     addInt((int) layer);
     addPoint(x, y);
     addPaint(paint);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
     const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
     uint32_t* location = addOp(DisplayList::DrawBitmap, reject);
     addBitmap(bitmap);
     addPoint(left, top);
     addPaint(paint);
     addSkip(location);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
     Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
     const mat4 transform(*matrix);
     transform.mapRect(r);
@@ -1517,9 +1522,10 @@
     addMatrix(matrix);
     addPaint(paint);
     addSkip(location);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
+status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
         float srcRight, float srcBottom, float dstLeft, float dstTop,
         float dstRight, float dstBottom, SkPaint* paint) {
     const bool reject = quickReject(dstLeft, dstTop, dstRight, dstBottom);
@@ -1529,18 +1535,21 @@
     addBounds(dstLeft, dstTop, dstRight, dstBottom);
     addPaint(paint);
     addSkip(location);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
+        SkPaint* paint) {
     const bool reject = quickReject(left, top, left + bitmap->width(), bitmap->height());
     uint32_t* location = addOp(DisplayList::DrawBitmapData, reject);
     addBitmapData(bitmap);
     addPoint(left, top);
     addPaint(paint);
     addSkip(location);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
+status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
         float* vertices, int* colors, SkPaint* paint) {
     addOp(DisplayList::DrawBitmapMesh);
     addBitmap(bitmap);
@@ -1554,11 +1563,12 @@
         addInt(0);
     }
     addPaint(paint);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
-        const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
-        float left, float top, float right, float bottom, SkPaint* paint) {
+status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs,
+        const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height,
+        int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) {
     const bool reject = quickReject(left, top, right, bottom);
     uint32_t* location = addOp(DisplayList::DrawPatch, reject);
     addBitmap(bitmap);
@@ -1568,15 +1578,17 @@
     addBounds(left, top, right, bottom);
     addPaint(paint);
     addSkip(location);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
+status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
     addOp(DisplayList::DrawColor);
     addInt(color);
     addInt(mode);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
+status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
         SkPaint* paint) {
     const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
             quickReject(left, top, right, bottom);
@@ -1584,9 +1596,10 @@
     addBounds(left, top, right, bottom);
     addPaint(paint);
     addSkip(location);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
+status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
         float rx, float ry, SkPaint* paint) {
     const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
             quickReject(left, top, right, bottom);
@@ -1595,32 +1608,36 @@
     addPoint(rx, ry);
     addPaint(paint);
     addSkip(location);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
+status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
     addOp(DisplayList::DrawCircle);
     addPoint(x, y);
     addFloat(radius);
     addPaint(paint);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
+status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
         SkPaint* paint) {
     addOp(DisplayList::DrawOval);
     addBounds(left, top, right, bottom);
     addPaint(paint);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
+status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
         float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
     addOp(DisplayList::DrawArc);
     addBounds(left, top, right, bottom);
     addPoint(startAngle, sweepAngle);
     addInt(useCenter ? 1 : 0);
     addPaint(paint);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
+status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
     float left, top, offset;
     uint32_t width, height;
     computePathBounds(path, paint, left, top, offset, width, height);
@@ -1630,23 +1647,26 @@
     addPath(path);
     addPaint(paint);
     addSkip(location);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
+status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
     addOp(DisplayList::DrawLines);
     addFloats(points, count);
     addPaint(paint);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
+status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
     addOp(DisplayList::DrawPoints);
     addFloats(points, count);
     addPaint(paint);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
+status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
         float x, float y, SkPaint* paint, float length) {
-    if (!text || count <= 0) return;
+    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
 
     // TODO: We should probably make a copy of the paint instead of modifying
     //       it; modifying the paint will change its generationID the first
@@ -1672,11 +1692,12 @@
     addPaint(paint);
     addFloat(length);
     addSkip(location);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
+status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
         SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
-    if (!text || count <= 0) return;
+    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
     addOp(DisplayList::DrawTextOnPath);
     addText(text, bytesCount);
     addInt(count);
@@ -1685,17 +1706,19 @@
     addFloat(vOffset);
     paint->setAntiAlias(true);
     addPaint(paint);
+    return DrawGlInfo::kStatusDone;
 }
 
-void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
+status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
         const float* positions, SkPaint* paint) {
-    if (!text || count <= 0) return;
+    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
     addOp(DisplayList::DrawPosText);
     addText(text, bytesCount);
     addInt(count);
     addFloats(positions, count * 2);
     paint->setAntiAlias(true);
     addPaint(paint);
+    return DrawGlInfo::kStatusDone;
 }
 
 void DisplayListRenderer::resetShader() {
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 0ba4078..4fa1baa 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -576,35 +576,35 @@
 
     virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t flags,
             uint32_t level = 0);
-    virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
-    virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
-    virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
-    virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
+    virtual status_t drawLayer(Layer* layer, float x, float y, SkPaint* paint);
+    virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
+    virtual status_t drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
+    virtual status_t drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
             float dstRight, float dstBottom, SkPaint* paint);
-    virtual void drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint);
-    virtual void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
+    virtual status_t drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint);
+    virtual status_t drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
             float* vertices, int* colors, SkPaint* paint);
-    virtual void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
+    virtual status_t drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
             const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
             float left, float top, float right, float bottom, SkPaint* paint);
-    virtual void drawColor(int color, SkXfermode::Mode mode);
-    virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
-    virtual void drawRoundRect(float left, float top, float right, float bottom,
+    virtual status_t drawColor(int color, SkXfermode::Mode mode);
+    virtual status_t drawRect(float left, float top, float right, float bottom, SkPaint* paint);
+    virtual status_t drawRoundRect(float left, float top, float right, float bottom,
             float rx, float ry, SkPaint* paint);
-    virtual void drawCircle(float x, float y, float radius, SkPaint* paint);
-    virtual void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
-    virtual void drawArc(float left, float top, float right, float bottom,
+    virtual status_t drawCircle(float x, float y, float radius, SkPaint* paint);
+    virtual status_t drawOval(float left, float top, float right, float bottom, SkPaint* paint);
+    virtual status_t drawArc(float left, float top, float right, float bottom,
             float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
-    virtual void drawPath(SkPath* path, SkPaint* paint);
-    virtual void drawLines(float* points, int count, SkPaint* paint);
-    virtual void drawPoints(float* points, int count, SkPaint* paint);
-    virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
+    virtual status_t drawPath(SkPath* path, SkPaint* paint);
+    virtual status_t drawLines(float* points, int count, SkPaint* paint);
+    virtual status_t drawPoints(float* points, int count, SkPaint* paint);
+    virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
             SkPaint* paint, float length = -1.0f);
-    virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
+    virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
             float hOffset, float vOffset, SkPaint* paint);
-    virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions,
-            SkPaint* paint);
+    virtual status_t drawPosText(const char* text, int bytesCount, int count,
+            const float* positions, SkPaint* paint);
 
     virtual void resetShader();
     virtual void setupShader(SkiaShader* shader);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 2a8b32c..2dc9726 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -336,7 +336,7 @@
     info.height = getSnapshot()->height;
     getSnapshot()->transform->copyTo(&info.transform[0]);
 
-    status_t result = (*functor)(DrawGlInfo::kModeDraw, &info);
+    status_t result = (*functor)(DrawGlInfo::kModeDraw, &info) | DrawGlInfo::kStatusDrew;
 
     if (result != DrawGlInfo::kStatusDone) {
         Rect localDirty(info.dirtyLeft, info.dirtyTop, info.dirtyRight, info.dirtyBottom);
@@ -1472,17 +1472,17 @@
     finishDrawTexture();
 }
 
-void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
+status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
     const float right = left + bitmap->width();
     const float bottom = top + bitmap->height();
 
     if (quickReject(left, top, right, bottom)) {
-        return;
+        return DrawGlInfo::kStatusDone;
     }
 
     mCaches.activeTexture(0);
     Texture* texture = mCaches.textureCache.get(bitmap);
-    if (!texture) return;
+    if (!texture) return DrawGlInfo::kStatusDone;
     const AutoTexture autoCleanup(texture);
 
     if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) {
@@ -1490,20 +1490,22 @@
     } else {
         drawTextureRect(left, top, right, bottom, texture, paint);
     }
+
+    return DrawGlInfo::kStatusDrew;
 }
 
-void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
+status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
     Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
     const mat4 transform(*matrix);
     transform.mapRect(r);
 
     if (quickReject(r.left, r.top, r.right, r.bottom)) {
-        return;
+        return DrawGlInfo::kStatusDone;
     }
 
     mCaches.activeTexture(0);
     Texture* texture = mCaches.textureCache.get(bitmap);
-    if (!texture) return;
+    if (!texture) return DrawGlInfo::kStatusDone;
     const AutoTexture autoCleanup(texture);
 
     // This could be done in a cheaper way, all we need is pass the matrix
@@ -1512,14 +1514,16 @@
     concatMatrix(matrix);
     drawTextureRect(0.0f, 0.0f, bitmap->width(), bitmap->height(), texture, paint);
     restore();
+
+    return DrawGlInfo::kStatusDrew;
 }
 
-void OpenGLRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
+status_t OpenGLRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
     const float right = left + bitmap->width();
     const float bottom = top + bitmap->height();
 
     if (quickReject(left, top, right, bottom)) {
-        return;
+        return DrawGlInfo::kStatusDone;
     }
 
     mCaches.activeTexture(0);
@@ -1527,18 +1531,20 @@
     const AutoTexture autoCleanup(texture);
 
     drawTextureRect(left, top, right, bottom, texture, paint);
+
+    return DrawGlInfo::kStatusDrew;
 }
 
-void OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
+status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
         float* vertices, int* colors, SkPaint* paint) {
     // TODO: Do a quickReject
     if (!vertices || mSnapshot->isIgnored()) {
-        return;
+        return DrawGlInfo::kStatusDone;
     }
 
     mCaches.activeTexture(0);
     Texture* texture = mCaches.textureCache.get(bitmap);
-    if (!texture) return;
+    if (!texture) return DrawGlInfo::kStatusDone;
     const AutoTexture autoCleanup(texture);
 
     texture->setWrap(GL_CLAMP_TO_EDGE, true);
@@ -1611,19 +1617,21 @@
     drawTextureMesh(0.0f, 0.0f, 1.0f, 1.0f, texture->id, alpha / 255.0f,
             mode, texture->blend, &mesh[0].position[0], &mesh[0].texture[0],
             GL_TRIANGLES, count, false, false, 0, false, false);
+
+    return DrawGlInfo::kStatusDrew;
 }
 
-void OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
+status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
          float srcLeft, float srcTop, float srcRight, float srcBottom,
          float dstLeft, float dstTop, float dstRight, float dstBottom,
          SkPaint* paint) {
     if (quickReject(dstLeft, dstTop, dstRight, dstBottom)) {
-        return;
+        return DrawGlInfo::kStatusDone;
     }
 
     mCaches.activeTexture(0);
     Texture* texture = mCaches.textureCache.get(bitmap);
-    if (!texture) return;
+    if (!texture) return DrawGlInfo::kStatusDone;
     const AutoTexture autoCleanup(texture);
 
     const float width = texture->width;
@@ -1666,18 +1674,20 @@
     }
 
     resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
+
+    return DrawGlInfo::kStatusDrew;
 }
 
-void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
+status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
         const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
         float left, float top, float right, float bottom, SkPaint* paint) {
     if (quickReject(left, top, right, bottom)) {
-        return;
+        return DrawGlInfo::kStatusDone;
     }
 
     mCaches.activeTexture(0);
     Texture* texture = mCaches.textureCache.get(bitmap);
-    if (!texture) return;
+    if (!texture) return DrawGlInfo::kStatusDone;
     const AutoTexture autoCleanup(texture);
     texture->setWrap(GL_CLAMP_TO_EDGE, true);
     texture->setFilter(GL_LINEAR, true);
@@ -1726,6 +1736,8 @@
                     true, !mesh->hasEmptyQuads);
         }
     }
+
+    return DrawGlInfo::kStatusDrew;
 }
 
 /**
@@ -1826,8 +1838,8 @@
  * 'inside' the line area being filled opaquely and the other pixels being filled according to
  * how far into the boundary region they are, which is determined by shader interpolation.
  */
-void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
-    if (mSnapshot->isIgnored()) return;
+status_t OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
+    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
 
     const bool isAA = paint->isAntiAlias();
     // We use half the stroke width here because we're going to position the quad
@@ -2083,10 +2095,12 @@
     if (isAA) {
         finishDrawAALine(widthSlot, lengthSlot);
     }
+
+    return DrawGlInfo::kStatusDrew;
 }
 
-void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {
-    if (mSnapshot->isIgnored()) return;
+status_t OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {
+    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
 
     // TODO: The paint's cap style defines whether the points are square or circular
     // TODO: Handle AA for round points
@@ -2138,86 +2152,92 @@
     }
 
     glDrawArrays(GL_POINTS, 0, generatedVerticesCount);
+
+    return DrawGlInfo::kStatusDrew;
 }
 
-void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
+status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
     // No need to check against the clip, we fill the clip region
-    if (mSnapshot->isIgnored()) return;
+    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
 
     Rect& clip(*mSnapshot->clipRect);
     clip.snapToPixelBoundaries();
 
     drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
+
+    return DrawGlInfo::kStatusDrew;
 }
 
-void OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture, SkPaint* paint) {
-    if (!texture) return;
+status_t OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture,
+        SkPaint* paint) {
+    if (!texture) return DrawGlInfo::kStatusDone;
     const AutoTexture autoCleanup(texture);
 
     const float x = left + texture->left - texture->offset;
     const float y = top + texture->top - texture->offset;
 
     drawPathTexture(texture, x, y, paint);
+
+    return DrawGlInfo::kStatusDrew;
 }
 
-void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
+status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
         float rx, float ry, SkPaint* paint) {
-    if (mSnapshot->isIgnored()) return;
+    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
 
     mCaches.activeTexture(0);
     const PathTexture* texture = mCaches.roundRectShapeCache.getRoundRect(
             right - left, bottom - top, rx, ry, paint);
-    drawShape(left, top, texture, paint);
+    return drawShape(left, top, texture, paint);
 }
 
-void OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
-    if (mSnapshot->isIgnored()) return;
+status_t OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
+    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
 
     mCaches.activeTexture(0);
     const PathTexture* texture = mCaches.circleShapeCache.getCircle(radius, paint);
-    drawShape(x - radius, y - radius, texture, paint);
+    return drawShape(x - radius, y - radius, texture, paint);
 }
 
-void OpenGLRenderer::drawOval(float left, float top, float right, float bottom, SkPaint* paint) {
-    if (mSnapshot->isIgnored()) return;
+status_t OpenGLRenderer::drawOval(float left, float top, float right, float bottom,
+        SkPaint* paint) {
+    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
 
     mCaches.activeTexture(0);
     const PathTexture* texture = mCaches.ovalShapeCache.getOval(right - left, bottom - top, paint);
-    drawShape(left, top, texture, paint);
+    return drawShape(left, top, texture, paint);
 }
 
-void OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
+status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
         float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
-    if (mSnapshot->isIgnored()) return;
+    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
 
     if (fabs(sweepAngle) >= 360.0f) {
-        drawOval(left, top, right, bottom, paint);
-        return;
+        return drawOval(left, top, right, bottom, paint);
     }
 
     mCaches.activeTexture(0);
     const PathTexture* texture = mCaches.arcShapeCache.getArc(right - left, bottom - top,
             startAngle, sweepAngle, useCenter, paint);
-    drawShape(left, top, texture, paint);
+    return drawShape(left, top, texture, paint);
 }
 
-void OpenGLRenderer::drawRectAsShape(float left, float top, float right, float bottom,
+status_t OpenGLRenderer::drawRectAsShape(float left, float top, float right, float bottom,
         SkPaint* paint) {
-    if (mSnapshot->isIgnored()) return;
+    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
 
     mCaches.activeTexture(0);
     const PathTexture* texture = mCaches.rectShapeCache.getRect(right - left, bottom - top, paint);
-    drawShape(left, top, texture, paint);
+    return drawShape(left, top, texture, paint);
 }
 
-void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) {
+status_t OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) {
     if (p->getStyle() != SkPaint::kFill_Style) {
-        drawRectAsShape(left, top, right, bottom, p);
-        return;
+        return drawRectAsShape(left, top, right, bottom, p);
     }
 
     if (quickReject(left, top, right, bottom)) {
-        return;
+        return DrawGlInfo::kStatusDone;
     }
 
     SkXfermode::Mode mode;
@@ -2237,18 +2257,20 @@
     } else {
         drawColorRect(left, top, right, bottom, color, mode);
     }
+
+    return DrawGlInfo::kStatusDrew;
 }
 
-void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
+status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
         const float* positions, SkPaint* paint) {
     if (text == NULL || count == 0 || mSnapshot->isIgnored() ||
             (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
-        return;
+        return DrawGlInfo::kStatusDone;
     }
 
     // NOTE: Skia does not support perspective transform on drawPosText yet
     if (!mSnapshot->transform->isSimple()) {
-        return;
+        return DrawGlInfo::kStatusDone;
     }
 
     float x = 0.0f;
@@ -2308,13 +2330,15 @@
         }
 #endif
     }
+
+    return DrawGlInfo::kStatusDrew;
 }
 
-void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
+status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
         float x, float y, SkPaint* paint, float length) {
     if (text == NULL || count == 0 || mSnapshot->isIgnored() ||
             (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
-        return;
+        return DrawGlInfo::kStatusDone;
     }
 
     if (length < 0.0f) length = paint->measureText(text, bytesCount);
@@ -2332,7 +2356,7 @@
     SkPaint::FontMetrics metrics;
     paint->getFontMetrics(&metrics, 0.0f);
     if (quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom)) {
-        return;
+        return DrawGlInfo::kStatusDone;
     }
 
     const float oldX = x;
@@ -2432,13 +2456,15 @@
     }
 
     drawTextDecorations(text, bytesCount, length, oldX, oldY, paint);
+
+    return DrawGlInfo::kStatusDrew;
 }
 
-void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
+status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
         float hOffset, float vOffset, SkPaint* paint) {
     if (text == NULL || count == 0 || mSnapshot->isIgnored() ||
             (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
-        return;
+        return DrawGlInfo::kStatusDone;
     }
 
     FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer(paint);
@@ -2482,27 +2508,31 @@
         }
 #endif
     }
+
+    return DrawGlInfo::kStatusDrew;
 }
 
-void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
-    if (mSnapshot->isIgnored()) return;
+status_t OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
+    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
 
     mCaches.activeTexture(0);
 
     // TODO: Perform early clip test before we rasterize the path
     const PathTexture* texture = mCaches.pathCache.get(path, paint);
-    if (!texture) return;
+    if (!texture) return DrawGlInfo::kStatusDone;
     const AutoTexture autoCleanup(texture);
 
     const float x = texture->left - texture->offset;
     const float y = texture->top - texture->offset;
 
     drawPathTexture(texture, x, y, paint);
+
+    return DrawGlInfo::kStatusDrew;
 }
 
-void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
+status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
     if (!layer || quickReject(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight())) {
-        return;
+        return DrawGlInfo::kStatusDone;
     }
 
     if (layer->deferredUpdateScheduled && layer->renderer && layer->displayList) {
@@ -2575,6 +2605,8 @@
     const Rect r(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight());
     composeLayerRect(layer, r);
 #endif
+
+    return DrawGlInfo::kStatusDrew;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index ad83b31..7703e80 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -111,34 +111,34 @@
     virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t flags,
             uint32_t level = 0);
     virtual void outputDisplayList(DisplayList* displayList, uint32_t level = 0);
-    virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
-    virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
-    virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
-    virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
+    virtual status_t drawLayer(Layer* layer, float x, float y, SkPaint* paint);
+    virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
+    virtual status_t drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
+    virtual status_t drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
             float dstRight, float dstBottom, SkPaint* paint);
-    virtual void drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint);
-    virtual void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
+    virtual status_t drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint);
+    virtual status_t drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
             float* vertices, int* colors, SkPaint* paint);
-    virtual void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
+    virtual status_t drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
             const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
             float left, float top, float right, float bottom, SkPaint* paint);
-    virtual void drawColor(int color, SkXfermode::Mode mode);
-    virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
-    virtual void drawRoundRect(float left, float top, float right, float bottom,
+    virtual status_t drawColor(int color, SkXfermode::Mode mode);
+    virtual status_t drawRect(float left, float top, float right, float bottom, SkPaint* paint);
+    virtual status_t drawRoundRect(float left, float top, float right, float bottom,
             float rx, float ry, SkPaint* paint);
-    virtual void drawCircle(float x, float y, float radius, SkPaint* paint);
-    virtual void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
-    virtual void drawArc(float left, float top, float right, float bottom,
+    virtual status_t drawCircle(float x, float y, float radius, SkPaint* paint);
+    virtual status_t drawOval(float left, float top, float right, float bottom, SkPaint* paint);
+    virtual status_t drawArc(float left, float top, float right, float bottom,
             float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
-    virtual void drawPath(SkPath* path, SkPaint* paint);
-    virtual void drawLines(float* points, int count, SkPaint* paint);
-    virtual void drawPoints(float* points, int count, SkPaint* paint);
-    virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
+    virtual status_t drawPath(SkPath* path, SkPaint* paint);
+    virtual status_t drawLines(float* points, int count, SkPaint* paint);
+    virtual status_t drawPoints(float* points, int count, SkPaint* paint);
+    virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
             SkPaint* paint, float length = -1.0f);
-    virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
+    virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
             float hOffset, float vOffset, SkPaint* paint);
-    virtual void drawPosText(const char* text, int bytesCount, int count,
+    virtual status_t drawPosText(const char* text, int bytesCount, int count,
             const float* positions, SkPaint* paint);
 
     virtual void resetShader();
@@ -336,7 +336,7 @@
      * @param texture The texture reprsenting the shape
      * @param paint The paint to draw the shape with
      */
-    void drawShape(float left, float top, const PathTexture* texture, SkPaint* paint);
+    status_t drawShape(float left, float top, const PathTexture* texture, SkPaint* paint);
 
     /**
      * Renders the rect defined by the specified bounds as a shape.
@@ -349,7 +349,7 @@
      * @param bottom The bottom coordinate of the rect to draw
      * @param p The paint to draw the rect with
      */
-    void drawRectAsShape(float left, float top, float right, float bottom, SkPaint* p);
+    status_t drawRectAsShape(float left, float top, float right, float bottom, SkPaint* p);
 
     /**
      * Draws the specified texture as an alpha bitmap. Alpha bitmaps obey
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 84856bf..a2c20fd 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -135,8 +135,8 @@
     private static final int MSG_RCDISPLAY_UPDATE = 13;
     private static final int MSG_SET_ALL_VOLUMES = 14;
     private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 15;
-    private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 16;
-    private static final int MSG_SET_A2DP_CONNECTION_STATE = 17;
+    private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 16;//handled under wakelock
+    private static final int MSG_SET_A2DP_CONNECTION_STATE = 17;        //handled under wakelock
 
 
     // flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
@@ -410,7 +410,7 @@
                 com.android.internal.R.bool.config_voice_capable);
 
         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
-        mMediaEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "mediaKeyEvent");
+        mMediaEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleMediaEvent");
 
         Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
         mHasVibrator = vibrator == null ? false : vibrator.hasVibrator();
@@ -2228,6 +2228,15 @@
     }
 
     // Message helper methods
+    /**
+     * Queue a message on the given handler's message queue, after acquiring the service wake lock.
+     * Note that the wake lock needs to be released after the message has been handled.
+     */
+    private void queueMsgUnderWakeLock(Handler handler, int msg,
+            int arg1, int arg2, Object obj, int delay) {
+        mMediaEventWakeLock.acquire();
+        sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay);
+    }
 
     private static void sendMsg(Handler handler, int msg,
             int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) {
@@ -2273,9 +2282,8 @@
     public void setWiredDeviceConnectionState(int device, int state, String name) {
         synchronized (mConnectedDevices) {
             int delay = checkSendBecomingNoisyIntent(device, state);
-            sendMsg(mAudioHandler,
+            queueMsgUnderWakeLock(mAudioHandler,
                     MSG_SET_WIRED_DEVICE_CONNECTION_STATE,
-                    SENDMSG_QUEUE,
                     device,
                     state,
                     name,
@@ -2289,9 +2297,8 @@
         synchronized (mConnectedDevices) {
             delay = checkSendBecomingNoisyIntent(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
                                             (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
-            sendMsg(mAudioHandler,
+            queueMsgUnderWakeLock(mAudioHandler,
                     MSG_SET_A2DP_CONNECTION_STATE,
-                    SENDMSG_QUEUE,
                     state,
                     0,
                     device,
@@ -3000,10 +3007,12 @@
 
                 case MSG_SET_WIRED_DEVICE_CONNECTION_STATE:
                     onSetWiredDeviceConnectionState(msg.arg1, msg.arg2, (String)msg.obj);
+                    mMediaEventWakeLock.release();
                     break;
 
                 case MSG_SET_A2DP_CONNECTION_STATE:
                     onSetA2dpConnectionState((BluetoothDevice)msg.obj, msg.arg1);
+                    mMediaEventWakeLock.release();
                     break;
             }
         }
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 ecdaa39..d40a763 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1054,6 +1054,9 @@
     }
 
     private static void makeSlippery(View view, boolean slippery) {
+        if (view == null) {
+            return;
+        }
         WindowManager.LayoutParams lp = (WindowManager.LayoutParams) view.getLayoutParams();
         if (slippery) {
             lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 584a69e4..273076c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -127,6 +127,7 @@
     private static final int INET_CONDITION_THRESHOLD = 50;
 
     private boolean mAirplaneMode = false;
+    private boolean mLastAirplaneMode = true;
 
     // our ui
     Context mContext;
@@ -1062,7 +1063,8 @@
          || mLastDataDirectionOverlayIconId != combinedActivityIconId
          || mLastWifiIconId                 != mWifiIconId
          || mLastWimaxIconId                != mWimaxIconId
-         || mLastDataTypeIconId             != mDataTypeIconId)
+         || mLastDataTypeIconId             != mDataTypeIconId
+         || mLastAirplaneMode               != mAirplaneMode)
         {
             // NB: the mLast*s will be updated later
             for (SignalCluster cluster : mSignalClusters) {
@@ -1070,6 +1072,10 @@
             }
         }
 
+        if (mLastAirplaneMode != mAirplaneMode) {
+            mLastAirplaneMode = mAirplaneMode;
+        }
+
         // the phone icon on phones
         if (mLastPhoneSignalIconId != mPhoneSignalIconId) {
             mLastPhoneSignalIconId = mPhoneSignalIconId;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 2c8ba22..febbd32 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -176,6 +176,7 @@
     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
     static final boolean DEBUG_VISBILITY = localLOGV || false;
     static final boolean DEBUG_PROCESSES = localLOGV || false;
+    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
     static final boolean DEBUG_PROVIDER = localLOGV || false;
     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
@@ -764,8 +765,24 @@
     boolean mAutoStopProfiler = false;
     String mOpenGlTraceApp = null;
 
+    static class ProcessChangeItem {
+        static final int CHANGE_ACTIVITIES = 1<<0;
+        static final int CHANGE_IMPORTANCE= 1<<1;
+        int changes;
+        int uid;
+        int pid;
+        int importance;
+        boolean foregroundActivities;
+    }
+
     final RemoteCallbackList<IProcessObserver> mProcessObservers
             = new RemoteCallbackList<IProcessObserver>();
+    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
+
+    final ArrayList<ProcessChangeItem> mPendingProcessChanges
+            = new ArrayList<ProcessChangeItem>();
+    final ArrayList<ProcessChangeItem> mAvailProcessChanges
+            = new ArrayList<ProcessChangeItem>();
 
     /**
      * Callback of last caller to {@link #requestPss}.
@@ -855,7 +872,7 @@
     static final int CLEAR_DNS_CACHE = 28;
     static final int UPDATE_HTTP_PROXY = 29;
     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
-    static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
+    static final int DISPATCH_PROCESSES_CHANGED = 31;
     static final int DISPATCH_PROCESS_DIED = 32;
     static final int REPORT_MEM_USAGE = 33;
 
@@ -1195,11 +1212,8 @@
                 }
                 break;
             }
-            case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
-                final int pid = msg.arg1;
-                final int uid = msg.arg2;
-                final boolean foregroundActivities = (Boolean) msg.obj;
-                dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
+            case DISPATCH_PROCESSES_CHANGED: {
+                dispatchProcessesChanged();
                 break;
             }
             case DISPATCH_PROCESS_DIED: {
@@ -2260,19 +2274,43 @@
 
     void reportResumedActivityLocked(ActivityRecord r) {
         //Slog.i(TAG, "**** REPORT RESUME: " + r);
-        
-        final int identHash = System.identityHashCode(r);
         updateUsageStats(r, true);
     }
 
-    private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
+    private void dispatchProcessesChanged() {
+        int N;
+        synchronized (this) {
+            N = mPendingProcessChanges.size();
+            if (mActiveProcessChanges.length < N) {
+                mActiveProcessChanges = new ProcessChangeItem[N];
+            }
+            mPendingProcessChanges.toArray(mActiveProcessChanges);
+            mAvailProcessChanges.addAll(mPendingProcessChanges);
+            mPendingProcessChanges.clear();
+            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
+        }
         int i = mProcessObservers.beginBroadcast();
         while (i > 0) {
             i--;
             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
             if (observer != null) {
                 try {
-                    observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
+                    for (int j=0; j<N; j++) {
+                        ProcessChangeItem item = mActiveProcessChanges[j];
+                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
+                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
+                                    + item.pid + " uid=" + item.uid + ": "
+                                    + item.foregroundActivities);
+                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
+                                    item.foregroundActivities);
+                        }
+                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
+                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
+                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
+                            observer.onImportanceChanged(item.pid, item.uid,
+                                    item.importance);
+                        }
+                    }
                 } catch (RemoteException e) {
                 }
             }
@@ -10802,6 +10840,13 @@
             }
         }
 
+        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
+            ProcessChangeItem item = mPendingProcessChanges.get(i);
+            if (item.pid == app.pid) {
+                mPendingProcessChanges.remove(i);
+                mAvailProcessChanges.add(item);
+            }
+        }
         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
 
         // If the caller is restarting this app, then leave it in its
@@ -13734,9 +13779,6 @@
             return (app.curAdj=app.maxAdj);
         }
 
-        final boolean hadForegroundActivities = app.foregroundActivities;
-
-        app.foregroundActivities = false;
         app.keeping = false;
         app.systemNoUi = false;
 
@@ -13744,18 +13786,22 @@
         // important to least, and assign an appropriate OOM adjustment.
         int adj;
         int schedGroup;
+        boolean foregroundActivities = false;
+        boolean interesting = false;
         BroadcastQueue queue;
         if (app == TOP_APP) {
             // The last app on the list is the foreground app.
             adj = ProcessList.FOREGROUND_APP_ADJ;
             schedGroup = Process.THREAD_GROUP_DEFAULT;
             app.adjType = "top-activity";
-            app.foregroundActivities = true;
+            foregroundActivities = true;
+            interesting = true;
         } else if (app.instrumentationClass != null) {
             // Don't want to kill running instrumentation.
             adj = ProcessList.FOREGROUND_APP_ADJ;
             schedGroup = Process.THREAD_GROUP_DEFAULT;
             app.adjType = "instrumentation";
+            interesting = true;
         } else if ((queue = isReceivingBroadcast(app)) != null) {
             // An app that is currently receiving a broadcast also
             // counts as being in the foreground for OOM killer purposes.
@@ -13791,7 +13837,7 @@
         boolean hasStoppingActivities = false;
 
         // Examine all activities if not already foreground.
-        if (!app.foregroundActivities && activitiesSize > 0) {
+        if (!foregroundActivities && activitiesSize > 0) {
             for (int j = 0; j < activitiesSize; j++) {
                 final ActivityRecord r = app.activities.get(j);
                 if (r.visible) {
@@ -13802,7 +13848,7 @@
                     }
                     schedGroup = Process.THREAD_GROUP_DEFAULT;
                     app.hidden = false;
-                    app.foregroundActivities = true;
+                    foregroundActivities = true;
                     break;
                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
@@ -13810,13 +13856,13 @@
                         app.adjType = "pausing";
                     }
                     app.hidden = false;
-                    app.foregroundActivities = true;
+                    foregroundActivities = true;
                 } else if (r.state == ActivityState.STOPPING) {
                     // We will apply the actual adjustment later, because
                     // we want to allow this process to immediately go through
                     // any memory trimming that is in effect.
                     app.hidden = false;
-                    app.foregroundActivities = true;
+                    foregroundActivities = true;
                     hasStoppingActivities = true;
                 }
             }
@@ -13839,6 +13885,10 @@
             }
         }
 
+        if (app.foregroundServices) {
+            interesting = true;
+        }
+
         if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
             // We don't want to kill the current heavy-weight process.
             adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
@@ -14188,12 +14238,84 @@
             }
         }
 
-        app.curAdj = adj;
-        app.curSchedGroup = schedGroup;
+        int importance = app.memImportance;
+        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
+            app.curAdj = adj;
+            app.curSchedGroup = schedGroup;
+            if (!interesting) {
+                // For this reporting, if there is not something explicitly
+                // interesting in this process then we will push it to the
+                // background importance.
+                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
+            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
+                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
+            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
+                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
+            } else if (adj >= ProcessList.HOME_APP_ADJ) {
+                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
+            } else if (adj >= ProcessList.SERVICE_ADJ) {
+                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
+            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
+                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
+            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
+                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
+            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
+                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
+            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
+                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+            } else {
+                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
+            }
+        }
 
-        if (hadForegroundActivities != app.foregroundActivities) {
-            mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
-                    app.foregroundActivities).sendToTarget();
+        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
+        if (foregroundActivities != app.foregroundActivities) {
+            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
+        }
+        if (changes != 0) {
+            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
+            app.memImportance = importance;
+            app.foregroundActivities = foregroundActivities;
+            int i = mPendingProcessChanges.size()-1;
+            ProcessChangeItem item = null;
+            while (i >= 0) {
+                item = mPendingProcessChanges.get(i);
+                if (item.pid == app.pid) {
+                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
+                    break;
+                }
+                i--;
+            }
+            if (i < 0) {
+                // No existing item in pending changes; need a new one.
+                final int NA = mAvailProcessChanges.size();
+                if (NA > 0) {
+                    item = mAvailProcessChanges.remove(NA-1);
+                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
+                } else {
+                    item = new ProcessChangeItem();
+                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
+                }
+                item.changes = 0;
+                item.pid = app.pid;
+                item.uid = app.info.uid;
+                if (mPendingProcessChanges.size() == 0) {
+                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
+                            "*** Enqueueing dispatch processes changed!");
+                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
+                }
+                mPendingProcessChanges.add(item);
+            }
+            item.changes |= changes;
+            item.importance = importance;
+            item.foregroundActivities = foregroundActivities;
+            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
+                    + Integer.toHexString(System.identityHashCode(item))
+                    + " " + app.toShortString() + ": changes=" + item.changes
+                    + " importance=" + item.importance
+                    + " foreground=" + item.foregroundActivities
+                    + " type=" + app.adjType + " source=" + app.adjSource
+                    + " target=" + app.adjTarget);
         }
 
         return app.curRawAdj;
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 8a3ba7f..cba9480 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -69,6 +69,7 @@
     int curSchedGroup;          // Currently desired scheduling class
     int setSchedGroup;          // Last set to background scheduling class
     int trimMemoryLevel;        // Last selected memory trimming level
+    int memImportance;          // Importance constant computed from curAdj
     boolean serviceb;           // Process currently is on the service B list
     boolean keeping;            // Actively running code so don't kill due to that?
     boolean setIsForeground;    // Running foreground UI when last set?
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index c82f37c..c4abac9 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -396,6 +396,10 @@
         }
 
         @Override
+        public void onImportanceChanged(int pid, int uid, int importance) {
+        }
+
+        @Override
         public void onProcessDied(int pid, int uid) {
             mHandler.obtainMessage(MSG_PROCESS_DIED, pid, uid).sendToTarget();
         }
diff --git a/services/java/com/android/server/pm/ShutdownThread.java b/services/java/com/android/server/pm/ShutdownThread.java
index 1d6e068..69406c8 100644
--- a/services/java/com/android/server/pm/ShutdownThread.java
+++ b/services/java/com/android/server/pm/ShutdownThread.java
@@ -51,11 +51,11 @@
 public final class ShutdownThread extends Thread {
     // constants
     private static final String TAG = "ShutdownThread";
-    private static final int MAX_NUM_PHONE_STATE_READS = 24;
     private static final int PHONE_STATE_POLL_SLEEP_MSEC = 500;
     // maximum time we wait for the shutdown broadcast before going on.
     private static final int MAX_BROADCAST_TIME = 10*1000;
     private static final int MAX_SHUTDOWN_WAIT_TIME = 20*1000;
+    private static final int MAX_RADIO_WAIT_TIME = 12*1000;
 
     // length of vibration before shutting down
     private static final int SHUTDOWN_VIBRATE_MS = 500;
@@ -263,10 +263,6 @@
      * Shuts off power regardless of radio and bluetooth state if the alloted time has passed.
      */
     public void run() {
-        boolean nfcOff;
-        boolean bluetoothOff;
-        boolean radioOff;
-
         BroadcastReceiver br = new BroadcastReceiver() {
             @Override public void onReceive(Context context, Intent intent) {
                 // We don't allow apps to cancel this, so ignore the result.
@@ -324,89 +320,9 @@
             } catch (RemoteException e) {
             }
         }
-        
-        final INfcAdapter nfc =
-                INfcAdapter.Stub.asInterface(ServiceManager.checkService("nfc"));
-        final ITelephony phone =
-                ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
-        final IBluetooth bluetooth =
-                IBluetooth.Stub.asInterface(ServiceManager.checkService(
-                        BluetoothAdapter.BLUETOOTH_SERVICE));
-        final IMountService mount =
-                IMountService.Stub.asInterface(
-                        ServiceManager.checkService("mount"));
 
-        try {
-            nfcOff = nfc == null ||
-                     nfc.getState() == NfcAdapter.STATE_OFF;
-            if (!nfcOff) {
-                Log.w(TAG, "Turning off NFC...");
-                nfc.disable(false); // Don't persist new state
-            }
-        } catch (RemoteException ex) {
-	    Log.e(TAG, "RemoteException during NFC shutdown", ex);
-            nfcOff = true;
-        }
-
-        try {
-            bluetoothOff = bluetooth == null ||
-                           bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
-            if (!bluetoothOff) {
-                Log.w(TAG, "Disabling Bluetooth...");
-                bluetooth.disable(false);  // disable but don't persist new state
-            }
-        } catch (RemoteException ex) {
-            Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
-            bluetoothOff = true;
-        }
-
-        try {
-            radioOff = phone == null || !phone.isRadioOn();
-            if (!radioOff) {
-                Log.w(TAG, "Turning off radio...");
-                phone.setRadio(false);
-            }
-        } catch (RemoteException ex) {
-            Log.e(TAG, "RemoteException during radio shutdown", ex);
-            radioOff = true;
-        }
-
-        Log.i(TAG, "Waiting for NFC, Bluetooth and Radio...");
-        
-        // Wait a max of 32 seconds for clean shutdown
-        for (int i = 0; i < MAX_NUM_PHONE_STATE_READS; i++) {
-            if (!bluetoothOff) {
-                try {
-                    bluetoothOff =
-                            bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
-                } catch (RemoteException ex) {
-                    Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
-                    bluetoothOff = true;
-                }
-            }
-            if (!radioOff) {
-                try {
-                    radioOff = !phone.isRadioOn();
-                } catch (RemoteException ex) {
-                    Log.e(TAG, "RemoteException during radio shutdown", ex);
-                    radioOff = true;
-                }
-            }
-            if (!nfcOff) {
-                try {
-                    nfcOff = nfc.getState() == NfcAdapter.STATE_OFF;
-                } catch (RemoteException ex) {
-                    Log.e(TAG, "RemoteException during NFC shutdown", ex);
-                    nfcOff = true;
-                }
-            }
-
-            if (radioOff && bluetoothOff && nfcOff) {
-                Log.i(TAG, "NFC, Radio and Bluetooth shutdown complete.");
-                break;
-            }
-            SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC);
-        }
+        // Shutdown radios.
+        shutdownRadios(MAX_RADIO_WAIT_TIME);
 
         // Shutdown MountService to ensure media is in a safe state
         IMountShutdownObserver observer = new IMountShutdownObserver.Stub() {
@@ -417,11 +333,14 @@
         };
 
         Log.i(TAG, "Shutting down MountService");
+
         // Set initial variables and time out time.
         mActionDone = false;
         final long endShutTime = SystemClock.elapsedRealtime() + MAX_SHUTDOWN_WAIT_TIME;
         synchronized (mActionDoneSync) {
             try {
+                final IMountService mount = IMountService.Stub.asInterface(
+                        ServiceManager.checkService("mount"));
                 if (mount != null) {
                     mount.shutdown(observer);
                 } else {
@@ -446,6 +365,118 @@
         rebootOrShutdown(mReboot, mRebootReason);
     }
 
+    private void shutdownRadios(int timeout) {
+        // If a radio is wedged, disabling it may hang so we do this work in another thread,
+        // just in case.
+        final long endTime = SystemClock.elapsedRealtime() + timeout;
+        final boolean[] done = new boolean[1];
+        Thread t = new Thread() {
+            public void run() {
+                boolean nfcOff;
+                boolean bluetoothOff;
+                boolean radioOff;
+
+                final INfcAdapter nfc =
+                        INfcAdapter.Stub.asInterface(ServiceManager.checkService("nfc"));
+                final ITelephony phone =
+                        ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
+                final IBluetooth bluetooth =
+                        IBluetooth.Stub.asInterface(ServiceManager.checkService(
+                                BluetoothAdapter.BLUETOOTH_SERVICE));
+
+                try {
+                    nfcOff = nfc == null ||
+                             nfc.getState() == NfcAdapter.STATE_OFF;
+                    if (!nfcOff) {
+                        Log.w(TAG, "Turning off NFC...");
+                        nfc.disable(false); // Don't persist new state
+                    }
+                } catch (RemoteException ex) {
+                Log.e(TAG, "RemoteException during NFC shutdown", ex);
+                    nfcOff = true;
+                }
+
+                try {
+                    bluetoothOff = bluetooth == null ||
+                                   bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
+                    if (!bluetoothOff) {
+                        Log.w(TAG, "Disabling Bluetooth...");
+                        bluetooth.disable(false);  // disable but don't persist new state
+                    }
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
+                    bluetoothOff = true;
+                }
+
+                try {
+                    radioOff = phone == null || !phone.isRadioOn();
+                    if (!radioOff) {
+                        Log.w(TAG, "Turning off radio...");
+                        phone.setRadio(false);
+                    }
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "RemoteException during radio shutdown", ex);
+                    radioOff = true;
+                }
+
+                Log.i(TAG, "Waiting for NFC, Bluetooth and Radio...");
+
+                while (SystemClock.elapsedRealtime() < endTime) {
+                    if (!bluetoothOff) {
+                        try {
+                            bluetoothOff =
+                                    bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
+                        } catch (RemoteException ex) {
+                            Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
+                            bluetoothOff = true;
+                        }
+                        if (bluetoothOff) {
+                            Log.i(TAG, "Bluetooth turned off.");
+                        }
+                    }
+                    if (!radioOff) {
+                        try {
+                            radioOff = !phone.isRadioOn();
+                        } catch (RemoteException ex) {
+                            Log.e(TAG, "RemoteException during radio shutdown", ex);
+                            radioOff = true;
+                        }
+                        if (radioOff) {
+                            Log.i(TAG, "Radio turned off.");
+                        }
+                    }
+                    if (!nfcOff) {
+                        try {
+                            nfcOff = nfc.getState() == NfcAdapter.STATE_OFF;
+                        } catch (RemoteException ex) {
+                            Log.e(TAG, "RemoteException during NFC shutdown", ex);
+                            nfcOff = true;
+                        }
+                        if (radioOff) {
+                            Log.i(TAG, "NFC turned off.");
+                        }
+                    }
+
+                    if (radioOff && bluetoothOff && nfcOff) {
+                        Log.i(TAG, "NFC, Radio and Bluetooth shutdown complete.");
+                        done[0] = true;
+                        break;
+                    }
+                    SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC);
+                }
+            }
+        };
+
+        t.start();
+        try {
+            t.join(timeout);
+        } catch (InterruptedException ex) {
+        }
+        if (!done[0]) {
+            Log.w(TAG, "Timed out waiting for NFC, Radio and Bluetooth shutdown.");
+        }
+    }
+
     /**
      * Do not call this directly. Use {@link #reboot(Context, String, boolean)}
      * or {@link #shutdown(Context, boolean)} instead.
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index c800182..806730c 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -897,7 +897,11 @@
                     break;
                 case WifiMonitor.P2P_DEVICE_LOST_EVENT:
                     WifiP2pDevice device = (WifiP2pDevice) message.obj;
-                    if (!mSavedPeerConfig.deviceAddress.equals(device.deviceAddress)) {
+
+                    // If we lose a device during an autonomous group creation,
+                    // mSavedPeerConfig can be empty
+                    if (mSavedPeerConfig != null &&
+                            !mSavedPeerConfig.deviceAddress.equals(device.deviceAddress)) {
                         // Do the regular device lost handling
                         ret = NOT_HANDLED;
                         break;