From a975bfc447b04fe90a5ec9c3d4757810f7d07af1 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Fri, 9 Jul 2021 09:46:58 -0700 Subject: Introduce InputMethodServiceInternal for better abstraction This is a mechanical refactoring CL that has no behavior change. This CL removes the direct dependency on AbstractInputMethodService from whenever possible. As a result, the following classes no longer directly depend on AbstractInputMethodService. * android.inputmethodservice.IInputMethodWrapper * android.inputmethodservice.RemoteInputConnection * com.android.internal.inputmethod.ImeTracing * com.android.internal.inputmethod.ImeTracingClientImpl * com.android.internal.inputmethod.ImeTracingServerImpl This is still a purely mechanical refactoring. There should be no observable behavior change. Bug: 192412909 Test: atest CtsInputMethodTestCases Test: Manually verified that IME tracing still works Change-Id: I2aeeeacd27195ce10059d6590e098a4a969e774d --- .../inputmethodservice/InputMethodService.java | 231 ++++++++++++--------- 1 file changed, 128 insertions(+), 103 deletions(-) (limited to 'core/java/android/inputmethodservice/InputMethodService.java') diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index e0b001f5ed19..dadea6792ac1 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -55,7 +55,6 @@ import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACK import static java.lang.annotation.RetentionPolicy.SOURCE; -import android.annotation.AnyThread; import android.annotation.CallSuper; import android.annotation.DrawableRes; import android.annotation.IntDef; @@ -740,7 +739,7 @@ public class InputMethodService extends AbstractInputMethodService { return; } ImeTracing.getInstance().triggerServiceDump( - "InputMethodService.InputMethodImpl#hideSoftInput", InputMethodService.this, + "InputMethodService.InputMethodImpl#hideSoftInput", mDumper, null /* icProto */); final boolean wasVisible = isInputViewShown(); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.hideSoftInput"); @@ -797,7 +796,7 @@ public class InputMethodService extends AbstractInputMethodService { } Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.showSoftInput"); ImeTracing.getInstance().triggerServiceDump( - "InputMethodService.InputMethodImpl#showSoftInput", InputMethodService.this, + "InputMethodService.InputMethodImpl#showSoftInput", mDumper, null /* icProto */); final boolean wasVisible = isInputViewShown(); if (dispatchOnShowInputRequested(flags, false)) { @@ -2222,7 +2221,7 @@ public class InputMethodService extends AbstractInputMethodService { return; } - ImeTracing.getInstance().triggerServiceDump("InputMethodService#showWindow", this, + ImeTracing.getInstance().triggerServiceDump("InputMethodService#showWindow", mDumper, null /* icProto */); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.showWindow"); mDecorViewWasVisible = mDecorViewVisible; @@ -2301,7 +2300,7 @@ public class InputMethodService extends AbstractInputMethodService { */ private void applyVisibilityInInsetsConsumerIfNecessary(boolean setVisible) { ImeTracing.getInstance().triggerServiceDump( - "InputMethodService#applyVisibilityInInsetsConsumerIfNecessary", this, + "InputMethodService#applyVisibilityInInsetsConsumerIfNecessary", mDumper, null /* icProto */); if (setVisible) { cancelImeSurfaceRemoval(); @@ -2330,7 +2329,7 @@ public class InputMethodService extends AbstractInputMethodService { public void hideWindow() { if (DEBUG) Log.v(TAG, "CALL: hideWindow"); - ImeTracing.getInstance().triggerServiceDump("InputMethodService#hideWindow", this, + ImeTracing.getInstance().triggerServiceDump("InputMethodService#hideWindow", mDumper, null /* icProto */); mWindowVisible = false; finishViews(false /* finishingInput */); @@ -2403,7 +2402,7 @@ public class InputMethodService extends AbstractInputMethodService { void doFinishInput() { if (DEBUG) Log.v(TAG, "CALL: doFinishInput"); - ImeTracing.getInstance().triggerServiceDump("InputMethodService#doFinishInput", this, + ImeTracing.getInstance().triggerServiceDump("InputMethodService#doFinishInput", mDumper, null /* icProto */); finishViews(true /* finishingInput */); if (mInputStarted) { @@ -2420,7 +2419,7 @@ public class InputMethodService extends AbstractInputMethodService { if (!restarting && mInputStarted) { doFinishInput(); } - ImeTracing.getInstance().triggerServiceDump("InputMethodService#doStartInput", this, + ImeTracing.getInstance().triggerServiceDump("InputMethodService#doStartInput", mDumper, null /* icProto */); mInputStarted = true; mStartedInputConnection = ic; @@ -2580,7 +2579,7 @@ public class InputMethodService extends AbstractInputMethodService { * @param flags Provides additional operating flags. */ public void requestHideSelf(int flags) { - ImeTracing.getInstance().triggerServiceDump("InputMethodService#requestHideSelf", this, + ImeTracing.getInstance().triggerServiceDump("InputMethodService#requestHideSelf", mDumper, null /* icProto */); mPrivOps.hideMySoftInput(flags); } @@ -2594,7 +2593,7 @@ public class InputMethodService extends AbstractInputMethodService { * @param flags Provides additional operating flags. */ public final void requestShowSelf(int flags) { - ImeTracing.getInstance().triggerServiceDump("InputMethodService#requestShowSelf", this, + ImeTracing.getInstance().triggerServiceDump("InputMethodService#requestShowSelf", mDumper, null /* icProto */); mPrivOps.showMySoftInput(flags); } @@ -3281,67 +3280,91 @@ public class InputMethodService extends AbstractInputMethodService { } /** - * Allow the receiver of {@link InputContentInfo} to obtain a temporary read-only access - * permission to the content. + * Used to inject custom {@link InputMethodServiceInternal}. * - * @param inputContentInfo Content to be temporarily exposed from the input method to the - * application. - * This cannot be {@code null}. - * @param inputConnection {@link InputConnection} with which - * {@link InputConnection#commitContent(InputContentInfo, int, Bundle)} will be called. - * @hide + * @return the {@link InputMethodServiceInternal} to be used. */ + @NonNull @Override - public final void exposeContent(@NonNull InputContentInfo inputContentInfo, - @NonNull InputConnection inputConnection) { - if (inputConnection == null) { - return; - } - if (getCurrentInputConnection() != inputConnection) { - return; - } - exposeContentInternal(inputContentInfo, getCurrentInputEditorInfo()); - } + final InputMethodServiceInternal createInputMethodServiceInternal() { + return new InputMethodServiceInternal() { + /** + * {@inheritDoc} + */ + @NonNull + @Override + public Context getContext() { + return InputMethodService.this; + } - /** - * {@inheritDoc} - * @hide - */ - @AnyThread - @Override - public final void notifyUserActionIfNecessary() { - synchronized (mLock) { - if (mNotifyUserActionSent) { - return; + /** + * {@inheritDoc} + */ + @Override + public void exposeContent(@NonNull InputContentInfo inputContentInfo, + @NonNull InputConnection inputConnection) { + if (inputConnection == null) { + return; + } + if (getCurrentInputConnection() != inputConnection) { + return; + } + exposeContentInternal(inputContentInfo, getCurrentInputEditorInfo()); } - mPrivOps.notifyUserActionAsync(); - mNotifyUserActionSent = true; - } - } - /** - * Allow the receiver of {@link InputContentInfo} to obtain a temporary read-only access - * permission to the content. - * - *

See {@link android.inputmethodservice.InputMethodService#exposeContent(InputContentInfo, - * InputConnection)} for details.

- * - * @param inputContentInfo Content to be temporarily exposed from the input method to the - * application. - * This cannot be {@code null}. - * @param editorInfo The editor that receives {@link InputContentInfo}. - */ - private void exposeContentInternal(@NonNull InputContentInfo inputContentInfo, - @NonNull EditorInfo editorInfo) { - final Uri contentUri = inputContentInfo.getContentUri(); - final IInputContentUriToken uriToken = - mPrivOps.createInputContentUriToken(contentUri, editorInfo.packageName); - if (uriToken == null) { - Log.e(TAG, "createInputContentAccessToken failed. contentUri=" + contentUri.toString() - + " packageName=" + editorInfo.packageName); - return; - } - inputContentInfo.setUriToken(uriToken); + /** + * {@inheritDoc} + */ + @Override + public void notifyUserActionIfNecessary() { + synchronized (mLock) { + if (mNotifyUserActionSent) { + return; + } + mPrivOps.notifyUserActionAsync(); + mNotifyUserActionSent = true; + } + } + + /** + * Allow the receiver of {@link InputContentInfo} to obtain a temporary read-only access + * permission to the content. + * + *

See {@link #exposeContent(InputContentInfo, InputConnection)} for details.

+ * + * @param inputContentInfo Content to be temporarily exposed from the input method to + * the application. This cannot be {@code null}. + * @param editorInfo The editor that receives {@link InputContentInfo}. + */ + private void exposeContentInternal(@NonNull InputContentInfo inputContentInfo, + @NonNull EditorInfo editorInfo) { + final Uri contentUri = inputContentInfo.getContentUri(); + final IInputContentUriToken uriToken = + mPrivOps.createInputContentUriToken(contentUri, editorInfo.packageName); + if (uriToken == null) { + Log.e(TAG, "createInputContentAccessToken failed. contentUri=" + + contentUri.toString() + " packageName=" + editorInfo.packageName); + return; + } + inputContentInfo.setUriToken(uriToken); + } + + /** + * {@inheritDoc} + */ + @Override + public void dump(FileDescriptor fd, PrintWriter fout, String[]args) { + InputMethodService.this.dump(fd, fout, args); + } + + /** + * {@inheritDoc} + */ + @Override + public void triggerServiceDump(String where, @Nullable byte[] icProto) { + ImeTracing.getInstance().triggerServiceDump(where, mDumper, icProto); + } + }; } private int mapToImeWindowStatus() { @@ -3411,42 +3434,44 @@ public class InputMethodService extends AbstractInputMethodService { p.println(" mSettingsObserver=" + mSettingsObserver); } - /** - * @hide - */ - @Override - public final void dumpProtoInternal(ProtoOutputStream proto, byte[] icProto) { - final long token = proto.start(InputMethodServiceTraceProto.INPUT_METHOD_SERVICE); - mWindow.dumpDebug(proto, SOFT_INPUT_WINDOW); - proto.write(VIEWS_CREATED, mViewsCreated); - proto.write(DECOR_VIEW_VISIBLE, mDecorViewVisible); - proto.write(DECOR_VIEW_WAS_VISIBLE, mDecorViewWasVisible); - proto.write(WINDOW_VISIBLE, mWindowVisible); - proto.write(IN_SHOW_WINDOW, mInShowWindow); - proto.write(CONFIGURATION, getResources().getConfiguration().toString()); - proto.write(TOKEN, Objects.toString(mToken)); - proto.write(INPUT_BINDING, Objects.toString(mInputBinding)); - proto.write(INPUT_STARTED, mInputStarted); - proto.write(INPUT_VIEW_STARTED, mInputViewStarted); - proto.write(CANDIDATES_VIEW_STARTED, mCandidatesViewStarted); - if (mInputEditorInfo != null) { - mInputEditorInfo.dumpDebug(proto, INPUT_EDITOR_INFO); - } - proto.write(SHOW_INPUT_REQUESTED, mShowInputRequested); - proto.write(LAST_SHOW_INPUT_REQUESTED, mLastShowInputRequested); - proto.write(SHOW_INPUT_FLAGS, mShowInputFlags); - proto.write(CANDIDATES_VISIBILITY, mCandidatesVisibility); - proto.write(FULLSCREEN_APPLIED, mFullscreenApplied); - proto.write(IS_FULLSCREEN, mIsFullscreen); - proto.write(EXTRACT_VIEW_HIDDEN, mExtractViewHidden); - proto.write(EXTRACTED_TOKEN, mExtractedToken); - proto.write(IS_INPUT_VIEW_SHOWN, mIsInputViewShown); - proto.write(STATUS_ICON, mStatusIcon); - mTmpInsets.dumpDebug(proto, LAST_COMPUTED_INSETS); - proto.write(SETTINGS_OBSERVER, Objects.toString(mSettingsObserver)); - if (icProto != null) { - proto.write(INPUT_CONNECTION_CALL, icProto); - } - proto.end(token); - } + private final ImeTracing.ServiceDumper mDumper = new ImeTracing.ServiceDumper() { + /** + * {@inheritDoc} + */ + @Override + public void dumpToProto(ProtoOutputStream proto, @Nullable byte[] icProto) { + final long token = proto.start(InputMethodServiceTraceProto.INPUT_METHOD_SERVICE); + mWindow.dumpDebug(proto, SOFT_INPUT_WINDOW); + proto.write(VIEWS_CREATED, mViewsCreated); + proto.write(DECOR_VIEW_VISIBLE, mDecorViewVisible); + proto.write(DECOR_VIEW_WAS_VISIBLE, mDecorViewWasVisible); + proto.write(WINDOW_VISIBLE, mWindowVisible); + proto.write(IN_SHOW_WINDOW, mInShowWindow); + proto.write(CONFIGURATION, getResources().getConfiguration().toString()); + proto.write(TOKEN, Objects.toString(mToken)); + proto.write(INPUT_BINDING, Objects.toString(mInputBinding)); + proto.write(INPUT_STARTED, mInputStarted); + proto.write(INPUT_VIEW_STARTED, mInputViewStarted); + proto.write(CANDIDATES_VIEW_STARTED, mCandidatesViewStarted); + if (mInputEditorInfo != null) { + mInputEditorInfo.dumpDebug(proto, INPUT_EDITOR_INFO); + } + proto.write(SHOW_INPUT_REQUESTED, mShowInputRequested); + proto.write(LAST_SHOW_INPUT_REQUESTED, mLastShowInputRequested); + proto.write(SHOW_INPUT_FLAGS, mShowInputFlags); + proto.write(CANDIDATES_VISIBILITY, mCandidatesVisibility); + proto.write(FULLSCREEN_APPLIED, mFullscreenApplied); + proto.write(IS_FULLSCREEN, mIsFullscreen); + proto.write(EXTRACT_VIEW_HIDDEN, mExtractViewHidden); + proto.write(EXTRACTED_TOKEN, mExtractedToken); + proto.write(IS_INPUT_VIEW_SHOWN, mIsInputViewShown); + proto.write(STATUS_ICON, mStatusIcon); + mTmpInsets.dumpDebug(proto, LAST_COMPUTED_INSETS); + proto.write(SETTINGS_OBSERVER, Objects.toString(mSettingsObserver)); + if (icProto != null) { + proto.write(INPUT_CONNECTION_CALL, icProto); + } + proto.end(token); + } + }; } -- cgit v1.2.3