Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 187706f3 authored by Evan Rosky's avatar Evan Rosky Committed by Android (Google) Code Review
Browse files

Merge "Don't notify parents of views made focusable off UI thread"

parents 74c73c21 f038cb45
Loading
Loading
Loading
Loading
+25 −3
Original line number Diff line number Diff line
@@ -858,6 +858,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    static boolean sHasFocusableExcludeAutoFocusable;
    /**
     * Prior to O, auto-focusable didn't exist and views marked as clickable weren't implicitly
     * made focusable by default. As a result, apps could (incorrectly) change the clickable
     * setting of views off the UI thread. Now that clickable can effect the focusable state,
     * changing the clickable attribute off the UI thread will cause an exception (since changing
     * the focusable state checks). In order to prevent apps from crashing, we will handle this
     * specific case and just not notify parents on new focusables resulting from marking views
     * clickable from outside the UI thread.
     */
    private static boolean sAutoFocusableOffUIThreadWontNotifyParents;
    /** @hide */
    @IntDef({NOT_FOCUSABLE, FOCUSABLE, FOCUSABLE_AUTO})
    @Retention(RetentionPolicy.SOURCE)
@@ -4182,6 +4193,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            sHasFocusableExcludeAutoFocusable = targetSdkVersion < Build.VERSION_CODES.O;
            sAutoFocusableOffUIThreadWontNotifyParents = targetSdkVersion < Build.VERSION_CODES.O;
            sCompatibilityDone = true;
        }
    }
@@ -12135,6 +12148,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        int privateFlags = mPrivateFlags;
        // If focusable is auto, update the FOCUSABLE bit.
        int focusableChangedByAuto = 0;
        if (((mViewFlags & FOCUSABLE_AUTO) != 0)
                && (changed & (FOCUSABLE_MASK | CLICKABLE | FOCUSABLE_IN_TOUCH_MODE)) != 0) {
            int newFocus = NOT_FOCUSABLE;
@@ -12144,8 +12158,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                mViewFlags = (mViewFlags & ~FOCUSABLE_IN_TOUCH_MODE);
            }
            mViewFlags = (mViewFlags & ~FOCUSABLE) | newFocus;
            int focusChanged = (old & FOCUSABLE) ^ (newFocus & FOCUSABLE);
            changed = (changed & ~FOCUSABLE) | focusChanged;
            focusableChangedByAuto = (old & FOCUSABLE) ^ (newFocus & FOCUSABLE);
            changed = (changed & ~FOCUSABLE) | focusableChangedByAuto;
        }
        /* Check if the FOCUSABLE bit has changed */
@@ -12160,7 +12174,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                 * Tell the view system that we are now available to take focus
                 * if no one else already has it.
                 */
                if (mParent != null) mParent.focusableViewAvailable(this);
                if (mParent != null) {
                    ViewRootImpl viewRootImpl = getViewRootImpl();
                    if (!sAutoFocusableOffUIThreadWontNotifyParents
                            || focusableChangedByAuto == 0
                            || viewRootImpl == null
                            || viewRootImpl.mThread == Thread.currentThread()) {
                        mParent.focusableViewAvailable(this);
                    }
                }
            }
        }