Loading core/java/android/view/HandwritingInitiator.java +3 −26 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static com.android.text.flags.Flags.handwritingTrackDisabled; import static com.android.text.flags.Flags.handwritingUnsupportedMessage; import static com.android.text.flags.Flags.handwritingUnsupportedShowSoftInputFix; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; Loading Loading @@ -330,7 +329,8 @@ public class HandwritingInitiator { mConnectionCount = 1; // A new view just gain focus. By default, we should show hover icon for it. mShowHoverIconForConnectedView = true; if (view.isHandwritingDelegate() && tryAcceptStylusHandwritingDelegation(view)) { if (view.isHandwritingDelegate()) { tryAcceptStylusHandwritingDelegation(view); // tryAcceptStylusHandwritingDelegation should set boolean below, however, we // cannot mock IMM to return true for acceptStylusDelegation(). // TODO(b/324670412): we should move any dependent tests to integration and remove Loading Loading @@ -477,30 +477,7 @@ public class HandwritingInitiator { * InputMethodManager#prepareStylusHandwritingDelegation} was previously called. */ @VisibleForTesting public boolean tryAcceptStylusHandwritingDelegation(@NonNull View view) { if (Flags.useZeroJankProxy()) { tryAcceptStylusHandwritingDelegationAsync(view); } else { return tryAcceptStylusHandwritingDelegationInternal(view); } return false; } private boolean tryAcceptStylusHandwritingDelegationInternal(@NonNull View view) { String delegatorPackageName = view.getAllowedHandwritingDelegatorPackageName(); if (delegatorPackageName == null) { delegatorPackageName = view.getContext().getOpPackageName(); } if (mImm.acceptStylusHandwritingDelegation(view, delegatorPackageName)) { onDelegationAccepted(view); return true; } return false; } @FlaggedApi(Flags.FLAG_USE_ZERO_JANK_PROXY) private void tryAcceptStylusHandwritingDelegationAsync(@NonNull View view) { public void tryAcceptStylusHandwritingDelegation(@NonNull View view) { String delegatorPackageName = view.getAllowedHandwritingDelegatorPackageName(); if (delegatorPackageName == null) { Loading core/java/android/view/inputmethod/InputMethodManager.java +36 −107 Original line number Diff line number Diff line Loading @@ -958,6 +958,7 @@ public final class InputMethodManager { // ignore the result Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMM.startInputOrWindowGainedFocus"); //TODO(b/418839448): use async method. IInputMethodManagerGlobalInvoker.startInputOrWindowGainedFocus( StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY, mClient, viewForWindowFocus.getWindowToken(), startInputFlags, softInputMode, Loading Loading @@ -3044,6 +3045,7 @@ public final class InputMethodManager { delegateView.getHandwritingDelegateFlags()); } // TODO (b/418839728): deprecate this method since zeroJankProxy is enabled by default. /** * Accepts and starts a stylus handwriting session on the delegate view, if handwriting * initiation delegation was previously requested using Loading @@ -3066,7 +3068,6 @@ public final class InputMethodManager { * @see #acceptStylusHandwritingDelegation(View) * @see #startConnectionlessStylusHandwritingForDelegation(View, CursorAnchorInfo, String, * Executor, ConnectionlessHandwritingCallback) * TODO (b/293640003): deprecate this method once flag is enabled. */ public boolean acceptStylusHandwritingDelegation( @NonNull View delegateView, @NonNull String delegatorPackageName) { Loading Loading @@ -3390,8 +3391,6 @@ public final class InputMethodManager { final InputConnection ic = connectionPair.first; final EditorInfo editorInfo = connectionPair.second; final Handler icHandler; InputBindResult res = null; final boolean hasServedView; final boolean imeRequestedVisible; synchronized (mH) { // Now that we are locked again, validate that our state hasn't Loading Loading @@ -3488,27 +3487,17 @@ public final class InputMethodManager { ? editorInfo.targetInputMethodUser.getIdentifier() : UserHandle.myUserId(); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMM.startInputOrWindowGainedFocus"); int startInputSeq = INVALID_SEQ_ID; if (Flags.useZeroJankProxy()) { // async result delivered via MSG_START_INPUT_RESULT. startInputSeq = IInputMethodManagerGlobalInvoker.startInputOrWindowGainedFocusAsync( final int startInputSeq = IInputMethodManagerGlobalInvoker.startInputOrWindowGainedFocusAsync( startInputReason, mClient, windowGainingFocus, startInputFlags, softInputMode, windowFlags, editorInfo, servedInputConnection, servedInputConnection == null ? null : servedInputConnection.asIRemoteAccessibilityInputConnection(), view.getContext().getApplicationInfo().targetSdkVersion, targetUserId, mImeDispatcher, imeRequestedVisible, mAsyncShowHideMethodEnabled); } else { res = IInputMethodManagerGlobalInvoker.startInputOrWindowGainedFocus( startInputReason, mClient, windowGainingFocus, startInputFlags, softInputMode, windowFlags, editorInfo, servedInputConnection, servedInputConnection == null ? null : servedInputConnection.asIRemoteAccessibilityInputConnection(), view.getContext().getApplicationInfo().targetSdkVersion, targetUserId, mImeDispatcher, imeRequestedVisible); } Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); if (Flags.useZeroJankProxy()) { // Create a runnable for delayed notification to the app that the InputConnection is // initialized and ready for use. if (ic != null) { Loading @@ -3533,67 +3522,7 @@ public final class InputMethodManager { } else { mReportInputConnectionOpenedRunner = null; } return true; } if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res); if (res == null) { Log.wtf(TAG, "startInputOrWindowGainedFocus must not return" + " null. startInputReason=" + InputMethodDebug.startInputReasonToString(startInputReason) + " editorInfo=" + editorInfo + " startInputFlags=" + InputMethodDebug.startInputFlagsToString(startInputFlags)); return false; } if (res.id != null) { updateInputChannelLocked(res.channel); mCurMethod = res.method; // for @UnsupportedAppUsage mCurBindState = new BindState(res); mAccessibilityInputMethodSession.clear(); if (res.accessibilitySessions != null) { for (int i = 0; i < res.accessibilitySessions.size(); i++) { IAccessibilityInputMethodSessionInvoker wrapper = IAccessibilityInputMethodSessionInvoker.createOrNull( res.accessibilitySessions.valueAt(i)); if (wrapper != null) { mAccessibilityInputMethodSession.append( res.accessibilitySessions.keyAt(i), wrapper); } } } mCurId = res.id; // for @UnsupportedAppUsage } else if (res.channel != null && res.channel != mCurChannel) { res.channel.dispose(); } switch (res.result) { case InputBindResult.ResultCode.ERROR_NOT_IME_TARGET_WINDOW: mRestartOnNextWindowFocus = true; if (initiationWithoutInputConnection()) { mServedView.getViewRootImpl().getHandwritingInitiator().clearFocusedView( mServedView); } mServedView = null; break; } if (mCompletions != null) { if (isImeSessionAvailableLocked()) { mCurBindState.mImeSession.displayCompletions(mCompletions); } } hasServedView = mServedView != null; } // Notify the app that the InputConnection is initialized and ready for use. if (ic != null && res != null && res.method != null && hasServedView) { if (DEBUG) { Log.v(TAG, "Calling View.onInputConnectionOpened: view= " + view + ", ic=" + ic + ", editorInfo=" + editorInfo + ", handler=" + icHandler); } reportInputConnectionOpened(ic, editorInfo, icHandler, view); } return true; } Loading core/java/com/android/internal/view/IInputMethodManager.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -83,7 +83,8 @@ interface IInputMethodManager { + "android.Manifest.permission.TEST_INPUT_METHOD)") void hideSoftInputFromServerForTest(); // TODO(b/293640003): Remove method once Flags.useZeroJankProxy() is enabled. // TODO(b/418839448): merge with startInputOrWindowGainedFocus once // WINDOW_FOCUS_GAIN_REPORT_ONLY uses async method. // If windowToken is null, this just does startInput(). Otherwise this reports that a window // has gained focus, and if 'editorInfo' is non-null then also does startInput. // @NonNull Loading core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java +0 −2 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import static org.junit.Assume.assumeFalse; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; Loading Loading @@ -126,7 +125,6 @@ public class HandwritingInitiatorTest { HW_BOUNDS_OFFSETS_BOTTOM_PX); mHandwritingInitiator.updateHandwritingAreasForView(mTestView1); mHandwritingInitiator.updateHandwritingAreasForView(mTestView2); doReturn(true).when(mHandwritingInitiator).tryAcceptStylusHandwritingDelegation(any()); mInitiateWithoutConnection = initiationWithoutInputConnection(); } Loading services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +4 −14 Original line number Diff line number Diff line Loading @@ -1041,12 +1041,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. @Override public void onStart() { mService.publishLocalService(); IInputMethodManagerImpl.Callback service; if (Flags.useZeroJankProxy()) { service = new ZeroJankProxy(mService.mHandler::post, mService); } else { service = mService; } IInputMethodManagerImpl.Callback service = new ZeroJankProxy(mService.mHandler::post, mService); publishBinderService(Context.INPUT_METHOD_SERVICE, IInputMethodManagerImpl.create(service), false /*allowIsolated*/, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO); Loading Loading @@ -2229,12 +2225,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. @UserIdInt int userId) { if (bindingController.hasMainConnection()) { if (bindingController.getCurMethod() != null) { if (!Flags.useZeroJankProxy()) { // Return to client, and we will get back with it when // we have had a session made for it. requestClientSessionLocked(cs, userId); requestClientSessionForAccessibilityLocked(cs); } return new InputBindResult( InputBindResult.ResultCode.SUCCESS_WAITING_IME_SESSION, null, null, null, Loading Loading @@ -3502,8 +3492,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. return imeClientFocus == WindowManagerInternal.ImeClientFocusResult.HAS_IME_FOCUS; } //TODO(b/293640003): merge with startInputOrWindowGainedFocus once Flags.useZeroJankProxy() // is enabled. //TODO(b/418839448): merge with startInputOrWindowGainedFocus once WINDOW_FOCUS_GAIN_REPORT_ONLY // uses async method. @Override public void startInputOrWindowGainedFocusAsync( @StartInputReason int startInputReason, IInputMethodClient client, IBinder windowToken, Loading Loading
core/java/android/view/HandwritingInitiator.java +3 −26 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static com.android.text.flags.Flags.handwritingTrackDisabled; import static com.android.text.flags.Flags.handwritingUnsupportedMessage; import static com.android.text.flags.Flags.handwritingUnsupportedShowSoftInputFix; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; Loading Loading @@ -330,7 +329,8 @@ public class HandwritingInitiator { mConnectionCount = 1; // A new view just gain focus. By default, we should show hover icon for it. mShowHoverIconForConnectedView = true; if (view.isHandwritingDelegate() && tryAcceptStylusHandwritingDelegation(view)) { if (view.isHandwritingDelegate()) { tryAcceptStylusHandwritingDelegation(view); // tryAcceptStylusHandwritingDelegation should set boolean below, however, we // cannot mock IMM to return true for acceptStylusDelegation(). // TODO(b/324670412): we should move any dependent tests to integration and remove Loading Loading @@ -477,30 +477,7 @@ public class HandwritingInitiator { * InputMethodManager#prepareStylusHandwritingDelegation} was previously called. */ @VisibleForTesting public boolean tryAcceptStylusHandwritingDelegation(@NonNull View view) { if (Flags.useZeroJankProxy()) { tryAcceptStylusHandwritingDelegationAsync(view); } else { return tryAcceptStylusHandwritingDelegationInternal(view); } return false; } private boolean tryAcceptStylusHandwritingDelegationInternal(@NonNull View view) { String delegatorPackageName = view.getAllowedHandwritingDelegatorPackageName(); if (delegatorPackageName == null) { delegatorPackageName = view.getContext().getOpPackageName(); } if (mImm.acceptStylusHandwritingDelegation(view, delegatorPackageName)) { onDelegationAccepted(view); return true; } return false; } @FlaggedApi(Flags.FLAG_USE_ZERO_JANK_PROXY) private void tryAcceptStylusHandwritingDelegationAsync(@NonNull View view) { public void tryAcceptStylusHandwritingDelegation(@NonNull View view) { String delegatorPackageName = view.getAllowedHandwritingDelegatorPackageName(); if (delegatorPackageName == null) { Loading
core/java/android/view/inputmethod/InputMethodManager.java +36 −107 Original line number Diff line number Diff line Loading @@ -958,6 +958,7 @@ public final class InputMethodManager { // ignore the result Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMM.startInputOrWindowGainedFocus"); //TODO(b/418839448): use async method. IInputMethodManagerGlobalInvoker.startInputOrWindowGainedFocus( StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY, mClient, viewForWindowFocus.getWindowToken(), startInputFlags, softInputMode, Loading Loading @@ -3044,6 +3045,7 @@ public final class InputMethodManager { delegateView.getHandwritingDelegateFlags()); } // TODO (b/418839728): deprecate this method since zeroJankProxy is enabled by default. /** * Accepts and starts a stylus handwriting session on the delegate view, if handwriting * initiation delegation was previously requested using Loading @@ -3066,7 +3068,6 @@ public final class InputMethodManager { * @see #acceptStylusHandwritingDelegation(View) * @see #startConnectionlessStylusHandwritingForDelegation(View, CursorAnchorInfo, String, * Executor, ConnectionlessHandwritingCallback) * TODO (b/293640003): deprecate this method once flag is enabled. */ public boolean acceptStylusHandwritingDelegation( @NonNull View delegateView, @NonNull String delegatorPackageName) { Loading Loading @@ -3390,8 +3391,6 @@ public final class InputMethodManager { final InputConnection ic = connectionPair.first; final EditorInfo editorInfo = connectionPair.second; final Handler icHandler; InputBindResult res = null; final boolean hasServedView; final boolean imeRequestedVisible; synchronized (mH) { // Now that we are locked again, validate that our state hasn't Loading Loading @@ -3488,27 +3487,17 @@ public final class InputMethodManager { ? editorInfo.targetInputMethodUser.getIdentifier() : UserHandle.myUserId(); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMM.startInputOrWindowGainedFocus"); int startInputSeq = INVALID_SEQ_ID; if (Flags.useZeroJankProxy()) { // async result delivered via MSG_START_INPUT_RESULT. startInputSeq = IInputMethodManagerGlobalInvoker.startInputOrWindowGainedFocusAsync( final int startInputSeq = IInputMethodManagerGlobalInvoker.startInputOrWindowGainedFocusAsync( startInputReason, mClient, windowGainingFocus, startInputFlags, softInputMode, windowFlags, editorInfo, servedInputConnection, servedInputConnection == null ? null : servedInputConnection.asIRemoteAccessibilityInputConnection(), view.getContext().getApplicationInfo().targetSdkVersion, targetUserId, mImeDispatcher, imeRequestedVisible, mAsyncShowHideMethodEnabled); } else { res = IInputMethodManagerGlobalInvoker.startInputOrWindowGainedFocus( startInputReason, mClient, windowGainingFocus, startInputFlags, softInputMode, windowFlags, editorInfo, servedInputConnection, servedInputConnection == null ? null : servedInputConnection.asIRemoteAccessibilityInputConnection(), view.getContext().getApplicationInfo().targetSdkVersion, targetUserId, mImeDispatcher, imeRequestedVisible); } Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); if (Flags.useZeroJankProxy()) { // Create a runnable for delayed notification to the app that the InputConnection is // initialized and ready for use. if (ic != null) { Loading @@ -3533,67 +3522,7 @@ public final class InputMethodManager { } else { mReportInputConnectionOpenedRunner = null; } return true; } if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res); if (res == null) { Log.wtf(TAG, "startInputOrWindowGainedFocus must not return" + " null. startInputReason=" + InputMethodDebug.startInputReasonToString(startInputReason) + " editorInfo=" + editorInfo + " startInputFlags=" + InputMethodDebug.startInputFlagsToString(startInputFlags)); return false; } if (res.id != null) { updateInputChannelLocked(res.channel); mCurMethod = res.method; // for @UnsupportedAppUsage mCurBindState = new BindState(res); mAccessibilityInputMethodSession.clear(); if (res.accessibilitySessions != null) { for (int i = 0; i < res.accessibilitySessions.size(); i++) { IAccessibilityInputMethodSessionInvoker wrapper = IAccessibilityInputMethodSessionInvoker.createOrNull( res.accessibilitySessions.valueAt(i)); if (wrapper != null) { mAccessibilityInputMethodSession.append( res.accessibilitySessions.keyAt(i), wrapper); } } } mCurId = res.id; // for @UnsupportedAppUsage } else if (res.channel != null && res.channel != mCurChannel) { res.channel.dispose(); } switch (res.result) { case InputBindResult.ResultCode.ERROR_NOT_IME_TARGET_WINDOW: mRestartOnNextWindowFocus = true; if (initiationWithoutInputConnection()) { mServedView.getViewRootImpl().getHandwritingInitiator().clearFocusedView( mServedView); } mServedView = null; break; } if (mCompletions != null) { if (isImeSessionAvailableLocked()) { mCurBindState.mImeSession.displayCompletions(mCompletions); } } hasServedView = mServedView != null; } // Notify the app that the InputConnection is initialized and ready for use. if (ic != null && res != null && res.method != null && hasServedView) { if (DEBUG) { Log.v(TAG, "Calling View.onInputConnectionOpened: view= " + view + ", ic=" + ic + ", editorInfo=" + editorInfo + ", handler=" + icHandler); } reportInputConnectionOpened(ic, editorInfo, icHandler, view); } return true; } Loading
core/java/com/android/internal/view/IInputMethodManager.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -83,7 +83,8 @@ interface IInputMethodManager { + "android.Manifest.permission.TEST_INPUT_METHOD)") void hideSoftInputFromServerForTest(); // TODO(b/293640003): Remove method once Flags.useZeroJankProxy() is enabled. // TODO(b/418839448): merge with startInputOrWindowGainedFocus once // WINDOW_FOCUS_GAIN_REPORT_ONLY uses async method. // If windowToken is null, this just does startInput(). Otherwise this reports that a window // has gained focus, and if 'editorInfo' is non-null then also does startInput. // @NonNull Loading
core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java +0 −2 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import static org.junit.Assume.assumeFalse; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; Loading Loading @@ -126,7 +125,6 @@ public class HandwritingInitiatorTest { HW_BOUNDS_OFFSETS_BOTTOM_PX); mHandwritingInitiator.updateHandwritingAreasForView(mTestView1); mHandwritingInitiator.updateHandwritingAreasForView(mTestView2); doReturn(true).when(mHandwritingInitiator).tryAcceptStylusHandwritingDelegation(any()); mInitiateWithoutConnection = initiationWithoutInputConnection(); } Loading
services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +4 −14 Original line number Diff line number Diff line Loading @@ -1041,12 +1041,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. @Override public void onStart() { mService.publishLocalService(); IInputMethodManagerImpl.Callback service; if (Flags.useZeroJankProxy()) { service = new ZeroJankProxy(mService.mHandler::post, mService); } else { service = mService; } IInputMethodManagerImpl.Callback service = new ZeroJankProxy(mService.mHandler::post, mService); publishBinderService(Context.INPUT_METHOD_SERVICE, IInputMethodManagerImpl.create(service), false /*allowIsolated*/, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO); Loading Loading @@ -2229,12 +2225,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. @UserIdInt int userId) { if (bindingController.hasMainConnection()) { if (bindingController.getCurMethod() != null) { if (!Flags.useZeroJankProxy()) { // Return to client, and we will get back with it when // we have had a session made for it. requestClientSessionLocked(cs, userId); requestClientSessionForAccessibilityLocked(cs); } return new InputBindResult( InputBindResult.ResultCode.SUCCESS_WAITING_IME_SESSION, null, null, null, Loading Loading @@ -3502,8 +3492,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. return imeClientFocus == WindowManagerInternal.ImeClientFocusResult.HAS_IME_FOCUS; } //TODO(b/293640003): merge with startInputOrWindowGainedFocus once Flags.useZeroJankProxy() // is enabled. //TODO(b/418839448): merge with startInputOrWindowGainedFocus once WINDOW_FOCUS_GAIN_REPORT_ONLY // uses async method. @Override public void startInputOrWindowGainedFocusAsync( @StartInputReason int startInputReason, IInputMethodClient client, IBinder windowToken, Loading