Loading core/java/android/view/View.java +14 −6 Original line number Diff line number Diff line Loading @@ -29901,6 +29901,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void setPointerIcon(PointerIcon pointerIcon) { mMousePointerIcon = pointerIcon; if (com.android.input.flags.Flags.enablePointerChoreographer()) { final ViewRootImpl viewRootImpl = getViewRootImpl(); if (viewRootImpl == null) { return; } viewRootImpl.refreshPointerIcon(); } else { if (mAttachInfo == null || mAttachInfo.mHandlingPointerEvent) { return; } Loading @@ -29909,6 +29916,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } catch (RemoteException e) { } } } /** * Gets the mouse pointer icon for the current view. core/java/android/view/ViewRootImpl.java +51 −10 Original line number Diff line number Diff line Loading @@ -1061,6 +1061,9 @@ public final class ViewRootImpl implements ViewParent, sToolkitSetFrameRateReadOnlyFlagValue = toolkitSetFrameRateReadOnly(); } // The latest input event from the gesture that was used to resolve the pointer icon. private MotionEvent mPointerIconEvent = null; public ViewRootImpl(Context context, Display display) { this(context, display, WindowManagerGlobal.getWindowSession(), new WindowLayout()); } Loading Loading @@ -6090,6 +6093,7 @@ public final class ViewRootImpl implements ViewParent, private static final int MSG_DECOR_VIEW_GESTURE_INTERCEPTION = 38; private static final int MSG_TOUCH_BOOST_TIMEOUT = 39; private static final int MSG_CHECK_INVALIDATION_IDLE = 40; private static final int MSG_REFRESH_POINTER_ICON = 41; final class ViewRootHandler extends Handler { @Override Loading Loading @@ -6155,6 +6159,8 @@ public final class ViewRootImpl implements ViewParent, return "MSG_WINDOW_TOUCH_MODE_CHANGED"; case MSG_KEEP_CLEAR_RECTS_CHANGED: return "MSG_KEEP_CLEAR_RECTS_CHANGED"; case MSG_REFRESH_POINTER_ICON: return "MSG_REFRESH_POINTER_ICON"; } return super.getMessageName(message); } Loading Loading @@ -6411,6 +6417,12 @@ public final class ViewRootImpl implements ViewParent, FRAME_RATE_IDLENESS_REEVALUATE_TIME); } break; case MSG_REFRESH_POINTER_ICON: if (mPointerIconEvent == null) { break; } updatePointerIcon(mPointerIconEvent); break; } } } Loading Loading @@ -7399,23 +7411,42 @@ public final class ViewRootImpl implements ViewParent, if (event.getPointerCount() != 1) { return; } final int action = event.getActionMasked(); final boolean needsStylusPointerIcon = event.isStylusPointer() && event.isHoverEvent() && mIsStylusPointerIconEnabled; if (needsStylusPointerIcon || event.isFromSource(InputDevice.SOURCE_MOUSE)) { if (event.getActionMasked() == MotionEvent.ACTION_HOVER_ENTER || event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT) { if (!needsStylusPointerIcon && !event.isFromSource(InputDevice.SOURCE_MOUSE)) { return; } if (action == MotionEvent.ACTION_HOVER_ENTER || action == MotionEvent.ACTION_HOVER_EXIT) { // Other apps or the window manager may change the icon type outside of // this app, therefore the icon type has to be reset on enter/exit event. mPointerIconType = null; } if (event.getActionMasked() != MotionEvent.ACTION_HOVER_EXIT) { if (!updatePointerIcon(event) && event.getActionMasked() == MotionEvent.ACTION_HOVER_MOVE) { if (action != MotionEvent.ACTION_HOVER_EXIT) { // Resolve the pointer icon if (!updatePointerIcon(event) && action == MotionEvent.ACTION_HOVER_MOVE) { mPointerIconType = null; } } // Keep track of the newest event used to resolve the pointer icon. switch (action) { case MotionEvent.ACTION_HOVER_EXIT: case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_CANCEL: if (mPointerIconEvent != null) { mPointerIconEvent.recycle(); } mPointerIconEvent = null; break; default: mPointerIconEvent = MotionEvent.obtain(event); break; } } Loading Loading @@ -7456,6 +7487,16 @@ public final class ViewRootImpl implements ViewParent, updatePointerIcon(event); } /** * If there is pointer that is showing a PointerIcon in this window, refresh the icon for that * pointer. This will resolve the PointerIcon through the view hierarchy. */ public void refreshPointerIcon() { mHandler.removeMessages(MSG_REFRESH_POINTER_ICON); mHandler.sendEmptyMessage(MSG_REFRESH_POINTER_ICON); } private boolean updatePointerIcon(MotionEvent event) { final int pointerIndex = 0; final float x = event.getX(pointerIndex); Loading Loading
core/java/android/view/View.java +14 −6 Original line number Diff line number Diff line Loading @@ -29901,6 +29901,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void setPointerIcon(PointerIcon pointerIcon) { mMousePointerIcon = pointerIcon; if (com.android.input.flags.Flags.enablePointerChoreographer()) { final ViewRootImpl viewRootImpl = getViewRootImpl(); if (viewRootImpl == null) { return; } viewRootImpl.refreshPointerIcon(); } else { if (mAttachInfo == null || mAttachInfo.mHandlingPointerEvent) { return; } Loading @@ -29909,6 +29916,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } catch (RemoteException e) { } } } /** * Gets the mouse pointer icon for the current view.
core/java/android/view/ViewRootImpl.java +51 −10 Original line number Diff line number Diff line Loading @@ -1061,6 +1061,9 @@ public final class ViewRootImpl implements ViewParent, sToolkitSetFrameRateReadOnlyFlagValue = toolkitSetFrameRateReadOnly(); } // The latest input event from the gesture that was used to resolve the pointer icon. private MotionEvent mPointerIconEvent = null; public ViewRootImpl(Context context, Display display) { this(context, display, WindowManagerGlobal.getWindowSession(), new WindowLayout()); } Loading Loading @@ -6090,6 +6093,7 @@ public final class ViewRootImpl implements ViewParent, private static final int MSG_DECOR_VIEW_GESTURE_INTERCEPTION = 38; private static final int MSG_TOUCH_BOOST_TIMEOUT = 39; private static final int MSG_CHECK_INVALIDATION_IDLE = 40; private static final int MSG_REFRESH_POINTER_ICON = 41; final class ViewRootHandler extends Handler { @Override Loading Loading @@ -6155,6 +6159,8 @@ public final class ViewRootImpl implements ViewParent, return "MSG_WINDOW_TOUCH_MODE_CHANGED"; case MSG_KEEP_CLEAR_RECTS_CHANGED: return "MSG_KEEP_CLEAR_RECTS_CHANGED"; case MSG_REFRESH_POINTER_ICON: return "MSG_REFRESH_POINTER_ICON"; } return super.getMessageName(message); } Loading Loading @@ -6411,6 +6417,12 @@ public final class ViewRootImpl implements ViewParent, FRAME_RATE_IDLENESS_REEVALUATE_TIME); } break; case MSG_REFRESH_POINTER_ICON: if (mPointerIconEvent == null) { break; } updatePointerIcon(mPointerIconEvent); break; } } } Loading Loading @@ -7399,23 +7411,42 @@ public final class ViewRootImpl implements ViewParent, if (event.getPointerCount() != 1) { return; } final int action = event.getActionMasked(); final boolean needsStylusPointerIcon = event.isStylusPointer() && event.isHoverEvent() && mIsStylusPointerIconEnabled; if (needsStylusPointerIcon || event.isFromSource(InputDevice.SOURCE_MOUSE)) { if (event.getActionMasked() == MotionEvent.ACTION_HOVER_ENTER || event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT) { if (!needsStylusPointerIcon && !event.isFromSource(InputDevice.SOURCE_MOUSE)) { return; } if (action == MotionEvent.ACTION_HOVER_ENTER || action == MotionEvent.ACTION_HOVER_EXIT) { // Other apps or the window manager may change the icon type outside of // this app, therefore the icon type has to be reset on enter/exit event. mPointerIconType = null; } if (event.getActionMasked() != MotionEvent.ACTION_HOVER_EXIT) { if (!updatePointerIcon(event) && event.getActionMasked() == MotionEvent.ACTION_HOVER_MOVE) { if (action != MotionEvent.ACTION_HOVER_EXIT) { // Resolve the pointer icon if (!updatePointerIcon(event) && action == MotionEvent.ACTION_HOVER_MOVE) { mPointerIconType = null; } } // Keep track of the newest event used to resolve the pointer icon. switch (action) { case MotionEvent.ACTION_HOVER_EXIT: case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_CANCEL: if (mPointerIconEvent != null) { mPointerIconEvent.recycle(); } mPointerIconEvent = null; break; default: mPointerIconEvent = MotionEvent.obtain(event); break; } } Loading Loading @@ -7456,6 +7487,16 @@ public final class ViewRootImpl implements ViewParent, updatePointerIcon(event); } /** * If there is pointer that is showing a PointerIcon in this window, refresh the icon for that * pointer. This will resolve the PointerIcon through the view hierarchy. */ public void refreshPointerIcon() { mHandler.removeMessages(MSG_REFRESH_POINTER_ICON); mHandler.sendEmptyMessage(MSG_REFRESH_POINTER_ICON); } private boolean updatePointerIcon(MotionEvent event) { final int pointerIndex = 0; final float x = event.getX(pointerIndex); Loading