Loading core/java/android/view/View.java +18 −3 Original line number Diff line number Diff line Loading @@ -4376,10 +4376,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if ((mPrivateFlags & PFLAG_FOCUSED) == 0) { mPrivateFlags |= PFLAG_FOCUSED; View oldFocus = (mAttachInfo != null) ? getRootView().findFocus() : null; if (mParent != null) { mParent.requestChildFocus(this, this); } if (mAttachInfo != null) { mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, this); } onFocusChanged(true, direction, previouslyFocusedRect); refreshDrawableState(); Loading Loading @@ -4486,7 +4492,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, refreshDrawableState(); ensureInputFocusOnFirstFocusable(); if (!rootViewRequestFocus()) { notifyGlobalFocusCleared(this); } if (AccessibilityManager.getInstance(mContext).isEnabled()) { notifyAccessibilityStateChanged(); Loading @@ -4494,11 +4502,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } void ensureInputFocusOnFirstFocusable() { void notifyGlobalFocusCleared(View oldFocus) { if (oldFocus != null && mAttachInfo != null) { mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, null); } } boolean rootViewRequestFocus() { View root = getRootView(); if (root != null) { root.requestFocus(); return root.requestFocus(); } return false; } /** Loading core/java/android/view/ViewGroup.java +26 −18 Original line number Diff line number Diff line Loading @@ -3697,7 +3697,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager clearChildFocus = true; } if (view.isAccessibilityFocused()) { view.clearAccessibilityFocus(); } cancelTouchTarget(view); cancelHoverTarget(view); Loading @@ -3719,11 +3721,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (clearChildFocus) { clearChildFocus(view); ensureInputFocusOnFirstFocusable(); if (!rootViewRequestFocus()) { notifyGlobalFocusCleared(this); } if (view.isAccessibilityFocused()) { view.clearAccessibilityFocus(); } onViewRemoved(view); Loading Loading @@ -3765,7 +3765,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager private void removeViewsInternal(int start, int count) { final View focused = mFocused; final boolean detach = mAttachInfo != null; View clearChildFocus = null; boolean clearChildFocus = false; final View[] children = mChildren; final int end = start + count; Loading @@ -3779,10 +3779,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (view == focused) { view.unFocus(); clearChildFocus = view; clearChildFocus = true; } if (view.isAccessibilityFocused()) { view.clearAccessibilityFocus(); } cancelTouchTarget(view); cancelHoverTarget(view); Loading @@ -3805,9 +3807,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager removeFromArray(start, count); if (clearChildFocus != null) { clearChildFocus(clearChildFocus); ensureInputFocusOnFirstFocusable(); if (clearChildFocus) { clearChildFocus(focused); if (!rootViewRequestFocus()) { notifyGlobalFocusCleared(focused); } } } Loading Loading @@ -3849,7 +3853,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final View focused = mFocused; final boolean detach = mAttachInfo != null; View clearChildFocus = null; boolean clearChildFocus = false; needGlobalAttributesUpdate(false); Loading @@ -3862,10 +3866,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (view == focused) { view.unFocus(); clearChildFocus = view; clearChildFocus = true; } if (view.isAccessibilityFocused()) { view.clearAccessibilityFocus(); } cancelTouchTarget(view); cancelHoverTarget(view); Loading @@ -3887,9 +3893,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager children[i] = null; } if (clearChildFocus != null) { clearChildFocus(clearChildFocus); ensureInputFocusOnFirstFocusable(); if (clearChildFocus) { clearChildFocus(focused); if (!rootViewRequestFocus()) { notifyGlobalFocusCleared(focused); } } } Loading core/java/android/view/ViewRootImpl.java +26 −55 Original line number Diff line number Diff line Loading @@ -169,9 +169,6 @@ public final class ViewRootImpl implements ViewParent, int mSeq; View mView; View mFocusedView; View mRealFocusedView; // this is not set to null in touch mode View mOldFocusedView; View mAccessibilityFocusedHost; AccessibilityNodeInfo mAccessibilityFocusedVirtualView; Loading Loading @@ -269,7 +266,7 @@ public final class ViewRootImpl implements ViewParent, boolean mScrollMayChange; int mSoftInputMode; View mLastScrolledFocus; WeakReference<View> mLastScrolledFocus; int mScrollY; int mCurScrollY; Scroller mScroller; Loading Loading @@ -1526,7 +1523,9 @@ public final class ViewRootImpl implements ViewParent, } else if (!mSurface.isValid()) { // If the surface has been removed, then reset the scroll // positions. mLastScrolledFocus = null; if (mLastScrolledFocus != null) { mLastScrolledFocus.clear(); } mScrollY = mCurScrollY = 0; if (mScroller != null) { mScroller.abortAnimation(); Loading Loading @@ -1802,13 +1801,11 @@ public final class ViewRootImpl implements ViewParent, if (mView != null) { if (!mView.hasFocus()) { mView.requestFocus(View.FOCUS_FORWARD); mFocusedView = mRealFocusedView = mView.findFocus(); if (DEBUG_INPUT_RESIZE) Log.v(TAG, "First: requested focused view=" + mFocusedView); + mView.findFocus()); } else { mRealFocusedView = mView.findFocus(); if (DEBUG_INPUT_RESIZE) Log.v(TAG, "First: existing focused view=" + mRealFocusedView); + mView.findFocus()); } } if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_ANIMATING) != 0) { Loading Loading @@ -2514,17 +2511,12 @@ public final class ViewRootImpl implements ViewParent, // requestChildRectangleOnScreen() call (in which case 'rectangle' // is non-null and we just want to scroll to whatever that // rectangle is). View focus = mRealFocusedView; // When in touch mode, focus points to the previously focused view, // which may have been removed from the view hierarchy. The following // line checks whether the view is still in our hierarchy. if (focus == null || focus.mAttachInfo != mAttachInfo) { mRealFocusedView = null; View focus = mView.findFocus(); if (focus == null) { return false; } if (focus != mLastScrolledFocus) { View lastScrolledFocus = (mLastScrolledFocus != null) ? mLastScrolledFocus.get() : null; if (lastScrolledFocus != null && focus != lastScrolledFocus) { // If the focus has changed, then ignore any requests to scroll // to a rectangle; first we want to make sure the entire focus // view is visible. Loading @@ -2533,8 +2525,7 @@ public final class ViewRootImpl implements ViewParent, if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Eval scroll: focus=" + focus + " rectangle=" + rectangle + " ci=" + ci + " vi=" + vi); if (focus == mLastScrolledFocus && !mScrollMayChange && rectangle == null) { if (focus == lastScrolledFocus && !mScrollMayChange && rectangle == null) { // Optimization: if the focus hasn't changed since last // time, and no layout has happened, then just leave things // as they are. Loading @@ -2544,7 +2535,7 @@ public final class ViewRootImpl implements ViewParent, // We need to determine if the currently focused view is // within the visible part of the window and, if not, apply // a pan so it can be seen. mLastScrolledFocus = focus; mLastScrolledFocus = new WeakReference<View>(focus); mScrollMayChange = false; if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Need to scroll?"); // Try to find the rectangle from the focus view. Loading Loading @@ -2671,33 +2662,19 @@ public final class ViewRootImpl implements ViewParent, } public void requestChildFocus(View child, View focused) { checkThread(); if (DEBUG_INPUT_RESIZE) { Log.v(TAG, "Request child focus: focus now " + focused); } mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(mOldFocusedView, focused); checkThread(); scheduleTraversals(); mFocusedView = mRealFocusedView = focused; } public void clearChildFocus(View child) { checkThread(); if (DEBUG_INPUT_RESIZE) { Log.v(TAG, "Clearing child focus"); } mOldFocusedView = mFocusedView; // Invoke the listener only if there is no view to take focus if (focusSearch(null, View.FOCUS_FORWARD) == null) { mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(mOldFocusedView, null); } mFocusedView = mRealFocusedView = null; checkThread(); scheduleTraversals(); } @Override Loading @@ -2714,18 +2691,17 @@ public final class ViewRootImpl implements ViewParent, // the one case where will transfer focus away from the current one // is if the current view is a view group that prefers to give focus // to its children first AND the view is a descendant of it. mFocusedView = mView.findFocus(); boolean descendantsHaveDibsOnFocus = (mFocusedView instanceof ViewGroup) && (((ViewGroup) mFocusedView).getDescendantFocusability() == ViewGroup.FOCUS_AFTER_DESCENDANTS); if (descendantsHaveDibsOnFocus && isViewDescendantOf(v, mFocusedView)) { // If a view gets the focus, the listener will be invoked from requestChildFocus() View focused = mView.findFocus(); if (focused instanceof ViewGroup) { ViewGroup group = (ViewGroup) focused; if (group.getDescendantFocusability() == ViewGroup.FOCUS_AFTER_DESCENDANTS && isViewDescendantOf(v, focused)) { v.requestFocus(); } } } } } public void recomputeViewAttributes(View child) { checkThread(); Loading Loading @@ -3199,7 +3175,6 @@ public final class ViewRootImpl implements ViewParent, // set yet. final View focused = mView.findFocus(); if (focused != null && !focused.isFocusableInTouchMode()) { final ViewGroup ancestorToTakeFocus = findAncestorToTakeFocusInTouchMode(focused); if (ancestorToTakeFocus != null) { Loading @@ -3208,10 +3183,7 @@ public final class ViewRootImpl implements ViewParent, return ancestorToTakeFocus.requestFocus(); } else { // nothing appropriate to have focus in touch mode, clear it out mView.unFocus(); mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(focused, null); mFocusedView = null; mOldFocusedView = null; focused.unFocus(); return true; } } Loading Loading @@ -3246,12 +3218,11 @@ public final class ViewRootImpl implements ViewParent, private boolean leaveTouchMode() { if (mView != null) { if (mView.hasFocus()) { // i learned the hard way to not trust mFocusedView :) mFocusedView = mView.findFocus(); if (!(mFocusedView instanceof ViewGroup)) { View focusedView = mView.findFocus(); if (!(focusedView instanceof ViewGroup)) { // some view has focus, let it keep it return false; } else if (((ViewGroup)mFocusedView).getDescendantFocusability() != } else if (((ViewGroup) focusedView).getDescendantFocusability() != ViewGroup.FOCUS_AFTER_DESCENDANTS) { // some view group has focus, and doesn't prefer its children // over itself for focus, so let them keep it. Loading Loading
core/java/android/view/View.java +18 −3 Original line number Diff line number Diff line Loading @@ -4376,10 +4376,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if ((mPrivateFlags & PFLAG_FOCUSED) == 0) { mPrivateFlags |= PFLAG_FOCUSED; View oldFocus = (mAttachInfo != null) ? getRootView().findFocus() : null; if (mParent != null) { mParent.requestChildFocus(this, this); } if (mAttachInfo != null) { mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, this); } onFocusChanged(true, direction, previouslyFocusedRect); refreshDrawableState(); Loading Loading @@ -4486,7 +4492,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, refreshDrawableState(); ensureInputFocusOnFirstFocusable(); if (!rootViewRequestFocus()) { notifyGlobalFocusCleared(this); } if (AccessibilityManager.getInstance(mContext).isEnabled()) { notifyAccessibilityStateChanged(); Loading @@ -4494,11 +4502,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } void ensureInputFocusOnFirstFocusable() { void notifyGlobalFocusCleared(View oldFocus) { if (oldFocus != null && mAttachInfo != null) { mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, null); } } boolean rootViewRequestFocus() { View root = getRootView(); if (root != null) { root.requestFocus(); return root.requestFocus(); } return false; } /** Loading
core/java/android/view/ViewGroup.java +26 −18 Original line number Diff line number Diff line Loading @@ -3697,7 +3697,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager clearChildFocus = true; } if (view.isAccessibilityFocused()) { view.clearAccessibilityFocus(); } cancelTouchTarget(view); cancelHoverTarget(view); Loading @@ -3719,11 +3721,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (clearChildFocus) { clearChildFocus(view); ensureInputFocusOnFirstFocusable(); if (!rootViewRequestFocus()) { notifyGlobalFocusCleared(this); } if (view.isAccessibilityFocused()) { view.clearAccessibilityFocus(); } onViewRemoved(view); Loading Loading @@ -3765,7 +3765,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager private void removeViewsInternal(int start, int count) { final View focused = mFocused; final boolean detach = mAttachInfo != null; View clearChildFocus = null; boolean clearChildFocus = false; final View[] children = mChildren; final int end = start + count; Loading @@ -3779,10 +3779,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (view == focused) { view.unFocus(); clearChildFocus = view; clearChildFocus = true; } if (view.isAccessibilityFocused()) { view.clearAccessibilityFocus(); } cancelTouchTarget(view); cancelHoverTarget(view); Loading @@ -3805,9 +3807,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager removeFromArray(start, count); if (clearChildFocus != null) { clearChildFocus(clearChildFocus); ensureInputFocusOnFirstFocusable(); if (clearChildFocus) { clearChildFocus(focused); if (!rootViewRequestFocus()) { notifyGlobalFocusCleared(focused); } } } Loading Loading @@ -3849,7 +3853,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final View focused = mFocused; final boolean detach = mAttachInfo != null; View clearChildFocus = null; boolean clearChildFocus = false; needGlobalAttributesUpdate(false); Loading @@ -3862,10 +3866,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (view == focused) { view.unFocus(); clearChildFocus = view; clearChildFocus = true; } if (view.isAccessibilityFocused()) { view.clearAccessibilityFocus(); } cancelTouchTarget(view); cancelHoverTarget(view); Loading @@ -3887,9 +3893,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager children[i] = null; } if (clearChildFocus != null) { clearChildFocus(clearChildFocus); ensureInputFocusOnFirstFocusable(); if (clearChildFocus) { clearChildFocus(focused); if (!rootViewRequestFocus()) { notifyGlobalFocusCleared(focused); } } } Loading
core/java/android/view/ViewRootImpl.java +26 −55 Original line number Diff line number Diff line Loading @@ -169,9 +169,6 @@ public final class ViewRootImpl implements ViewParent, int mSeq; View mView; View mFocusedView; View mRealFocusedView; // this is not set to null in touch mode View mOldFocusedView; View mAccessibilityFocusedHost; AccessibilityNodeInfo mAccessibilityFocusedVirtualView; Loading Loading @@ -269,7 +266,7 @@ public final class ViewRootImpl implements ViewParent, boolean mScrollMayChange; int mSoftInputMode; View mLastScrolledFocus; WeakReference<View> mLastScrolledFocus; int mScrollY; int mCurScrollY; Scroller mScroller; Loading Loading @@ -1526,7 +1523,9 @@ public final class ViewRootImpl implements ViewParent, } else if (!mSurface.isValid()) { // If the surface has been removed, then reset the scroll // positions. mLastScrolledFocus = null; if (mLastScrolledFocus != null) { mLastScrolledFocus.clear(); } mScrollY = mCurScrollY = 0; if (mScroller != null) { mScroller.abortAnimation(); Loading Loading @@ -1802,13 +1801,11 @@ public final class ViewRootImpl implements ViewParent, if (mView != null) { if (!mView.hasFocus()) { mView.requestFocus(View.FOCUS_FORWARD); mFocusedView = mRealFocusedView = mView.findFocus(); if (DEBUG_INPUT_RESIZE) Log.v(TAG, "First: requested focused view=" + mFocusedView); + mView.findFocus()); } else { mRealFocusedView = mView.findFocus(); if (DEBUG_INPUT_RESIZE) Log.v(TAG, "First: existing focused view=" + mRealFocusedView); + mView.findFocus()); } } if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_ANIMATING) != 0) { Loading Loading @@ -2514,17 +2511,12 @@ public final class ViewRootImpl implements ViewParent, // requestChildRectangleOnScreen() call (in which case 'rectangle' // is non-null and we just want to scroll to whatever that // rectangle is). View focus = mRealFocusedView; // When in touch mode, focus points to the previously focused view, // which may have been removed from the view hierarchy. The following // line checks whether the view is still in our hierarchy. if (focus == null || focus.mAttachInfo != mAttachInfo) { mRealFocusedView = null; View focus = mView.findFocus(); if (focus == null) { return false; } if (focus != mLastScrolledFocus) { View lastScrolledFocus = (mLastScrolledFocus != null) ? mLastScrolledFocus.get() : null; if (lastScrolledFocus != null && focus != lastScrolledFocus) { // If the focus has changed, then ignore any requests to scroll // to a rectangle; first we want to make sure the entire focus // view is visible. Loading @@ -2533,8 +2525,7 @@ public final class ViewRootImpl implements ViewParent, if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Eval scroll: focus=" + focus + " rectangle=" + rectangle + " ci=" + ci + " vi=" + vi); if (focus == mLastScrolledFocus && !mScrollMayChange && rectangle == null) { if (focus == lastScrolledFocus && !mScrollMayChange && rectangle == null) { // Optimization: if the focus hasn't changed since last // time, and no layout has happened, then just leave things // as they are. Loading @@ -2544,7 +2535,7 @@ public final class ViewRootImpl implements ViewParent, // We need to determine if the currently focused view is // within the visible part of the window and, if not, apply // a pan so it can be seen. mLastScrolledFocus = focus; mLastScrolledFocus = new WeakReference<View>(focus); mScrollMayChange = false; if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Need to scroll?"); // Try to find the rectangle from the focus view. Loading Loading @@ -2671,33 +2662,19 @@ public final class ViewRootImpl implements ViewParent, } public void requestChildFocus(View child, View focused) { checkThread(); if (DEBUG_INPUT_RESIZE) { Log.v(TAG, "Request child focus: focus now " + focused); } mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(mOldFocusedView, focused); checkThread(); scheduleTraversals(); mFocusedView = mRealFocusedView = focused; } public void clearChildFocus(View child) { checkThread(); if (DEBUG_INPUT_RESIZE) { Log.v(TAG, "Clearing child focus"); } mOldFocusedView = mFocusedView; // Invoke the listener only if there is no view to take focus if (focusSearch(null, View.FOCUS_FORWARD) == null) { mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(mOldFocusedView, null); } mFocusedView = mRealFocusedView = null; checkThread(); scheduleTraversals(); } @Override Loading @@ -2714,18 +2691,17 @@ public final class ViewRootImpl implements ViewParent, // the one case where will transfer focus away from the current one // is if the current view is a view group that prefers to give focus // to its children first AND the view is a descendant of it. mFocusedView = mView.findFocus(); boolean descendantsHaveDibsOnFocus = (mFocusedView instanceof ViewGroup) && (((ViewGroup) mFocusedView).getDescendantFocusability() == ViewGroup.FOCUS_AFTER_DESCENDANTS); if (descendantsHaveDibsOnFocus && isViewDescendantOf(v, mFocusedView)) { // If a view gets the focus, the listener will be invoked from requestChildFocus() View focused = mView.findFocus(); if (focused instanceof ViewGroup) { ViewGroup group = (ViewGroup) focused; if (group.getDescendantFocusability() == ViewGroup.FOCUS_AFTER_DESCENDANTS && isViewDescendantOf(v, focused)) { v.requestFocus(); } } } } } public void recomputeViewAttributes(View child) { checkThread(); Loading Loading @@ -3199,7 +3175,6 @@ public final class ViewRootImpl implements ViewParent, // set yet. final View focused = mView.findFocus(); if (focused != null && !focused.isFocusableInTouchMode()) { final ViewGroup ancestorToTakeFocus = findAncestorToTakeFocusInTouchMode(focused); if (ancestorToTakeFocus != null) { Loading @@ -3208,10 +3183,7 @@ public final class ViewRootImpl implements ViewParent, return ancestorToTakeFocus.requestFocus(); } else { // nothing appropriate to have focus in touch mode, clear it out mView.unFocus(); mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(focused, null); mFocusedView = null; mOldFocusedView = null; focused.unFocus(); return true; } } Loading Loading @@ -3246,12 +3218,11 @@ public final class ViewRootImpl implements ViewParent, private boolean leaveTouchMode() { if (mView != null) { if (mView.hasFocus()) { // i learned the hard way to not trust mFocusedView :) mFocusedView = mView.findFocus(); if (!(mFocusedView instanceof ViewGroup)) { View focusedView = mView.findFocus(); if (!(focusedView instanceof ViewGroup)) { // some view has focus, let it keep it return false; } else if (((ViewGroup)mFocusedView).getDescendantFocusability() != } else if (((ViewGroup) focusedView).getDescendantFocusability() != ViewGroup.FOCUS_AFTER_DESCENDANTS) { // some view group has focus, and doesn't prefer its children // over itself for focus, so let them keep it. Loading