Merge "Prevent refocus after entering touch mode" into klp-dev
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index df2e09f..747e8ea 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4572,10 +4572,23 @@
             System.out.println(this + " clearFocus()");
         }
 
+        clearFocusInternal(true, true);
+    }
+
+    /**
+     * Clears focus from the view, optionally propagating the change up through
+     * the parent hierarchy and requesting that the root view place new focus.
+     *
+     * @param propagate whether to propagate the change up through the parent
+     *            hierarchy
+     * @param refocus when propagate is true, specifies whether to request the
+     *            root view place new focus
+     */
+    void clearFocusInternal(boolean propagate, boolean refocus) {
         if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
             mPrivateFlags &= ~PFLAG_FOCUSED;
 
-            if (mParent != null) {
+            if (propagate && mParent != null) {
                 mParent.clearChildFocus(this);
             }
 
@@ -4583,7 +4596,7 @@
 
             refreshDrawableState();
 
-            if (!rootViewRequestFocus()) {
+            if (propagate && (!refocus || !rootViewRequestFocus())) {
                 notifyGlobalFocusCleared(this);
             }
         }
@@ -4613,12 +4626,7 @@
             System.out.println(this + " unFocus()");
         }
 
-        if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
-            mPrivateFlags &= ~PFLAG_FOCUSED;
-
-            onFocusChanged(false, 0, null);
-            refreshDrawableState();
-        }
+        clearFocusInternal(false, false);
     }
 
     /**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 3977a33..e90705c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3271,9 +3271,9 @@
                     // focus
                     return ancestorToTakeFocus.requestFocus();
                 } else {
-                    // nothing appropriate to have focus in touch mode, clear it
-                    // out
-                    focused.clearFocus();
+                    // There's nothing to focus. Clear and propagate through the
+                    // hierarchy, but don't attempt to place new focus.
+                    focused.clearFocusInternal(true, false);
                     return true;
                 }
             }