summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt20
-rw-r--r--core/java/android/view/HandwritingDelegateConfiguration.java74
-rw-r--r--core/java/android/view/HandwritingInitiator.java50
-rw-r--r--core/java/android/view/View.java178
-rw-r--r--core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java34
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java171
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl9
-rw-r--r--core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java14
-rw-r--r--services/core/java/com/android/server/inputmethod/HandwritingModeController.java51
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java87
10 files changed, 150 insertions, 538 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index f7ef26bf09df..a7f69374ff00 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -50381,6 +50381,12 @@ package android.view {
field public static final int VERTICAL_GRAVITY_MASK = 112; // 0x70
}
+ public class HandwritingDelegateConfiguration {
+ ctor public HandwritingDelegateConfiguration(@IdRes int, @NonNull Runnable);
+ method public int getDelegatorViewId();
+ method @NonNull public Runnable getInitiationCallback();
+ }
+
public class HapticFeedbackConstants {
field public static final int CLOCK_TICK = 4; // 0x4
field public static final int CONFIRM = 16; // 0x10
@@ -51978,8 +51984,6 @@ package android.view {
method @Nullable public CharSequence getAccessibilityPaneTitle();
method @IdRes public int getAccessibilityTraversalAfter();
method @IdRes public int getAccessibilityTraversalBefore();
- method @NonNull public String getAllowedHandwritingDelegatePackageName();
- method @NonNull public String getAllowedHandwritingDelegatorPackageName();
method public float getAlpha();
method public android.view.animation.Animation getAnimation();
method @Nullable public android.graphics.Matrix getAnimationMatrix();
@@ -52035,7 +52039,7 @@ package android.view {
method public float getHandwritingBoundsOffsetLeft();
method public float getHandwritingBoundsOffsetRight();
method public float getHandwritingBoundsOffsetTop();
- method @Nullable public Runnable getHandwritingDelegatorCallback();
+ method @Nullable public android.view.HandwritingDelegateConfiguration getHandwritingDelegateConfiguration();
method public final boolean getHasOverlappingRendering();
method public final int getHeight();
method public void getHitRect(android.graphics.Rect);
@@ -52191,7 +52195,6 @@ package android.view {
method public boolean isFocused();
method public final boolean isFocusedByDefault();
method public boolean isForceDarkAllowed();
- method public boolean isHandwritingDelegate();
method public boolean isHapticFeedbackEnabled();
method public boolean isHardwareAccelerated();
method public boolean isHorizontalFadingEdgeEnabled();
@@ -52362,8 +52365,6 @@ package android.view {
method public void setAccessibilityTraversalBefore(@IdRes int);
method public void setActivated(boolean);
method public void setAllowClickWhenDisabled(boolean);
- method public void setAllowedHandwritingDelegatePackage(@NonNull String);
- method public void setAllowedHandwritingDelegatorPackage(@NonNull String);
method public void setAlpha(@FloatRange(from=0.0, to=1.0) float);
method public void setAnimation(android.view.animation.Animation);
method public void setAnimationMatrix(@Nullable android.graphics.Matrix);
@@ -52406,7 +52407,7 @@ package android.view {
method public void setForegroundTintList(@Nullable android.content.res.ColorStateList);
method public void setForegroundTintMode(@Nullable android.graphics.PorterDuff.Mode);
method public void setHandwritingBoundsOffsets(float, float, float, float);
- method public void setHandwritingDelegatorCallback(@Nullable Runnable);
+ method public void setHandwritingDelegateConfiguration(@Nullable android.view.HandwritingDelegateConfiguration);
method public void setHapticFeedbackEnabled(boolean);
method public void setHasTransientState(boolean);
method public void setHorizontalFadingEdgeEnabled(boolean);
@@ -52419,7 +52420,6 @@ package android.view {
method public void setImportantForAutofill(int);
method public void setImportantForContentCapture(int);
method public void setIsCredential(boolean);
- method public void setIsHandwritingDelegate(boolean);
method public void setKeepScreenOn(boolean);
method public void setKeyboardNavigationCluster(boolean);
method public void setLabelFor(@IdRes int);
@@ -55618,8 +55618,6 @@ package android.view.inputmethod {
}
public final class InputMethodManager {
- method public boolean acceptStylusHandwritingDelegation(@NonNull android.view.View);
- method public boolean acceptStylusHandwritingDelegation(@NonNull android.view.View, @NonNull String);
method public void dispatchKeyEventFromInputMethod(@Nullable android.view.View, @NonNull android.view.KeyEvent);
method public void displayCompletions(android.view.View, android.view.inputmethod.CompletionInfo[]);
method @Nullable public android.view.inputmethod.InputMethodInfo getCurrentInputMethodInfo();
@@ -55641,8 +55639,6 @@ package android.view.inputmethod {
method public boolean isInputMethodSuppressingSpellChecker();
method public boolean isStylusHandwritingAvailable();
method @Deprecated public boolean isWatchingCursor(android.view.View);
- method public void prepareStylusHandwritingDelegation(@NonNull android.view.View);
- method public void prepareStylusHandwritingDelegation(@NonNull android.view.View, @NonNull String);
method public void restartInput(android.view.View);
method public void sendAppPrivateCommand(android.view.View, String, android.os.Bundle);
method @Deprecated public void setAdditionalInputMethodSubtypes(@NonNull String, @NonNull android.view.inputmethod.InputMethodSubtype[]);
diff --git a/core/java/android/view/HandwritingDelegateConfiguration.java b/core/java/android/view/HandwritingDelegateConfiguration.java
new file mode 100644
index 000000000000..719c614f42f0
--- /dev/null
+++ b/core/java/android/view/HandwritingDelegateConfiguration.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.annotation.IdRes;
+import android.annotation.NonNull;
+
+/**
+ * Configuration for a view to act as a handwriting initiation delegate. This allows handwriting
+ * mode for a delegator editor view to be initiated by stylus movement on the delegate view.
+ *
+ * <p>If a stylus {@link MotionEvent} occurs within the delegate view's bounds, the callback
+ * returned by {@link #getInitiationCallback()} will be called. The callback implementation is
+ * expected to show and focus the delegator editor view. If a view with identifier matching {@link
+ * #getDelegatorViewId()} creates an input connection while the same stylus {@link MotionEvent}
+ * sequence is ongoing, handwriting mode will be initiated for that view.
+ *
+ * <p>A common use case is a custom view which looks like a text editor but does not actually
+ * support text editing itself, and clicking on the custom view causes an EditText to be shown. To
+ * support handwriting initiation in this case, {@link View#setHandwritingDelegateConfiguration} can
+ * be called on the custom view to configure it as a delegate, and set the EditText as the delegator
+ * by passing the EditText's identifier as the {@code delegatorViewId}. The {@code
+ * initiationCallback} implementation is typically the same as the click listener implementation
+ * which shows the EditText.
+ */
+public class HandwritingDelegateConfiguration {
+ @IdRes private final int mDelegatorViewId;
+ @NonNull private final Runnable mInitiationCallback;
+
+ /**
+ * Constructs a HandwritingDelegateConfiguration instance.
+ *
+ * @param delegatorViewId identifier of the delegator editor view for which handwriting mode
+ * should be initiated
+ * @param initiationCallback callback called when a stylus {@link MotionEvent} occurs within
+ * this view's bounds. This will be called from the UI thread.
+ */
+ public HandwritingDelegateConfiguration(
+ @IdRes int delegatorViewId, @NonNull Runnable initiationCallback) {
+ mDelegatorViewId = delegatorViewId;
+ mInitiationCallback = initiationCallback;
+ }
+
+ /**
+ * Returns the identifier of the delegator editor view for which handwriting mode should be
+ * initiated.
+ */
+ public int getDelegatorViewId() {
+ return mDelegatorViewId;
+ }
+
+ /**
+ * Returns the callback which should be called when a stylus {@link MotionEvent} occurs within
+ * the delegate view's bounds. The callback should only be called from the UI thread.
+ */
+ @NonNull
+ public Runnable getInitiationCallback() {
+ return mInitiationCallback;
+ }
+}
diff --git a/core/java/android/view/HandwritingInitiator.java b/core/java/android/view/HandwritingInitiator.java
index 98f61a366381..8d221ab0b70a 100644
--- a/core/java/android/view/HandwritingInitiator.java
+++ b/core/java/android/view/HandwritingInitiator.java
@@ -16,6 +16,7 @@
package android.view;
+import android.annotation.IdRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -171,11 +172,15 @@ public class HandwritingInitiator {
if (candidateView != null) {
if (candidateView == getConnectedView()) {
startHandwriting(candidateView);
- } else if (candidateView.getHandwritingDelegatorCallback() != null) {
- mImm.prepareStylusHandwritingDelegation(
- candidateView,
- candidateView.getAllowedHandwritingDelegatePackageName());
- candidateView.getHandwritingDelegatorCallback().run();
+ } else if (candidateView.getHandwritingDelegateConfiguration() != null) {
+ mState.mDelegatorViewId =
+ candidateView
+ .getHandwritingDelegateConfiguration()
+ .getDelegatorViewId();
+ candidateView
+ .getHandwritingDelegateConfiguration()
+ .getInitiationCallback()
+ .run();
} else {
if (candidateView.getRevealOnFocusHint()) {
candidateView.setRevealOnFocusHint(false);
@@ -222,9 +227,6 @@ public class HandwritingInitiator {
} else {
mConnectedView = new WeakReference<>(view);
mConnectionCount = 1;
- if (view.isHandwritingDelegate() && tryAcceptStylusHandwritingDelegation(view)) {
- return;
- }
if (mState != null && mState.mShouldInitHandwriting) {
tryStartHandwriting();
}
@@ -277,15 +279,17 @@ public class HandwritingInitiator {
}
final Rect handwritingArea = getViewHandwritingArea(connectedView);
- if (isInHandwritingArea(
- handwritingArea, mState.mStylusDownX, mState.mStylusDownY, connectedView)) {
+ if ((mState.mDelegatorViewId != View.NO_ID
+ && mState.mDelegatorViewId == connectedView.getId())
+ || isInHandwritingArea(
+ handwritingArea, mState.mStylusDownX, mState.mStylusDownY, connectedView)) {
startHandwriting(connectedView);
} else {
mState.mShouldInitHandwriting = false;
}
}
- /** Starts a stylus handwriting session for the view. */
+ /** For test only. */
@VisibleForTesting
public void startHandwriting(@NonNull View view) {
mImm.startStylusHandwriting(view);
@@ -294,23 +298,6 @@ public class HandwritingInitiator {
}
/**
- * Starts a stylus handwriting session for the delegate view, if {@link
- * InputMethodManager#prepareStylusHandwritingDelegation} was previously called.
- */
- @VisibleForTesting
- public boolean tryAcceptStylusHandwritingDelegation(@NonNull View view) {
- if (mImm.acceptStylusHandwritingDelegation(
- view, view.getAllowedHandwritingDelegatorPackageName())) {
- if (mState != null) {
- mState.mHasInitiatedHandwriting = true;
- mState.mShouldInitHandwriting = false;
- }
- return true;
- }
- return false;
- }
-
- /**
* Notify that the handwriting area for the given view might be updated.
* @param view the view whose handwriting area might be updated.
*/
@@ -555,6 +542,13 @@ public class HandwritingInitiator {
* built InputConnection.
*/
private boolean mExceedHandwritingSlop;
+ /**
+ * If the current ongoing stylus MotionEvent sequence started over a handwriting initiation
+ * delegate view, then this is the view identifier of the corresponding delegator view. If
+ * the delegator view creates an input connection while the MotionEvent sequence is still
+ * ongoing, then handwriting mode will be initiated for the delegator view.
+ */
+ @IdRes private int mDelegatorViewId = View.NO_ID;
/** The pointer id of the stylus pointer that is being tracked. */
private final int mStylusPointerId;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index fee20517a499..7d18bf082bcb 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5101,13 +5101,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
private boolean mHoveringTouchDelegate = false;
- // These two fields are set if the view is a handwriting delegator.
- private Runnable mHandwritingDelegatorCallback;
- private String mAllowedHandwritingDelegatePackageName;
-
- // These two fields are set if the view is a handwriting delegate.
- private boolean mIsHandwritingDelegate;
- private String mAllowedHandwritingDelegatorPackageName;
+ /**
+ * Configuration for this view to act as a handwriting initiation delegate. This allows
+ * handwriting mode for a delegator editor view to be initiated by stylus movement on this
+ * delegate view.
+ */
+ private HandwritingDelegateConfiguration mHandwritingDelegateConfiguration;
/**
* Solid color to use as a background when creating the drawing cache. Enables
@@ -12411,168 +12410,27 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * Sets a callback which should be called when a stylus {@link MotionEvent} occurs within this
- * view's bounds. The callback will be called from the UI thread.
- *
- * <p>Setting a callback allows this view to act as a handwriting delegator, so that handwriting
- * mode for a delegate editor view can be initiated by stylus movement on this delegator view.
- * The callback implementation is expected to show and focus the delegate editor view. If a view
- * which returns {@code true} for {@link #isHandwritingDelegate()} creates an input connection
- * while the same stylus {@link MotionEvent} sequence is ongoing, handwriting mode will be
- * initiated for that view.
- *
- * <p>A common use case is a custom view which looks like a text editor but does not actually
- * support text editing itself, and clicking on the custom view causes an EditText to be shown.
- * To support handwriting initiation in this case, this method can be called on the custom view
- * to configure it as a delegator. The EditText should call {@link #setIsHandwritingDelegate} to
- * set it as a delegate. The {@code callback} implementation is typically the same as the click
- * listener implementation which shows the EditText.
+ * Configures this view to act as a handwriting initiation delegate. This allows handwriting
+ * mode for a delegator editor view to be initiated by stylus movement on this delegate view.
*
* <p>If {@code null} is passed, this view will no longer act as a handwriting initiation
- * delegator.
- *
- * @param callback a callback which should be called when a stylus {@link MotionEvent} occurs
- * within this view's bounds
+ * delegate.
*/
- public void setHandwritingDelegatorCallback(@Nullable Runnable callback) {
- mHandwritingDelegatorCallback = callback;
- if (callback != null) {
- // By default, the delegate must be from the same package as the delegator view.
- mAllowedHandwritingDelegatePackageName = mContext.getOpPackageName();
+ public void setHandwritingDelegateConfiguration(
+ @Nullable HandwritingDelegateConfiguration configuration) {
+ mHandwritingDelegateConfiguration = configuration;
+ if (configuration != null) {
setHandwritingArea(new Rect(0, 0, getWidth(), getHeight()));
- } else {
- mAllowedHandwritingDelegatePackageName = null;
}
}
/**
- * Returns the callback set by {@link #setHandwritingDelegatorCallback} which should be called
- * when a stylus {@link MotionEvent} occurs within this view's bounds. The callback should only
- * be called from the UI thread.
+ * If this view has been configured as a handwriting initiation delegate, returns the delegate
+ * configuration.
*/
@Nullable
- public Runnable getHandwritingDelegatorCallback() {
- return mHandwritingDelegatorCallback;
- }
-
- /**
- * Specifies that this view may act as a handwriting initiation delegator for a delegate editor
- * view from the specified package. If this method is not called, delegators may only be used to
- * initiate handwriting mode for a delegate editor view from the same package as the delegator
- * view. This method allows specifying a different trusted package which may contain a delegate
- * editor view linked to this delegator view. This should be called after {@link
- * #setHandwritingDelegatorCallback}.
- *
- * <p>If this method is called on the delegator view, then {@link
- * #setAllowedHandwritingDelegatorPackage} should also be called on the delegate editor view.
- *
- * <p>For example, to configure a delegator view in package 1:
- *
- * <pre>
- * delegatorView.setHandwritingDelegatorCallback(callback);
- * delegatorView.setAllowedHandwritingDelegatePackage(package2);</pre>
- *
- * Then to configure the corresponding delegate editor view in package 2:
- *
- * <pre>
- * delegateEditorView.setIsHandwritingDelegate(true);
- * delegateEditorView.setAllowedHandwritingDelegatorPackage(package1);</pre>
- *
- * @param allowedPackageName the package name of a delegate editor view linked to this delegator
- * view
- * @throws IllegalStateException If the view has not been configured as a handwriting delegator
- * using {@link #setHandwritingDelegatorCallback}.
- */
- public void setAllowedHandwritingDelegatePackage(@NonNull String allowedPackageName) {
- if (mHandwritingDelegatorCallback == null) {
- throw new IllegalStateException("This view is not a handwriting delegator.");
- }
- mAllowedHandwritingDelegatePackageName = allowedPackageName;
- }
-
- /**
- * Returns the allowed package for delegate editor views for which this view may act as a
- * handwriting delegator. If {@link #setAllowedHandwritingDelegatePackage} has not been called,
- * this will return this view's package name, since by default delegators may only be used to
- * initiate handwriting mode for a delegate editor view from the same package as the delegator
- * view. This will return a different allowed package if set by {@link
- * #setAllowedHandwritingDelegatePackage}.
- *
- * @throws IllegalStateException If the view has not been configured as a handwriting delegator
- * using {@link #setHandwritingDelegatorCallback}.
- */
- @NonNull
- public String getAllowedHandwritingDelegatePackageName() {
- if (mHandwritingDelegatorCallback == null) {
- throw new IllegalStateException("This view is not a handwriting delegator.");
- }
- return mAllowedHandwritingDelegatePackageName;
- }
-
- /**
- * Sets this view to be a handwriting delegate. If a delegate view creates an input connection
- * while a stylus {@link MotionEvent} sequence from a delegator view is ongoing, handwriting
- * mode will be initiated for the delegate view.
- *
- * @param isHandwritingDelegate whether this view is a handwriting initiation delegate
- * @see #setHandwritingDelegatorCallback(Runnable)
- */
- public void setIsHandwritingDelegate(boolean isHandwritingDelegate) {
- mIsHandwritingDelegate = isHandwritingDelegate;
- if (mIsHandwritingDelegate) {
- // By default, the delegator must be from the same package as the delegate view.
- mAllowedHandwritingDelegatorPackageName = mContext.getOpPackageName();
- } else {
- mAllowedHandwritingDelegatePackageName = null;
- }
- }
-
- /**
- * Returns whether this view has been set as a handwriting delegate by {@link
- * #setIsHandwritingDelegate}.
- */
- public boolean isHandwritingDelegate() {
- return mIsHandwritingDelegate;
- }
-
- /**
- * Specifies that a view from the specified package may act as a handwriting delegator for this
- * delegate editor view. If this method is not called, only views from the same package as the
- * delegate editor view may act as a handwriting delegator. This method allows specifying a
- * different trusted package which may contain a delegator view linked to this delegate editor
- * view. This should be called after {@link #setIsHandwritingDelegate}.
- *
- * <p>If this method is called on the delegate editor view, then {@link
- * #setAllowedHandwritingDelegatePackage} should also be called on the delegator view.
- *
- * @param allowedPackageName the package name of a delegator view linked to this delegate editor
- * view
- * @throws IllegalStateException If the view has not been configured as a handwriting delegate
- * using {@link #setIsHandwritingDelegate}.
- */
- public void setAllowedHandwritingDelegatorPackage(@NonNull String allowedPackageName) {
- if (!mIsHandwritingDelegate) {
- throw new IllegalStateException("This view is not a handwriting delegate.");
- }
- mAllowedHandwritingDelegatorPackageName = allowedPackageName;
- }
-
- /**
- * Returns the allowed package for views which may act as a handwriting delegator for this
- * delegate editor view. If {@link #setAllowedHandwritingDelegatorPackage} has not been called,
- * this will return this view's package name, since by default only views from the same package
- * as the delegator editor view may act as a handwriting delegator. This will return a different
- * allowed package if set by {@link #setAllowedHandwritingDelegatorPackage}.
- *
- * @throws IllegalStateException If the view has not been configured as a handwriting delegate
- * using {@link #setIsHandwritingDelegate}.
- */
- @NonNull
- public String getAllowedHandwritingDelegatorPackageName() {
- if (!mIsHandwritingDelegate) {
- throw new IllegalStateException("This view is not a handwriting delegate.");
- }
- return mAllowedHandwritingDelegatorPackageName;
+ public HandwritingDelegateConfiguration getHandwritingDelegateConfiguration() {
+ return mHandwritingDelegateConfiguration;
}
/**
@@ -24616,7 +24474,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
}
rebuildOutline();
- if (onCheckIsTextEditor() || mHandwritingDelegatorCallback != null) {
+ if (onCheckIsTextEditor() || mHandwritingDelegateConfiguration != null) {
setHandwritingArea(new Rect(0, 0, newWidth, newHeight));
}
}
diff --git a/core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java b/core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java
index db17a533c303..966026198a21 100644
--- a/core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java
+++ b/core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java
@@ -505,40 +505,6 @@ final class IInputMethodManagerGlobalInvoker {
}
@AnyThread
- static void prepareStylusHandwritingDelegation(
- @NonNull IInputMethodClient client,
- @NonNull String delegatePackageName,
- @NonNull String delegatorPackageName) {
- final IInputMethodManager service = getService();
- if (service == null) {
- return;
- }
- try {
- service.prepareStylusHandwritingDelegation(
- client, delegatePackageName, delegatorPackageName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- @AnyThread
- static boolean acceptStylusHandwritingDelegation(
- @NonNull IInputMethodClient client,
- @NonNull String delegatePackageName,
- @NonNull String delegatorPackageName) {
- final IInputMethodManager service = getService();
- if (service == null) {
- return false;
- }
- try {
- return service.acceptStylusHandwritingDelegation(
- client, delegatePackageName, delegatorPackageName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- @AnyThread
@RequiresPermission(value = Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)
static boolean isStylusHandwritingAvailableAsUser(@UserIdInt int userId) {
final IInputMethodManager service = getService();
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 36d2b8a89779..642182b5ddfd 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -99,7 +99,6 @@ import android.view.WindowManager;
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
-import android.widget.Editor;
import android.window.ImeOnBackInvokedDispatcher;
import android.window.WindowOnBackInvokedDispatcher;
@@ -1553,7 +1552,11 @@ public final class InputMethodManager {
if (fallbackContext == null) {
return false;
}
- if (!isStylusHandwritingEnabled(fallbackContext)) {
+ if (Settings.Global.getInt(fallbackContext.getContentResolver(),
+ Settings.Global.STYLUS_HANDWRITING_ENABLED, 0) == 0) {
+ if (DEBUG) {
+ Log.d(TAG, "Stylus handwriting is not enabled in settings.");
+ }
return false;
}
return IInputMethodManagerGlobalInvoker.isStylusHandwritingAvailableAsUser(userId);
@@ -2230,173 +2233,35 @@ public final class InputMethodManager {
* @see #isStylusHandwritingAvailable()
*/
public void startStylusHandwriting(@NonNull View view) {
- startStylusHandwritingInternal(view, null /* delegatorPackageName */);
- }
-
- private boolean startStylusHandwritingInternal(
- @NonNull View view, @Nullable String delegatorPackageName) {
- Objects.requireNonNull(view);
-
// Re-dispatch if there is a context mismatch.
final InputMethodManager fallbackImm = getFallbackInputMethodManagerIfNecessary(view);
if (fallbackImm != null) {
- fallbackImm.startStylusHandwritingInternal(view, delegatorPackageName);
+ fallbackImm.startStylusHandwriting(view);
}
+ Objects.requireNonNull(view);
- boolean useDelegation = !TextUtils.isEmpty(delegatorPackageName);
- if (!isStylusHandwritingEnabled(view.getContext())) {
- Log.w(TAG, "Stylus handwriting pref is disabled. "
- + "Ignoring calls to start stylus handwriting.");
- return false;
+ if (Settings.Global.getInt(view.getContext().getContentResolver(),
+ Settings.Global.STYLUS_HANDWRITING_ENABLED, 0) == 0) {
+ Log.d(TAG, "Ignoring startStylusHandwriting(view) as stylus handwriting is disabled");
+ return;
}
checkFocus();
synchronized (mH) {
if (!hasServedByInputMethodLocked(view)) {
Log.w(TAG,
- "Ignoring startStylusHandwriting as view=" + view + " is not served.");
- return false;
+ "Ignoring startStylusHandwriting() as view=" + view + " is not served.");
+ return;
}
if (view.getViewRootImpl() != mCurRootView) {
- Log.w(TAG,
- "Ignoring startStylusHandwriting: View's window does not have focus.");
- return false;
- }
- if (useDelegation) {
- return IInputMethodManagerGlobalInvoker.acceptStylusHandwritingDelegation(
- mClient, view.getContext().getOpPackageName(), delegatorPackageName);
- } else {
- IInputMethodManagerGlobalInvoker.startStylusHandwriting(mClient);
+ Log.w(TAG, "Ignoring startStylusHandwriting: View's window does not have focus.");
+ return;
}
- return false;
- }
- }
- private boolean isStylusHandwritingEnabled(@NonNull Context context) {
- if (Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED, 0) == 0) {
- Log.d(TAG, "Stylus handwriting pref is disabled.");
- return false;
+ IInputMethodManagerGlobalInvoker.startStylusHandwriting(mClient);
+ // TODO(b/210039666): do we need any extra work for supporting non-native
+ // UI toolkits?
}
- return true;
- }
-
- /**
- * Prepares delegation of starting stylus handwriting session to a different editor in same
- * or different window than the view on which initial handwriting stroke was detected.
- *
- * Delegation can be used to start stylus handwriting session before the {@link Editor} view or
- * its {@link InputConnection} is started. Calling this method starts buffering of stylus
- * motion events until {@link #acceptStylusHandwritingDelegation(View)} is called, at which
- * point the handwriting session can be started and the buffered stylus motion events will be
- * delivered to the IME.
- * e.g. Delegation can be used when initial handwriting stroke is
- * on a pseudo {@link Editor} like widget (with no {@link InputConnection}) but actual
- * {@link Editor} is on a different window.
- *
- * <p> Note: If an actual {@link Editor} capable of {@link InputConnection} is being scribbled
- * upon using stylus, use {@link #startStylusHandwriting(View)} instead.</p>
- *
- * @param delegatorView the view that receives initial stylus stroke and delegates it to the
- * actual editor. Its window must {@link View#hasWindowFocus have focus}.
- * @see #prepareStylusHandwritingDelegation(View, String)
- * @see #acceptStylusHandwritingDelegation(View)
- * @see #startStylusHandwriting(View)
- */
- public void prepareStylusHandwritingDelegation(@NonNull View delegatorView) {
- prepareStylusHandwritingDelegation(
- delegatorView, delegatorView.getContext().getOpPackageName());
- }
-
- /**
- * Prepares delegation of starting stylus handwriting session to a different editor in same or a
- * different window in a different package than the view on which initial handwriting stroke
- * was detected.
- *
- * Delegation can be used to start stylus handwriting session before the {@link Editor} view or
- * its {@link InputConnection} is started. Calling this method starts buffering of stylus
- * motion events until {@link #acceptStylusHandwritingDelegation(View, String)} is called, at
- * which point the handwriting session can be started and the buffered stylus motion events will
- * be delivered to the IME.
- * e.g. Delegation can be used when initial handwriting stroke is
- * on a pseudo {@link Editor} like widget (with no {@link InputConnection}) but actual
- * {@link Editor} is on a different window in the given package.
- *
- * <p>Note: If delegator and delegate are in same package use
- * {@link #prepareStylusHandwritingDelegation(View)} instead.</p>
- *
- * @param delegatorView the view that receives initial stylus stroke and delegates it to the
- * actual editor. Its window must {@link View#hasWindowFocus have focus}.
- * @param delegatePackageName package name that contains actual {@link Editor} which should
- * start stylus handwriting session by calling {@link #acceptStylusHandwritingDelegation}.
- * @see #prepareStylusHandwritingDelegation(View)
- * @see #acceptStylusHandwritingDelegation(View, String)
- */
- public void prepareStylusHandwritingDelegation(
- @NonNull View delegatorView, @NonNull String delegatePackageName) {
- Objects.requireNonNull(delegatorView);
- Objects.requireNonNull(delegatePackageName);
-
- // Re-dispatch if there is a context mismatch.
- final InputMethodManager fallbackImm =
- getFallbackInputMethodManagerIfNecessary(delegatorView);
- if (fallbackImm != null) {
- fallbackImm.prepareStylusHandwritingDelegation(delegatorView, delegatePackageName);
- }
-
- if (!isStylusHandwritingEnabled(delegatorView.getContext())) {
- Log.w(TAG, "Stylus handwriting pref is disabled. "
- + "Ignoring prepareStylusHandwritingDelegation().");
- return;
- }
- IInputMethodManagerGlobalInvoker.prepareStylusHandwritingDelegation(
- mClient,
- delegatePackageName,
- delegatorView.getContext().getOpPackageName());
- }
-
- /**
- * Accepts and starts a stylus handwriting session on the delegate view, if handwriting
- * initiation delegation was previously requested using
- * {@link #prepareStylusHandwritingDelegation(View)} from the delegator.
- *
- * <p>Note: If delegator and delegate are in different application packages, use
- * {@link #acceptStylusHandwritingDelegation(View, String)} instead.</p>
- *
- * @param delegateView delegate view capable of receiving input via {@link InputConnection}
- * on which {@link #startStylusHandwriting(View)} will be called.
- * @return {@code true} if view belongs to same application package as used in
- * {@link #prepareStylusHandwritingDelegation(View)} and handwriting session can start.
- * @see #acceptStylusHandwritingDelegation(View, String)
- * @see #prepareStylusHandwritingDelegation(View)
- */
- public boolean acceptStylusHandwritingDelegation(@NonNull View delegateView) {
- return startStylusHandwritingInternal(
- delegateView, delegateView.getContext().getOpPackageName());
- }
-
- /**
- * Accepts and starts a stylus handwriting session on the delegate view, if handwriting
- * initiation delegation was previously requested using
- * {@link #prepareStylusHandwritingDelegation(View, String)} from te delegator and the view
- * belongs to a specified delegate package.
- *
- * <p>Note: If delegator and delegate are in same application package use
- * {@link #acceptStylusHandwritingDelegation(View)} instead.</p>
- *
- * @param delegateView delegate view capable of receiving input via {@link InputConnection}
- * on which {@link #startStylusHandwriting(View)} will be called.
- * @param delegatorPackageName package name of the delegator that handled initial stylus stroke.
- * @return {@code true} if view belongs to allowed delegate package declared in
- * {@link #prepareStylusHandwritingDelegation(View, String)} and handwriting session can start.
- * @see #prepareStylusHandwritingDelegation(View, String)
- * @see #acceptStylusHandwritingDelegation(View)
- */
- public boolean acceptStylusHandwritingDelegation(
- @NonNull View delegateView, @NonNull String delegatorPackageName) {
- Objects.requireNonNull(delegatorPackageName);
-
- return startStylusHandwritingInternal(delegateView, delegatorPackageName);
}
/**
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 5805d0e050d1..9116cb3ec9fa 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -148,15 +148,6 @@ interface IInputMethodManager {
/** Start Stylus handwriting session **/
void startStylusHandwriting(in IInputMethodClient client);
- /** Prepares delegation of starting stylus handwriting session to a different editor **/
- void prepareStylusHandwritingDelegation(in IInputMethodClient client,
- in String delegatePackageName,
- in String delegatorPackageName);
-
- /** Accepts and starts a stylus handwriting session for the delegate view **/
- boolean acceptStylusHandwritingDelegation(in IInputMethodClient client,
- in String delegatePackageName, in String delegatorPackageName);
-
/** Returns {@code true} if currently selected IME supports Stylus handwriting. */
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)")
diff --git a/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java b/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
index 76f5277cfe0b..95aa5d0de119 100644
--- a/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
+++ b/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
@@ -32,6 +32,7 @@ import android.app.Instrumentation;
import android.content.Context;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
+import android.view.HandwritingDelegateConfiguration;
import android.view.HandwritingInitiator;
import android.view.InputDevice;
import android.view.MotionEvent;
@@ -209,11 +210,14 @@ public class HandwritingInitiatorTest {
@Test
public void onTouchEvent_startHandwriting_delegate() {
- View delegateView = new View(mContext);
- delegateView.setIsHandwritingDelegate(true);
+ int delegatorViewId = 234;
+ View delegatorView = new View(mContext);
+ delegatorView.setId(delegatorViewId);
- mTestView.setHandwritingDelegatorCallback(
- () -> mHandwritingInitiator.onInputConnectionCreated(delegateView));
+ mTestView.setHandwritingDelegateConfiguration(
+ new HandwritingDelegateConfiguration(
+ delegatorViewId,
+ () -> mHandwritingInitiator.onInputConnectionCreated(delegatorView)));
final int x1 = (sHwArea.left + sHwArea.right) / 2;
final int y1 = (sHwArea.top + sHwArea.bottom) / 2;
@@ -225,7 +229,7 @@ public class HandwritingInitiatorTest {
MotionEvent stylusEvent2 = createStylusEvent(ACTION_MOVE, x2, y2, 0);
mHandwritingInitiator.onTouchEvent(stylusEvent2);
- verify(mHandwritingInitiator, times(1)).tryAcceptStylusHandwritingDelegation(delegateView);
+ verify(mHandwritingInitiator, times(1)).startHandwriting(delegatorView);
}
@Test
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
index eb4dba63dea9..1c7294f8a9d5 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
@@ -20,14 +20,12 @@ import static android.view.InputDevice.SOURCE_STYLUS;
import android.Manifest;
import android.annotation.AnyThread;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.UiThread;
import android.hardware.input.InputManager;
import android.os.IBinder;
import android.os.Looper;
-import android.text.TextUtils;
import android.util.Slog;
import android.view.BatchedInputEventReceiver;
import android.view.Choreographer;
@@ -37,8 +35,6 @@ import android.view.InputEvent;
import android.view.InputEventReceiver;
import android.view.MotionEvent;
import android.view.SurfaceControl;
-import android.view.View;
-import android.view.inputmethod.InputMethodManager;
import com.android.server.LocalServices;
import com.android.server.input.InputManagerInternal;
@@ -56,9 +52,6 @@ final class HandwritingModeController {
// TODO(b/210039666): flip the flag.
static final boolean DEBUG = true;
private static final int EVENT_BUFFER_SIZE = 100;
- // A longer event buffer used for handwriting delegation
- // TODO(b/210039666): make this device touch sampling rate dependent.
- private static final int LONG_EVENT_BUFFER = EVENT_BUFFER_SIZE * 20;
// This must be the looper for the UiThread.
private final Looper mLooper;
@@ -70,9 +63,6 @@ final class HandwritingModeController {
private Runnable mInkWindowInitRunnable;
private boolean mRecordingGesture;
private int mCurrentDisplayId;
- // when set, package names are used for handwriting delegation.
- private @Nullable String mDelegatePackageName;
- private @Nullable String mDelegatorPackageName;
private HandwritingEventReceiverSurface mHandwritingSurface;
@@ -147,41 +137,6 @@ final class HandwritingModeController {
return mRecordingGesture;
}
- boolean hasOngoingStylusHandwritingSession() {
- return mHandwritingSurface != null && mHandwritingSurface.isIntercepting();
- }
-
- /**
- * Prepare delegation of stylus handwriting to a different editor
- * @see InputMethodManager#prepareStylusHandwritingDelegation(View, String)
- */
- void prepareStylusHandwritingDelegation(
- @NonNull String delegatePackageName, @NonNull String delegatorPackageName) {
- mDelegatePackageName = delegatePackageName;
- mDelegatorPackageName = delegatorPackageName;
- ((ArrayList) mHandwritingBuffer).ensureCapacity(LONG_EVENT_BUFFER);
- // TODO(b/210039666): cancel delegation after a timeout or next input method client binding.
- }
-
- @Nullable String getDelegatePackageName() {
- return mDelegatePackageName;
- }
-
- @Nullable String getDelegatorPackageName() {
- return mDelegatorPackageName;
- }
-
- /**
- * Clear any pending handwriting delegation info.
- */
- void clearPendingHandwritingDelegation() {
- if (DEBUG) {
- Slog.d(TAG, "clearPendingHandwritingDelegation");
- }
- mDelegatorPackageName = null;
- mDelegatePackageName = null;
- }
-
/**
* Starts a {@link HandwritingSession} to transfer to the IME.
*
@@ -268,7 +223,6 @@ final class HandwritingModeController {
}
}
- clearPendingHandwritingDelegation();
mRecordingGesture = false;
}
@@ -305,10 +259,7 @@ final class HandwritingModeController {
mInkWindowInitRunnable = null;
}
- // If handwriting delegation is ongoing, don't clear the buffer so that multiple strokes
- // can be buffered across windows.
- if (TextUtils.isEmpty(mDelegatePackageName)
- && (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL)) {
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
mRecordingGesture = false;
mHandwritingBuffer.clear();
return;
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 8ef4e4afae9b..f5875abe17e6 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -236,8 +236,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
private static final int MSG_FINISH_HANDWRITING = 1110;
private static final int MSG_REMOVE_HANDWRITING_WINDOW = 1120;
- private static final int MSG_PREPARE_HANDWRITING_DELEGATION = 1130;
-
private static final int MSG_SET_INTERACTIVE = 3030;
private static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000;
@@ -2691,14 +2689,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
@AnyThread
- void schedulePrepareStylusHandwritingDelegation(
- @NonNull String delegatePackageName, @NonNull String delegatorPackageName) {
- mHandler.obtainMessage(
- MSG_PREPARE_HANDWRITING_DELEGATION,
- new Pair<>(delegatePackageName, delegatorPackageName)).sendToTarget();
- }
-
- @AnyThread
void scheduleRemoveStylusHandwritingWindow() {
mHandler.obtainMessage(MSG_REMOVE_HANDWRITING_WINDOW).sendToTarget();
}
@@ -3314,7 +3304,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
"InputMethodManagerService#startStylusHandwriting");
int uid = Binder.getCallingUid();
synchronized (ImfLock.class) {
- mHwController.clearPendingHandwritingDelegation();
if (!canInteractWithImeLocked(uid, client, "startStylusHandwriting",
null /* statsToken */)) {
return;
@@ -3342,13 +3331,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
"There is no ongoing stylus gesture to start stylus handwriting.");
return;
}
- if (mHwController.hasOngoingStylusHandwritingSession()) {
- // prevent duplicate calls to startStylusHandwriting().
- Slog.e(TAG,
- "Stylus handwriting session is already ongoing."
- + " Ignoring startStylusHandwriting().");
- return;
- }
if (DEBUG) Slog.v(TAG, "Client requesting Stylus Handwriting to be started");
final IInputMethodInvoker curMethod = getCurMethodLocked();
if (curMethod != null) {
@@ -3363,68 +3345,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- @Override
- public void prepareStylusHandwritingDelegation(
- @NonNull IInputMethodClient client,
- @NonNull String delegatePackageName,
- @NonNull String delegatorPackageName) {
- if (!verifyClientAndPackageMatch(client, delegatorPackageName)) {
- Slog.w(TAG, "prepareStylusHandwritingDelegation() fail");
- throw new IllegalArgumentException("Delegator doesn't match Uid");
- }
- schedulePrepareStylusHandwritingDelegation(delegatePackageName, delegatorPackageName);
- }
-
- @Override
- public boolean acceptStylusHandwritingDelegation(
- @NonNull IInputMethodClient client,
- @NonNull String delegatePackageName,
- @NonNull String delegatorPackageName) {
- if (!verifyDelegator(client, delegatePackageName, delegatorPackageName)) {
- return false;
- }
-
- startStylusHandwriting(client);
- return true;
- }
-
- private boolean verifyClientAndPackageMatch(
- @NonNull IInputMethodClient client, @NonNull String packageName) {
- ClientState cs;
- synchronized (ImfLock.class) {
- cs = mClients.get(client.asBinder());
- }
- if (cs == null) {
- throw new IllegalArgumentException("unknown client " + client.asBinder());
- }
- return InputMethodUtils.checkIfPackageBelongsToUid(
- mPackageManagerInternal, cs.mUid, packageName);
- }
-
- private boolean verifyDelegator(
- @NonNull IInputMethodClient client,
- @NonNull String delegatePackageName,
- @NonNull String delegatorPackageName) {
- if (!verifyClientAndPackageMatch(client, delegatePackageName)) {
- Slog.w(TAG, "Delegate package does not belong to the same user. Ignoring"
- + " startStylusHandwriting");
- return false;
- }
- synchronized (ImfLock.class) {
- if (!delegatorPackageName.equals(mHwController.getDelegatorPackageName())) {
- Slog.w(TAG,
- "Delegator package does not match. Ignoring startStylusHandwriting");
- return false;
- }
- if (!delegatePackageName.equals(mHwController.getDelegatePackageName())) {
- Slog.w(TAG,
- "Delegate package does not match. Ignoring startStylusHandwriting");
- return false;
- }
- }
- return true;
- }
-
@BinderThread
@Override
public void reportPerceptibleAsync(IBinder windowToken, boolean perceptible) {
@@ -4932,13 +4852,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
return true;
}
- case MSG_PREPARE_HANDWRITING_DELEGATION:
- synchronized (ImfLock.class) {
- String delegate = (String) ((Pair) msg.obj).first;
- String delegator = (String) ((Pair) msg.obj).second;
- mHwController.prepareStylusHandwritingDelegation(delegate, delegator);
- }
- return true;
case MSG_START_HANDWRITING:
synchronized (ImfLock.class) {
IInputMethodInvoker curMethod = getCurMethodLocked();