diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl index c8b45c78c5b5f..c6ae14ea9bc1b 100644 --- a/core/java/android/hardware/input/IInputManager.aidl +++ b/core/java/android/hardware/input/IInputManager.aidl @@ -67,4 +67,6 @@ interface IInputManager { // Input device vibrator control. void vibrate(int deviceId, in long[] pattern, int repeat, IBinder token); void cancelVibrate(int deviceId, IBinder token); + + void setPointerIconShape(int shapeId); } diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index bae5757b03a70..3949d97e40889 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -757,6 +757,22 @@ public final class InputManager { } } + /** + * Changes the mouse pointer's icon shape into the specified id. + * + * @param iconId The id of the pointer graphic, as a value between + * {@link PointerIcon.STYLE_ARROW} and {@link PointerIcon.STYLE_GRABBING}. + * + * @hide + */ + public void setPointerIconShape(int iconId) { + try { + mIm.setPointerIconShape(iconId); + } catch (RemoteException ex) { + // Do nothing. + } + } + private void populateInputDevicesLocked() { if (mInputDevicesChangedListener == null) { final InputDevicesChangedListener listener = new InputDevicesChangedListener(); diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java index cc4598d16de9f..bae51d3b9d1f8 100644 --- a/core/java/android/view/InputDevice.java +++ b/core/java/android/view/InputDevice.java @@ -765,6 +765,15 @@ public final class InputDevice implements Parcelable { return mHasButtonUnderPad; } + /** + * Sets the current pointer shape. + * @param pointerShape the id of the pointer icon. + * @hide + */ + public void setPointerShape(int pointerShape) { + InputManager.getInstance().setPointerIconShape(pointerShape); + } + /** * Provides information about the range of values for a particular {@link MotionEvent} axis. * diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java index cf35ce534a976..88e9a952f778c 100644 --- a/core/java/android/view/PointerIcon.java +++ b/core/java/android/view/PointerIcon.java @@ -48,6 +48,12 @@ public final class PointerIcon implements Parcelable { /** Style constant: Null icon. It has no bitmap. */ public static final int STYLE_NULL = 0; + /** Style constant: no icons are specified. If all views uses this, then falls back + * to the default style, but this is helpful to distinguish a view explicitly want + * to have the default icon. + */ + public static final int STYLE_NOT_SPECIFIED = 1; + /** Style constant: Arrow icon. (Default mouse pointer) */ public static final int STYLE_ARROW = 1000; @@ -60,12 +66,74 @@ public final class PointerIcon implements Parcelable { /** {@hide} Style constant: Spot anchor icon for touchpads. */ public static final int STYLE_SPOT_ANCHOR = 2002; + // Style constants for additional predefined icons for mice. + /** Style constant: context-menu. */ + public static final int STYLE_CONTEXT_MENU = 1001; + + /** Style constant: hand. */ + public static final int STYLE_HAND = 1002; + + /** Style constant: help. */ + public static final int STYLE_HELP = 1003; + + /** Style constant: wait. */ + public static final int STYLE_WAIT = 1004; + + /** Style constant: cell. */ + public static final int STYLE_CELL = 1006; + + /** Style constant: crosshair. */ + public static final int STYLE_CROSSHAIR = 1007; + + /** Style constant: text. */ + public static final int STYLE_TEXT = 1008; + + /** Style constant: vertical-text. */ + public static final int STYLE_VERTICAL_TEXT = 1009; + + /** Style constant: alias (indicating an alias of/shortcut to something is + * to be created. */ + public static final int STYLE_ALIAS = 1010; + + /** Style constant: copy. */ + public static final int STYLE_COPY = 1011; + + /** Style constant: no-drop. */ + public static final int STYLE_NO_DROP = 1012; + + /** Style constant: all-scroll. */ + public static final int STYLE_ALL_SCROLL = 1013; + + /** Style constant: horizontal double arrow mainly for resizing. */ + public static final int STYLE_HORIZONTAL_DOUBLE_ARROW = 1014; + + /** Style constant: vertical double arrow mainly for resizing. */ + public static final int STYLE_VERTICAL_DOUBLE_ARROW = 1015; + + /** Style constant: diagonal double arrow -- top-right to bottom-left. */ + public static final int STYLE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW = 1016; + + /** Style constant: diagonal double arrow -- top-left to bottom-right. */ + public static final int STYLE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW = 1017; + + /** Style constant: zoom-in. */ + public static final int STYLE_ZOOM_IN = 1018; + + /** Style constant: zoom-out. */ + public static final int STYLE_ZOOM_OUT = 1019; + + /** Style constant: grab. */ + public static final int STYLE_GRAB = 1020; + + /** Style constant: grabbing. */ + public static final int STYLE_GRABBING = 1021; + // OEM private styles should be defined starting at this range to avoid // conflicts with any system styles that may be defined in the future. private static final int STYLE_OEM_FIRST = 10000; - // The default pointer icon. - private static final int STYLE_DEFAULT = STYLE_ARROW; + /** {@hide} The default pointer icon. */ + public static final int STYLE_DEFAULT = STYLE_ARROW; private static final PointerIcon gNullIcon = new PointerIcon(STYLE_NULL); @@ -434,6 +502,49 @@ public final class PointerIcon implements Parcelable { return com.android.internal.R.styleable.Pointer_pointerIconSpotTouch; case STYLE_SPOT_ANCHOR: return com.android.internal.R.styleable.Pointer_pointerIconSpotAnchor; + case STYLE_HAND: + return com.android.internal.R.styleable.Pointer_pointerIconHand; + case STYLE_CONTEXT_MENU: + return com.android.internal.R.styleable.Pointer_pointerIconContextMenu; + case STYLE_HELP: + return com.android.internal.R.styleable.Pointer_pointerIconHelp; + case STYLE_WAIT: + // falls back to the default icon because no animation support. + return com.android.internal.R.styleable.Pointer_pointerIconArrow; + case STYLE_CELL: + return com.android.internal.R.styleable.Pointer_pointerIconCell; + case STYLE_CROSSHAIR: + return com.android.internal.R.styleable.Pointer_pointerIconCrosshair; + case STYLE_TEXT: + return com.android.internal.R.styleable.Pointer_pointerIconText; + case STYLE_VERTICAL_TEXT: + return com.android.internal.R.styleable.Pointer_pointerIconVerticalText; + case STYLE_ALIAS: + return com.android.internal.R.styleable.Pointer_pointerIconAlias; + case STYLE_COPY: + return com.android.internal.R.styleable.Pointer_pointerIconCopy; + case STYLE_ALL_SCROLL: + return com.android.internal.R.styleable.Pointer_pointerIconAllScroll; + case STYLE_NO_DROP: + return com.android.internal.R.styleable.Pointer_pointerIconNodrop; + case STYLE_HORIZONTAL_DOUBLE_ARROW: + return com.android.internal.R.styleable.Pointer_pointerIconHorizontalDoubleArrow; + case STYLE_VERTICAL_DOUBLE_ARROW: + return com.android.internal.R.styleable.Pointer_pointerIconVerticalDoubleArrow; + case STYLE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW: + return com.android.internal.R.styleable. + Pointer_pointerIconTopRightDiagonalDoubleArrow; + case STYLE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW: + return com.android.internal.R.styleable. + Pointer_pointerIconTopLeftDiagonalDoubleArrow; + case STYLE_ZOOM_IN: + return com.android.internal.R.styleable.Pointer_pointerIconZoomIn; + case STYLE_ZOOM_OUT: + return com.android.internal.R.styleable.Pointer_pointerIconZoomOut; + case STYLE_GRAB: + return com.android.internal.R.styleable.Pointer_pointerIconGrab; + case STYLE_GRABBING: + return com.android.internal.R.styleable.Pointer_pointerIconGrabbing; default: return 0; } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 7752ed890dc06..4bc211220d363 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -20995,6 +20995,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } + /** @hide */ + public int getPointerShape(MotionEvent event, float x, float y) { + return PointerIcon.STYLE_NOT_SPECIFIED; + } + // // Properties // diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 475ce2feed508..44aabd2e739ef 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -1715,6 +1715,36 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return false; } + /** @hide */ + @Override + public int getPointerShape(MotionEvent event, float x, float y) { + // Check what the child under the pointer says about the pointer. + final int childrenCount = mChildrenCount; + if (childrenCount != 0) { + final ArrayList preorderedList = buildOrderedChildList(); + final boolean customOrder = preorderedList == null + && isChildrenDrawingOrderEnabled(); + final View[] children = mChildren; + for (int i = childrenCount - 1; i >= 0; i--) { + final int childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i; + final View child = (preorderedList == null) + ? children[childIndex] : preorderedList.get(childIndex); + PointF point = getLocalPoint(); + if (isTransformedTouchPointInView(x, y, child, point)) { + final int pointerShape = child.getPointerShape(event, point.x, point.y); + if (pointerShape != PointerIcon.STYLE_NOT_SPECIFIED) { + return pointerShape; + } + break; + } + } + } + + // The pointer is not a child or the child has no preferences, returning the default + // implementation. + return super.getPointerShape(event, x, y); + } + /** * {@inheritDoc} */ diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 3d10289ac8e9b..13b6a42e8d023 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -37,6 +37,7 @@ import android.graphics.Region; import android.graphics.drawable.Drawable; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; +import android.hardware.input.InputManager; import android.media.AudioManager; import android.os.Binder; import android.os.Build; @@ -324,6 +325,8 @@ public final class ViewRootImpl implements ViewParent, private long mFpsPrevTime = -1; private int mFpsNumFrames; + private int mPointerIconShape = PointerIcon.STYLE_NOT_SPECIFIED; + /** * see {@link #playSoundEffect(int)} */ @@ -4168,6 +4171,30 @@ public final class ViewRootImpl implements ViewParent, private int processPointerEvent(QueuedInputEvent q) { final MotionEvent event = (MotionEvent)q.mEvent; + if (event.getPointerCount() == 1 + && event.isFromSource(InputDevice.SOURCE_MOUSE)) { + if (event.getActionMasked() == MotionEvent.ACTION_HOVER_ENTER + || event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT) { + // Other apps or the window manager may change the icon shape outside of + // this app, therefore the icon shape has to be reset on enter/exit event. + mPointerIconShape = PointerIcon.STYLE_NOT_SPECIFIED; + } + + final float x = event.getX(); + final float y = event.getY(); + if (x >= 0 && x < mView.getWidth() && y >= 0 && y < mView.getHeight()) { + int pointerShape = mView.getPointerShape(event, x, y); + if (pointerShape == PointerIcon.STYLE_NOT_SPECIFIED) { + pointerShape = PointerIcon.STYLE_DEFAULT; + } + + if (mPointerIconShape != pointerShape) { + mPointerIconShape = pointerShape; + event.getDevice().setPointerShape(pointerShape); + } + } + } + mAttachInfo.mUnbufferedDispatchRequested = false; boolean handled = mView.dispatchPointerEvent(event); if (mAttachInfo.mUnbufferedDispatchRequested && !mUnbufferedInputDispatch) { diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 071205248c91e..1aeb9c938c0cc 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -116,6 +116,7 @@ import android.view.HapticFeedbackConstants; import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.MotionEvent; +import android.view.PointerIcon; import android.view.View; import android.view.ViewParent; import android.view.ViewStructure; @@ -5905,6 +5906,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return mLayout != null ? mLayout.getHeight() : 0; } + /** + * @hide + */ + @Override + public int getPointerShape(MotionEvent event, float x, float y) { + if (isTextSelectable() || isTextEditable()) { + return PointerIcon.STYLE_TEXT; + } + return super.getPointerShape(event, x, y); + } + @Override public boolean onKeyPreIme(int keyCode, KeyEvent event) { // Note: If the IME is in fullscreen mode and IMS#mExtractEditText is in text action mode, diff --git a/core/jni/android_view_PointerIcon.h b/core/jni/android_view_PointerIcon.h index 3bfd64526ad67..86f288d0d7114 100644 --- a/core/jni/android_view_PointerIcon.h +++ b/core/jni/android_view_PointerIcon.h @@ -31,6 +31,27 @@ enum { POINTER_ICON_STYLE_CUSTOM = -1, POINTER_ICON_STYLE_NULL = 0, POINTER_ICON_STYLE_ARROW = 1000, + POINTER_ICON_STYLE_CONTEXT_MENU = 1001, + POINTER_ICON_STYLE_HAND = 1002, + POINTER_ICON_STYLE_HELP = 1003, + POINTER_ICON_STYLE_WAIT = 1004, + POINTER_ICON_STYLE_CELL = 1006, + POINTER_ICON_STYLE_CROSSHAIR = 1007, + POINTER_ICON_STYLE_TEXT = 1008, + POINTER_ICON_STYLE_VERTICAL_TEXT = 1009, + POINTER_ICON_STYLE_ALIAS = 1010, + POINTER_ICON_STYLE_COPY = 1011, + POINTER_ICON_STYLE_NO_DROP = 1012, + POINTER_ICON_STYLE_ALL_SCROLL = 1013, + POINTER_ICON_STYLE_HORIZONTAL_DOUBLE_ARROW = 1014, + POINTER_ICON_STYLE_VERTICAL_DOUBLE_ARROW = 1015, + POINTER_ICON_STYLE_TOP_RIGHT_DOUBLE_ARROW = 1016, + POINTER_ICON_STYLE_TOP_LEFT_DOUBLE_ARROW = 1017, + POINTER_ICON_STYLE_ZOOM_IN = 1018, + POINTER_ICON_STYLE_ZOOM_OUT = 1019, + POINTER_ICON_STYLE_GRAB = 1020, + POINTER_ICON_STYLE_GRABBING = 1021, + POINTER_ICON_STYLE_SPOT_HOVER = 2000, POINTER_ICON_STYLE_SPOT_TOUCH = 2001, POINTER_ICON_STYLE_SPOT_ANCHOR = 2002, diff --git a/core/res/res/drawable-mdpi/pointer_alias.png b/core/res/res/drawable-mdpi/pointer_alias.png new file mode 100644 index 0000000000000..8f61a39dd2097 Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_alias.png differ diff --git a/core/res/res/drawable-mdpi/pointer_all_scroll.png b/core/res/res/drawable-mdpi/pointer_all_scroll.png new file mode 100644 index 0000000000000..a897ef4799a40 Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_all_scroll.png differ diff --git a/core/res/res/drawable-mdpi/pointer_cell.png b/core/res/res/drawable-mdpi/pointer_cell.png new file mode 100644 index 0000000000000..b5213890f0acb Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_cell.png differ diff --git a/core/res/res/drawable-mdpi/pointer_context_menu.png b/core/res/res/drawable-mdpi/pointer_context_menu.png new file mode 100644 index 0000000000000..4e1ba4ef3fbe4 Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_context_menu.png differ diff --git a/core/res/res/drawable-mdpi/pointer_copy.png b/core/res/res/drawable-mdpi/pointer_copy.png new file mode 100644 index 0000000000000..7d41036138c42 Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_copy.png differ diff --git a/core/res/res/drawable-mdpi/pointer_crosshair.png b/core/res/res/drawable-mdpi/pointer_crosshair.png new file mode 100644 index 0000000000000..8a06c773de7ee Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_crosshair.png differ diff --git a/core/res/res/drawable-mdpi/pointer_grab.png b/core/res/res/drawable-mdpi/pointer_grab.png new file mode 100644 index 0000000000000..0e0ea2eff0720 Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_grab.png differ diff --git a/core/res/res/drawable-mdpi/pointer_grabbing.png b/core/res/res/drawable-mdpi/pointer_grabbing.png new file mode 100644 index 0000000000000..9deb64cb108d1 Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_grabbing.png differ diff --git a/core/res/res/drawable-mdpi/pointer_hand.png b/core/res/res/drawable-mdpi/pointer_hand.png new file mode 100644 index 0000000000000..c614d9ebce7ff Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_hand.png differ diff --git a/core/res/res/drawable-mdpi/pointer_help.png b/core/res/res/drawable-mdpi/pointer_help.png new file mode 100644 index 0000000000000..d54b2b109bbde Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_help.png differ diff --git a/core/res/res/drawable-mdpi/pointer_horizontal_double_arrow.png b/core/res/res/drawable-mdpi/pointer_horizontal_double_arrow.png new file mode 100644 index 0000000000000..a2951a9ef0770 Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_horizontal_double_arrow.png differ diff --git a/core/res/res/drawable-mdpi/pointer_nodrop.png b/core/res/res/drawable-mdpi/pointer_nodrop.png new file mode 100644 index 0000000000000..ad13c663d3284 Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_nodrop.png differ diff --git a/core/res/res/drawable-mdpi/pointer_text.png b/core/res/res/drawable-mdpi/pointer_text.png new file mode 100644 index 0000000000000..34d1698c6ff12 Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_text.png differ diff --git a/core/res/res/drawable-mdpi/pointer_top_left_diagonal_double_arrow.png b/core/res/res/drawable-mdpi/pointer_top_left_diagonal_double_arrow.png new file mode 100644 index 0000000000000..b0cd92ced9a94 Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_top_left_diagonal_double_arrow.png differ diff --git a/core/res/res/drawable-mdpi/pointer_top_right_diagonal_double_arrow.png b/core/res/res/drawable-mdpi/pointer_top_right_diagonal_double_arrow.png new file mode 100644 index 0000000000000..f8d3527fcd0a9 Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_top_right_diagonal_double_arrow.png differ diff --git a/core/res/res/drawable-mdpi/pointer_vertical_double_arrow.png b/core/res/res/drawable-mdpi/pointer_vertical_double_arrow.png new file mode 100644 index 0000000000000..48c93798714e0 Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_vertical_double_arrow.png differ diff --git a/core/res/res/drawable-mdpi/pointer_vertical_text.png b/core/res/res/drawable-mdpi/pointer_vertical_text.png new file mode 100644 index 0000000000000..9fcbcba808670 Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_vertical_text.png differ diff --git a/core/res/res/drawable-mdpi/pointer_zoom_in.png b/core/res/res/drawable-mdpi/pointer_zoom_in.png new file mode 100644 index 0000000000000..17c4e664f41c4 Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_zoom_in.png differ diff --git a/core/res/res/drawable-mdpi/pointer_zoom_out.png b/core/res/res/drawable-mdpi/pointer_zoom_out.png new file mode 100644 index 0000000000000..742f705960bb3 Binary files /dev/null and b/core/res/res/drawable-mdpi/pointer_zoom_out.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_alias.png b/core/res/res/drawable-xhdpi/pointer_alias.png new file mode 100644 index 0000000000000..fe0fd25d14469 Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_alias.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_all_scroll.png b/core/res/res/drawable-xhdpi/pointer_all_scroll.png new file mode 100644 index 0000000000000..e2374ece10678 Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_all_scroll.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_cell.png b/core/res/res/drawable-xhdpi/pointer_cell.png new file mode 100644 index 0000000000000..4ca09e3229a26 Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_cell.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_context_menu.png b/core/res/res/drawable-xhdpi/pointer_context_menu.png new file mode 100644 index 0000000000000..05a59f8c9690c Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_context_menu.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_copy.png b/core/res/res/drawable-xhdpi/pointer_copy.png new file mode 100644 index 0000000000000..f28a3e9e923d7 Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_copy.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_crosshair.png b/core/res/res/drawable-xhdpi/pointer_crosshair.png new file mode 100644 index 0000000000000..86c649c1a1bc0 Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_crosshair.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_grab.png b/core/res/res/drawable-xhdpi/pointer_grab.png new file mode 100644 index 0000000000000..b5c28ba159804 Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_grab.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_grabbing.png b/core/res/res/drawable-xhdpi/pointer_grabbing.png new file mode 100644 index 0000000000000..6aba589f92356 Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_grabbing.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_hand.png b/core/res/res/drawable-xhdpi/pointer_hand.png new file mode 100644 index 0000000000000..486cb24f09658 Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_hand.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_help.png b/core/res/res/drawable-xhdpi/pointer_help.png new file mode 100644 index 0000000000000..98a66322887a8 Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_help.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_horizontal_double_arrow.png b/core/res/res/drawable-xhdpi/pointer_horizontal_double_arrow.png new file mode 100644 index 0000000000000..299ae1198b7f4 Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_horizontal_double_arrow.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_nodrop.png b/core/res/res/drawable-xhdpi/pointer_nodrop.png new file mode 100644 index 0000000000000..c56bfbb89a729 Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_nodrop.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_text.png b/core/res/res/drawable-xhdpi/pointer_text.png new file mode 100644 index 0000000000000..0cebeae84cc9d Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_text.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_top_left_diagonal_double_arrow.png b/core/res/res/drawable-xhdpi/pointer_top_left_diagonal_double_arrow.png new file mode 100644 index 0000000000000..5454a8ba5ccbf Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_top_left_diagonal_double_arrow.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_top_right_diagonal_double_arrow.png b/core/res/res/drawable-xhdpi/pointer_top_right_diagonal_double_arrow.png new file mode 100644 index 0000000000000..a4268e4c3be4a Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_top_right_diagonal_double_arrow.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_vertical_double_arrow.png b/core/res/res/drawable-xhdpi/pointer_vertical_double_arrow.png new file mode 100644 index 0000000000000..95ca954d5d711 Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_vertical_double_arrow.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_vertical_text.png b/core/res/res/drawable-xhdpi/pointer_vertical_text.png new file mode 100644 index 0000000000000..a07d091395a2c Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_vertical_text.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_zoom_in.png b/core/res/res/drawable-xhdpi/pointer_zoom_in.png new file mode 100644 index 0000000000000..9c29fcb528c49 Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_zoom_in.png differ diff --git a/core/res/res/drawable-xhdpi/pointer_zoom_out.png b/core/res/res/drawable-xhdpi/pointer_zoom_out.png new file mode 100644 index 0000000000000..710552b66fbcc Binary files /dev/null and b/core/res/res/drawable-xhdpi/pointer_zoom_out.png differ diff --git a/core/res/res/drawable/pointer_alias_icon.xml b/core/res/res/drawable/pointer_alias_icon.xml new file mode 100644 index 0000000000000..8ba930165b48b --- /dev/null +++ b/core/res/res/drawable/pointer_alias_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_all_scroll_icon.xml b/core/res/res/drawable/pointer_all_scroll_icon.xml new file mode 100644 index 0000000000000..e9469488be3ac --- /dev/null +++ b/core/res/res/drawable/pointer_all_scroll_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_cell_icon.xml b/core/res/res/drawable/pointer_cell_icon.xml new file mode 100644 index 0000000000000..da1e320c1d711 --- /dev/null +++ b/core/res/res/drawable/pointer_cell_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_context_menu_icon.xml b/core/res/res/drawable/pointer_context_menu_icon.xml new file mode 100644 index 0000000000000..330b627b5d02c --- /dev/null +++ b/core/res/res/drawable/pointer_context_menu_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_copy_icon.xml b/core/res/res/drawable/pointer_copy_icon.xml new file mode 100644 index 0000000000000..e299db5b23b59 --- /dev/null +++ b/core/res/res/drawable/pointer_copy_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_crosshair_icon.xml b/core/res/res/drawable/pointer_crosshair_icon.xml new file mode 100644 index 0000000000000..3b96a8ad3ace1 --- /dev/null +++ b/core/res/res/drawable/pointer_crosshair_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_grab_icon.xml b/core/res/res/drawable/pointer_grab_icon.xml new file mode 100644 index 0000000000000..d437b3a7bf8a2 --- /dev/null +++ b/core/res/res/drawable/pointer_grab_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_grabbing_icon.xml b/core/res/res/drawable/pointer_grabbing_icon.xml new file mode 100644 index 0000000000000..38f4c3a064fa4 --- /dev/null +++ b/core/res/res/drawable/pointer_grabbing_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_hand_icon.xml b/core/res/res/drawable/pointer_hand_icon.xml new file mode 100644 index 0000000000000..3d90b88d5dca5 --- /dev/null +++ b/core/res/res/drawable/pointer_hand_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_help_icon.xml b/core/res/res/drawable/pointer_help_icon.xml new file mode 100644 index 0000000000000..49ae554249f81 --- /dev/null +++ b/core/res/res/drawable/pointer_help_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_horizontal_double_arrow_icon.xml b/core/res/res/drawable/pointer_horizontal_double_arrow_icon.xml new file mode 100644 index 0000000000000..5a5ad9e62657f --- /dev/null +++ b/core/res/res/drawable/pointer_horizontal_double_arrow_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_nodrop_icon.xml b/core/res/res/drawable/pointer_nodrop_icon.xml new file mode 100644 index 0000000000000..955b40f2d567a --- /dev/null +++ b/core/res/res/drawable/pointer_nodrop_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_text_icon.xml b/core/res/res/drawable/pointer_text_icon.xml new file mode 100644 index 0000000000000..d948c8916963b --- /dev/null +++ b/core/res/res/drawable/pointer_text_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_top_left_diagonal_double_arrow_icon.xml b/core/res/res/drawable/pointer_top_left_diagonal_double_arrow_icon.xml new file mode 100644 index 0000000000000..de5efe25dae21 --- /dev/null +++ b/core/res/res/drawable/pointer_top_left_diagonal_double_arrow_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_top_right_diagonal_double_arrow_icon.xml b/core/res/res/drawable/pointer_top_right_diagonal_double_arrow_icon.xml new file mode 100644 index 0000000000000..e87b526864263 --- /dev/null +++ b/core/res/res/drawable/pointer_top_right_diagonal_double_arrow_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_vertical_double_arrow_icon.xml b/core/res/res/drawable/pointer_vertical_double_arrow_icon.xml new file mode 100644 index 0000000000000..5759079a47fa0 --- /dev/null +++ b/core/res/res/drawable/pointer_vertical_double_arrow_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_vertical_text_icon.xml b/core/res/res/drawable/pointer_vertical_text_icon.xml new file mode 100644 index 0000000000000..3b48dc89fb563 --- /dev/null +++ b/core/res/res/drawable/pointer_vertical_text_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_zoom_in_icon.xml b/core/res/res/drawable/pointer_zoom_in_icon.xml new file mode 100644 index 0000000000000..e2dcb49c16002 --- /dev/null +++ b/core/res/res/drawable/pointer_zoom_in_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/drawable/pointer_zoom_out_icon.xml b/core/res/res/drawable/pointer_zoom_out_icon.xml new file mode 100644 index 0000000000000..b805df3d18c12 --- /dev/null +++ b/core/res/res/drawable/pointer_zoom_out_icon.xml @@ -0,0 +1,5 @@ + + diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index a6eb68b73baa4..b818fe0a3e1a4 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -7605,6 +7605,44 @@ i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 11c4cc01ee82f..b831df827a8c8 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -1336,6 +1336,33 @@ please see styles_device_defaults.xml. @drawable/pointer_spot_hover_icon @drawable/pointer_spot_touch_icon @drawable/pointer_spot_anchor_icon + @drawable/pointer_hand_icon + @drawable/pointer_context_menu_icon + @drawable/pointer_help_icon + @drawable/pointer_cell_icon + @drawable/pointer_crosshair_icon + @drawable/pointer_text_icon + @drawable/pointer_vertical_text_icon + @drawable/pointer_alias_icon + @drawable/pointer_copy_icon + @drawable/pointer_all_scroll_icon + @drawable/pointer_nodrop_icon + + @drawable/pointer_horizontal_double_arrow_icon + + + @drawable/pointer_vertical_double_arrow_icon + + + @drawable/pointer_top_right_diagonal_double_arrow_icon + + + @drawable/pointer_top_left_diagonal_double_arrow_icon + + @drawable/pointer_zoom_in_icon + @drawable/pointer_zoom_out_icon + @drawable/pointer_grab_icon + @drawable/pointer_grabbing_icon diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp index 11527378f586e..0f86bc614b2bd 100644 --- a/libs/input/PointerController.cpp +++ b/libs/input/PointerController.cpp @@ -78,6 +78,7 @@ PointerController::PointerController(const sp& mLocked.pointerAlpha = 0.0f; // pointer is initially faded mLocked.pointerSprite = mSpriteController->createSprite(); mLocked.pointerIconChanged = false; + mLocked.requestedPointerShape = 0; mLocked.buttonState = 0; @@ -231,6 +232,10 @@ void PointerController::unfade(Transition transition) { void PointerController::setPresentation(Presentation presentation) { AutoMutex _l(mLock); + if (presentation == PRESENTATION_POINTER && mLocked.additionalMouseResources.empty()) { + mPolicy->loadAdditionalMouseResources(&mLocked.additionalMouseResources); + } + if (mLocked.presentation != presentation) { mLocked.presentation = presentation; mLocked.presentationChanged = true; @@ -391,6 +396,15 @@ void PointerController::setDisplayViewport(int32_t width, int32_t height, int32_ updatePointerLocked(); } +void PointerController::updatePointerShape(int iconId) { + AutoMutex _l(mLock); + if (mLocked.requestedPointerShape != iconId) { + mLocked.requestedPointerShape = iconId; + mLocked.presentationChanged = true; + updatePointerLocked(); + } +} + void PointerController::setPointerIcon(const SpriteIcon& icon) { AutoMutex _l(mLock); @@ -497,8 +511,22 @@ void PointerController::updatePointerLocked() { } if (mLocked.pointerIconChanged || mLocked.presentationChanged) { - mLocked.pointerSprite->setIcon(mLocked.presentation == PRESENTATION_POINTER - ? mLocked.pointerIcon : mResources.spotAnchor); + if (mLocked.presentation == PRESENTATION_POINTER) { + if (mLocked.requestedPointerShape == 0) { + mLocked.pointerSprite->setIcon(mLocked.pointerIcon); + } else { + std::map::const_iterator iter = + mLocked.additionalMouseResources.find(mLocked.requestedPointerShape); + if (iter != mLocked.additionalMouseResources.end()) { + mLocked.pointerSprite->setIcon(iter->second); + } else { + ALOGW("Can't find the resource for icon id %d", mLocked.requestedPointerShape); + mLocked.pointerSprite->setIcon(mLocked.pointerIcon); + } + } + } else { + mLocked.pointerSprite->setIcon(mResources.spotAnchor); + } mLocked.pointerIconChanged = false; mLocked.presentationChanged = false; } diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h index b9e4ce7e7ed01..308ff12420640 100644 --- a/libs/input/PointerController.h +++ b/libs/input/PointerController.h @@ -19,6 +19,8 @@ #include "SpriteController.h" +#include + #include #include #include @@ -40,7 +42,6 @@ struct PointerResources { SpriteIcon spotAnchor; }; - /* * Pointer controller policy interface. * @@ -57,6 +58,7 @@ protected: public: virtual void loadPointerResources(PointerResources* outResources) = 0; + virtual void loadAdditionalMouseResources(std::map* outResources) = 0; }; @@ -93,6 +95,7 @@ public: const uint32_t* spotIdToIndex, BitSet32 spotIdBits); virtual void clearSpots(); + void updatePointerShape(int iconId); void setDisplayViewport(int32_t width, int32_t height, int32_t orientation); void setPointerIcon(const SpriteIcon& icon); void setInactivityTimeout(InactivityTimeout inactivityTimeout); @@ -155,6 +158,10 @@ private: SpriteIcon pointerIcon; bool pointerIconChanged; + std::map additionalMouseResources; + + int32_t requestedPointerShape; + int32_t buttonState; Vector spots; diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 5a136729291ac..5b40375007c15 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -206,6 +206,7 @@ public class InputManagerService extends IInputManager.Stub private static native void nativeReloadDeviceAliases(long ptr); private static native String nativeDump(long ptr); private static native void nativeMonitor(long ptr); + private static native void nativeSetPointerIconShape(long ptr, int iconId); // Input event injection constants defined in InputDispatcher.h. private static final int INPUT_EVENT_INJECTION_SUCCEEDED = 0; @@ -1407,6 +1408,12 @@ public class InputManagerService extends IInputManager.Stub } } + // Binder call + @Override + public void setPointerIconShape(int iconId) { + nativeSetPointerIconShape(mPtr, iconId); + } + @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP) diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 1d4f047ff605b..8cb0a1310ec52 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -199,6 +199,7 @@ public: void setShowTouches(bool enabled); void setInteractive(bool interactive); void reloadCalibration(); + void setPointerIconShape(int32_t iconId); /* --- InputReaderPolicyInterface implementation --- */ @@ -237,6 +238,7 @@ public: /* --- PointerControllerPolicyInterface implementation --- */ virtual void loadPointerResources(PointerResources* outResources); + virtual void loadAdditionalMouseResources(std::map* outResources); private: sp mInputManager; @@ -779,6 +781,15 @@ void NativeInputManager::reloadCalibration() { InputReaderConfiguration::CHANGE_TOUCH_AFFINE_TRANSFORMATION); } +void NativeInputManager::setPointerIconShape(int32_t iconId) { + AutoMutex _l(mLock); + sp controller = mLocked.pointerController.promote(); + if (controller != NULL) { + // Use 0 (the default icon) for ARROW. + controller->updatePointerShape((iconId == POINTER_ICON_STYLE_ARROW) ? 0 : iconId); + } +} + TouchAffineTransformation NativeInputManager::getTouchAffineTransformation( JNIEnv *env, jfloatArray matrixArr) { ScopedFloatArrayRO matrix(env, matrixArr); @@ -1029,6 +1040,15 @@ void NativeInputManager::loadPointerResources(PointerResources* outResources) { &outResources->spotAnchor); } +void NativeInputManager::loadAdditionalMouseResources(std::map* outResources) { + JNIEnv* env = jniEnv(); + + for (int iconId = POINTER_ICON_STYLE_CONTEXT_MENU; iconId <= POINTER_ICON_STYLE_GRABBING; + ++iconId) { + loadSystemIconAsSprite(env, mContextObj, iconId, &((*outResources)[iconId])); + } +} + // ---------------------------------------------------------------------------- @@ -1367,6 +1387,11 @@ static void nativeMonitor(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) { im->getInputManager()->getDispatcher()->monitor(); } +static void nativeSetPointerIconShape(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jint iconId) { + NativeInputManager* im = reinterpret_cast(ptr); + im->setPointerIconShape(iconId); +} + // ---------------------------------------------------------------------------- static const JNINativeMethod gInputManagerMethods[] = { @@ -1425,6 +1450,8 @@ static const JNINativeMethod gInputManagerMethods[] = { (void*) nativeDump }, { "nativeMonitor", "(J)V", (void*) nativeMonitor }, + { "nativeSetPointerIconShape", "(JI)V", + (void*) nativeSetPointerIconShape }, }; #define FIND_CLASS(var, className) \