Loading core/java/android/view/HandwritingInitiator.java +14 −7 Original line number Diff line number Diff line Loading @@ -116,9 +116,6 @@ public class HandwritingInitiator { // The motion event is not from a stylus event, ignore it. return false; } if (!mImm.isStylusHandwritingAvailable()) { return false; } mState = new State(motionEvent); break; case MotionEvent.ACTION_POINTER_UP: Loading Loading @@ -280,6 +277,13 @@ public class HandwritingInitiator { mHandwritingAreasTracker.updateHandwritingAreaForView(view); } private static boolean shouldTriggerStylusHandwritingForView(@NonNull View view) { if (!view.isAutoHandwritingEnabled()) { return false; } return view.isStylusHandwritingAvailable(); } /** * Given the location of the stylus event, return the best candidate view to initialize * handwriting mode. Loading @@ -296,9 +300,10 @@ public class HandwritingInitiator { // whether the connectedView's boundary contains the initial stylus position. If true, // directly return the connectedView. final View connectedView = getConnectedView(); if (connectedView != null && connectedView.isAutoHandwritingEnabled()) { if (connectedView != null) { Rect handwritingArea = getViewHandwritingArea(connectedView); if (isInHandwritingArea(handwritingArea, x, y, connectedView)) { if (isInHandwritingArea(handwritingArea, x, y, connectedView) && shouldTriggerStylusHandwritingForView(connectedView)) { final float distance = distance(handwritingArea, x, y); if (distance == 0f) return connectedView; Loading @@ -313,10 +318,12 @@ public class HandwritingInitiator { for (HandwritableViewInfo viewInfo : handwritableViewInfos) { final View view = viewInfo.getView(); final Rect handwritingArea = viewInfo.getHandwritingArea(); if (!isInHandwritingArea(handwritingArea, x, y, view)) continue; if (!isInHandwritingArea(handwritingArea, x, y, view) || !shouldTriggerStylusHandwritingForView(view)) { continue; } final float distance = distance(handwritingArea, x, y); if (distance == 0f) return view; if (distance < minDistance) { minDistance = distance; Loading core/java/android/view/View.java +10 −0 Original line number Diff line number Diff line Loading @@ -151,6 +151,7 @@ import android.view.displayhash.DisplayHashManager; import android.view.displayhash.DisplayHashResultCallback; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; import android.view.inspector.InspectableProperty; import android.view.inspector.InspectableProperty.EnumEntry; import android.view.inspector.InspectableProperty.FlagEntry; Loading Loading @@ -31799,6 +31800,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, == PFLAG4_AUTO_HANDWRITING_ENABLED; } /** * Return whether the stylus handwriting is available for this View. * @hide */ public boolean isStylusHandwritingAvailable() { return getContext().getSystemService(InputMethodManager.class) .isStylusHandwritingAvailable(); } /** * Collects a {@link ViewTranslationRequest} which represents the content to be translated in * the view. core/java/android/widget/TextView.java +11 −0 Original line number Diff line number Diff line Loading @@ -12049,6 +12049,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } /** @hide */ @Override public boolean isStylusHandwritingAvailable() { if (mTextOperationUser == null) { return super.isStylusHandwritingAvailable(); } final int userId = mTextOperationUser.getIdentifier(); final InputMethodManager imm = getInputMethodManager(); return imm.isStylusHandwritingAvailableAsUser(userId); } @Nullable final TextServicesManager getTextServicesManagerForUser() { return getServiceManagerForUser("android", TextServicesManager.class); Loading core/tests/coretests/src/android/view/stylus/HandwritableViewInfoTest.java +2 −1 Original line number Diff line number Diff line Loading @@ -70,7 +70,8 @@ public class HandwritableViewInfoTest { @Test public void update_viewDisableAutoHandwriting() { final Rect rect = new Rect(1, 2, 3, 4); final View view = HandwritingTestUtil.createView(rect, false /* autoHandwritingEnabled */); final View view = HandwritingTestUtil.createView(rect, false /* autoHandwritingEnabled */, true /* isStylusHandwritingAvailable */); final HandwritingInitiator.HandwritableViewInfo handwritableViewInfo = new HandwritingInitiator.HandwritableViewInfo(view); Loading core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java +13 −50 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package android.view.stylus; import static android.provider.Settings.Global.STYLUS_HANDWRITING_ENABLED; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_MOVE; import static android.view.MotionEvent.ACTION_UP; Loading @@ -33,7 +32,6 @@ import android.app.Instrumentation; import android.content.Context; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.provider.Settings; import android.view.HandwritingInitiator; import android.view.InputDevice; import android.view.MotionEvent; Loading @@ -45,15 +43,10 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import com.android.compatibility.common.util.PollingCheck; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.concurrent.TimeUnit; /** * Tests for {@link HandwritingInitiator} * Loading @@ -69,8 +62,6 @@ public class HandwritingInitiatorTest { private static final int HW_BOUNDS_OFFSETS_TOP_PX = 20; private static final int HW_BOUNDS_OFFSETS_RIGHT_PX = 30; private static final int HW_BOUNDS_OFFSETS_BOTTOM_PX = 40; private static final int SETTING_VALUE_ON = 1; private static final int SETTING_VALUE_OFF = 0; private int mHandwritingSlop = 4; private static final Rect sHwArea = new Rect(100, 200, 500, 500); Loading @@ -78,29 +69,12 @@ public class HandwritingInitiatorTest { private HandwritingInitiator mHandwritingInitiator; private View mTestView; private Context mContext; private int mHwInitialState; private boolean mShouldRestoreInitialHwState; @Before public void setup() throws Exception { final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); mContext = instrumentation.getTargetContext(); mHwInitialState = Settings.Global.getInt(mContext.getContentResolver(), STYLUS_HANDWRITING_ENABLED, SETTING_VALUE_OFF); if (mHwInitialState != SETTING_VALUE_ON) { Settings.Global.putInt(mContext.getContentResolver(), STYLUS_HANDWRITING_ENABLED, SETTING_VALUE_ON); mShouldRestoreInitialHwState = true; } String imeId = HandwritingImeService.getImeId(); instrumentation.getUiAutomation().executeShellCommand("ime enable " + imeId); instrumentation.getUiAutomation().executeShellCommand("ime set " + imeId); PollingCheck.check("Check that stylus handwriting is available", TimeUnit.SECONDS.toMillis(10), () -> mContext.getSystemService(InputMethodManager.class) .isStylusHandwritingAvailable()); final ViewConfiguration viewConfiguration = ViewConfiguration.get(mContext); mHandwritingSlop = viewConfiguration.getScaledHandwritingSlop(); Loading @@ -108,7 +82,8 @@ public class HandwritingInitiatorTest { mHandwritingInitiator = spy(new HandwritingInitiator(viewConfiguration, inputMethodManager)); mTestView = createView(sHwArea, true, mTestView = createView(sHwArea, true /* autoHandwritingEnabled */, true /* isStylusHandwritingAvailable */, HW_BOUNDS_OFFSETS_LEFT_PX, HW_BOUNDS_OFFSETS_TOP_PX, HW_BOUNDS_OFFSETS_RIGHT_PX, Loading @@ -116,17 +91,6 @@ public class HandwritingInitiatorTest { mHandwritingInitiator.updateHandwritingAreasForView(mTestView); } @After public void tearDown() throws Exception { if (mShouldRestoreInitialHwState) { mShouldRestoreInitialHwState = false; Settings.Global.putInt(mContext.getContentResolver(), STYLUS_HANDWRITING_ENABLED, mHwInitialState); } InstrumentationRegistry.getInstrumentation().getUiAutomation() .executeShellCommand("ime reset"); } @Test public void onTouchEvent_startHandwriting_when_stylusMoveOnce_withinHWArea() { mHandwritingInitiator.onInputConnectionCreated(mTestView); Loading Loading @@ -244,17 +208,15 @@ public class HandwritingInitiatorTest { } @Test public void onTouchEvent_notStartHandwriting_whenHandwritingNotAvailable() throws Exception { InstrumentationRegistry.getInstrumentation().getUiAutomation() .executeShellCommand("ime reset"); PollingCheck.check("Check that stylus handwriting is unavailable", TimeUnit.SECONDS.toMillis(10), () -> !mContext.getSystemService(InputMethodManager.class) .isStylusHandwritingAvailable()); mHandwritingInitiator.onInputConnectionCreated(mTestView); final int x1 = (sHwArea.left + sHwArea.right) / 2; final int y1 = (sHwArea.top + sHwArea.bottom) / 2; public void onTouchEvent_notStartHandwriting_whenHandwritingNotAvailable() { final Rect rect = new Rect(600, 600, 900, 900); final View testView = createView(rect, true /* autoHandwritingEnabled */, false /* isStylusHandwritingAvailable */); mHandwritingInitiator.updateHandwritingAreasForView(testView); mHandwritingInitiator.onInputConnectionCreated(testView); final int x1 = (rect.left + rect.right) / 2; final int y1 = (rect.top + rect.bottom) / 2; MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0); mHandwritingInitiator.onTouchEvent(stylusEvent1); Loading Loading @@ -356,7 +318,8 @@ public class HandwritingInitiatorTest { @Test public void autoHandwriting_whenDisabled_wontStartHW() { View mockView = createView(sHwArea, false); View mockView = createView(sHwArea, false /* autoHandwritingEnabled */, true /* isStylusHandwritingAvailable */); mHandwritingInitiator.onInputConnectionCreated(mockView); final int x1 = (sHwArea.left + sHwArea.right) / 2; final int y1 = (sHwArea.top + sHwArea.bottom) / 2; Loading Loading
core/java/android/view/HandwritingInitiator.java +14 −7 Original line number Diff line number Diff line Loading @@ -116,9 +116,6 @@ public class HandwritingInitiator { // The motion event is not from a stylus event, ignore it. return false; } if (!mImm.isStylusHandwritingAvailable()) { return false; } mState = new State(motionEvent); break; case MotionEvent.ACTION_POINTER_UP: Loading Loading @@ -280,6 +277,13 @@ public class HandwritingInitiator { mHandwritingAreasTracker.updateHandwritingAreaForView(view); } private static boolean shouldTriggerStylusHandwritingForView(@NonNull View view) { if (!view.isAutoHandwritingEnabled()) { return false; } return view.isStylusHandwritingAvailable(); } /** * Given the location of the stylus event, return the best candidate view to initialize * handwriting mode. Loading @@ -296,9 +300,10 @@ public class HandwritingInitiator { // whether the connectedView's boundary contains the initial stylus position. If true, // directly return the connectedView. final View connectedView = getConnectedView(); if (connectedView != null && connectedView.isAutoHandwritingEnabled()) { if (connectedView != null) { Rect handwritingArea = getViewHandwritingArea(connectedView); if (isInHandwritingArea(handwritingArea, x, y, connectedView)) { if (isInHandwritingArea(handwritingArea, x, y, connectedView) && shouldTriggerStylusHandwritingForView(connectedView)) { final float distance = distance(handwritingArea, x, y); if (distance == 0f) return connectedView; Loading @@ -313,10 +318,12 @@ public class HandwritingInitiator { for (HandwritableViewInfo viewInfo : handwritableViewInfos) { final View view = viewInfo.getView(); final Rect handwritingArea = viewInfo.getHandwritingArea(); if (!isInHandwritingArea(handwritingArea, x, y, view)) continue; if (!isInHandwritingArea(handwritingArea, x, y, view) || !shouldTriggerStylusHandwritingForView(view)) { continue; } final float distance = distance(handwritingArea, x, y); if (distance == 0f) return view; if (distance < minDistance) { minDistance = distance; Loading
core/java/android/view/View.java +10 −0 Original line number Diff line number Diff line Loading @@ -151,6 +151,7 @@ import android.view.displayhash.DisplayHashManager; import android.view.displayhash.DisplayHashResultCallback; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; import android.view.inspector.InspectableProperty; import android.view.inspector.InspectableProperty.EnumEntry; import android.view.inspector.InspectableProperty.FlagEntry; Loading Loading @@ -31799,6 +31800,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, == PFLAG4_AUTO_HANDWRITING_ENABLED; } /** * Return whether the stylus handwriting is available for this View. * @hide */ public boolean isStylusHandwritingAvailable() { return getContext().getSystemService(InputMethodManager.class) .isStylusHandwritingAvailable(); } /** * Collects a {@link ViewTranslationRequest} which represents the content to be translated in * the view.
core/java/android/widget/TextView.java +11 −0 Original line number Diff line number Diff line Loading @@ -12049,6 +12049,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } /** @hide */ @Override public boolean isStylusHandwritingAvailable() { if (mTextOperationUser == null) { return super.isStylusHandwritingAvailable(); } final int userId = mTextOperationUser.getIdentifier(); final InputMethodManager imm = getInputMethodManager(); return imm.isStylusHandwritingAvailableAsUser(userId); } @Nullable final TextServicesManager getTextServicesManagerForUser() { return getServiceManagerForUser("android", TextServicesManager.class); Loading
core/tests/coretests/src/android/view/stylus/HandwritableViewInfoTest.java +2 −1 Original line number Diff line number Diff line Loading @@ -70,7 +70,8 @@ public class HandwritableViewInfoTest { @Test public void update_viewDisableAutoHandwriting() { final Rect rect = new Rect(1, 2, 3, 4); final View view = HandwritingTestUtil.createView(rect, false /* autoHandwritingEnabled */); final View view = HandwritingTestUtil.createView(rect, false /* autoHandwritingEnabled */, true /* isStylusHandwritingAvailable */); final HandwritingInitiator.HandwritableViewInfo handwritableViewInfo = new HandwritingInitiator.HandwritableViewInfo(view); Loading
core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java +13 −50 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package android.view.stylus; import static android.provider.Settings.Global.STYLUS_HANDWRITING_ENABLED; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_MOVE; import static android.view.MotionEvent.ACTION_UP; Loading @@ -33,7 +32,6 @@ import android.app.Instrumentation; import android.content.Context; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.provider.Settings; import android.view.HandwritingInitiator; import android.view.InputDevice; import android.view.MotionEvent; Loading @@ -45,15 +43,10 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import com.android.compatibility.common.util.PollingCheck; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.concurrent.TimeUnit; /** * Tests for {@link HandwritingInitiator} * Loading @@ -69,8 +62,6 @@ public class HandwritingInitiatorTest { private static final int HW_BOUNDS_OFFSETS_TOP_PX = 20; private static final int HW_BOUNDS_OFFSETS_RIGHT_PX = 30; private static final int HW_BOUNDS_OFFSETS_BOTTOM_PX = 40; private static final int SETTING_VALUE_ON = 1; private static final int SETTING_VALUE_OFF = 0; private int mHandwritingSlop = 4; private static final Rect sHwArea = new Rect(100, 200, 500, 500); Loading @@ -78,29 +69,12 @@ public class HandwritingInitiatorTest { private HandwritingInitiator mHandwritingInitiator; private View mTestView; private Context mContext; private int mHwInitialState; private boolean mShouldRestoreInitialHwState; @Before public void setup() throws Exception { final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); mContext = instrumentation.getTargetContext(); mHwInitialState = Settings.Global.getInt(mContext.getContentResolver(), STYLUS_HANDWRITING_ENABLED, SETTING_VALUE_OFF); if (mHwInitialState != SETTING_VALUE_ON) { Settings.Global.putInt(mContext.getContentResolver(), STYLUS_HANDWRITING_ENABLED, SETTING_VALUE_ON); mShouldRestoreInitialHwState = true; } String imeId = HandwritingImeService.getImeId(); instrumentation.getUiAutomation().executeShellCommand("ime enable " + imeId); instrumentation.getUiAutomation().executeShellCommand("ime set " + imeId); PollingCheck.check("Check that stylus handwriting is available", TimeUnit.SECONDS.toMillis(10), () -> mContext.getSystemService(InputMethodManager.class) .isStylusHandwritingAvailable()); final ViewConfiguration viewConfiguration = ViewConfiguration.get(mContext); mHandwritingSlop = viewConfiguration.getScaledHandwritingSlop(); Loading @@ -108,7 +82,8 @@ public class HandwritingInitiatorTest { mHandwritingInitiator = spy(new HandwritingInitiator(viewConfiguration, inputMethodManager)); mTestView = createView(sHwArea, true, mTestView = createView(sHwArea, true /* autoHandwritingEnabled */, true /* isStylusHandwritingAvailable */, HW_BOUNDS_OFFSETS_LEFT_PX, HW_BOUNDS_OFFSETS_TOP_PX, HW_BOUNDS_OFFSETS_RIGHT_PX, Loading @@ -116,17 +91,6 @@ public class HandwritingInitiatorTest { mHandwritingInitiator.updateHandwritingAreasForView(mTestView); } @After public void tearDown() throws Exception { if (mShouldRestoreInitialHwState) { mShouldRestoreInitialHwState = false; Settings.Global.putInt(mContext.getContentResolver(), STYLUS_HANDWRITING_ENABLED, mHwInitialState); } InstrumentationRegistry.getInstrumentation().getUiAutomation() .executeShellCommand("ime reset"); } @Test public void onTouchEvent_startHandwriting_when_stylusMoveOnce_withinHWArea() { mHandwritingInitiator.onInputConnectionCreated(mTestView); Loading Loading @@ -244,17 +208,15 @@ public class HandwritingInitiatorTest { } @Test public void onTouchEvent_notStartHandwriting_whenHandwritingNotAvailable() throws Exception { InstrumentationRegistry.getInstrumentation().getUiAutomation() .executeShellCommand("ime reset"); PollingCheck.check("Check that stylus handwriting is unavailable", TimeUnit.SECONDS.toMillis(10), () -> !mContext.getSystemService(InputMethodManager.class) .isStylusHandwritingAvailable()); mHandwritingInitiator.onInputConnectionCreated(mTestView); final int x1 = (sHwArea.left + sHwArea.right) / 2; final int y1 = (sHwArea.top + sHwArea.bottom) / 2; public void onTouchEvent_notStartHandwriting_whenHandwritingNotAvailable() { final Rect rect = new Rect(600, 600, 900, 900); final View testView = createView(rect, true /* autoHandwritingEnabled */, false /* isStylusHandwritingAvailable */); mHandwritingInitiator.updateHandwritingAreasForView(testView); mHandwritingInitiator.onInputConnectionCreated(testView); final int x1 = (rect.left + rect.right) / 2; final int y1 = (rect.top + rect.bottom) / 2; MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0); mHandwritingInitiator.onTouchEvent(stylusEvent1); Loading Loading @@ -356,7 +318,8 @@ public class HandwritingInitiatorTest { @Test public void autoHandwriting_whenDisabled_wontStartHW() { View mockView = createView(sHwArea, false); View mockView = createView(sHwArea, false /* autoHandwritingEnabled */, true /* isStylusHandwritingAvailable */); mHandwritingInitiator.onInputConnectionCreated(mockView); final int x1 = (sHwArea.left + sHwArea.right) / 2; final int y1 = (sHwArea.top + sHwArea.bottom) / 2; Loading