summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt18
-rw-r--r--api/system-current.txt18
-rw-r--r--core/java/android/app/AssistStructure.java11
-rw-r--r--core/java/android/view/HapticFeedbackConstants.java5
-rw-r--r--core/java/android/view/MotionEvent.java12
-rw-r--r--core/java/android/view/View.java181
-rw-r--r--core/java/android/view/ViewAssistStructure.java2
-rw-r--r--core/java/android/view/accessibility/AccessibilityEvent.java14
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java34
-rw-r--r--core/res/res/values/attrs.xml5
-rwxr-xr-xcore/res/res/values/config.xml8
-rw-r--r--core/res/res/values/ids.xml3
-rw-r--r--core/res/res/values/public.xml2
-rwxr-xr-xcore/res/res/values/symbols.xml1
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java8
15 files changed, 314 insertions, 8 deletions
diff --git a/api/current.txt b/api/current.txt
index 1ffa5aa..fc869ad 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1173,6 +1173,7 @@ package android {
field public static final int strokeLineJoin = 16843788; // 0x101040c
field public static final int strokeMiterLimit = 16843789; // 0x101040d
field public static final int strokeWidth = 16843783; // 0x1010407
+ field public static final int stylusButtonPressable = 16844020; // 0x10104f4
field public static final int submitBackground = 16843912; // 0x1010488
field public static final int subtitle = 16843473; // 0x10102d1
field public static final int subtitleTextAppearance = 16843823; // 0x101042f
@@ -1686,6 +1687,7 @@ package android {
ctor public R.id();
field public static final int accessibilityActionScrollToPosition = 16908342; // 0x1020036
field public static final int accessibilityActionShowOnScreen = 16908341; // 0x1020035
+ field public static final int accessibilityActionStylusButtonPress = 16908344; // 0x1020038
field public static final int addToDictionary = 16908330; // 0x102002a
field public static final int background = 16908288; // 0x1020000
field public static final int button1 = 16908313; // 0x1020019
@@ -4079,6 +4081,7 @@ package android.app {
method public boolean isFocused();
method public boolean isLongClickable();
method public boolean isSelected();
+ method public boolean isStylusButtonPressable();
field public static final int TEXT_COLOR_UNDEFINED = 1; // 0x1
field public static final int TEXT_STYLE_BOLD = 1; // 0x1
field public static final int TEXT_STYLE_ITALIC = 2; // 0x2
@@ -34874,6 +34877,7 @@ package android.view {
field public static final int FLAG_IGNORE_VIEW_SETTING = 1; // 0x1
field public static final int KEYBOARD_TAP = 3; // 0x3
field public static final int LONG_PRESS = 0; // 0x0
+ field public static final int STYLUS_BUTTON_PRESS = 6; // 0x6
field public static final int VIRTUAL_KEY = 1; // 0x1
}
@@ -35606,6 +35610,7 @@ package android.view {
method public final float getY(int);
method public final float getYPrecision();
method public final boolean isButtonPressed(int);
+ method public final boolean isStylusButtonPressed();
method public static android.view.MotionEvent obtain(long, long, int, int, android.view.MotionEvent.PointerProperties[], android.view.MotionEvent.PointerCoords[], int, int, float, float, int, int, int, int);
method public static deprecated android.view.MotionEvent obtain(long, long, int, int, int[], android.view.MotionEvent.PointerCoords[], int, float, float, int, int, int, int);
method public static android.view.MotionEvent obtain(long, long, int, float, float, float, float, int, float, float, int, int);
@@ -36210,6 +36215,7 @@ package android.view {
method public boolean isSelected();
method public boolean isShown();
method public boolean isSoundEffectsEnabled();
+ method public boolean isStylusButtonPressable();
method public boolean isTextAlignmentResolved();
method public boolean isTextDirectionResolved();
method public boolean isVerticalFadingEdgeEnabled();
@@ -36277,6 +36283,7 @@ package android.view {
method public boolean performHapticFeedback(int);
method public boolean performHapticFeedback(int, int);
method public boolean performLongClick();
+ method public boolean performStylusButtonPress();
method public void playSoundEffect(int);
method public boolean post(java.lang.Runnable);
method public boolean postDelayed(java.lang.Runnable, long);
@@ -36380,6 +36387,7 @@ package android.view {
method public void setOnKeyListener(android.view.View.OnKeyListener);
method public void setOnLongClickListener(android.view.View.OnLongClickListener);
method public void setOnScrollChangeListener(android.view.View.OnScrollChangeListener);
+ method public void setOnStylusButtonPressListener(android.view.View.OnStylusButtonPressListener);
method public void setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener);
method public void setOnTouchListener(android.view.View.OnTouchListener);
method public void setOutlineProvider(android.view.ViewOutlineProvider);
@@ -36408,6 +36416,7 @@ package android.view {
method public void setSelected(boolean);
method public void setSoundEffectsEnabled(boolean);
method public void setStateListAnimator(android.animation.StateListAnimator);
+ method public void setStylusButtonPressable(boolean);
method public void setSystemUiVisibility(int);
method public void setTag(java.lang.Object);
method public void setTag(int, java.lang.Object);
@@ -36655,6 +36664,10 @@ package android.view {
method public abstract void onScrollChange(android.view.View, int, int, int, int);
}
+ public static abstract interface View.OnStylusButtonPressListener {
+ method public abstract boolean onStylusButtonPress(android.view.View);
+ }
+
public static abstract interface View.OnSystemUiVisibilityChangeListener {
method public abstract void onSystemUiVisibilityChange(int);
}
@@ -36696,6 +36709,7 @@ package android.view {
method public abstract void setId(int, java.lang.String, java.lang.String, java.lang.String);
method public abstract void setLongClickable(boolean);
method public abstract void setSelected(boolean);
+ method public abstract void setStylusButtonPressable(boolean);
method public abstract void setText(java.lang.CharSequence);
method public abstract void setText(java.lang.CharSequence, int, int);
method public abstract void setTextPaint(android.text.TextPaint);
@@ -37581,6 +37595,7 @@ package android.view.accessibility {
field public static final int TYPE_VIEW_LONG_CLICKED = 2; // 0x2
field public static final int TYPE_VIEW_SCROLLED = 4096; // 0x1000
field public static final int TYPE_VIEW_SELECTED = 4; // 0x4
+ field public static final int TYPE_VIEW_STYLUS_BUTTON_PRESSED = 8388608; // 0x800000
field public static final int TYPE_VIEW_TEXT_CHANGED = 16; // 0x10
field public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192; // 0x2000
field public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072; // 0x20000
@@ -37671,6 +37686,7 @@ package android.view.accessibility {
method public boolean isPassword();
method public boolean isScrollable();
method public boolean isSelected();
+ method public boolean isStylusButtonPressable();
method public boolean isVisibleToUser();
method public static android.view.accessibility.AccessibilityNodeInfo obtain(android.view.View);
method public static android.view.accessibility.AccessibilityNodeInfo obtain(android.view.View, int);
@@ -37721,6 +37737,7 @@ package android.view.accessibility {
method public void setSelected(boolean);
method public void setSource(android.view.View);
method public void setSource(android.view.View, int);
+ method public void setStylusButtonPressable(boolean);
method public void setText(java.lang.CharSequence);
method public void setTextSelection(int, int);
method public void setTraversalAfter(android.view.View);
@@ -37798,6 +37815,7 @@ package android.view.accessibility {
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SET_SELECTION;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SET_TEXT;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SHOW_ON_SCREEN;
+ field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_STYLUS_BUTTON_PRESS;
}
public static final class AccessibilityNodeInfo.CollectionInfo {
diff --git a/api/system-current.txt b/api/system-current.txt
index 15989b3..5416ef6 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1248,6 +1248,7 @@ package android {
field public static final int strokeLineJoin = 16843788; // 0x101040c
field public static final int strokeMiterLimit = 16843789; // 0x101040d
field public static final int strokeWidth = 16843783; // 0x1010407
+ field public static final int stylusButtonPressable = 16844020; // 0x10104f4
field public static final int submitBackground = 16843912; // 0x1010488
field public static final int subtitle = 16843473; // 0x10102d1
field public static final int subtitleTextAppearance = 16843823; // 0x101042f
@@ -1761,6 +1762,7 @@ package android {
ctor public R.id();
field public static final int accessibilityActionScrollToPosition = 16908342; // 0x1020036
field public static final int accessibilityActionShowOnScreen = 16908341; // 0x1020035
+ field public static final int accessibilityActionStylusButtonPress = 16908344; // 0x1020038
field public static final int addToDictionary = 16908330; // 0x102002a
field public static final int background = 16908288; // 0x1020000
field public static final int button1 = 16908313; // 0x1020019
@@ -4169,6 +4171,7 @@ package android.app {
method public boolean isFocused();
method public boolean isLongClickable();
method public boolean isSelected();
+ method public boolean isStylusButtonPressable();
field public static final int TEXT_COLOR_UNDEFINED = 1; // 0x1
field public static final int TEXT_STYLE_BOLD = 1; // 0x1
field public static final int TEXT_STYLE_ITALIC = 2; // 0x2
@@ -37084,6 +37087,7 @@ package android.view {
field public static final int FLAG_IGNORE_VIEW_SETTING = 1; // 0x1
field public static final int KEYBOARD_TAP = 3; // 0x3
field public static final int LONG_PRESS = 0; // 0x0
+ field public static final int STYLUS_BUTTON_PRESS = 6; // 0x6
field public static final int VIRTUAL_KEY = 1; // 0x1
}
@@ -37816,6 +37820,7 @@ package android.view {
method public final float getY(int);
method public final float getYPrecision();
method public final boolean isButtonPressed(int);
+ method public final boolean isStylusButtonPressed();
method public static android.view.MotionEvent obtain(long, long, int, int, android.view.MotionEvent.PointerProperties[], android.view.MotionEvent.PointerCoords[], int, int, float, float, int, int, int, int);
method public static deprecated android.view.MotionEvent obtain(long, long, int, int, int[], android.view.MotionEvent.PointerCoords[], int, float, float, int, int, int, int);
method public static android.view.MotionEvent obtain(long, long, int, float, float, float, float, int, float, float, int, int);
@@ -38420,6 +38425,7 @@ package android.view {
method public boolean isSelected();
method public boolean isShown();
method public boolean isSoundEffectsEnabled();
+ method public boolean isStylusButtonPressable();
method public boolean isTextAlignmentResolved();
method public boolean isTextDirectionResolved();
method public boolean isVerticalFadingEdgeEnabled();
@@ -38487,6 +38493,7 @@ package android.view {
method public boolean performHapticFeedback(int);
method public boolean performHapticFeedback(int, int);
method public boolean performLongClick();
+ method public boolean performStylusButtonPress();
method public void playSoundEffect(int);
method public boolean post(java.lang.Runnable);
method public boolean postDelayed(java.lang.Runnable, long);
@@ -38590,6 +38597,7 @@ package android.view {
method public void setOnKeyListener(android.view.View.OnKeyListener);
method public void setOnLongClickListener(android.view.View.OnLongClickListener);
method public void setOnScrollChangeListener(android.view.View.OnScrollChangeListener);
+ method public void setOnStylusButtonPressListener(android.view.View.OnStylusButtonPressListener);
method public void setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener);
method public void setOnTouchListener(android.view.View.OnTouchListener);
method public void setOutlineProvider(android.view.ViewOutlineProvider);
@@ -38618,6 +38626,7 @@ package android.view {
method public void setSelected(boolean);
method public void setSoundEffectsEnabled(boolean);
method public void setStateListAnimator(android.animation.StateListAnimator);
+ method public void setStylusButtonPressable(boolean);
method public void setSystemUiVisibility(int);
method public void setTag(java.lang.Object);
method public void setTag(int, java.lang.Object);
@@ -38865,6 +38874,10 @@ package android.view {
method public abstract void onScrollChange(android.view.View, int, int, int, int);
}
+ public static abstract interface View.OnStylusButtonPressListener {
+ method public abstract boolean onStylusButtonPress(android.view.View);
+ }
+
public static abstract interface View.OnSystemUiVisibilityChangeListener {
method public abstract void onSystemUiVisibilityChange(int);
}
@@ -38906,6 +38919,7 @@ package android.view {
method public abstract void setId(int, java.lang.String, java.lang.String, java.lang.String);
method public abstract void setLongClickable(boolean);
method public abstract void setSelected(boolean);
+ method public abstract void setStylusButtonPressable(boolean);
method public abstract void setText(java.lang.CharSequence);
method public abstract void setText(java.lang.CharSequence, int, int);
method public abstract void setTextPaint(android.text.TextPaint);
@@ -39794,6 +39808,7 @@ package android.view.accessibility {
field public static final int TYPE_VIEW_LONG_CLICKED = 2; // 0x2
field public static final int TYPE_VIEW_SCROLLED = 4096; // 0x1000
field public static final int TYPE_VIEW_SELECTED = 4; // 0x4
+ field public static final int TYPE_VIEW_STYLUS_BUTTON_PRESSED = 8388608; // 0x800000
field public static final int TYPE_VIEW_TEXT_CHANGED = 16; // 0x10
field public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192; // 0x2000
field public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072; // 0x20000
@@ -39884,6 +39899,7 @@ package android.view.accessibility {
method public boolean isPassword();
method public boolean isScrollable();
method public boolean isSelected();
+ method public boolean isStylusButtonPressable();
method public boolean isVisibleToUser();
method public static android.view.accessibility.AccessibilityNodeInfo obtain(android.view.View);
method public static android.view.accessibility.AccessibilityNodeInfo obtain(android.view.View, int);
@@ -39934,6 +39950,7 @@ package android.view.accessibility {
method public void setSelected(boolean);
method public void setSource(android.view.View);
method public void setSource(android.view.View, int);
+ method public void setStylusButtonPressable(boolean);
method public void setText(java.lang.CharSequence);
method public void setTextSelection(int, int);
method public void setTraversalAfter(android.view.View);
@@ -40011,6 +40028,7 @@ package android.view.accessibility {
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SET_SELECTION;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SET_TEXT;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SHOW_ON_SCREEN;
+ field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_STYLUS_BUTTON_PRESS;
}
public static final class AccessibilityNodeInfo.CollectionInfo {
diff --git a/core/java/android/app/AssistStructure.java b/core/java/android/app/AssistStructure.java
index 9946d79..3abbb5b 100644
--- a/core/java/android/app/AssistStructure.java
+++ b/core/java/android/app/AssistStructure.java
@@ -224,6 +224,7 @@ final public class AssistStructure implements Parcelable {
static final int FLAGS_CHECKED = 0x00000200;
static final int FLAGS_CLICKABLE = 0x00004000;
static final int FLAGS_LONG_CLICKABLE = 0x00200000;
+ static final int FLAGS_STYLUS_BUTTON_PRESSABLE = 0x00400000;
int mFlags;
@@ -401,6 +402,10 @@ final public class AssistStructure implements Parcelable {
return (mFlags&ViewNode.FLAGS_LONG_CLICKABLE) != 0;
}
+ public boolean isStylusButtonPressable() {
+ return (mFlags&ViewNode.FLAGS_STYLUS_BUTTON_PRESSABLE) != 0;
+ }
+
public String getClassName() {
return mClassName;
}
@@ -513,6 +518,12 @@ final public class AssistStructure implements Parcelable {
}
@Override
+ public void setStylusButtonPressable(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_STYLUS_BUTTON_PRESSABLE)
+ | (state ? ViewNode.FLAGS_STYLUS_BUTTON_PRESSABLE : 0);
+ }
+
+ @Override
public void setFocusable(boolean state) {
mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_FOCUSABLE)
| (state ? ViewNode.FLAGS_FOCUSABLE : 0);
diff --git a/core/java/android/view/HapticFeedbackConstants.java b/core/java/android/view/HapticFeedbackConstants.java
index cc090ad..6651b83 100644
--- a/core/java/android/view/HapticFeedbackConstants.java
+++ b/core/java/android/view/HapticFeedbackConstants.java
@@ -52,6 +52,11 @@ public class HapticFeedbackConstants {
public static final int CALENDAR_DATE = 5;
/**
+ * The user has touched the screen with a stylus and pressed the stylus button.
+ */
+ public static final int STYLUS_BUTTON_PRESS = 6;
+
+ /**
* This is a private constant. Feel free to renumber as desired.
* @hide
*/
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 5e45c8f..5df596a 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -3180,6 +3180,18 @@ public final class MotionEvent extends InputEvent implements Parcelable {
return (getButtonState() & button) == button;
}
+ /**
+ * Checks if a stylus is being used and if the first stylus button is
+ * pressed.
+ *
+ * @return True if the tool is a stylus and if the first stylus button is
+ * pressed.
+ * @see #BUTTON_SECONDARY
+ */
+ public final boolean isStylusButtonPressed() {
+ return (isButtonPressed(BUTTON_SECONDARY) && getToolType(0) == TOOL_TYPE_STYLUS);
+ }
+
public static final Parcelable.Creator<MotionEvent> CREATOR
= new Parcelable.Creator<MotionEvent>() {
public MotionEvent createFromParcel(Parcel in) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b5b7f0f..81ad5ad 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -987,6 +987,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
static final int DUPLICATE_PARENT_STATE = 0x00400000;
+ /**
+ * <p>
+ * Indicates this view can be stylus button pressed. When stylus button
+ * pressable, a View reacts to stylus button presses by notifiying
+ * the OnStylusButtonPressListener.
+ * </p>
+ * {@hide}
+ */
+ static final int STYLUS_BUTTON_PRESSABLE = 0x00800000;
+
+
/** @hide */
@IntDef({
SCROLLBARS_INSIDE_OVERLAY,
@@ -3270,6 +3281,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
protected OnLongClickListener mOnLongClickListener;
/**
+ * Listener used to dispatch stylus touch and button press events. This field should be made
+ * private, so it is hidden from the SDK.
+ * {@hide}
+ */
+ protected OnStylusButtonPressListener mOnStylusButtonPressListener;
+
+ /**
* Listener used to build the context menu.
* This field should be made private, so it is hidden from the SDK.
* {@hide}
@@ -3360,6 +3378,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
private boolean mHasPerformedLongPress;
/**
+ * Whether the stylus button is currently pressed down. This is true when
+ * the stylus is touching the screen and the button has been pressed, this
+ * is false once the stylus has been lifted.
+ */
+ private boolean mInStylusButtonPress = false;
+
+ /**
* The minimum height of the view. We'll try our best to have the height
* of this view to at least this amount.
*/
@@ -3875,6 +3900,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
viewFlagMasks |= LONG_CLICKABLE;
}
break;
+ case com.android.internal.R.styleable.View_stylusButtonPressable:
+ if (a.getBoolean(attr, false)) {
+ viewFlagValues |= STYLUS_BUTTON_PRESSABLE;
+ viewFlagMasks |= STYLUS_BUTTON_PRESSABLE;
+ }
+ break;
case com.android.internal.R.styleable.View_saveEnabled:
if (!a.getBoolean(attr, true)) {
viewFlagValues |= SAVE_DISABLED;
@@ -4340,6 +4371,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
out.append((mViewFlags&SCROLLBARS_VERTICAL) != 0 ? 'V' : '.');
out.append((mViewFlags&CLICKABLE) != 0 ? 'C' : '.');
out.append((mViewFlags&LONG_CLICKABLE) != 0 ? 'L' : '.');
+ out.append((mViewFlags & STYLUS_BUTTON_PRESSABLE) != 0 ? 'S' : '.');
out.append(' ');
out.append((mPrivateFlags&PFLAG_IS_ROOT_NAMESPACE) != 0 ? 'R' : '.');
out.append((mPrivateFlags&PFLAG_FOCUSED) != 0 ? 'F' : '.');
@@ -4835,6 +4867,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Register a callback to be invoked when this view is touched with a stylus and the button is
+ * pressed.
+ *
+ * @param l The callback that will run
+ * @see #setStylusButtonPressable(boolean)
+ */
+ public void setOnStylusButtonPressListener(@Nullable OnStylusButtonPressListener l) {
+ if (!isStylusButtonPressable()) {
+ setStylusButtonPressable(true);
+ }
+ getListenerInfo().mOnStylusButtonPressListener = l;
+ }
+
+ /**
* Register a callback to be invoked when the context menu for this view is
* being built. If this view is not long clickable, it becomes long clickable.
*
@@ -4912,6 +4958,46 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Call this view's OnStylusButtonPressListener, if it is defined.
+ *
+ * @return True if there was an assigned OnStylusButtonPressListener that consumed the event,
+ * false otherwise.
+ */
+ public boolean performStylusButtonPress() {
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_STYLUS_BUTTON_PRESSED);
+
+ boolean handled = false;
+ ListenerInfo li = mListenerInfo;
+ if (li != null && li.mOnStylusButtonPressListener != null) {
+ handled = li.mOnStylusButtonPressListener.onStylusButtonPress(View.this);
+ }
+ if (handled) {
+ performHapticFeedback(HapticFeedbackConstants.STYLUS_BUTTON_PRESS);
+ }
+ return handled;
+ }
+
+ /**
+ * Checks for a stylus button press and calls the listener.
+ *
+ * @param event The event.
+ * @return True if the event was consumed.
+ */
+ private boolean performStylusActionOnButtonPress(MotionEvent event) {
+ if (isStylusButtonPressable() && !mInStylusButtonPress
+ && !mHasPerformedLongPress && event.isStylusButtonPressed()) {
+ if (performStylusButtonPress()) {
+ mInStylusButtonPress = true;
+ setPressed(true, event.getX(), event.getY());
+ removeTapCallback();
+ removeLongPressCallback();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* Performs button-related actions during a touch down event.
*
* @param event The event.
@@ -5701,6 +5787,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* <li>{@link AccessibilityNodeInfo#setFocused(boolean)},</li>
* <li>{@link AccessibilityNodeInfo#setLongClickable(boolean)},</li>
* <li>{@link AccessibilityNodeInfo#setSelected(boolean)},</li>
+ * <li>{@link AccessibilityNodeInfo#setStylusButtonPressable(boolean)}</li>
* </ul>
* <p>
* Subclasses should override this method, call the super implementation,
@@ -5852,6 +5939,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
structure.setChecked(true);
}
}
+ if (isStylusButtonPressable()) {
+ structure.setStylusButtonPressable(true);
+ }
structure.setClassName(getAccessibilityClassName().toString());
structure.setContentDescription(getContentDescription());
}
@@ -5909,6 +5999,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
structure.setChecked(true);
}
}
+ if (info.isStylusButtonPressable()) {
+ structure.setStylusButtonPressable(true);
+ }
CharSequence cname = info.getClassName();
structure.setClassName(cname != null ? cname.toString() : null);
structure.setContentDescription(info.getContentDescription());
@@ -6038,6 +6131,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
info.setAccessibilityFocused(isAccessibilityFocused());
info.setSelected(isSelected());
info.setLongClickable(isLongClickable());
+ info.setStylusButtonPressable(isStylusButtonPressable());
info.setLiveRegion(getAccessibilityLiveRegion());
// TODO: These make sense only if we are in an AdapterView but all
@@ -6068,6 +6162,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
}
+ if (isStylusButtonPressable() && isEnabled()) {
+ info.addAction(AccessibilityAction.ACTION_STYLUS_BUTTON_PRESS);
+ }
+
CharSequence text = getIterableTextForAccessibility();
if (text != null && text.length() > 0) {
info.setTextSelection(getAccessibilitySelectionStart(), getAccessibilitySelectionEnd());
@@ -7442,6 +7540,31 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Indicates whether this view reacts to stylus button press events or not.
+ *
+ * @return true if the view is stylus button pressable, false otherwise
+ * @see #setStylusButtonPressable(boolean)
+ * @attr ref android.R.styleable#View_stylusButtonPressable
+ */
+ public boolean isStylusButtonPressable() {
+ return (mViewFlags & STYLUS_BUTTON_PRESSABLE) == STYLUS_BUTTON_PRESSABLE;
+ }
+
+ /**
+ * Enables or disables stylus button press events for this view. When a view is stylus button
+ * pressable it reacts to the user touching the screen with a stylus and pressing the first
+ * stylus button. This event can launch the listener.
+ *
+ * @param stylusButtonPressable true to make the view react to a stylus button press, false
+ * otherwise
+ * @see #isStylusButtonPressable()
+ * @attr ref android.R.styleable#View_stylusButtonPressable
+ */
+ public void setStylusButtonPressable(boolean stylusButtonPressable) {
+ setFlags(stylusButtonPressable ? STYLUS_BUTTON_PRESSABLE : 0, STYLUS_BUTTON_PRESSABLE);
+ }
+
+ /**
* Sets the pressed state for this view and provides a touch coordinate for
* animation hinting.
*
@@ -7856,7 +7979,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public void addTouchables(ArrayList<View> views) {
final int viewFlags = mViewFlags;
- if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)
+ if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE
+ || (viewFlags & STYLUS_BUTTON_PRESSABLE) == STYLUS_BUTTON_PRESSABLE)
&& (viewFlags & ENABLED_MASK) == ENABLED) {
views.add(this);
}
@@ -8571,6 +8695,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
return requestRectangleOnScreen(r, true);
}
} break;
+ case R.id.accessibilityActionStylusButtonPress: {
+ if (isStylusButtonPressable()) {
+ performStylusButtonPress();
+ return true;
+ }
+ } break;
}
return false;
}
@@ -9728,7 +9858,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
return (viewFlags & CLICKABLE) == CLICKABLE
- || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE;
+ || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE
+ || (viewFlags & STYLUS_BUTTON_PRESSABLE) == STYLUS_BUTTON_PRESSABLE;
}
/**
@@ -9811,15 +9942,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
final float x = event.getX();
final float y = event.getY();
final int viewFlags = mViewFlags;
+ final int action = event.getAction();
if ((viewFlags & ENABLED_MASK) == DISABLED) {
- if (event.getAction() == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) {
+ if (action == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) {
setPressed(false);
}
// A disabled view that is clickable still consumes the touch
// events, it just doesn't respond to them.
- return (((viewFlags & CLICKABLE) == CLICKABLE ||
- (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE));
+ return (((viewFlags & CLICKABLE) == CLICKABLE
+ || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)
+ || (viewFlags & STYLUS_BUTTON_PRESSABLE) == STYLUS_BUTTON_PRESSABLE);
}
if (mTouchDelegate != null) {
@@ -9829,9 +9962,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
if (((viewFlags & CLICKABLE) == CLICKABLE ||
- (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
- switch (event.getAction()) {
+ (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) ||
+ (viewFlags & STYLUS_BUTTON_PRESSABLE) == STYLUS_BUTTON_PRESSABLE) {
+ switch (action) {
case MotionEvent.ACTION_UP:
+ if (mInStylusButtonPress) {
+ mInStylusButtonPress = false;
+ mHasPerformedLongPress = false;
+ }
boolean prepressed = (mPrivateFlags & PFLAG_PREPRESSED) != 0;
if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) {
// take focus if we don't have it already and we should in
@@ -9885,6 +10023,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
case MotionEvent.ACTION_DOWN:
mHasPerformedLongPress = false;
+ mInStylusButtonPress = false;
+
+ if (performStylusActionOnButtonPress(event)) {
+ break;
+ }
if (performButtonActionOnTouchDown(event)) {
break;
@@ -9914,6 +10057,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
setPressed(false);
removeTapCallback();
removeLongPressCallback();
+ if (mInStylusButtonPress) {
+ mInStylusButtonPress = false;
+ mHasPerformedLongPress = false;
+ }
break;
case MotionEvent.ACTION_MOVE:
@@ -9929,6 +10076,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
setPressed(false);
}
+ } else if (performStylusActionOnButtonPress(event)) {
+ // Check for stylus button press if we're within the view.
+ break;
}
break;
}
@@ -10216,7 +10366,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (accessibilityEnabled) {
if ((changed & FOCUSABLE_MASK) != 0 || (changed & VISIBILITY_MASK) != 0
- || (changed & CLICKABLE) != 0 || (changed & LONG_CLICKABLE) != 0) {
+ || (changed & CLICKABLE) != 0 || (changed & LONG_CLICKABLE) != 0
+ || (changed & STYLUS_BUTTON_PRESSABLE) != 0) {
if (oldIncludeForAccessibility != includeForAccessibility()) {
notifySubtreeAccessibilityStateChangedIfNeeded();
} else {
@@ -20782,6 +20933,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Interface definition for a callback to be invoked when a view is touched with a stylus while
+ * the stylus button is pressed.
+ */
+ public interface OnStylusButtonPressListener {
+ /**
+ * Called when a view is touched with a stylus while the stylus button is pressed.
+ *
+ * @param v The view that was touched.
+ * @return true if the callback consumed the stylus button press, false otherwise.
+ */
+ boolean onStylusButtonPress(View v);
+ }
+
+ /**
* Interface definition for a callback to be invoked when the context menu
* for this view is being built.
*/
diff --git a/core/java/android/view/ViewAssistStructure.java b/core/java/android/view/ViewAssistStructure.java
index 346b8ec..fccfbb8 100644
--- a/core/java/android/view/ViewAssistStructure.java
+++ b/core/java/android/view/ViewAssistStructure.java
@@ -40,6 +40,8 @@ public abstract class ViewAssistStructure {
public abstract void setLongClickable(boolean state);
+ public abstract void setStylusButtonPressable(boolean state);
+
public abstract void setFocusable(boolean state);
public abstract void setFocused(boolean state);
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 417e22c..b0dbeca 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -684,6 +684,11 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
public static final int TYPE_WINDOWS_CHANGED = 0x00400000;
/**
+ * Represents the event of a stylus button press on a {@link android.view.View}.
+ */
+ public static final int TYPE_VIEW_STYLUS_BUTTON_PRESSED = 0x00800000;
+
+ /**
* Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
* The type of change is not defined.
*/
@@ -731,6 +736,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
* @see #TYPE_TOUCH_INTERACTION_START
* @see #TYPE_TOUCH_INTERACTION_END
* @see #TYPE_WINDOWS_CHANGED
+ * @see #TYPE_VIEW_STYLUS_BUTTON_PRESSED
*/
public static final int TYPES_ALL_MASK = 0xFFFFFFFF;
@@ -1396,6 +1402,14 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
builder.append("TYPE_WINDOWS_CHANGED");
eventTypeCount++;
} break;
+ case TYPE_VIEW_STYLUS_BUTTON_PRESSED: {
+ if (eventTypeCount > 0) {
+ builder.append(", ");
+ }
+ builder.append("TYPE_VIEW_STYLUS_BUTTON_PRESSED");
+ eventTypeCount++;
+ }
+ break;
}
}
if (eventTypeCount > 1) {
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 0736ed8..bf4b7ae 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -520,6 +520,8 @@ public class AccessibilityNodeInfo implements Parcelable {
private static final int BOOLEAN_PROPERTY_CONTENT_INVALID = 0x00010000;
+ private static final int BOOLEAN_PROPERTY_STYLUS_BUTTON_PRESSABLE = 0x00020000;
+
/**
* Bits that provide the id of a virtual descendant of a view.
*/
@@ -1930,6 +1932,30 @@ public class AccessibilityNodeInfo implements Parcelable {
}
/**
+ * Gets whether this node is stylus button pressable.
+ *
+ * @return True if the node is stylus button pressable.
+ */
+ public boolean isStylusButtonPressable() {
+ return getBooleanProperty(BOOLEAN_PROPERTY_STYLUS_BUTTON_PRESSABLE);
+ }
+
+ /**
+ * Sets whether this node is stylus button pressable.
+ * <p>
+ * <strong>Note:</strong> Cannot be called from an
+ * {@link android.accessibilityservice.AccessibilityService}. This class is made immutable
+ * before being delivered to an AccessibilityService.
+ * </p>
+ *
+ * @param stylusButtonPressable True if the node is stylus button pressable.
+ * @throws IllegalStateException If called from an AccessibilityService.
+ */
+ public void setStylusButtonPressable(boolean stylusButtonPressable) {
+ setBooleanProperty(BOOLEAN_PROPERTY_STYLUS_BUTTON_PRESSABLE, stylusButtonPressable);
+ }
+
+ /**
* Gets the node's live region mode.
* <p>
* A live region is a node that contains information that is important for
@@ -3117,6 +3143,7 @@ public class AccessibilityNodeInfo implements Parcelable {
builder.append("; selected: ").append(isSelected());
builder.append("; clickable: ").append(isClickable());
builder.append("; longClickable: ").append(isLongClickable());
+ builder.append("; stylusButtonPressable: ").append(isStylusButtonPressable());
builder.append("; enabled: ").append(isEnabled());
builder.append("; password: ").append(isPassword());
builder.append("; scrollable: ").append(isScrollable());
@@ -3472,6 +3499,12 @@ public class AccessibilityNodeInfo implements Parcelable {
public static final AccessibilityAction ACTION_SCROLL_TO_POSITION =
new AccessibilityAction(R.id.accessibilityActionScrollToPosition, null);
+ /**
+ * Action that stylus button presses the node.
+ */
+ public static final AccessibilityAction ACTION_STYLUS_BUTTON_PRESS =
+ new AccessibilityAction(R.id.accessibilityActionStylusButtonPress, null);
+
private static final ArraySet<AccessibilityAction> sStandardActions = new ArraySet<>();
static {
sStandardActions.add(ACTION_FOCUS);
@@ -3498,6 +3531,7 @@ public class AccessibilityNodeInfo implements Parcelable {
sStandardActions.add(ACTION_SET_TEXT);
sStandardActions.add(ACTION_SHOW_ON_SCREEN);
sStandardActions.add(ACTION_SCROLL_TO_POSITION);
+ sStandardActions.add(ACTION_STYLUS_BUTTON_PRESS);
}
private final int mActionId;
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index a95cc79..87dc3fa 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2329,6 +2329,9 @@
<!-- Defines whether this view reacts to long click events. -->
<attr name="longClickable" format="boolean" />
+ <!-- Defines whether this view reacts to stylus button press events. -->
+ <attr name="stylusButtonPressable" format="boolean" />
+
<!-- If false, no state will be saved for this view when it is being
frozen. The default is true, allowing the view to be saved
(however it also must have an ID assigned to it for its
@@ -3076,6 +3079,8 @@
<flag name="typeTouchInteractionEnd" value="0x00200000" />
<!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_WINDOWS_CHANGED} events. -->
<flag name="typeWindowsChanged" value="0x00400000" />
+ <!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_STYLUS_BUTTON_PRESSED} events. -->
+ <flag name="typeStylusButtonPressed" value="0x00800000" />
<!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPES_ALL_MASK} i.e. all events. -->
<flag name="typeAllMask" value="0xffffffff" />
</attr>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6f60188..0b8b280 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -771,6 +771,14 @@
<item>10</item>
</integer-array>
+ <!-- Vibrator pattern for feedback about a stylus button press -->
+ <integer-array name="config_stylusButtonPressVibePattern">
+ <item>0</item>
+ <item>1</item>
+ <item>20</item>
+ <item>21</item>
+ </integer-array>
+
<bool name="config_use_strict_phone_number_comparation">false</bool>
<!-- Display low battery warning when battery level dips to this value.
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index bdc8d9f..4b8bd0f 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -100,4 +100,7 @@
<!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SCROLL_TO_POSITION}. -->
<item type="id" name="accessibilityActionScrollToPosition" />
+
+ <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_STYLUS_BUTTON_PRESS}. -->
+ <item type="id" name="accessibilityActionStylusButtonPress" />
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index dd4c134..cf21a1c 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2652,6 +2652,7 @@
<public type="id" name="accessibilityActionShowOnScreen" />
<public type="id" name="accessibilityActionScrollToPosition" />
<public type="id" name="shareText" />
+ <public type="id" name="accessibilityActionStylusButtonPress" />
<public type="attr" name="allowUndo" />
<public type="attr" name="colorBackgroundFloating" />
@@ -2678,4 +2679,5 @@
<public type="attr" name="dynamicResources" />
<public type="attr" name="assistBlocked" />
+ <public type="attr" name="stylusButtonPressable" />
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 625f003..50d2f80 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1442,6 +1442,7 @@
<java-symbol type="array" name="config_longPressVibePattern" />
<java-symbol type="array" name="config_safeModeDisabledVibePattern" />
<java-symbol type="array" name="config_safeModeEnabledVibePattern" />
+ <java-symbol type="array" name="config_stylusButtonPressVibePattern" />
<java-symbol type="array" name="config_virtualKeyVibePattern" />
<java-symbol type="attr" name="actionModePopupWindowStyle" />
<java-symbol type="attr" name="dialogCustomTitleDecorLayout" />
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 5536d4d..adc3a7d 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -285,6 +285,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Vibrator pattern for haptic feedback during boot when safe mode is enabled.
long[] mSafeModeEnabledVibePattern;
+ // Vibrator pattern for haptic feedback of a stylus button press.
+ long[] mStylusButtonPressVibePattern;
+
/** If true, hitting shift & menu will broadcast Intent.ACTION_BUG_REPORT */
boolean mEnableShiftMenuBugReports = false;
@@ -1436,6 +1439,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
com.android.internal.R.array.config_safeModeDisabledVibePattern);
mSafeModeEnabledVibePattern = getLongIntArray(mContext.getResources(),
com.android.internal.R.array.config_safeModeEnabledVibePattern);
+ mStylusButtonPressVibePattern = getLongIntArray(mContext.getResources(),
+ com.android.internal.R.array.config_stylusButtonPressVibePattern);
mScreenshotChordEnabled = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_enableScreenshotChord);
@@ -6164,6 +6169,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case HapticFeedbackConstants.SAFE_MODE_ENABLED:
pattern = mSafeModeEnabledVibePattern;
break;
+ case HapticFeedbackConstants.STYLUS_BUTTON_PRESS:
+ pattern = mStylusButtonPressVibePattern;
+ break;
default:
return false;
}