From 6591174401e9011ebae147f8d65acb6814d6130a Mon Sep 17 00:00:00 2001 From: Charles Chen Date: Thu, 7 May 2020 15:13:47 +0800 Subject: Annotating context in framework base Bug: 151414704 Test: build & run Change-Id: I42c8ab699433c51158a1af201da0521413d74dcd --- core/java/android/inputmethodservice/InputMethodService.java | 2 ++ 1 file changed, 2 insertions(+) (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 c5a11abe1136..7250801eec81 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -32,6 +32,7 @@ import android.annotation.IntDef; import android.annotation.MainThread; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UiContext; import android.app.ActivityManager; import android.app.Dialog; import android.compat.annotation.UnsupportedAppUsage; @@ -258,6 +259,7 @@ import java.util.Collections; * @attr ref android.R.styleable#InputMethodService_imeExtractEnterAnimation * @attr ref android.R.styleable#InputMethodService_imeExtractExitAnimation */ +@UiContext public class InputMethodService extends AbstractInputMethodService { static final String TAG = "InputMethodService"; static final boolean DEBUG = false; -- cgit v1.2.3 From 6ef3b6e1376f6a13e08365c7a8fed21c42efc616 Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Wed, 16 Sep 2020 15:43:45 +0800 Subject: Remove the legacy insets mode This CL also refines the color view logic which checks the system bar appearance instead of system UI flags. Bug: 149813814 Test: atest InsetsAnimationControlImplTest InsetsControllerTest InsetsStateTest InsetsPolicyTest InsetsStateControllerTest Change-Id: I26d93b3508c84e436133085bd316ade54d00d76a --- .../inputmethodservice/InputMethodService.java | 23 +++++----------------- 1 file changed, 5 insertions(+), 18 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 27bb9e20f968..60ddd8ab22a0 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -18,7 +18,6 @@ package android.inputmethodservice; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; -import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE; import static android.view.WindowInsets.Type.navigationBars; import static android.view.WindowInsets.Type.statusBars; import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; @@ -2201,22 +2200,15 @@ public class InputMethodService extends AbstractInputMethodService { } /** - * Apply the IME visibility in {@link android.view.ImeInsetsSourceConsumer} when - * {@link ViewRootImpl.sNewInsetsMode} is enabled. + * Applies the IME visibility in {@link android.view.ImeInsetsSourceConsumer}. + * * @param setVisible {@code true} to make it visible, false to hide it. */ private void applyVisibilityInInsetsConsumerIfNecessary(boolean setVisible) { - if (!isVisibilityAppliedUsingInsetsConsumer()) { - return; - } mPrivOps.applyImeVisibility(setVisible ? mCurShowInputToken : mCurHideInputToken, setVisible); } - private boolean isVisibilityAppliedUsingInsetsConsumer() { - return ViewRootImpl.sNewInsetsMode > NEW_INSETS_MODE_NONE; - } - private void finishViews(boolean finishingInput) { if (mInputViewStarted) { if (DEBUG) Log.v(TAG, "CALL: onFinishInputView"); @@ -2241,14 +2233,9 @@ public class InputMethodService extends AbstractInputMethodService { mWindowVisible = false; finishViews(false /* finishingInput */); if (mDecorViewVisible) { - // When insets API is enabled, it is responsible for client and server side - // visibility of IME window. - if (isVisibilityAppliedUsingInsetsConsumer()) { - if (mInputView != null) { - mInputView.dispatchWindowVisibilityChanged(View.GONE); - } - } else { - mWindow.hide(); + // It is responsible for client and server side visibility of IME window. + if (mInputView != null) { + mInputView.dispatchWindowVisibilityChanged(View.GONE); } mDecorViewVisible = false; onWindowHidden(); -- cgit v1.2.3 From 5e68eeac86cc0179e25a1719bb5182ea9405ee78 Mon Sep 17 00:00:00 2001 From: Anmol Gupta Date: Thu, 30 Apr 2020 21:06:56 -0700 Subject: Add proto-based InputMethodService and server side dumping for IME This CL implements a mechanism to dump InputMethodService and IME related server states into a proto file which can later be imported to Winscope to allow easy debugging. The Design Doc for the IME tracing project is: go/ime-tracing Bug: 154348613 Test: start trace by calling "adb shell ime tracing start" end trace by calling "adb shell ime tracing stop" pull trace using "adb pull /data/misc/wmtrace/ime_trace.pb ime_trace.pb" Change-Id: Icbfb8c11e882f29eb45dea9d4c23315c48e9d619 --- .../inputmethodservice/InputMethodService.java | 86 +++++++++++++++++++++- 1 file changed, 83 insertions(+), 3 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 d62d1e1e5775..78cc71a782a5 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -17,6 +17,37 @@ package android.inputmethodservice; import static android.graphics.Color.TRANSPARENT; +import static android.inputmethodservice.InputMethodServiceProto.CANDIDATES_VIEW_STARTED; +import static android.inputmethodservice.InputMethodServiceProto.CANDIDATES_VISIBILITY; +import static android.inputmethodservice.InputMethodServiceProto.CAN_PRE_RENDER; +import static android.inputmethodservice.InputMethodServiceProto.CONFIGURATION; +import static android.inputmethodservice.InputMethodServiceProto.DECOR_VIEW_VISIBLE; +import static android.inputmethodservice.InputMethodServiceProto.DECOR_VIEW_WAS_VISIBLE; +import static android.inputmethodservice.InputMethodServiceProto.EXTRACTED_TOKEN; +import static android.inputmethodservice.InputMethodServiceProto.EXTRACT_VIEW_HIDDEN; +import static android.inputmethodservice.InputMethodServiceProto.FULLSCREEN_APPLIED; +import static android.inputmethodservice.InputMethodServiceProto.INPUT_BINDING; +import static android.inputmethodservice.InputMethodServiceProto.INPUT_EDITOR_INFO; +import static android.inputmethodservice.InputMethodServiceProto.INPUT_STARTED; +import static android.inputmethodservice.InputMethodServiceProto.INPUT_VIEW_STARTED; +import static android.inputmethodservice.InputMethodServiceProto.IN_SHOW_WINDOW; +import static android.inputmethodservice.InputMethodServiceProto.IS_FULLSCREEN; +import static android.inputmethodservice.InputMethodServiceProto.IS_INPUT_VIEW_SHOWN; +import static android.inputmethodservice.InputMethodServiceProto.IS_PRE_RENDERED; +import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.CONTENT_TOP_INSETS; +import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.TOUCHABLE_INSETS; +import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.TOUCHABLE_REGION; +import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.VISIBLE_TOP_INSETS; +import static android.inputmethodservice.InputMethodServiceProto.LAST_COMPUTED_INSETS; +import static android.inputmethodservice.InputMethodServiceProto.LAST_SHOW_INPUT_REQUESTED; +import static android.inputmethodservice.InputMethodServiceProto.SETTINGS_OBSERVER; +import static android.inputmethodservice.InputMethodServiceProto.SHOW_INPUT_FLAGS; +import static android.inputmethodservice.InputMethodServiceProto.SHOW_INPUT_REQUESTED; +import static android.inputmethodservice.InputMethodServiceProto.SOFT_INPUT_WINDOW; +import static android.inputmethodservice.InputMethodServiceProto.STATUS_ICON; +import static android.inputmethodservice.InputMethodServiceProto.TOKEN; +import static android.inputmethodservice.InputMethodServiceProto.VIEWS_CREATED; +import static android.inputmethodservice.InputMethodServiceProto.WINDOW_VISIBLE; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static android.view.WindowInsets.Type.navigationBars; @@ -59,6 +90,7 @@ import android.text.method.MovementMethod; import android.util.Log; import android.util.PrintWriterPrinter; import android.util.Printer; +import android.util.proto.ProtoOutputStream; import android.view.Gravity; import android.view.KeyCharacterMap; import android.view.KeyEvent; @@ -104,6 +136,7 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Collections; +import java.util.Objects; /** * InputMethodService provides a standard implementation of an InputMethod, @@ -1041,6 +1074,15 @@ public class InputMethodService extends AbstractInputMethodService { * or {@link #TOUCHABLE_INSETS_REGION}. */ public int touchableInsets; + + private void dumpDebug(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + proto.write(CONTENT_TOP_INSETS, contentTopInsets); + proto.write(VISIBLE_TOP_INSETS, visibleTopInsets); + proto.write(TOUCHABLE_INSETS, touchableInsets); + proto.write(TOUCHABLE_REGION, touchableRegion.toString()); + proto.end(token); + } } /** @@ -1380,7 +1422,7 @@ public class InputMethodService extends AbstractInputMethodService { public AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface() { return new InputMethodSessionImpl(); } - + public LayoutInflater getLayoutInflater() { return mInflater; } @@ -3294,7 +3336,7 @@ public class InputMethodService extends AbstractInputMethodService { } else { p.println(" mInputEditorInfo: null"); } - + p.println(" mShowInputRequested=" + mShowInputRequested + " mLastShowInputRequested=" + mLastShowInputRequested + " mCanPreRender=" + mCanPreRender @@ -3304,7 +3346,7 @@ public class InputMethodService extends AbstractInputMethodService { + " mFullscreenApplied=" + mFullscreenApplied + " mIsFullscreen=" + mIsFullscreen + " mExtractViewHidden=" + mExtractViewHidden); - + if (mExtractedText != null) { p.println(" mExtractedText:"); p.println(" text=" + mExtractedText.text.length() + " chars" @@ -3325,4 +3367,42 @@ public class InputMethodService extends AbstractInputMethodService { + " touchableRegion=" + mTmpInsets.touchableRegion); p.println(" mSettingsObserver=" + mSettingsObserver); } + + /** + * @hide + */ + @Override + final void dumpProtoInternal(FileDescriptor fd, String[] args) { + final ProtoOutputStream proto = new ProtoOutputStream(fd); + 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(CAN_PRE_RENDER, mCanPreRender); + proto.write(IS_PRE_RENDERED, mIsPreRendered); + 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)); + proto.flush(); + } } -- cgit v1.2.3 From 72f07d6a8a32db4a0dedd7682a0b3385be2b9cd6 Mon Sep 17 00:00:00 2001 From: Mathew Inwood Date: Tue, 27 Oct 2020 11:47:29 +0000 Subject: Add maxTargetSdk restriction to unused APIs. These are APIs that have @UnsupportedAppUsage but for which we don't have any evidence of them currently being used, so should be safe to remove from the unsupported list. Bug: 170729553 Test: Treehugger Change-Id: I4c8fd0006f950de9955242e93968fb0996ceb372 --- core/java/android/inputmethodservice/InputMethodService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 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 78cc71a782a5..070bec11b93a 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -1139,7 +1139,7 @@ public class InputMethodService extends AbstractInputMethodService { mService.getContentResolver().unregisterContentObserver(this); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean shouldShowImeWithHardKeyboard() { // Lazily initialize as needed. if (mShowImeWithHardKeyboard == ShowImeWithHardKeyboardType.UNKNOWN) { @@ -1179,7 +1179,7 @@ public class InputMethodService extends AbstractInputMethodService { return "SettingsObserver{mShowImeWithHardKeyboard=" + mShowImeWithHardKeyboard + "}"; } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private SettingsObserver mSettingsObserver; /** -- cgit v1.2.3 From 050275cd83f4a66dc3705714ccbe8db025626ce8 Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Wed, 28 Oct 2020 19:38:11 +0000 Subject: Revert "Add maxTargetSdk restriction to unused APIs." This reverts commit 72f07d6a8a32db4a0dedd7682a0b3385be2b9cd6. Reason for revert: Droidcop-triggered revert due to breakage https://android-build.googleplex.com/builds/quarterdeck?testMethod=testAppZygotePreload&testClass=android.app.cts.ServiceTest&atpConfigName=suite%2Ftest-mapping-presubmit-retry_cloud-tf&testModule=CtsAppTestCases&fkbb=6936597&lkbb=6936969&lkgb=6936551&testResults=true&branch=git_master&target=cf_x86_phone-userdebug>, bug b/171886397 Bug: 171886397 Change-Id: Ibe0f0430a3451477c1ee8ef56a596e91ea1e7672 --- core/java/android/inputmethodservice/InputMethodService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 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 070bec11b93a..78cc71a782a5 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -1139,7 +1139,7 @@ public class InputMethodService extends AbstractInputMethodService { mService.getContentResolver().unregisterContentObserver(this); } - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage private boolean shouldShowImeWithHardKeyboard() { // Lazily initialize as needed. if (mShowImeWithHardKeyboard == ShowImeWithHardKeyboardType.UNKNOWN) { @@ -1179,7 +1179,7 @@ public class InputMethodService extends AbstractInputMethodService { return "SettingsObserver{mShowImeWithHardKeyboard=" + mShowImeWithHardKeyboard + "}"; } } - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage private SettingsObserver mSettingsObserver; /** -- cgit v1.2.3 From 8e742f928e0b3d242a290fb46d80a2c892dd18a3 Mon Sep 17 00:00:00 2001 From: Mathew Inwood Date: Tue, 27 Oct 2020 11:47:29 +0000 Subject: Add maxTargetSdk restriction to unused APIs. These are APIs that have @UnsupportedAppUsage but for which we don't have any evidence of them currently being used, so should be safe to remove from the unsupported list. This is a resubmit of ag/12929664 with some APIs excluded that caused test failures; see bugs 171886397, 171888296, 171864568. APIs excluded: Landroid/bluetooth/le/ScanRecord;->parseFromBytes([B)Landroid/bluetooth/le/ScanRecord; Landroid/os/Process;->myPpid()I Landroid/os/SharedMemory;->getFd()I Landroid/hardware/input/InputManager;->INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH:I Bug: 170729553 Test: Treehugger Change-Id: I8285daa8530260251ecad6f3f38f98e263629ca7 --- core/java/android/inputmethodservice/InputMethodService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 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 78cc71a782a5..070bec11b93a 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -1139,7 +1139,7 @@ public class InputMethodService extends AbstractInputMethodService { mService.getContentResolver().unregisterContentObserver(this); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean shouldShowImeWithHardKeyboard() { // Lazily initialize as needed. if (mShowImeWithHardKeyboard == ShowImeWithHardKeyboardType.UNKNOWN) { @@ -1179,7 +1179,7 @@ public class InputMethodService extends AbstractInputMethodService { return "SettingsObserver{mShowImeWithHardKeyboard=" + mShowImeWithHardKeyboard + "}"; } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private SettingsObserver mSettingsObserver; /** -- cgit v1.2.3 From 72de8ead9e6c7bdfd4c43036eab2ae85132e90a9 Mon Sep 17 00:00:00 2001 From: Taran Singh Date: Tue, 27 Oct 2020 16:04:39 -0700 Subject: Remove preRender input Cleanup unused pre-render input. We've no plans to enable it. It adds unnecessary complexity. Bug: 159201509 Bug: 167948123 Bug: 118599175 Test: atest CtsInputMethodTestCases Change-Id: I32fe3759b9aeb56c868f9abf42bab124b9b83374 --- .../inputmethodservice/InputMethodService.java | 117 +++------------------ 1 file changed, 14 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 78cc71a782a5..ed7491dae060 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -19,7 +19,6 @@ package android.inputmethodservice; import static android.graphics.Color.TRANSPARENT; import static android.inputmethodservice.InputMethodServiceProto.CANDIDATES_VIEW_STARTED; import static android.inputmethodservice.InputMethodServiceProto.CANDIDATES_VISIBILITY; -import static android.inputmethodservice.InputMethodServiceProto.CAN_PRE_RENDER; import static android.inputmethodservice.InputMethodServiceProto.CONFIGURATION; import static android.inputmethodservice.InputMethodServiceProto.DECOR_VIEW_VISIBLE; import static android.inputmethodservice.InputMethodServiceProto.DECOR_VIEW_WAS_VISIBLE; @@ -33,7 +32,6 @@ import static android.inputmethodservice.InputMethodServiceProto.INPUT_VIEW_STAR import static android.inputmethodservice.InputMethodServiceProto.IN_SHOW_WINDOW; import static android.inputmethodservice.InputMethodServiceProto.IS_FULLSCREEN; import static android.inputmethodservice.InputMethodServiceProto.IS_INPUT_VIEW_SHOWN; -import static android.inputmethodservice.InputMethodServiceProto.IS_PRE_RENDERED; import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.CONTENT_TOP_INSETS; import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.TOUCHABLE_INSETS; import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.TOUCHABLE_REGION; @@ -420,10 +418,6 @@ public class InputMethodService extends AbstractInputMethodService { boolean mDecorViewVisible; boolean mDecorViewWasVisible; boolean mInShowWindow; - // True if pre-rendering of IME views/window is supported. - boolean mCanPreRender; - // If IME is pre-rendered. - boolean mIsPreRendered; // IME window visibility. // Use (mDecorViewVisible && mWindowVisible) to check if IME is visible to the user. boolean mWindowVisible; @@ -671,10 +665,8 @@ public class InputMethodService extends AbstractInputMethodService { @Override public final void dispatchStartInputWithToken(@Nullable InputConnection inputConnection, @NonNull EditorInfo editorInfo, boolean restarting, - @NonNull IBinder startInputToken, boolean shouldPreRenderIme) { + @NonNull IBinder startInputToken) { mPrivOps.reportStartInput(startInputToken); - mCanPreRender = shouldPreRenderIme; - if (DEBUG) Log.v(TAG, "Will Pre-render IME: " + mCanPreRender); if (restarting) { restartInput(inputConnection, editorInfo); @@ -711,22 +703,12 @@ public class InputMethodService extends AbstractInputMethodService { + " Use requestHideSelf(int) itself"); return; } - final boolean wasVisible = mIsPreRendered - ? mDecorViewVisible && mWindowVisible : isInputViewShown(); + final boolean wasVisible = isInputViewShown(); applyVisibilityInInsetsConsumerIfNecessary(false /* setVisible */); - if (mIsPreRendered) { - if (DEBUG) { - Log.v(TAG, "Making IME window invisible"); - } - setImeWindowStatus(IME_ACTIVE | IME_INVISIBLE, mBackDisposition); - onPreRenderedWindowVisibilityChanged(false /* setVisible */); - } else { - mShowInputFlags = 0; - mShowInputRequested = false; - doHideWindow(); - } - final boolean isVisible = mIsPreRendered - ? mDecorViewVisible && mWindowVisible : isInputViewShown(); + mShowInputFlags = 0; + mShowInputRequested = false; + doHideWindow(); + final boolean isVisible = isInputViewShown(); final boolean visibilityChanged = isVisible != wasVisible; if (resultReceiver != null) { resultReceiver.send(visibilityChanged @@ -765,23 +747,15 @@ public class InputMethodService extends AbstractInputMethodService { + " Use requestShowSelf(int) itself"); return; } - final boolean wasVisible = mIsPreRendered - ? mDecorViewVisible && mWindowVisible : isInputViewShown(); + final boolean wasVisible = isInputViewShown(); if (dispatchOnShowInputRequested(flags, false)) { - if (mIsPreRendered) { - if (DEBUG) { - Log.v(TAG, "Making IME window visible"); - } - onPreRenderedWindowVisibilityChanged(true /* setVisible */); - } else { - showWindow(true); - } + + showWindow(true); applyVisibilityInInsetsConsumerIfNecessary(true /* setVisible */); } // If user uses hard keyboard, IME button should always be shown. setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition); - final boolean isVisible = mIsPreRendered - ? mDecorViewVisible && mWindowVisible : isInputViewShown(); + final boolean isVisible = isInputViewShown(); final boolean visibilityChanged = isVisible != wasVisible; if (resultReceiver != null) { resultReceiver.send(visibilityChanged @@ -1788,7 +1762,7 @@ public class InputMethodService extends AbstractInputMethodService { * applied by {@link #updateInputViewShown()}. */ public boolean isInputViewShown() { - return mCanPreRender ? mWindowVisible : mIsInputViewShown && mDecorViewVisible; + return mDecorViewVisible; } /** @@ -2141,10 +2115,9 @@ public class InputMethodService extends AbstractInputMethodService { mDecorViewWasVisible = mDecorViewVisible; mInShowWindow = true; - boolean isPreRenderedAndInvisible = mIsPreRendered && !mWindowVisible; final int previousImeWindowStatus = (mDecorViewVisible ? IME_ACTIVE : 0) | (isInputViewShown() - ? (isPreRenderedAndInvisible ? IME_INVISIBLE : IME_VISIBLE) : 0); + ? (!mWindowVisible ? IME_INVISIBLE : IME_VISIBLE) : 0); startViews(prepareWindow(showInput)); final int nextImeWindowStatus = mapToImeWindowStatus(); if (previousImeWindowStatus != nextImeWindowStatus) { @@ -2153,14 +2126,7 @@ public class InputMethodService extends AbstractInputMethodService { // compute visibility onWindowShown(); - mIsPreRendered = mCanPreRender; - if (mIsPreRendered) { - onPreRenderedWindowVisibilityChanged(true /* setVisible */); - } else { - // Pre-rendering not supported. - if (DEBUG) Log.d(TAG, "No pre-rendering supported"); - mWindowVisible = true; - } + mWindowVisible = true; // request draw for the IME surface. // When IME is not pre-rendered, this will actually show the IME. @@ -2168,22 +2134,10 @@ public class InputMethodService extends AbstractInputMethodService { if (DEBUG) Log.v(TAG, "showWindow: draw decorView!"); mWindow.show(); } - maybeNotifyPreRendered(); mDecorViewWasVisible = true; mInShowWindow = false; } - /** - * Notify {@link android.view.ImeInsetsSourceConsumer} if IME has been pre-rendered - * for current EditorInfo, when pre-rendering is enabled. - */ - private void maybeNotifyPreRendered() { - if (!mCanPreRender || !mIsPreRendered) { - return; - } - mPrivOps.reportPreRendered(getCurrentInputEditorInfo()); - } - private boolean prepareWindow(boolean showInput) { boolean doShowInput = false; @@ -2227,16 +2181,6 @@ public class InputMethodService extends AbstractInputMethodService { if (doShowInput) startExtractingText(false); } - private void onPreRenderedWindowVisibilityChanged(boolean setVisible) { - mWindowVisible = setVisible; - mShowInputFlags = setVisible ? mShowInputFlags : 0; - mShowInputRequested = setVisible; - mDecorViewVisible = setVisible; - if (setVisible) { - onWindowShown(); - } - } - /** * Applies the IME visibility in {@link android.view.ImeInsetsSourceConsumer}. * @@ -2267,7 +2211,6 @@ public class InputMethodService extends AbstractInputMethodService { public void hideWindow() { if (DEBUG) Log.v(TAG, "CALL: hideWindow"); - mIsPreRendered = false; mWindowVisible = false; finishViews(false /* finishingInput */); if (mDecorViewVisible) { @@ -2374,32 +2317,6 @@ public class InputMethodService extends AbstractInputMethodService { mCandidatesViewStarted = true; onStartCandidatesView(mInputEditorInfo, restarting); } - } else if (mCanPreRender && mInputEditorInfo != null && mStartedInputConnection != null) { - // Pre-render IME views and window when real EditorInfo is available. - // pre-render IME window and keep it invisible. - if (DEBUG) Log.v(TAG, "Pre-Render IME for " + mInputEditorInfo.fieldName); - if (mInShowWindow) { - Log.w(TAG, "Re-entrance in to showWindow"); - return; - } - - mDecorViewWasVisible = mDecorViewVisible; - mInShowWindow = true; - startViews(prepareWindow(true /* showInput */)); - - // compute visibility - mIsPreRendered = true; - onPreRenderedWindowVisibilityChanged(false /* setVisible */); - - // request draw for the IME surface. - // When IME is not pre-rendered, this will actually show the IME. - if (DEBUG) Log.v(TAG, "showWindow: draw decorView!"); - mWindow.show(); - maybeNotifyPreRendered(); - mDecorViewWasVisible = true; - mInShowWindow = false; - } else { - mIsPreRendered = false; } } @@ -3299,9 +3216,7 @@ public class InputMethodService extends AbstractInputMethodService { private int mapToImeWindowStatus() { return IME_ACTIVE - | (isInputViewShown() - ? (mCanPreRender ? (mWindowVisible ? IME_VISIBLE : IME_INVISIBLE) - : IME_VISIBLE) : 0); + | (isInputViewShown() ? IME_VISIBLE : 0); } private boolean isAutomotive() { @@ -3339,8 +3254,6 @@ public class InputMethodService extends AbstractInputMethodService { p.println(" mShowInputRequested=" + mShowInputRequested + " mLastShowInputRequested=" + mLastShowInputRequested - + " mCanPreRender=" + mCanPreRender - + " mIsPreRendered=" + mIsPreRendered + " mShowInputFlags=0x" + Integer.toHexString(mShowInputFlags)); p.println(" mCandidatesVisibility=" + mCandidatesVisibility + " mFullscreenApplied=" + mFullscreenApplied @@ -3391,8 +3304,6 @@ public class InputMethodService extends AbstractInputMethodService { } proto.write(SHOW_INPUT_REQUESTED, mShowInputRequested); proto.write(LAST_SHOW_INPUT_REQUESTED, mLastShowInputRequested); - proto.write(CAN_PRE_RENDER, mCanPreRender); - proto.write(IS_PRE_RENDERED, mIsPreRendered); proto.write(SHOW_INPUT_FLAGS, mShowInputFlags); proto.write(CANDIDATES_VISIBILITY, mCandidatesVisibility); proto.write(FULLSCREEN_APPLIED, mFullscreenApplied); -- cgit v1.2.3 From 72e6319254769db69414f952c15dfaeeb14fc69a Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Thu, 22 Oct 2020 12:52:43 -0700 Subject: Only use system gesture insets for exclusion rects with root ime view - Instead of using the whole IME frame, we should only exclude the left and right regions for excluding the back gesture (the intention of the original change), otherwise the full IME frame will exclude the bottom gesture area which is respected by Launcher to prevent quickswitch. Bug: 171501996 Test: Dump exclusion rects received by SysUI with normal IME (only edges) floating IME (no exclusion requested) and extract mode (only edges) Change-Id: Id8e01d56190f8fafdc2da1cf95203e597acdb970 --- .../inputmethodservice/InputMethodService.java | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 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 78cc71a782a5..69db7c44ceae 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -102,6 +102,7 @@ import android.view.ViewRootImpl; import android.view.ViewTreeObserver; import android.view.Window; import android.view.WindowInsets.Side; +import android.view.WindowInsets.Type; import android.view.WindowManager; import android.view.animation.AnimationUtils; import android.view.inputmethod.CompletionInfo; @@ -135,7 +136,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.Collections; +import java.util.ArrayList; import java.util.Objects; /** @@ -883,10 +884,19 @@ public class InputMethodService extends AbstractInputMethodService { /** Set region of the keyboard to be avoided from back gesture */ private void setImeExclusionRect(int visibleTopInsets) { - View inputFrameRootView = mInputFrame.getRootView(); - Rect r = new Rect(0, visibleTopInsets, inputFrameRootView.getWidth(), - inputFrameRootView.getHeight()); - inputFrameRootView.setSystemGestureExclusionRects(Collections.singletonList(r)); + View rootView = mInputFrame.getRootView(); + android.graphics.Insets systemGesture = + rootView.getRootWindowInsets().getInsets(Type.systemGestures()); + ArrayList exclusionRects = new ArrayList<>(); + exclusionRects.add(new Rect(0, + visibleTopInsets, + systemGesture.left, + rootView.getHeight())); + exclusionRects.add(new Rect(rootView.getWidth() - systemGesture.right, + visibleTopInsets, + rootView.getWidth(), + rootView.getHeight())); + rootView.setSystemGestureExclusionRects(exclusionRects); } /** -- cgit v1.2.3 From 5c61eefbafeec60522b1e3d51d0fa13361099159 Mon Sep 17 00:00:00 2001 From: Taran Singh Date: Tue, 3 Nov 2020 11:48:03 -0800 Subject: Measure baseline IMF latency (2/n) Add methods to trace. Refer to design doc in bug. Bug: 167947940 Test: atest ImePerfTests and also refer to README.md Change-Id: I423e4f3f9253707d9b6d3d5a2dee260f872b879f --- .../android/inputmethodservice/InputMethodService.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (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 32a8c0af0c01..44640c44332e 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -46,6 +46,7 @@ import static android.inputmethodservice.InputMethodServiceProto.STATUS_ICON; import static android.inputmethodservice.InputMethodServiceProto.TOKEN; import static android.inputmethodservice.InputMethodServiceProto.VIEWS_CREATED; import static android.inputmethodservice.InputMethodServiceProto.WINDOW_VISIBLE; +import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static android.view.WindowInsets.Type.navigationBars; @@ -80,6 +81,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.ResultReceiver; import android.os.SystemClock; +import android.os.Trace; import android.provider.Settings; import android.text.InputType; import android.text.Layout; @@ -645,7 +647,9 @@ public class InputMethodService extends AbstractInputMethodService { @Override public void startInput(InputConnection ic, EditorInfo attribute) { if (DEBUG) Log.v(TAG, "startInput(): editor=" + attribute); + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.startInput"); doStartInput(ic, attribute, false); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } /** @@ -705,6 +709,8 @@ public class InputMethodService extends AbstractInputMethodService { return; } final boolean wasVisible = isInputViewShown(); + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.hideSoftInput"); + applyVisibilityInInsetsConsumerIfNecessary(false /* setVisible */); mShowInputFlags = 0; mShowInputRequested = false; @@ -717,6 +723,7 @@ public class InputMethodService extends AbstractInputMethodService { : (wasVisible ? InputMethodManager.RESULT_UNCHANGED_SHOWN : InputMethodManager.RESULT_UNCHANGED_HIDDEN), null); } + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } /** @@ -748,6 +755,13 @@ public class InputMethodService extends AbstractInputMethodService { + " Use requestShowSelf(int) itself"); return; } + + if (Trace.isEnabled()) { + Binder.enableTracing(); + } else { + Binder.disableTracing(); + } + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.showSoftInput"); final boolean wasVisible = isInputViewShown(); if (dispatchOnShowInputRequested(flags, false)) { @@ -764,6 +778,7 @@ public class InputMethodService extends AbstractInputMethodService { : (wasVisible ? InputMethodManager.RESULT_UNCHANGED_SHOWN : InputMethodManager.RESULT_UNCHANGED_HIDDEN), null); } + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } /** -- cgit v1.2.3 From 145f71182ab1c1e0be4f128683c97403c97d2696 Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Sun, 8 Nov 2020 19:04:16 +0800 Subject: Do let IME fit invisible insets Otherwise, the fullscreen IME won't cover the entire display while there is a hidden system bar. Fix: 168657591 Test: 1. Steps in the bug. 2. Play WindowInsetsTests with combinations of system bar visibilities, navigation mode, screen orientation, and display cutout. Change-Id: I6e7d665c55839dfbb14c8d2e5365537416f5f6c6 --- core/java/android/inputmethodservice/InputMethodService.java | 9 ++------- 1 file changed, 2 insertions(+), 7 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 44640c44332e..abc2a69a8dee 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -16,7 +16,6 @@ package android.inputmethodservice; -import static android.graphics.Color.TRANSPARENT; import static android.inputmethodservice.InputMethodServiceProto.CANDIDATES_VIEW_STARTED; import static android.inputmethodservice.InputMethodServiceProto.CANDIDATES_VISIBILITY; import static android.inputmethodservice.InputMethodServiceProto.CONFIGURATION; @@ -50,6 +49,7 @@ import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static android.view.WindowInsets.Type.navigationBars; +import static android.view.WindowInsets.Type.statusBars; import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; import static java.lang.annotation.RetentionPolicy.SOURCE; @@ -1244,13 +1244,8 @@ public class InputMethodService extends AbstractInputMethodService { Context.LAYOUT_INFLATER_SERVICE); mWindow = new SoftInputWindow(this, "InputMethod", mTheme, null, null, mDispatcherState, WindowManager.LayoutParams.TYPE_INPUT_METHOD, Gravity.BOTTOM, false); - mWindow.getWindow().getAttributes().setFitInsetsTypes(navigationBars()); + mWindow.getWindow().getAttributes().setFitInsetsTypes(statusBars() | navigationBars()); mWindow.getWindow().getAttributes().setFitInsetsSides(Side.all() & ~Side.BOTTOM); - mWindow.getWindow().getAttributes().setFitInsetsIgnoringVisibility(true); - - // Our window will extend into the status bar area no matter the bar is visible or not. - // We don't want the ColorView to be visible when status bar is shown. - mWindow.getWindow().setStatusBarColor(TRANSPARENT); // Automotive devices may request the navigation bar to be hidden when the IME shows up // (controlled via config_automotiveHideNavBarForKeyboard) in order to maximize the visible -- cgit v1.2.3 From 8418bef70abf31d3cbfcfa500b2e694988735557 Mon Sep 17 00:00:00 2001 From: Ioana Stefan Date: Tue, 27 Oct 2020 11:30:38 +0000 Subject: Optimized workflow for IME tracing on InputMethodService side Optimized the tracing logic for the IMS information. The InputMethodService triggers a tracing dump through the new method triggerServiceDump, exposed by the meTracing interface. This change was done to be able to support custom dumps from clients and custom dumps from InputMethodService. This change only covers the IMS information. The IMMS information will be dumped in next changes. Bug: 154348613 Test: start IME tracing by calling "adb shell ime tracing start" end IME tracing by calling "adb shell ime tracing stop" pull trace using "adb pull /data/misc/wmtrace/ime_trace_service.pb ime_trace_service.pb" Change-Id: Icda0f82d76fb7db5b2bd8d021069b1ff15a4e15b --- .../inputmethodservice/InputMethodService.java | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 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 44640c44332e..fe8f3d7edae0 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -90,6 +90,7 @@ import android.text.method.MovementMethod; import android.util.Log; import android.util.PrintWriterPrinter; import android.util.Printer; +import android.util.imetracing.ImeTracing; import android.util.proto.ProtoOutputStream; import android.view.Gravity; import android.view.KeyCharacterMap; @@ -116,6 +117,7 @@ import android.view.inputmethod.InputBinding; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputContentInfo; import android.view.inputmethod.InputMethod; +import android.view.inputmethod.InputMethodEditorTraceProto.InputMethodServiceTraceProto; import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; import android.widget.FrameLayout; @@ -708,6 +710,8 @@ public class InputMethodService extends AbstractInputMethodService { + " Use requestHideSelf(int) itself"); return; } + ImeTracing.getInstance().triggerServiceDump( + "InputMethodService.InputMethodImpl#hideSoftInput", InputMethodService.this); final boolean wasVisible = isInputViewShown(); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.hideSoftInput"); @@ -762,6 +766,8 @@ public class InputMethodService extends AbstractInputMethodService { Binder.disableTracing(); } Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.showSoftInput"); + ImeTracing.getInstance().triggerServiceDump( + "InputMethodService.InputMethodImpl#showSoftInput", InputMethodService.this); final boolean wasVisible = isInputViewShown(); if (dispatchOnShowInputRequested(flags, false)) { @@ -2138,6 +2144,8 @@ public class InputMethodService extends AbstractInputMethodService { return; } + ImeTracing.getInstance().triggerServiceDump("InputMethodService#showWindow", this); + mDecorViewWasVisible = mDecorViewVisible; mInShowWindow = true; final int previousImeWindowStatus = @@ -2212,6 +2220,8 @@ public class InputMethodService extends AbstractInputMethodService { * @param setVisible {@code true} to make it visible, false to hide it. */ private void applyVisibilityInInsetsConsumerIfNecessary(boolean setVisible) { + ImeTracing.getInstance().triggerServiceDump( + "InputMethodService#applyVisibilityInInsetsConsumerIfNecessary", this); mPrivOps.applyImeVisibility(setVisible ? mCurShowInputToken : mCurHideInputToken, setVisible); } @@ -2236,6 +2246,7 @@ public class InputMethodService extends AbstractInputMethodService { public void hideWindow() { if (DEBUG) Log.v(TAG, "CALL: hideWindow"); + ImeTracing.getInstance().triggerServiceDump("InputMethodService#hideWindow", this); mWindowVisible = false; finishViews(false /* finishingInput */); if (mDecorViewVisible) { @@ -2306,6 +2317,7 @@ public class InputMethodService extends AbstractInputMethodService { void doFinishInput() { if (DEBUG) Log.v(TAG, "CALL: doFinishInput"); + ImeTracing.getInstance().triggerServiceDump("InputMethodService#doFinishInput", this); finishViews(true /* finishingInput */); if (mInputStarted) { mInlineSuggestionSessionController.notifyOnFinishInput(); @@ -2321,6 +2333,7 @@ public class InputMethodService extends AbstractInputMethodService { if (!restarting) { doFinishInput(); } + ImeTracing.getInstance().triggerServiceDump("InputMethodService#doStartInput", this); mInputStarted = true; mStartedInputConnection = ic; mInputEditorInfo = attribute; @@ -2479,6 +2492,7 @@ public class InputMethodService extends AbstractInputMethodService { * @param flags Provides additional operating flags. */ public void requestHideSelf(int flags) { + ImeTracing.getInstance().triggerServiceDump("InputMethodService#requestHideSelf", this); mPrivOps.hideMySoftInput(flags); } @@ -2491,6 +2505,7 @@ public class InputMethodService extends AbstractInputMethodService { * @param flags Provides additional operating flags. */ public final void requestShowSelf(int flags) { + ImeTracing.getInstance().triggerServiceDump("InputMethodService#requestShowSelf", this); mPrivOps.showMySoftInput(flags); } @@ -3310,8 +3325,8 @@ public class InputMethodService extends AbstractInputMethodService { * @hide */ @Override - final void dumpProtoInternal(FileDescriptor fd, String[] args) { - final ProtoOutputStream proto = new ProtoOutputStream(fd); + public final void dumpProtoInternal(ProtoOutputStream proto) { + 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); @@ -3339,6 +3354,6 @@ public class InputMethodService extends AbstractInputMethodService { proto.write(STATUS_ICON, mStatusIcon); mTmpInsets.dumpDebug(proto, LAST_COMPUTED_INSETS); proto.write(SETTINGS_OBSERVER, Objects.toString(mSettingsObserver)); - proto.flush(); + proto.end(token); } } -- cgit v1.2.3 From a2b45708ef298bf908341d6b287fc591781a05e7 Mon Sep 17 00:00:00 2001 From: Taran Singh Date: Fri, 13 Nov 2020 13:31:20 -0800 Subject: Measure and optimize IMF latency 6/n Few low-hanging optimizations to improve IMF latency: - Remove duplicate call to setImeWindowStatus when showWindow() is called from showSoftInput() already. - Remove redundant fancy animations preference check. IME window animation is controlled by client. - Cache mShowImeWithHardKeyboard early on. - Remove rendundant removeOnComputeInternalInsetsListener() when called from onCreate(). Refer to design doc in bug for amount of latency improvements caused by this CL. Bug: 167947940 Bug: 167948123 Test: atest CtsInputMethodTestCases Change-Id: I0b0750f146634d8e90e0b0ac46e9208675626d0a --- .../inputmethodservice/InputMethodService.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 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 44640c44332e..9e22befe8bcc 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -600,6 +600,9 @@ public class InputMethodService extends AbstractInputMethodService { @MainThread @Override public void updateInputMethodDisplay(int displayId) { + if (getDisplayId() == displayId) { + return; + } // Update display for adding IME window to the right display. // TODO(b/111364446) Need to address context lifecycle issue if need to re-create // for update resources & configuration correctly when show soft input @@ -764,12 +767,12 @@ public class InputMethodService extends AbstractInputMethodService { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.showSoftInput"); final boolean wasVisible = isInputViewShown(); if (dispatchOnShowInputRequested(flags, false)) { - showWindow(true); applyVisibilityInInsetsConsumerIfNecessary(true /* setVisible */); + } else { + // If user uses hard keyboard, IME button should always be shown. + setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition); } - // If user uses hard keyboard, IME button should always be shown. - setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition); final boolean isVisible = isInputViewShown(); final boolean visibilityChanged = isVisible != wasVisible; if (resultReceiver != null) { @@ -1232,6 +1235,9 @@ public class InputMethodService extends AbstractInputMethodService { super.onCreate(); mImm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE); mSettingsObserver = SettingsObserver.createAndRegister(this); + // cache preference so we don't have to read ContentProvider when IME is requested to be + // shown the first time (cold start). + mSettingsObserver.shouldShowImeWithHardKeyboard(); mIsAutomotive = isAutomotive(); mAutomotiveHideNavBarForKeyboard = getApplicationContext().getResources().getBoolean( @@ -1301,13 +1307,7 @@ public class InputMethodService extends AbstractInputMethodService { mRootView = mInflater.inflate( com.android.internal.R.layout.input_method, null); mWindow.setContentView(mRootView); - mRootView.getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsComputer); mRootView.getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsComputer); - if (Settings.Global.getInt(getContentResolver(), - Settings.Global.FANCY_IME_ANIMATIONS, 0) != 0) { - mWindow.getWindow().setWindowAnimations( - com.android.internal.R.style.Animation_InputMethodFancy); - } mFullscreenArea = mRootView.findViewById(com.android.internal.R.id.fullscreenArea); mExtractViewHidden = false; mExtractFrame = mRootView.findViewById(android.R.id.extractArea); @@ -1371,6 +1371,7 @@ public class InputMethodService extends AbstractInputMethodService { int showFlags = mShowInputFlags; boolean showingInput = mShowInputRequested; CompletionInfo[] completions = mCurCompletions; + mRootView.getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsComputer); initViews(); mInputViewStarted = false; mCandidatesViewStarted = false; -- cgit v1.2.3 From d663b62186a7678a7edfb5636c84978b38241c2b Mon Sep 17 00:00:00 2001 From: Taran Singh Date: Thu, 12 Nov 2020 19:42:13 -0800 Subject: Measure IMF latency 4/n Add more traces to measure cold IMF startup. Bug: 167947940 Test: atest ImePerfTests Change-Id: I586341426916f9b9e0f1efe988894621972da4ff --- .../inputmethodservice/InputMethodService.java | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (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 ae260e16806f..8d9fe28bdc59 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -560,10 +560,12 @@ public class InputMethodService extends AbstractInputMethodService { Log.w(TAG, "The token has already registered, ignore this initialization."); return; } + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initializeInternal"); mPrivOps.set(privilegedOperations); InputMethodPrivilegedOperationsRegistry.put(token, mPrivOps); updateInputMethodDisplay(displayId); attachToken(token); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } /** @@ -617,6 +619,7 @@ public class InputMethodService extends AbstractInputMethodService { @MainThread @Override public void bindInput(InputBinding binding) { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.bindInput"); mInputBinding = binding; mInputConnection = binding.getConnection(); if (DEBUG) Log.v(TAG, "bindInput(): binding=" + binding @@ -624,6 +627,7 @@ public class InputMethodService extends AbstractInputMethodService { reportFullscreenMode(); initialize(); onBindInput(); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } /** @@ -661,7 +665,9 @@ public class InputMethodService extends AbstractInputMethodService { @Override public void restartInput(InputConnection ic, EditorInfo attribute) { if (DEBUG) Log.v(TAG, "restartInput(): editor=" + attribute); + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.restartInput"); doStartInput(ic, attribute, true); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } /** @@ -1228,6 +1234,7 @@ public class InputMethodService extends AbstractInputMethodService { } @Override public void onCreate() { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.onCreate"); mTheme = Resources.selectSystemTheme(mTheme, getApplicationInfo().targetSdkVersion, android.R.style.Theme_InputMethod, @@ -1248,6 +1255,7 @@ public class InputMethodService extends AbstractInputMethodService { // in non-default display. mInflater = (LayoutInflater)getSystemService( Context.LAYOUT_INFLATER_SERVICE); + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initSoftInputWindow"); mWindow = new SoftInputWindow(this, "InputMethod", mTheme, null, null, mDispatcherState, WindowManager.LayoutParams.TYPE_INPUT_METHOD, Gravity.BOTTOM, false); mWindow.getWindow().getAttributes().setFitInsetsTypes(statusBars() | navigationBars()); @@ -1269,10 +1277,12 @@ public class InputMethodService extends AbstractInputMethodService { initViews(); mWindow.getWindow().setLayout(MATCH_PARENT, WRAP_CONTENT); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); mInlineSuggestionSessionController = new InlineSuggestionSessionController( this::onCreateInlineSuggestionsRequest, this::getHostInputToken, this::onInlineSuggestionsResponse); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } /** @@ -1293,6 +1303,7 @@ public class InputMethodService extends AbstractInputMethodService { } void initViews() { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initViews"); mInitialized = false; mViewsCreated = false; mShowInputRequested = false; @@ -1327,6 +1338,7 @@ public class InputMethodService extends AbstractInputMethodService { mCandidatesVisibility = getCandidatesHiddenVisibility(); mCandidatesFrame.setVisibility(mCandidatesVisibility); mInputFrame.setVisibility(View.GONE); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } @Override public void onDestroy() { @@ -1368,6 +1380,7 @@ public class InputMethodService extends AbstractInputMethodService { } private void resetStateForNewConfiguration() { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.resetStateForNewConfiguration"); boolean visible = mDecorViewVisible; int showFlags = mShowInputFlags; boolean showingInput = mShowInputRequested; @@ -1403,6 +1416,7 @@ public class InputMethodService extends AbstractInputMethodService { boolean showing = onEvaluateInputViewShown(); setImeWindowStatus(IME_ACTIVE | (showing ? IME_VISIBLE : 0), mBackDisposition); } + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } /** @@ -1564,6 +1578,7 @@ public class InputMethodService extends AbstractInputMethodService { * is currently running in fullscreen mode. */ public void updateFullscreenMode() { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.updateFullscreenMode"); boolean isFullscreen = mShowInputRequested && onEvaluateFullscreenMode(); boolean changed = mLastShowInputRequested != mShowInputRequested; if (mIsFullscreen != isFullscreen || !mFullscreenApplied) { @@ -1602,6 +1617,7 @@ public class InputMethodService extends AbstractInputMethodService { onConfigureWindow(mWindow.getWindow(), isFullscreen, !mShowInputRequested); mLastShowInputRequested = mShowInputRequested; } + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } /** @@ -1730,6 +1746,7 @@ public class InputMethodService extends AbstractInputMethodService { * @param outInsets Fill in with the current UI insets. */ public void onComputeInsets(Insets outInsets) { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.onComputeInsets"); int[] loc = mTmpLocation; if (mInputFrame.getVisibility() == View.VISIBLE) { mInputFrame.getLocationInWindow(loc); @@ -1750,6 +1767,7 @@ public class InputMethodService extends AbstractInputMethodService { outInsets.visibleTopInsets = loc[1]; outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_VISIBLE; outInsets.touchableRegion.setEmpty(); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } /** @@ -2140,7 +2158,7 @@ public class InputMethodService extends AbstractInputMethodService { } ImeTracing.getInstance().triggerServiceDump("InputMethodService#showWindow", this); - + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.showWindow"); mDecorViewWasVisible = mDecorViewVisible; mInShowWindow = true; final int previousImeWindowStatus = @@ -2164,6 +2182,7 @@ public class InputMethodService extends AbstractInputMethodService { } mDecorViewWasVisible = true; mInShowWindow = false; + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } -- cgit v1.2.3 From 152eacec4f5e1c78eafd42abbcf62fc12b0eee33 Mon Sep 17 00:00:00 2001 From: Ming-Shin Lu Date: Mon, 28 Sep 2020 01:35:31 +0800 Subject: Let IME#onFinishInput called without dup onStartInput when screen-off Also called IME#onStartInput without dup onFinishInput when screen-on, to fix the long-standing IME input connection lifecycle issue when device screen state changes. Bug: 156215187 Bug: 26851566 Test: atest InputMethodStartInputLifecycleTest Test: manual as below steps 0) Enable InputMethodService debug flag. 0-1) In Settings -> Develop options -> AppCompatibility Changes, Select Gboard and then toggle "FINISH_INPUT_NO_FALLBACK_CONNECTION" change. 1) Launch a app with focused a editor and show soft-input 2) When device screen turned-off, will see InputMethodService only callbacks below logs: CALL: doFinishInput CALL: onFinishInputView CALL: onFinishInput 3) When device screen turned-on, will see InputMethodService only callbacks below logs: CALL: onStartInput CALL: onStartInputView Change-Id: I8a657e75e274d842fb46b60375f6aeafeab96a59 --- .../inputmethodservice/InputMethodService.java | 29 ++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 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 ae260e16806f..4a5d831cd705 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -61,9 +61,12 @@ import android.annotation.IntDef; import android.annotation.MainThread; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.TestApi; import android.annotation.UiContext; import android.app.ActivityManager; import android.app.Dialog; +import android.compat.annotation.ChangeId; +import android.compat.annotation.EnabledSince; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; @@ -411,7 +414,29 @@ public class InputMethodService extends AbstractInputMethodService { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) int mTheme = 0; - + + /** + * Finish the {@link InputConnection} when the device becomes + * {@link android.os.PowerManager#isInteractive non-interactive}. + * + *

+ * If enabled by the current {@link InputMethodService input method}, the current input + * connection will be {@link InputMethodService#onFinishInput finished} whenever the devices + * becomes non-interactive. + * + *

+ * If not enabled, the current input connection will instead be silently deactivated when the + * devices becomes non-interactive, and an {@link InputMethodService#onFinishInput + * onFinishInput()} {@link InputMethodService#onStartInput onStartInput()} pair is dispatched + * when the device becomes interactive again. + * + * @hide + */ + @TestApi + @ChangeId + @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S) + public static final long FINISH_INPUT_NO_FALLBACK_CONNECTION = 156215187L; // This is a bug id. + LayoutInflater mInflater; TypedArray mThemeAttrs; @UnsupportedAppUsage @@ -2325,7 +2350,7 @@ public class InputMethodService extends AbstractInputMethodService { } void doStartInput(InputConnection ic, EditorInfo attribute, boolean restarting) { - if (!restarting) { + if (!restarting && mInputStarted) { doFinishInput(); } ImeTracing.getInstance().triggerServiceDump("InputMethodService#doStartInput", this); -- cgit v1.2.3 From 0653b692d1f420e799962efeeb8a26e8c57b579e Mon Sep 17 00:00:00 2001 From: Ioana Stefan Date: Fri, 13 Nov 2020 17:21:04 +0000 Subject: Add InputConnection app and service dump This change dumps information through IME tracing for the getter methods exposed by the InputConnection interface. The dump is done through the ImeTracing interface and is triggered by events in the wrapper classes used to handle InputConnection implementations corresponding to: - different apps - InputMethodService The new data is available under inputConnectionCall in the clients output proto. Bug: 154348613 Test: flash a device start IME tracing by calling "adb shell ime tracing start" end IME tracing by calling "adb shell ime tracing stop" pull generated trace files and visualize in Winscope or start tracing directly through ADB Connect and visualize traces Change-Id: Iabd6af1b858803030848a0ef5e7dd9ecfc562716 --- .../inputmethodservice/InputMethodService.java | 33 +++++++++++++++------- 1 file changed, 23 insertions(+), 10 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 67e75d205f97..5576857d1f6b 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -25,6 +25,7 @@ import static android.inputmethodservice.InputMethodServiceProto.EXTRACTED_TOKEN import static android.inputmethodservice.InputMethodServiceProto.EXTRACT_VIEW_HIDDEN; import static android.inputmethodservice.InputMethodServiceProto.FULLSCREEN_APPLIED; import static android.inputmethodservice.InputMethodServiceProto.INPUT_BINDING; +import static android.inputmethodservice.InputMethodServiceProto.INPUT_CONNECTION_CALL; import static android.inputmethodservice.InputMethodServiceProto.INPUT_EDITOR_INFO; import static android.inputmethodservice.InputMethodServiceProto.INPUT_STARTED; import static android.inputmethodservice.InputMethodServiceProto.INPUT_VIEW_STARTED; @@ -742,7 +743,8 @@ public class InputMethodService extends AbstractInputMethodService { return; } ImeTracing.getInstance().triggerServiceDump( - "InputMethodService.InputMethodImpl#hideSoftInput", InputMethodService.this); + "InputMethodService.InputMethodImpl#hideSoftInput", InputMethodService.this, + null /* icProto */); final boolean wasVisible = isInputViewShown(); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.hideSoftInput"); @@ -798,7 +800,8 @@ public class InputMethodService extends AbstractInputMethodService { } Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.showSoftInput"); ImeTracing.getInstance().triggerServiceDump( - "InputMethodService.InputMethodImpl#showSoftInput", InputMethodService.this); + "InputMethodService.InputMethodImpl#showSoftInput", InputMethodService.this, + null /* icProto */); final boolean wasVisible = isInputViewShown(); if (dispatchOnShowInputRequested(flags, false)) { @@ -2182,7 +2185,8 @@ public class InputMethodService extends AbstractInputMethodService { return; } - ImeTracing.getInstance().triggerServiceDump("InputMethodService#showWindow", this); + ImeTracing.getInstance().triggerServiceDump("InputMethodService#showWindow", this, + null /* icProto */); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.showWindow"); mDecorViewWasVisible = mDecorViewVisible; mInShowWindow = true; @@ -2260,7 +2264,8 @@ public class InputMethodService extends AbstractInputMethodService { */ private void applyVisibilityInInsetsConsumerIfNecessary(boolean setVisible) { ImeTracing.getInstance().triggerServiceDump( - "InputMethodService#applyVisibilityInInsetsConsumerIfNecessary", this); + "InputMethodService#applyVisibilityInInsetsConsumerIfNecessary", this, + null /* icProto */); mPrivOps.applyImeVisibility(setVisible ? mCurShowInputToken : mCurHideInputToken, setVisible); } @@ -2285,7 +2290,8 @@ 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", this, + null /* icProto */); mWindowVisible = false; finishViews(false /* finishingInput */); if (mDecorViewVisible) { @@ -2356,7 +2362,8 @@ 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", this, + null /* icProto */); finishViews(true /* finishingInput */); if (mInputStarted) { mInlineSuggestionSessionController.notifyOnFinishInput(); @@ -2372,7 +2379,8 @@ public class InputMethodService extends AbstractInputMethodService { if (!restarting && mInputStarted) { doFinishInput(); } - ImeTracing.getInstance().triggerServiceDump("InputMethodService#doStartInput", this); + ImeTracing.getInstance().triggerServiceDump("InputMethodService#doStartInput", this, + null /* icProto */); mInputStarted = true; mStartedInputConnection = ic; mInputEditorInfo = attribute; @@ -2531,7 +2539,8 @@ 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", this, + null /* icProto */); mPrivOps.hideMySoftInput(flags); } @@ -2544,7 +2553,8 @@ 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", this, + null /* icProto */); mPrivOps.showMySoftInput(flags); } @@ -3364,7 +3374,7 @@ public class InputMethodService extends AbstractInputMethodService { * @hide */ @Override - public final void dumpProtoInternal(ProtoOutputStream proto) { + public final void dumpProtoInternal(ProtoOutputStream proto, ProtoOutputStream icProto) { final long token = proto.start(InputMethodServiceTraceProto.INPUT_METHOD_SERVICE); mWindow.dumpDebug(proto, SOFT_INPUT_WINDOW); proto.write(VIEWS_CREATED, mViewsCreated); @@ -3393,6 +3403,9 @@ public class InputMethodService extends AbstractInputMethodService { 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.getBytes()); + } proto.end(token); } } -- cgit v1.2.3 From 3d62f739a869c97a265506ac1e1ab58f93fa3b34 Mon Sep 17 00:00:00 2001 From: Jeff DeCew Date: Thu, 3 Dec 2020 19:13:34 +0000 Subject: Revert "Let IME#onFinishInput called without dup onStartInput wh..." Revert "Verify lifecycle test when screen on/off" Revert submission 12716106-ims_screenstate_lifecycle Reason for revert: b/174512702 Reverted Changes: Iba0332ed3:Verify lifecycle test when screen on/off I8a657e75e:Let IME#onFinishInput called without dup onStartIn... Change-Id: I16f4a34360a2f64b69978724648a9be741f140b5 --- .../inputmethodservice/InputMethodService.java | 29 ++-------------------- 1 file changed, 2 insertions(+), 27 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 4a5d831cd705..ae260e16806f 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -61,12 +61,9 @@ import android.annotation.IntDef; import android.annotation.MainThread; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.TestApi; import android.annotation.UiContext; import android.app.ActivityManager; import android.app.Dialog; -import android.compat.annotation.ChangeId; -import android.compat.annotation.EnabledSince; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; @@ -414,29 +411,7 @@ public class InputMethodService extends AbstractInputMethodService { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) int mTheme = 0; - - /** - * Finish the {@link InputConnection} when the device becomes - * {@link android.os.PowerManager#isInteractive non-interactive}. - * - *

- * If enabled by the current {@link InputMethodService input method}, the current input - * connection will be {@link InputMethodService#onFinishInput finished} whenever the devices - * becomes non-interactive. - * - *

- * If not enabled, the current input connection will instead be silently deactivated when the - * devices becomes non-interactive, and an {@link InputMethodService#onFinishInput - * onFinishInput()} {@link InputMethodService#onStartInput onStartInput()} pair is dispatched - * when the device becomes interactive again. - * - * @hide - */ - @TestApi - @ChangeId - @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S) - public static final long FINISH_INPUT_NO_FALLBACK_CONNECTION = 156215187L; // This is a bug id. - + LayoutInflater mInflater; TypedArray mThemeAttrs; @UnsupportedAppUsage @@ -2350,7 +2325,7 @@ public class InputMethodService extends AbstractInputMethodService { } void doStartInput(InputConnection ic, EditorInfo attribute, boolean restarting) { - if (!restarting && mInputStarted) { + if (!restarting) { doFinishInput(); } ImeTracing.getInstance().triggerServiceDump("InputMethodService#doStartInput", this); -- cgit v1.2.3 From 4ba8484ffbef4fac301ea70210549692e9684e0d Mon Sep 17 00:00:00 2001 From: Ming-Shin Lu Date: Fri, 4 Dec 2020 03:21:12 +0000 Subject: Revert "Revert "Let IME#onFinishInput called without dup onStart..." Revert^2 "Verify lifecycle test when screen on/off" c2769e41ea17d7f0d261396d28ddde3563422701 Reason: Fix forward Bug 174512702 and Bug 174445559 with CL[1]. CL[1]: Icf1504d40b25fc5f53eae65d4bab48a3070db1d6 Change-Id: Id4e71a822bfde5fe6a263bbe094c0d238017efe1 --- .../inputmethodservice/InputMethodService.java | 29 ++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 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 14bc1ddad5f0..6831eca32f72 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -62,9 +62,12 @@ import android.annotation.IntDef; import android.annotation.MainThread; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.TestApi; import android.annotation.UiContext; import android.app.ActivityManager; import android.app.Dialog; +import android.compat.annotation.ChangeId; +import android.compat.annotation.EnabledSince; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; @@ -412,7 +415,29 @@ public class InputMethodService extends AbstractInputMethodService { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) int mTheme = 0; - + + /** + * Finish the {@link InputConnection} when the device becomes + * {@link android.os.PowerManager#isInteractive non-interactive}. + * + *

+ * If enabled by the current {@link InputMethodService input method}, the current input + * connection will be {@link InputMethodService#onFinishInput finished} whenever the devices + * becomes non-interactive. + * + *

+ * If not enabled, the current input connection will instead be silently deactivated when the + * devices becomes non-interactive, and an {@link InputMethodService#onFinishInput + * onFinishInput()} {@link InputMethodService#onStartInput onStartInput()} pair is dispatched + * when the device becomes interactive again. + * + * @hide + */ + @TestApi + @ChangeId + @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S) + public static final long FINISH_INPUT_NO_FALLBACK_CONNECTION = 156215187L; // This is a bug id. + LayoutInflater mInflater; TypedArray mThemeAttrs; @UnsupportedAppUsage @@ -2352,7 +2377,7 @@ public class InputMethodService extends AbstractInputMethodService { } void doStartInput(InputConnection ic, EditorInfo attribute, boolean restarting) { - if (!restarting) { + if (!restarting && mInputStarted) { doFinishInput(); } ImeTracing.getInstance().triggerServiceDump("InputMethodService#doStartInput", this, -- cgit v1.2.3 From dc211bfac3e8f6e75f8b9e7a6f31c112f30d4901 Mon Sep 17 00:00:00 2001 From: Taran Singh Date: Wed, 18 Nov 2020 15:04:27 -0800 Subject: Prevent Fullscreen IME when app is in portrait. When an app is running in portrait orientation, regardless of what orientation display is in, IME shouldn't use fullscreen-mode. Setting IME_FLAG_NO_FULLSCREEN in EditorInfo makes sure IME doesn't go fullscreen. Bug: 157870379 Test: Manually using steps in bug Change-Id: I5a5e73e1dec776665f28a7e2eb091b555198001b --- core/java/android/inputmethodservice/InputMethodService.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 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 6831eca32f72..df9a7c2cb586 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -1700,8 +1700,12 @@ public class InputMethodService extends AbstractInputMethodService { if (config.orientation != Configuration.ORIENTATION_LANDSCAPE) { return false; } - if (mInputEditorInfo != null - && (mInputEditorInfo.imeOptions & EditorInfo.IME_FLAG_NO_FULLSCREEN) != 0) { + if ((mInputEditorInfo != null + && (mInputEditorInfo.imeOptions & EditorInfo.IME_FLAG_NO_FULLSCREEN) != 0) + // If app window has portrait orientation, regardless of what display orientation + // is, IME shouldn't use fullscreen-mode. + || (mInputEditorInfo.internalImeOptions + & EditorInfo.IME_FLAG_APP_WINDOW_PORTRAIT) != 0) { return false; } return true; -- cgit v1.2.3 From 533596c71d2502ff8b4d99ae4d1b4201d84d4c4a Mon Sep 17 00:00:00 2001 From: Taran Singh Date: Tue, 12 Jan 2021 18:51:10 +0000 Subject: Retain IME surface with a timeout As of today, IME surface is removed immidiately after its hidden. This causes IME surface to be recreated when next time its requested, which takes noticeable amount of time ~30ms on a typical phone [1] In order to improve IME latency, we keep the surface in memory a little longer. This is ideal for use cases where IME has to move between DisplayAreas OR when IME is closed only briefly. While there could be other strategies to hold IME surface in memory, timeout is simplistic and is also unaffected by IMF lifecycle, which could vary when moving between DisplayAreas or Displays. Bug: 167948419 Bug: 167948123 Test: atest CtsInputMethodTestCases [1] refer design doc in bug 167947940 Change-Id: Ib062640b68164efbb647e7bf27b7f8eb5ed252dc --- .../inputmethodservice/InputMethodService.java | 36 ++++++++++++++++++++-- 1 file changed, 33 insertions(+), 3 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 df9a7c2cb586..44a2e97e6f04 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -410,6 +410,11 @@ public class InputMethodService extends AbstractInputMethodService { private static final int BACK_DISPOSITION_MIN = BACK_DISPOSITION_DEFAULT; private static final int BACK_DISPOSITION_MAX = BACK_DISPOSITION_ADJUST_NOTHING; + /** + * Timeout after which hidden IME surface will be removed from memory + */ + private static final long TIMEOUT_SURFACE_REMOVAL_MILLIS = 5000; + InputMethodManager mImm; private InputMethodPrivilegedOperations mPrivOps = new InputMethodPrivilegedOperations(); @@ -506,6 +511,8 @@ public class InputMethodService extends AbstractInputMethodService { private boolean mAutomotiveHideNavBarForKeyboard; private boolean mIsAutomotive; + private Handler mHandler; + private boolean mImeSurfaceScheduledForRemoval; /** * An opaque {@link Binder} token of window requesting {@link InputMethodImpl#showSoftInput} @@ -903,11 +910,31 @@ public class InputMethodService extends AbstractInputMethodService { requestHideSelf(0); } + private void scheduleImeSurfaceRemoval() { + if (mShowInputRequested || mWindowVisible || mWindow == null + || mImeSurfaceScheduledForRemoval) { + return; + } + if (mHandler == null) { + mHandler = new Handler(getMainLooper()); + } + mImeSurfaceScheduledForRemoval = true; + mHandler.postDelayed(() -> removeImeSurface(), TIMEOUT_SURFACE_REMOVAL_MILLIS); + } + private void removeImeSurface() { - if (!mShowInputRequested && !mWindowVisible) { - // hiding a window removes its surface. + // hiding a window removes its surface. + if (mWindow != null) { mWindow.hide(); } + mImeSurfaceScheduledForRemoval = false; + } + + private void cancelImeSurfaceRemoval() { + if (mHandler != null && mImeSurfaceScheduledForRemoval) { + mHandler.removeCallbacksAndMessages(null /* token */); + mImeSurfaceScheduledForRemoval = false; + } } private void setImeWindowStatus(int visibilityFlags, int backDisposition) { @@ -1043,7 +1070,7 @@ public class InputMethodService extends AbstractInputMethodService { * @hide */ public final void removeImeSurface() { - InputMethodService.this.removeImeSurface(); + InputMethodService.this.scheduleImeSurfaceRemoval(); } } @@ -2271,6 +2298,9 @@ public class InputMethodService extends AbstractInputMethodService { ImeTracing.getInstance().triggerServiceDump( "InputMethodService#applyVisibilityInInsetsConsumerIfNecessary", this, null /* icProto */); + if (setVisible) { + cancelImeSurfaceRemoval(); + } mPrivOps.applyImeVisibility(setVisible ? mCurShowInputToken : mCurHideInputToken, setVisible); } -- cgit v1.2.3 From 2b4bd4c6fba5500e2c72d4d08208403f501895d2 Mon Sep 17 00:00:00 2001 From: Taran Singh Date: Fri, 29 Jan 2021 16:29:04 +0000 Subject: Make EditorInfo.internalImeOptions parcelable. Followup to I5a5e73e1dec776665f28a7e2eb091b555198001b. internalImeOptions field should be parcelable. Fix: 157870379 Test: Manually using steps in bug Change-Id: I12b442b8b2d8cf83aa4cc789133b42251ad2c191 --- core/java/android/inputmethodservice/InputMethodService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (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 44a2e97e6f04..7e2be01feb01 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -1732,7 +1732,7 @@ public class InputMethodService extends AbstractInputMethodService { // If app window has portrait orientation, regardless of what display orientation // is, IME shouldn't use fullscreen-mode. || (mInputEditorInfo.internalImeOptions - & EditorInfo.IME_FLAG_APP_WINDOW_PORTRAIT) != 0) { + & EditorInfo.IME_INTERNAL_FLAG_APP_WINDOW_PORTRAIT) != 0) { return false; } return true; -- cgit v1.2.3 From d6f8a1ada1d1d3501f2d11aa6d514965fba00e46 Mon Sep 17 00:00:00 2001 From: Taran Singh Date: Fri, 29 Jan 2021 16:42:52 +0000 Subject: Avoid IME restart for configChanges Handle onConfigurationChanged() in order to prevent restarting InputMethodService everytime. We introduce a new API attribute "configChanges" in InputMethod(attrs.xml) which when declared by IME, will be responsible for handling mentioned configuration changes. Bug: 167948419 Test: atest InputMethodServiceTest Manually: 1. Patch Ie91e7a8e06b80864ef9409031e8543858552d70d to use dual display area. 2. Open applications with editors on both display areas. 3. Attach a debug point for IMS#onConfigurationChanged(). 4. Make sure IMS#resetStateForNewConfiguration() is not called when IME moves between these two identical DisplayAreas Change-Id: Iff88b768c6b06cf5cf1fe9e97ee97f8f78e6f0bd --- .../inputmethodservice/InputMethodService.java | 52 ++++++++++++++++++++-- 1 file changed, 49 insertions(+), 3 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 7e2be01feb01..03dd3067e64e 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -70,6 +70,7 @@ import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; @@ -131,6 +132,7 @@ import android.widget.TextView; import android.window.WindowMetricsHelper; import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.inputmethod.IInputContentUriToken; import com.android.internal.inputmethod.IInputMethodPrivilegedOperations; import com.android.internal.inputmethod.InputMethodPrivilegedOperations; @@ -513,6 +515,8 @@ public class InputMethodService extends AbstractInputMethodService { private boolean mIsAutomotive; private Handler mHandler; private boolean mImeSurfaceScheduledForRemoval; + private Configuration mLastKnownConfig; + private int mHandledConfigChanges; /** * An opaque {@link Binder} token of window requesting {@link InputMethodImpl#showSoftInput} @@ -588,12 +592,14 @@ public class InputMethodService extends AbstractInputMethodService { @MainThread @Override public final void initializeInternal(@NonNull IBinder token, int displayId, - IInputMethodPrivilegedOperations privilegedOperations) { + IInputMethodPrivilegedOperations privilegedOperations, + int configChanges) { if (InputMethodPrivilegedOperationsRegistry.isRegistered(token)) { Log.w(TAG, "The token has already registered, ignore this initialization."); return; } Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initializeInternal"); + mHandledConfigChanges = configChanges; mPrivOps.set(privilegedOperations); InputMethodPrivilegedOperationsRegistry.put(token, mPrivOps); updateInputMethodDisplay(displayId); @@ -821,6 +827,9 @@ public class InputMethodService extends AbstractInputMethodService { setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition); } final boolean isVisible = isInputViewShown(); + if (isVisible && getResources() != null) { + mLastKnownConfig = getResources().getConfiguration(); + } final boolean visibilityChanged = isVisible != wasVisible; if (resultReceiver != null) { resultReceiver.send(visibilityChanged @@ -1428,10 +1437,37 @@ public class InputMethodService extends AbstractInputMethodService { * state: {@link #onStartInput} if input is active, and * {@link #onCreateInputView} and {@link #onStartInputView} and related * appropriate functions if the UI is displayed. + *

Starting with {@link Build.VERSION_CODES#S}, IMEs can opt into handling configuration + * changes themselves instead of being restarted with + * {@link android.R.styleable#InputMethod_configChanges}. */ @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); - resetStateForNewConfiguration(); + if (shouldImeRestartForConfig(newConfig)) { + resetStateForNewConfiguration(); + } + } + + /** + * @return {@code true} if {@link InputMethodService} needs to restart to handle + * .{@link #onConfigurationChanged(Configuration)} + */ + @VisibleForTesting + boolean shouldImeRestartForConfig(@NonNull Configuration newConfig) { + if (mLastKnownConfig == null) { + return true; + } + // If the new config is the same as the config this Service is already running with, + // then don't bother calling resetStateForNewConfiguration. + int diff = mLastKnownConfig.diffPublicOnly(newConfig); + if (diff != 0) { + // remove attrs not-relevant to IME service. + diff &= ActivityInfo.CONFIG_KEYBOARD_HIDDEN; + diff &= ActivityInfo.CONFIG_KEYBOARD; + diff &= ActivityInfo.CONFIG_NAVIGATION; + } + int unhandledDiff = (diff & ~mHandledConfigChanges); + return unhandledDiff != 0; } private void resetStateForNewConfiguration() { @@ -3181,7 +3217,17 @@ public class InputMethodService extends AbstractInputMethodService { requestHideSelf(InputMethodManager.HIDE_NOT_ALWAYS); } } - + + @VisibleForTesting + void setLastKnownConfig(@NonNull Configuration config) { + mLastKnownConfig = config; + } + + @VisibleForTesting + void setHandledConfigChanges(int configChanges) { + mHandledConfigChanges = configChanges; + } + void startExtractingText(boolean inputChanged) { final ExtractEditText eet = mExtractEditText; if (eet != null && getCurrentInputStarted() -- cgit v1.2.3 From 712fc24a340f13b470c5295a6a87ff128f2ac6d3 Mon Sep 17 00:00:00 2001 From: Taran Singh Date: Fri, 26 Feb 2021 20:05:54 +0000 Subject: Revert "Avoid IME restart for configChanges" Revert "Add cts for InputMethodService configChanges" Revert submission 13417792-b/167948419 Reason for revert: Causes bugs like b/181195100 Reverted Changes: Iff88b768c:Avoid IME restart for configChanges Ib7ce13340:Add cts for InputMethodService configChanges Bug: 167948419 Fix: 181195100 Change-Id: I36bca545b09b4f870560964ec61fa6bb344fceaf --- .../inputmethodservice/InputMethodService.java | 52 ++-------------------- 1 file changed, 3 insertions(+), 49 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 03dd3067e64e..7e2be01feb01 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -70,7 +70,6 @@ import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; -import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; @@ -132,7 +131,6 @@ import android.widget.TextView; import android.window.WindowMetricsHelper; import com.android.internal.annotations.GuardedBy; -import com.android.internal.annotations.VisibleForTesting; import com.android.internal.inputmethod.IInputContentUriToken; import com.android.internal.inputmethod.IInputMethodPrivilegedOperations; import com.android.internal.inputmethod.InputMethodPrivilegedOperations; @@ -515,8 +513,6 @@ public class InputMethodService extends AbstractInputMethodService { private boolean mIsAutomotive; private Handler mHandler; private boolean mImeSurfaceScheduledForRemoval; - private Configuration mLastKnownConfig; - private int mHandledConfigChanges; /** * An opaque {@link Binder} token of window requesting {@link InputMethodImpl#showSoftInput} @@ -592,14 +588,12 @@ public class InputMethodService extends AbstractInputMethodService { @MainThread @Override public final void initializeInternal(@NonNull IBinder token, int displayId, - IInputMethodPrivilegedOperations privilegedOperations, - int configChanges) { + IInputMethodPrivilegedOperations privilegedOperations) { if (InputMethodPrivilegedOperationsRegistry.isRegistered(token)) { Log.w(TAG, "The token has already registered, ignore this initialization."); return; } Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initializeInternal"); - mHandledConfigChanges = configChanges; mPrivOps.set(privilegedOperations); InputMethodPrivilegedOperationsRegistry.put(token, mPrivOps); updateInputMethodDisplay(displayId); @@ -827,9 +821,6 @@ public class InputMethodService extends AbstractInputMethodService { setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition); } final boolean isVisible = isInputViewShown(); - if (isVisible && getResources() != null) { - mLastKnownConfig = getResources().getConfiguration(); - } final boolean visibilityChanged = isVisible != wasVisible; if (resultReceiver != null) { resultReceiver.send(visibilityChanged @@ -1437,37 +1428,10 @@ public class InputMethodService extends AbstractInputMethodService { * state: {@link #onStartInput} if input is active, and * {@link #onCreateInputView} and {@link #onStartInputView} and related * appropriate functions if the UI is displayed. - *

Starting with {@link Build.VERSION_CODES#S}, IMEs can opt into handling configuration - * changes themselves instead of being restarted with - * {@link android.R.styleable#InputMethod_configChanges}. */ @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); - if (shouldImeRestartForConfig(newConfig)) { - resetStateForNewConfiguration(); - } - } - - /** - * @return {@code true} if {@link InputMethodService} needs to restart to handle - * .{@link #onConfigurationChanged(Configuration)} - */ - @VisibleForTesting - boolean shouldImeRestartForConfig(@NonNull Configuration newConfig) { - if (mLastKnownConfig == null) { - return true; - } - // If the new config is the same as the config this Service is already running with, - // then don't bother calling resetStateForNewConfiguration. - int diff = mLastKnownConfig.diffPublicOnly(newConfig); - if (diff != 0) { - // remove attrs not-relevant to IME service. - diff &= ActivityInfo.CONFIG_KEYBOARD_HIDDEN; - diff &= ActivityInfo.CONFIG_KEYBOARD; - diff &= ActivityInfo.CONFIG_NAVIGATION; - } - int unhandledDiff = (diff & ~mHandledConfigChanges); - return unhandledDiff != 0; + resetStateForNewConfiguration(); } private void resetStateForNewConfiguration() { @@ -3217,17 +3181,7 @@ public class InputMethodService extends AbstractInputMethodService { requestHideSelf(InputMethodManager.HIDE_NOT_ALWAYS); } } - - @VisibleForTesting - void setLastKnownConfig(@NonNull Configuration config) { - mLastKnownConfig = config; - } - - @VisibleForTesting - void setHandledConfigChanges(int configChanges) { - mHandledConfigChanges = configChanges; - } - + void startExtractingText(boolean inputChanged) { final ExtractEditText eet = mExtractEditText; if (eet != null && getCurrentInputStarted() -- cgit v1.2.3 From 9a2eed9f496f1fbca3434b672dfdeb2f59448078 Mon Sep 17 00:00:00 2001 From: Taran Singh Date: Mon, 1 Mar 2021 19:35:51 +0000 Subject: Avoid IME restart for configChanges Handle onConfigurationChanged() in order to prevent restarting InputMethodService everytime. We introduce a new API attribute "configChanges" in InputMethod(attrs.xml) which when declared by IME, will be responsible for handling mentioned configuration changes. This CL re-introduces [1] with fix: Use new Configuration instance for IMS#mLastKnownConfig [1] Iff88b768c6b06cf5cf1fe9e97ee97f8f78e6f0bd Bug: 167948419 Test: atest InputMethodServiceTest Manually: 1. Patch Ie91e7a8e06b80864ef9409031e8543858552d70d to use dual display area. 2. Open applications with editors on both display areas. 3. Attach a debug point for IMS#onConfigurationChanged(). 4. Make sure IMS#resetStateForNewConfiguration() is not called when IME moves between these two identical DisplayAreas Change-Id: Ib94fddadb0dae648cf73a4c1642e51edebd19f50 --- .../inputmethodservice/InputMethodService.java | 44 ++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 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 7e2be01feb01..40a0fc4e8339 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -70,6 +70,7 @@ import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; @@ -131,6 +132,7 @@ import android.widget.TextView; import android.window.WindowMetricsHelper; import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.inputmethod.IInputContentUriToken; import com.android.internal.inputmethod.IInputMethodPrivilegedOperations; import com.android.internal.inputmethod.InputMethodPrivilegedOperations; @@ -513,6 +515,8 @@ public class InputMethodService extends AbstractInputMethodService { private boolean mIsAutomotive; private Handler mHandler; private boolean mImeSurfaceScheduledForRemoval; + private Configuration mLastKnownConfig; + private int mHandledConfigChanges; /** * An opaque {@link Binder} token of window requesting {@link InputMethodImpl#showSoftInput} @@ -588,12 +592,13 @@ public class InputMethodService extends AbstractInputMethodService { @MainThread @Override public final void initializeInternal(@NonNull IBinder token, int displayId, - IInputMethodPrivilegedOperations privilegedOperations) { + IInputMethodPrivilegedOperations privilegedOperations, int configChanges) { if (InputMethodPrivilegedOperationsRegistry.isRegistered(token)) { Log.w(TAG, "The token has already registered, ignore this initialization."); return; } Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initializeInternal"); + mHandledConfigChanges = configChanges; mPrivOps.set(privilegedOperations); InputMethodPrivilegedOperationsRegistry.put(token, mPrivOps); updateInputMethodDisplay(displayId); @@ -821,6 +826,9 @@ public class InputMethodService extends AbstractInputMethodService { setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition); } final boolean isVisible = isInputViewShown(); + if (isVisible && getResources() != null) { + mLastKnownConfig = new Configuration(getResources().getConfiguration()); + } final boolean visibilityChanged = isVisible != wasVisible; if (resultReceiver != null) { resultReceiver.send(visibilityChanged @@ -1428,10 +1436,30 @@ public class InputMethodService extends AbstractInputMethodService { * state: {@link #onStartInput} if input is active, and * {@link #onCreateInputView} and {@link #onStartInputView} and related * appropriate functions if the UI is displayed. + *

Starting with {@link Build.VERSION_CODES#S}, IMEs can opt into handling configuration + * changes themselves instead of being restarted with + * {@link android.R.styleable#InputMethod_configChanges}. */ @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); - resetStateForNewConfiguration(); + if (shouldImeRestartForConfig(newConfig)) { + resetStateForNewConfiguration(); + } + } + + /** + * @return {@code true} if {@link InputMethodService} needs to restart to handle + * .{@link #onConfigurationChanged(Configuration)} + */ + @VisibleForTesting + boolean shouldImeRestartForConfig(@NonNull Configuration newConfig) { + if (mLastKnownConfig == null) { + return true; + } + // If the new config is the same as the config this Service is already running with, + // then don't bother calling resetStateForNewConfiguration. + int unhandledDiff = (mLastKnownConfig.diffPublicOnly(newConfig) & ~mHandledConfigChanges); + return unhandledDiff != 0; } private void resetStateForNewConfiguration() { @@ -3181,7 +3209,17 @@ public class InputMethodService extends AbstractInputMethodService { requestHideSelf(InputMethodManager.HIDE_NOT_ALWAYS); } } - + + @VisibleForTesting + void setLastKnownConfig(@NonNull Configuration config) { + mLastKnownConfig = config; + } + + @VisibleForTesting + void setHandledConfigChanges(int configChanges) { + mHandledConfigChanges = configChanges; + } + void startExtractingText(boolean inputChanged) { final ExtractEditText eet = mExtractEditText; if (eet != null && getCurrentInputStarted() -- cgit v1.2.3 From 1e7d1256620bd79858cb69b0d00d7a2dce6d4a64 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Sat, 13 Mar 2021 01:08:03 +0000 Subject: Revert "Avoid IME restart for configChanges" Revert "Add cts for InputMethodService configChanges" Revert submission 13727407-167948419 Reason for revert: Possible root cause of Bug 182604598. Reverted Changes: Ib94fddadb:Avoid IME restart for configChanges Ieca327b2e:Add cts for InputMethodService configChanges Bug: 167948419 Bug: 182604598 Test: presubmit Change-Id: I3accc55ac65d0e2ec30c3f6023680fda27ad3e97 --- .../inputmethodservice/InputMethodService.java | 44 ++-------------------- 1 file changed, 3 insertions(+), 41 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 40a0fc4e8339..7e2be01feb01 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -70,7 +70,6 @@ import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; -import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; @@ -132,7 +131,6 @@ import android.widget.TextView; import android.window.WindowMetricsHelper; import com.android.internal.annotations.GuardedBy; -import com.android.internal.annotations.VisibleForTesting; import com.android.internal.inputmethod.IInputContentUriToken; import com.android.internal.inputmethod.IInputMethodPrivilegedOperations; import com.android.internal.inputmethod.InputMethodPrivilegedOperations; @@ -515,8 +513,6 @@ public class InputMethodService extends AbstractInputMethodService { private boolean mIsAutomotive; private Handler mHandler; private boolean mImeSurfaceScheduledForRemoval; - private Configuration mLastKnownConfig; - private int mHandledConfigChanges; /** * An opaque {@link Binder} token of window requesting {@link InputMethodImpl#showSoftInput} @@ -592,13 +588,12 @@ public class InputMethodService extends AbstractInputMethodService { @MainThread @Override public final void initializeInternal(@NonNull IBinder token, int displayId, - IInputMethodPrivilegedOperations privilegedOperations, int configChanges) { + IInputMethodPrivilegedOperations privilegedOperations) { if (InputMethodPrivilegedOperationsRegistry.isRegistered(token)) { Log.w(TAG, "The token has already registered, ignore this initialization."); return; } Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initializeInternal"); - mHandledConfigChanges = configChanges; mPrivOps.set(privilegedOperations); InputMethodPrivilegedOperationsRegistry.put(token, mPrivOps); updateInputMethodDisplay(displayId); @@ -826,9 +821,6 @@ public class InputMethodService extends AbstractInputMethodService { setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition); } final boolean isVisible = isInputViewShown(); - if (isVisible && getResources() != null) { - mLastKnownConfig = new Configuration(getResources().getConfiguration()); - } final boolean visibilityChanged = isVisible != wasVisible; if (resultReceiver != null) { resultReceiver.send(visibilityChanged @@ -1436,30 +1428,10 @@ public class InputMethodService extends AbstractInputMethodService { * state: {@link #onStartInput} if input is active, and * {@link #onCreateInputView} and {@link #onStartInputView} and related * appropriate functions if the UI is displayed. - *

Starting with {@link Build.VERSION_CODES#S}, IMEs can opt into handling configuration - * changes themselves instead of being restarted with - * {@link android.R.styleable#InputMethod_configChanges}. */ @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); - if (shouldImeRestartForConfig(newConfig)) { - resetStateForNewConfiguration(); - } - } - - /** - * @return {@code true} if {@link InputMethodService} needs to restart to handle - * .{@link #onConfigurationChanged(Configuration)} - */ - @VisibleForTesting - boolean shouldImeRestartForConfig(@NonNull Configuration newConfig) { - if (mLastKnownConfig == null) { - return true; - } - // If the new config is the same as the config this Service is already running with, - // then don't bother calling resetStateForNewConfiguration. - int unhandledDiff = (mLastKnownConfig.diffPublicOnly(newConfig) & ~mHandledConfigChanges); - return unhandledDiff != 0; + resetStateForNewConfiguration(); } private void resetStateForNewConfiguration() { @@ -3209,17 +3181,7 @@ public class InputMethodService extends AbstractInputMethodService { requestHideSelf(InputMethodManager.HIDE_NOT_ALWAYS); } } - - @VisibleForTesting - void setLastKnownConfig(@NonNull Configuration config) { - mLastKnownConfig = config; - } - - @VisibleForTesting - void setHandledConfigChanges(int configChanges) { - mHandledConfigChanges = configChanges; - } - + void startExtractingText(boolean inputChanged) { final ExtractEditText eet = mExtractEditText; if (eet != null && getCurrentInputStarted() -- cgit v1.2.3 From 1b8593fdfeb9b53e3595e3fb2e20d4db927842e0 Mon Sep 17 00:00:00 2001 From: Wilson Wu Date: Wed, 24 Mar 2021 18:38:36 +0800 Subject: Make IInputMethodPrivilegedOperations to async (1/N) -. Remove VoidResultCallback of setImeWindowStatus and let it be asynchronous. -. Rename function naming to setImeWindowStatusAsync. Bug: 183587528 Test: atest CtsInputMethodTestCases Change-Id: Ia9f19ca5ae418089ce43816dcd50487e1b1172f1 --- core/java/android/inputmethodservice/InputMethodService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (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 7e2be01feb01..7819bbb19971 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -938,7 +938,7 @@ public class InputMethodService extends AbstractInputMethodService { } private void setImeWindowStatus(int visibilityFlags, int backDisposition) { - mPrivOps.setImeWindowStatus(visibilityFlags, backDisposition); + mPrivOps.setImeWindowStatusAsync(visibilityFlags, backDisposition); } /** Set region of the keyboard to be avoided from back gesture */ -- cgit v1.2.3 From 71ab752fc59e3db45e12d6ed9c922eb1ffca84a7 Mon Sep 17 00:00:00 2001 From: Taran Singh Date: Fri, 19 Mar 2021 15:34:02 +0000 Subject: Avoid IME restart for configChanges Handle onConfigurationChanged() in order to prevent restarting InputMethodService everytime. We introduce a new API attribute "configChanges" in InputMethod(attrs.xml) which when declared by IME, will be responsible for handling mentioned configuration changes. This CL re-introduces [1] with fix: Use new Configuration instance for IMS#mLastKnownConfig and also handle followup comments. [1] Ib94fddadb0dae648cf73a4c1642e51edebd19f50 Note: this change has no impact for devices not using DisplayAreas. Bug: 167948419 Test: atest InputMethodServiceTest Manually: 1. Patch Ie91e7a8e06b80864ef9409031e8543858552d70d to use dual display area. 2. Open applications with editors on both display areas. 3. Attach a debug point for IMS#onConfigurationChanged(). 4. Make sure IMS#resetStateForNewConfiguration() is not called when IME moves between these two identical DisplayAreas Also verify that bug 182604598 don't happen. Change-Id: I43b6b80cdb35410554412ee1d3b0917ee3198272 --- core/java/android/inputmethodservice/InputMethodService.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 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 7e2be01feb01..bf016124da31 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -513,6 +513,7 @@ public class InputMethodService extends AbstractInputMethodService { private boolean mIsAutomotive; private Handler mHandler; private boolean mImeSurfaceScheduledForRemoval; + private ImsConfigurationTracker mConfigTracker = new ImsConfigurationTracker(); /** * An opaque {@link Binder} token of window requesting {@link InputMethodImpl#showSoftInput} @@ -588,12 +589,13 @@ public class InputMethodService extends AbstractInputMethodService { @MainThread @Override public final void initializeInternal(@NonNull IBinder token, int displayId, - IInputMethodPrivilegedOperations privilegedOperations) { + IInputMethodPrivilegedOperations privilegedOperations, int configChanges) { if (InputMethodPrivilegedOperationsRegistry.isRegistered(token)) { Log.w(TAG, "The token has already registered, ignore this initialization."); return; } Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initializeInternal"); + mConfigTracker.onInitialize(configChanges); mPrivOps.set(privilegedOperations); InputMethodPrivilegedOperationsRegistry.put(token, mPrivOps); updateInputMethodDisplay(displayId); @@ -663,6 +665,7 @@ public class InputMethodService extends AbstractInputMethodService { reportFullscreenMode(); initialize(); onBindInput(); + mConfigTracker.onBindInput(getResources()); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } @@ -1428,10 +1431,13 @@ public class InputMethodService extends AbstractInputMethodService { * state: {@link #onStartInput} if input is active, and * {@link #onCreateInputView} and {@link #onStartInputView} and related * appropriate functions if the UI is displayed. + *

Starting with {@link Build.VERSION_CODES#S}, IMEs can opt into handling configuration + * changes themselves instead of being restarted with + * {@link android.R.styleable#InputMethod_configChanges}. */ @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); - resetStateForNewConfiguration(); + mConfigTracker.onConfigurationChanged(newConfig, this::resetStateForNewConfiguration); } private void resetStateForNewConfiguration() { @@ -3181,7 +3187,7 @@ public class InputMethodService extends AbstractInputMethodService { requestHideSelf(InputMethodManager.HIDE_NOT_ALWAYS); } } - + void startExtractingText(boolean inputChanged) { final ExtractEditText eet = mExtractEditText; if (eet != null && getCurrentInputStarted() -- cgit v1.2.3 From 738468ba1751e50cc624476473ec8e23187b32f3 Mon Sep 17 00:00:00 2001 From: Wilson Wu Date: Thu, 15 Apr 2021 19:02:53 +0800 Subject: Make IInputMethodPrivilegedOperations to async (2/N) -. Remove VoidResultCallback of reportStartInput and let it be truly asynchronous. -. Rename this method to reportStartInputAsync. Bug: 183587528 Test: atest CtsInputMethodTestCases Change-Id: Ic8e7f888f78f7c536a9228db02a8b355555d7220 --- core/java/android/inputmethodservice/InputMethodService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (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 4ee5383a56be..f03da7cd390b 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -718,7 +718,7 @@ public class InputMethodService extends AbstractInputMethodService { public final void dispatchStartInputWithToken(@Nullable InputConnection inputConnection, @NonNull EditorInfo editorInfo, boolean restarting, @NonNull IBinder startInputToken) { - mPrivOps.reportStartInput(startInputToken); + mPrivOps.reportStartInputAsync(startInputToken); if (restarting) { restartInput(inputConnection, editorInfo); -- cgit v1.2.3 From c66dd0af0250a3923904bf8d3c9c9474023a15b1 Mon Sep 17 00:00:00 2001 From: Ming-Shin Lu Date: Sun, 18 Apr 2021 22:28:22 +0800 Subject: Fix not invoke setImeWindowStatus when unlocked by PIN lock CL[1] removed setImeWindowStatatus call in showSoftInput() since showWindow() has a call. Howerver, the call invokes only when the IME visibility has changed. It overlooked the case that when the screen unlocked by PIN lock, since the focused app and IME visiblity is the same, so the setImeWindowStatus in showWindow() doesn't invoked. When then keyguard shown, IMMS side will invoke updateSystemUiLocked to update navbar icon as invisible, so after the user unlocked, user won't see the navbar icon set visible back. As the result, we still need setImeWindowStatus called in showSoftInput to fix this case. [1]: I0b0750f146634d8e90e0b0ac46e9208675626d0a Fix: 181294561 Test: manual as below steps: 0) setup PIN lock for the device 1) launch an app (e.g. Messaging) and show IME 2) turn-off the screen and unlock the screen with PIN 3) verify if the keyboard is visible and the navbar icon is visible Change-Id: I168fda76c1c7bdcabe94f7c2550c6b5c7c41e5e0 --- core/java/android/inputmethodservice/InputMethodService.java | 5 ++--- 1 file changed, 2 insertions(+), 3 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 f03da7cd390b..4b8e37c56061 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -819,10 +819,9 @@ public class InputMethodService extends AbstractInputMethodService { if (dispatchOnShowInputRequested(flags, false)) { showWindow(true); applyVisibilityInInsetsConsumerIfNecessary(true /* setVisible */); - } else { - // If user uses hard keyboard, IME button should always be shown. - setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition); } + setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition); + final boolean isVisible = isInputViewShown(); final boolean visibilityChanged = isVisible != wasVisible; if (resultReceiver != null) { -- cgit v1.2.3 From c84b3e15df74382ffd00cfd8eff24b1c7948e614 Mon Sep 17 00:00:00 2001 From: Wilson Wu Date: Fri, 16 Apr 2021 14:37:12 +0800 Subject: Make IInputMethodPrivilegedOperations to async (3/N) -. Remove VoidResultCallback of reportFullscreenMode and let it be truly asynchronous. -. Rename this method to reportFullscreenModeAsync. Bug: 183587528 Test: atest CtsInputMethodTestCases Test: Manually verified as follows. 1. Build flame-userdebug and flash it. 2. Make sure that the screen rotation is enabled. 3. make -j SoftKeyboard 4. adb install -r $OUT/system/app/SoftKeyboard/SoftKeyboard.apk 5. adb shell ime enable com.example.android.softkeyboard/.SoftKeyboard 6. adb shell ime set com.example.android.softkeyboard/.SoftKeyboard 7. make -j EditTextVariations 8. adb install -r $ANDROID_TARGET_OUT_TESTCASES/EditTextVariations/arm64/EditTextVariations.apk 9. adb shell am start -n com.android.inputmethod.tools.edittextvariations/.EditTextVariations 10. Make sure that the device is in the landscape mode, and the SoftKeyboard sample IME is not yet shown. 11. adb shell dumpsys input_method | grep mFullscreenMode Then make sure the mFullscreenMode is "false" 12. Tap the first edit field then make sure that SoftKeyboard sample IME becomes visible in the fullscreen mode. 13. adb shell dumpsys input_method | grep mFullscreenMode Then make sure the mFullscreenMode is "true" 14. Tap the down button on the navbar to hide the SoftKeyboard sample IME. 15. adb shell dumpsys input_method | grep mFullscreenMode Then make sure the mFullscreenMode is "false" Change-Id: I92e8b0d420be3dd16cc4f3ba29e0bde5f12ab2ce --- core/java/android/inputmethodservice/InputMethodService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (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 4ee5383a56be..ad5c21295e15 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -1628,7 +1628,7 @@ public class InputMethodService extends AbstractInputMethodService { } private void reportFullscreenMode() { - mPrivOps.reportFullscreenMode(mIsFullscreen); + mPrivOps.reportFullscreenModeAsync(mIsFullscreen); } /** -- cgit v1.2.3 From 2c8068c98a96a5439d1fdd537eee1f1729f7fab4 Mon Sep 17 00:00:00 2001 From: Ming-Shin Lu Date: Sat, 10 Apr 2021 00:17:35 +0800 Subject: Consolidate InputMethodManager#toggleSoftInput reliability As previously InputMethodManager#toggleSoftInput is designed to tell InputMethodService directly through IInputMethodSession to toggle soft-keyboard visibility, this could be happened some unexpected IME visibility issues that when the app calling this method in the wrong state like the app toggling IME visibility when the app is off-screen but unexpectedly it ends up showing soft-keyboard when the IME is in invisible state. To minimize the app compatibility without changing the public API surface and reducing unexpected IME visibilty been toggled behavior especially happens when switching the apps, changed the internal IPC protocols to call IMMS#showSoftInput or IMMS#hideSoftInput directly according the previous IME consumer requested visibility state, so that in IMMS side can validate to see if the token user is still focused and ready to toggle the IME visibility to show or hide. As the result, we deprecated toggleSoftInput and toggleSoftInputFromWindow to state the reason as the above, and recommand to use showSoftInput or hideSoftInputFromWindow instead, so that framework side no longer has to call {InputMethodSessionWrapper, InputMethodSessionImpl}#toggleSoftInput. Bug: 182071625 Test: m checkapi doc-comment-check-docs Test: atest KeyboardVisibilityControlTest#testToggleSoftInput Change-Id: I390dc029e7bcc30c200926a9bfbbbd0268a1f714 --- core/java/android/inputmethodservice/InputMethodService.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (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 5267aa81bdaf..4defc55fbd97 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -1042,8 +1042,14 @@ public class InputMethodService extends AbstractInputMethodService { } /** - * + * Handles a request to toggle the IME visibility. + * + * @deprecated Starting in {@link Build.VERSION_CODES#S} the system no longer invokes this + * method, instead it explicitly shows or hides the IME. An {@code InputMethodService} + * wishing to toggle its own visibility should instead invoke {@link + * InputMethodService#requestShowSelf} or {@link InputMethodService#requestHideSelf} */ + @Deprecated public void toggleSoftInput(int showFlags, int hideFlags) { InputMethodService.this.onToggleSoftInput(showFlags, hideFlags); } -- cgit v1.2.3 From 78a23141be035dd069d4053f21ceb1cd189bdcf0 Mon Sep 17 00:00:00 2001 From: Wilson Wu Date: Wed, 28 Apr 2021 12:55:10 +0800 Subject: Make IInputMethodPrivilegedOperations to async (4/N) -. Remove VoidResultCallback of updateStatusIcon and let it be truly asynchronous. -. Rename this method to updateStatusIconAsync. Bug: 183587528 Test: atest CtsInputMethodTestCases Change-Id: Ic7759354ec06a3293ea370ab7afe7422eb2d9356 --- core/java/android/inputmethodservice/InputMethodService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 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 4b8e37c56061..86ad5fa6afec 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -1941,12 +1941,12 @@ public class InputMethodService extends AbstractInputMethodService { public void showStatusIcon(@DrawableRes int iconResId) { mStatusIcon = iconResId; - mPrivOps.updateStatusIcon(getPackageName(), iconResId); + mPrivOps.updateStatusIconAsync(getPackageName(), iconResId); } public void hideStatusIcon() { mStatusIcon = 0; - mPrivOps.updateStatusIcon(null, 0); + mPrivOps.updateStatusIconAsync(null, 0); } /** -- cgit v1.2.3 From e702c9d3815baefc921ecdc240b46b9c6b539941 Mon Sep 17 00:00:00 2001 From: Wilson Wu Date: Wed, 28 Apr 2021 14:40:08 +0800 Subject: Make IInputMethodPrivilegedOperations to async (5/N) -. Remove VoidResultCallback of notifyUserAction. and let it be truly asynchronous. -. Rename this method to notifyUserActionAsync. Bug: 183587528 Test: atest CtsInputMethodTestCases Change-Id: I384fd689b6bd1d418ff5208444fbba2c1eac6f85 --- core/java/android/inputmethodservice/InputMethodService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (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 4b8e37c56061..ed544dedd39d 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -3313,7 +3313,7 @@ public class InputMethodService extends AbstractInputMethodService { if (mNotifyUserActionSent) { return; } - mPrivOps.notifyUserAction(); + mPrivOps.notifyUserActionAsync(); mNotifyUserActionSent = true; } } -- cgit v1.2.3 From 37051aef3866c358ab7c1060767f23a2cb70ebf8 Mon Sep 17 00:00:00 2001 From: Wilson Wu Date: Wed, 28 Apr 2021 16:28:26 +0800 Subject: Make IInputMethodPrivilegedOperations to async (6/N) -. Remove VoidResultCallback of applyImeVisibility. and let it be truly asynchronous. -. Rename this method to applyImeVisibilityAsync. Bug: 183587528 Test: atest CtsInputMethodTestCases Change-Id: Ica564c526223d32641a2485c0c0f3490fe4bfd39 --- core/java/android/inputmethodservice/InputMethodService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (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 1965e55daae1..d7b96dfb7827 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -2312,7 +2312,7 @@ public class InputMethodService extends AbstractInputMethodService { if (setVisible) { cancelImeSurfaceRemoval(); } - mPrivOps.applyImeVisibility(setVisible + mPrivOps.applyImeVisibilityAsync(setVisible ? mCurShowInputToken : mCurHideInputToken, setVisible); } -- cgit v1.2.3 From ea491da863774457299ffd5f2534dc2ba4d3ba52 Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Mon, 3 May 2021 23:20:33 +0800 Subject: Let IME receive insets ignoring z-order When IME is targeting notification shade, IME will be above status bar, and IME won't receive status bar insets anymore. The surface position of the control of IME will be changed because IME fits status bar. If the IME control target receives the new IME control (new surface position) after the IME animation starts, the IME position will be stale until the next IME animation, because the controls would be copied before playing the insets animation. This CL lets IME receive insets no matter what z-order IME has. So the IME position will stay the same while it is moved above system bars, and the IME behavior will be the same as before Android S (receiving status bar insets while targeting notification shade). Fix: 186178729 Test: Steps as below: 1. Make, install, and open EditTextVariations. 2. Open menu, and select Direct Reply. 3. Expand notification shade. 4. Expand the notification of EditTextVariations. 5. Click Direct Teply Test. 6. See if IME is overlapped with (button-based) navigation bar. If no, press home button and repeat 3-6 for several times. Change-Id: I53c64a5598f246ad577f652156903e4666a30cd9 --- core/java/android/inputmethodservice/InputMethodService.java | 1 + 1 file changed, 1 insertion(+) (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 5267aa81bdaf..c5b4d48f0191 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -1323,6 +1323,7 @@ public class InputMethodService extends AbstractInputMethodService { WindowManager.LayoutParams.TYPE_INPUT_METHOD, Gravity.BOTTOM, false); mWindow.getWindow().getAttributes().setFitInsetsTypes(statusBars() | navigationBars()); mWindow.getWindow().getAttributes().setFitInsetsSides(Side.all() & ~Side.BOTTOM); + mWindow.getWindow().getAttributes().receiveInsetsIgnoringZOrder = true; // Automotive devices may request the navigation bar to be hidden when the IME shows up // (controlled via config_automotiveHideNavBarForKeyboard) in order to maximize the visible -- cgit v1.2.3 From d661177926ad0ec26943efd5697c10058e6094ff Mon Sep 17 00:00:00 2001 From: Taran Singh Date: Thu, 20 May 2021 20:04:43 +0000 Subject: Don't cache IME surface in fullscreen mode Dont cache IME surface when IME was in fullscreen mode. This is done in order to fix IME closing when it is used with RecyclerView. There can be a special case where RecyclerView detaches the view holding mServedView when IME is in fullscreen mode While exact reason is still a mystery, short term solution is to not cache IME when it was in fullscreen mode. Fix: 187772544 Bug: 188818557 Bug: 167948123 Test: Manually using steps in bug Change-Id: I1194d08a00622f1dfa232209a70dcb0797ba192b --- .../android/inputmethodservice/InputMethodService.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 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 f0d410f46f81..881e0cfb58d7 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -481,6 +481,7 @@ public class InputMethodService extends AbstractInputMethodService { boolean mFullscreenApplied; boolean mIsFullscreen; + private boolean mLastWasInFullscreenMode; @UnsupportedAppUsage View mExtractView; boolean mExtractViewHidden; @@ -920,8 +921,17 @@ public class InputMethodService extends AbstractInputMethodService { if (mHandler == null) { mHandler = new Handler(getMainLooper()); } - mImeSurfaceScheduledForRemoval = true; - mHandler.postDelayed(() -> removeImeSurface(), TIMEOUT_SURFACE_REMOVAL_MILLIS); + + if (mLastWasInFullscreenMode) { + // Caching surface / delaying surface removal can cause mServedView to detach in certain + // cases in RecyclerView (b/187772544). + // TODO(b/188818557): Re-enable IME surface caching for fullscreen mode once detaching + // view issues is resolved in RecyclerView. + removeImeSurface(); + } else { + mImeSurfaceScheduledForRemoval = true; + mHandler.postDelayed(() -> removeImeSurface(), TIMEOUT_SURFACE_REMOVAL_MILLIS); + } } private void removeImeSurface() { @@ -2350,6 +2360,7 @@ public class InputMethodService extends AbstractInputMethodService { onWindowHidden(); mDecorViewWasVisible = false; } + mLastWasInFullscreenMode = mIsFullscreen; updateFullscreenMode(); } -- cgit v1.2.3