diff options
10 files changed, 187 insertions, 58 deletions
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 0d21673dfc71..5f8b13b5b548 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -611,7 +611,8 @@ public final class InputMethodManager { @Override public void startInputAsyncOnWindowFocusGain(View focusedView, @SoftInputModeFlags int softInputMode, int windowFlags, boolean forceNewFocus) { - final int startInputFlags = getStartInputFlags(focusedView, 0); + int startInputFlags = getStartInputFlags(focusedView, 0); + startInputFlags |= StartInputFlags.WINDOW_GAINED_FOCUS; final ImeFocusController controller = getFocusController(); if (controller == null) { diff --git a/core/java/com/android/internal/inputmethod/InputMethodDebug.java b/core/java/com/android/internal/inputmethod/InputMethodDebug.java index 37f68233db53..3bcba75ec163 100644 --- a/core/java/com/android/internal/inputmethod/InputMethodDebug.java +++ b/core/java/com/android/internal/inputmethod/InputMethodDebug.java @@ -224,6 +224,8 @@ public final class InputMethodDebug { return "HIDE_DOCKED_STACK_ATTACHED"; case SoftInputShowHideReason.HIDE_RECENTS_ANIMATION: return "HIDE_RECENTS_ANIMATION"; + case SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR: + return "HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR"; default: return "Unknown=" + reason; } diff --git a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java index 4b968b45f122..f46626be48a8 100644 --- a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java +++ b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java @@ -47,7 +47,8 @@ import java.lang.annotation.Retention; SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME, SoftInputShowHideReason.HIDE_DOCKED_STACK_ATTACHED, SoftInputShowHideReason.HIDE_RECENTS_ANIMATION, - SoftInputShowHideReason.HIDE_BUBBLES}) + SoftInputShowHideReason.HIDE_BUBBLES, + SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR}) public @interface SoftInputShowHideReason { /** Show soft input by {@link android.view.inputmethod.InputMethodManager#showSoftInput}. */ int SHOW_SOFT_INPUT = 0; @@ -147,4 +148,17 @@ public @interface SoftInputShowHideReason { * switching, or collapsing Bubbles. */ int HIDE_BUBBLES = 19; + + /** + * Hide soft input when focusing the same window (e.g. screen turned-off and turn-on) which no + * valid focused editor. + * + * Note: From Android R, the window focus change callback is processed by InputDispatcher, + * some focus behavior changes (e.g. There are an activity with a dialog window, after + * screen turned-off and turned-on, before Android R the window focus sequence would be + * the activity first and then the dialog focused, however, in R the focus sequence would be + * only the dialog focused as it's the latest window with input focus) makes we need to hide + * soft-input when the same window focused again to align with the same behavior prior to R. + */ + int HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR = 20; } diff --git a/core/java/com/android/internal/inputmethod/StartInputFlags.java b/core/java/com/android/internal/inputmethod/StartInputFlags.java index 5a8d2c227256..ac83987ef12c 100644 --- a/core/java/com/android/internal/inputmethod/StartInputFlags.java +++ b/core/java/com/android/internal/inputmethod/StartInputFlags.java @@ -47,4 +47,10 @@ public @interface StartInputFlags { * documented hence we probably need to revisit this though. */ int INITIAL_CONNECTION = 4; + + /** + * The start input happens when the window gained focus to call + * {@code android.view.inputmethod.InputMethodManager#startInputAsyncOnWindowFocusGain}. + */ + int WINDOW_GAINED_FOCUS = 8; } diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index 696ed2955daa..f13d9b860dce 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -538,7 +538,7 @@ <string name="user_setup_button_setup_now" msgid="1708269547187760639">"지금 설정"</string> <string name="user_setup_button_setup_later" msgid="8712980133555493516">"나중에"</string> <string name="user_add_user_type_title" msgid="551279664052914497">"추가"</string> - <string name="user_new_user_name" msgid="60979820612818840">"새 사용자"</string> + <string name="user_new_user_name" msgid="60979820612818840">"신규 사용자"</string> <string name="user_new_profile_name" msgid="2405500423304678841">"새 프로필"</string> <string name="user_info_settings_title" msgid="6351390762733279907">"사용자 정보"</string> <string name="profile_info_settings_title" msgid="105699672534365099">"프로필 정보"</string> diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt index 102a4842e3c3..a993d00df01e 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt @@ -16,7 +16,6 @@ package com.android.systemui.media -import android.content.Context import android.media.MediaRouter2Manager import android.media.session.MediaController import androidx.annotation.AnyThread @@ -24,20 +23,22 @@ import androidx.annotation.MainThread import androidx.annotation.WorkerThread import com.android.settingslib.media.LocalMediaManager import com.android.settingslib.media.MediaDevice +import com.android.systemui.Dumpable import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main -import com.android.systemui.Dumpable import com.android.systemui.dump.DumpManager import java.io.FileDescriptor import java.io.PrintWriter import java.util.concurrent.Executor import javax.inject.Inject +private const val PLAYBACK_TYPE_UNKNOWN = 0 + /** * Provides information about the route (ie. device) where playback is occurring. */ class MediaDeviceManager @Inject constructor( - private val context: Context, + private val controllerFactory: MediaControllerFactory, private val localMediaManagerFactory: LocalMediaManagerFactory, private val mr2manager: MediaRouter2Manager, @Main private val fgExecutor: Executor, @@ -71,7 +72,7 @@ class MediaDeviceManager @Inject constructor( if (entry == null || entry?.token != data.token) { entry?.stop() val controller = data.token?.let { - MediaController(context, it) + controllerFactory.create(it) } entry = Entry(key, oldKey, controller, localMediaManagerFactory.create(data.packageName)) @@ -122,11 +123,12 @@ class MediaDeviceManager @Inject constructor( val oldKey: String?, val controller: MediaController?, val localMediaManager: LocalMediaManager - ) : LocalMediaManager.DeviceCallback { + ) : LocalMediaManager.DeviceCallback, MediaController.Callback() { val token get() = controller?.sessionToken private var started = false + private var playbackType = PLAYBACK_TYPE_UNKNOWN private var current: MediaDevice? = null set(value) { if (!started || value != field) { @@ -141,6 +143,8 @@ class MediaDeviceManager @Inject constructor( fun start() = bgExecutor.execute { localMediaManager.registerCallback(this) localMediaManager.startScan() + playbackType = controller?.playbackInfo?.playbackType ?: PLAYBACK_TYPE_UNKNOWN + controller?.registerCallback(this) updateCurrent() started = true } @@ -148,22 +152,37 @@ class MediaDeviceManager @Inject constructor( @AnyThread fun stop() = bgExecutor.execute { started = false + controller?.unregisterCallback(this) localMediaManager.stopScan() localMediaManager.unregisterCallback(this) } fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<String>) { - val route = controller?.let { + val routingSession = controller?.let { mr2manager.getRoutingSessionForMediaController(it) } + val selectedRoutes = routingSession?.let { + mr2manager.getSelectedRoutes(it) + } with(pw) { println(" current device is ${current?.name}") val type = controller?.playbackInfo?.playbackType - println(" PlaybackType=$type (1 for local, 2 for remote)") - println(" route=$route") + println(" PlaybackType=$type (1 for local, 2 for remote) cached=$playbackType") + println(" routingSession=$routingSession") + println(" selectedRoutes=$selectedRoutes") } } + @WorkerThread + override fun onAudioInfoChanged(info: MediaController.PlaybackInfo?) { + val newPlaybackType = info?.playbackType ?: PLAYBACK_TYPE_UNKNOWN + if (newPlaybackType == playbackType) { + return + } + playbackType = newPlaybackType + updateCurrent() + } + override fun onDeviceListUpdate(devices: List<MediaDevice>?) = bgExecutor.execute { updateCurrent() } diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java index 89f469a438a9..dd4ea578dafe 100644 --- a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java +++ b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java @@ -228,12 +228,22 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged mHandler.post(() -> { final Point lastSurfacePosition = mImeSourceControl != null ? mImeSourceControl.getSurfacePosition() : null; + final boolean positionChanged = + !activeControl.getSurfacePosition().equals(lastSurfacePosition); + final boolean leashChanged = + !haveSameLeash(mImeSourceControl, activeControl); mImeSourceControl = activeControl; - if (!activeControl.getSurfacePosition().equals(lastSurfacePosition) - && mAnimation != null) { - startAnimation(mImeShowing, true /* forceRestart */); - } else if (!mImeShowing) { - removeImeSurface(); + if (mAnimation != null) { + if (positionChanged) { + startAnimation(mImeShowing, true /* forceRestart */); + } + } else { + if (leashChanged) { + applyVisibilityToLeash(); + } + if (!mImeShowing) { + removeImeSurface(); + } } }); } @@ -241,6 +251,20 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged } } + private void applyVisibilityToLeash() { + SurfaceControl leash = mImeSourceControl.getLeash(); + if (leash != null) { + SurfaceControl.Transaction t = mTransactionPool.acquire(); + if (mImeShowing) { + t.show(leash); + } else { + t.hide(leash); + } + t.apply(); + mTransactionPool.release(t); + } + } + @Override public void showInsets(int types, boolean fromIme) { if ((types & WindowInsets.Type.ime()) == 0) { @@ -492,4 +516,20 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged return IInputMethodManager.Stub.asInterface( ServiceManager.getService(Context.INPUT_METHOD_SERVICE)); } + + private static boolean haveSameLeash(InsetsSourceControl a, InsetsSourceControl b) { + if (a == b) { + return true; + } + if (a == null || b == null) { + return false; + } + if (a.getLeash() == b.getLeash()) { + return true; + } + if (a.getLeash() == null || b.getLeash() == null) { + return false; + } + return a.getLeash().isSameSurface(b.getLeash()); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt index fdb432cc097c..ab3b20898b23 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt @@ -16,13 +16,12 @@ package com.android.systemui.media -import android.app.Notification import android.graphics.drawable.Drawable -import android.media.MediaMetadata import android.media.MediaRouter2Manager import android.media.RoutingSessionInfo +import android.media.session.MediaController +import android.media.session.MediaController.PlaybackInfo import android.media.session.MediaSession -import android.media.session.PlaybackState import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest @@ -55,7 +54,6 @@ private const val KEY = "TEST_KEY" private const val KEY_OLD = "TEST_KEY_OLD" private const val PACKAGE = "PKG" private const val SESSION_KEY = "SESSION_KEY" -private const val SESSION_ARTIST = "SESSION_ARTIST" private const val SESSION_TITLE = "SESSION_TITLE" private const val DEVICE_NAME = "DEVICE_NAME" private const val USER_ID = 0 @@ -68,6 +66,7 @@ private fun <T> eq(value: T): T = Mockito.eq(value) ?: value public class MediaDeviceManagerTest : SysuiTestCase() { private lateinit var manager: MediaDeviceManager + @Mock private lateinit var controllerFactory: MediaControllerFactory @Mock private lateinit var lmmFactory: LocalMediaManagerFactory @Mock private lateinit var lmm: LocalMediaManager @Mock private lateinit var mr2: MediaRouter2Manager @@ -78,10 +77,9 @@ public class MediaDeviceManagerTest : SysuiTestCase() { @Mock private lateinit var device: MediaDevice @Mock private lateinit var icon: Drawable @Mock private lateinit var route: RoutingSessionInfo + @Mock private lateinit var controller: MediaController + @Mock private lateinit var playbackInfo: PlaybackInfo private lateinit var session: MediaSession - private lateinit var metadataBuilder: MediaMetadata.Builder - private lateinit var playbackBuilder: PlaybackState.Builder - private lateinit var notifBuilder: Notification.Builder private lateinit var mediaData: MediaData @JvmField @Rule val mockito = MockitoJUnit.rule() @@ -89,8 +87,8 @@ public class MediaDeviceManagerTest : SysuiTestCase() { fun setUp() { fakeFgExecutor = FakeExecutor(FakeSystemClock()) fakeBgExecutor = FakeExecutor(FakeSystemClock()) - manager = MediaDeviceManager(context, lmmFactory, mr2, fakeFgExecutor, fakeBgExecutor, - dumpster) + manager = MediaDeviceManager(controllerFactory, lmmFactory, mr2, fakeFgExecutor, + fakeBgExecutor, dumpster) manager.addListener(listener) // Configure mocks. @@ -101,28 +99,13 @@ public class MediaDeviceManagerTest : SysuiTestCase() { whenever(mr2.getRoutingSessionForMediaController(any())).thenReturn(route) // Create a media sesssion and notification for testing. - metadataBuilder = MediaMetadata.Builder().apply { - putString(MediaMetadata.METADATA_KEY_ARTIST, SESSION_ARTIST) - putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_TITLE) - } - playbackBuilder = PlaybackState.Builder().apply { - setState(PlaybackState.STATE_PAUSED, 6000L, 1f) - setActions(PlaybackState.ACTION_PLAY) - } - session = MediaSession(context, SESSION_KEY).apply { - setMetadata(metadataBuilder.build()) - setPlaybackState(playbackBuilder.build()) - } - session.setActive(true) - notifBuilder = Notification.Builder(context, "NONE").apply { - setContentTitle(SESSION_TITLE) - setContentText(SESSION_ARTIST) - setSmallIcon(android.R.drawable.ic_media_pause) - setStyle(Notification.MediaStyle().setMediaSession(session.getSessionToken())) - } + session = MediaSession(context, SESSION_KEY) + mediaData = MediaData(USER_ID, true, 0, PACKAGE, null, null, SESSION_TITLE, null, emptyList(), emptyList(), PACKAGE, session.sessionToken, clickIntent = null, device = null, active = true, resumeAction = null) + whenever(controllerFactory.create(session.sessionToken)) + .thenReturn(controller) } @After @@ -336,6 +319,41 @@ public class MediaDeviceManagerTest : SysuiTestCase() { assertThat(data.icon).isNull() } + @Test + fun audioInfoChanged() { + whenever(playbackInfo.getPlaybackType()).thenReturn(PlaybackInfo.PLAYBACK_TYPE_LOCAL) + whenever(controller.getPlaybackInfo()).thenReturn(playbackInfo) + // GIVEN a controller with local playback type + manager.onMediaDataLoaded(KEY, null, mediaData) + fakeBgExecutor.runAllReady() + fakeFgExecutor.runAllReady() + reset(mr2) + // WHEN onAudioInfoChanged fires with remote playback type + whenever(playbackInfo.getPlaybackType()).thenReturn(PlaybackInfo.PLAYBACK_TYPE_REMOTE) + val captor = ArgumentCaptor.forClass(MediaController.Callback::class.java) + verify(controller).registerCallback(captor.capture()) + captor.value.onAudioInfoChanged(playbackInfo) + // THEN the route is checked + verify(mr2).getRoutingSessionForMediaController(eq(controller)) + } + + @Test + fun audioInfoHasntChanged() { + whenever(playbackInfo.getPlaybackType()).thenReturn(PlaybackInfo.PLAYBACK_TYPE_REMOTE) + whenever(controller.getPlaybackInfo()).thenReturn(playbackInfo) + // GIVEN a controller with remote playback type + manager.onMediaDataLoaded(KEY, null, mediaData) + fakeBgExecutor.runAllReady() + fakeFgExecutor.runAllReady() + reset(mr2) + // WHEN onAudioInfoChanged fires with remote playback type + val captor = ArgumentCaptor.forClass(MediaController.Callback::class.java) + verify(controller).registerCallback(captor.capture()) + captor.value.onAudioInfoChanged(playbackInfo) + // THEN the route is not checked + verify(mr2, never()).getRoutingSessionForMediaController(eq(controller)) + } + fun captureCallback(): LocalMediaManager.DeviceCallback { val captor = ArgumentCaptor.forClass(LocalMediaManager.DeviceCallback::class.java) verify(lmm).registerCallback(captor.capture()) diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 7cce78bb661d..bcfbcd124e71 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -3275,6 +3275,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub boolean hideCurrentInputLocked(IBinder windowToken, int flags, ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) { + if (mCurClient == null || mCurClient.curSession == null) { + return false; + } if ((flags&InputMethodManager.HIDE_IMPLICIT_ONLY) != 0 && (mShowExplicitlyRequested || mShowForced)) { if (DEBUG) Slog.v(TAG, "Not hiding: explicit show not cancelled by non-explicit hide"); @@ -3459,7 +3462,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // pre-rendering not supported on low-ram devices. cs.shouldPreRenderIme = DebugFlags.FLAG_PRE_RENDER_IME_VIEWS.value() && !mIsLowRam; - if (mCurFocusedWindow == windowToken) { + final boolean sameWindowFocused = mCurFocusedWindow == windowToken; + final boolean isTextEditor = (startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0; + final boolean startInputByWinGainedFocus = + (startInputFlags & StartInputFlags.WINDOW_GAINED_FOCUS) != 0; + + if (sameWindowFocused && isTextEditor) { if (DEBUG) { Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client + " attribute=" + attribute + ", token = " + windowToken @@ -3474,6 +3482,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub InputBindResult.ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY, null, null, null, -1, null); } + mCurFocusedWindow = windowToken; mCurFocusedWindowSoftInputMode = softInputMode; mCurFocusedWindowClient = cs; @@ -3491,7 +3500,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub == LayoutParams.SOFT_INPUT_ADJUST_RESIZE || mRes.getConfiguration().isLayoutSizeAtLeast( Configuration.SCREENLAYOUT_SIZE_LARGE); - final boolean isTextEditor = (startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0; // We want to start input before showing the IME, but after closing // it. We want to do this after closing it to help the IME disappear @@ -3502,7 +3510,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub InputBindResult res = null; switch (softInputMode & LayoutParams.SOFT_INPUT_MASK_STATE) { case LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED: - if (!isTextEditor || !doAutoShow) { + if (!sameWindowFocused && (!isTextEditor || !doAutoShow)) { if (LayoutParams.mayUseInputMethod(windowFlags)) { // There is no focus view, and this window will // be behind any soft input window, so hide the @@ -3551,9 +3559,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } break; case LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN: - if (DEBUG) Slog.v(TAG, "Window asks to hide input"); - hideCurrentInputLocked(mCurFocusedWindow, 0, null, - SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE); + if (!sameWindowFocused) { + if (DEBUG) Slog.v(TAG, "Window asks to hide input"); + hideCurrentInputLocked(mCurFocusedWindow, 0, null, + SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE); + } break; case LayoutParams.SOFT_INPUT_STATE_VISIBLE: if ((softInputMode & LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) { @@ -3578,13 +3588,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (DEBUG) Slog.v(TAG, "Window asks to always show input"); if (InputMethodUtils.isSoftInputModeStateVisibleAllowed( unverifiedTargetSdkVersion, startInputFlags)) { - if (attribute != null) { - res = startInputUncheckedLocked(cs, inputContext, missingMethods, - attribute, startInputFlags, startInputReason); - didStart = true; + if (!sameWindowFocused) { + if (attribute != null) { + res = startInputUncheckedLocked(cs, inputContext, missingMethods, + attribute, startInputFlags, startInputReason); + didStart = true; + } + showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null, + SoftInputShowHideReason.SHOW_STATE_ALWAYS_VISIBLE); } - showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null, - SoftInputShowHideReason.SHOW_STATE_ALWAYS_VISIBLE); } else { Slog.e(TAG, "SOFT_INPUT_STATE_ALWAYS_VISIBLE is ignored because" + " there is no focused view that also returns true from" @@ -3595,7 +3607,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (!didStart) { if (attribute != null) { - if (!DebugFlags.FLAG_OPTIMIZE_START_INPUT.value() + if (sameWindowFocused) { + // On previous platforms, when Dialogs re-gained focus, the Activity behind + // would briefly gain focus first, and dismiss the IME. + // On R that behavior has been fixed, but unfortunately apps have come + // to rely on this behavior to hide the IME when the editor no longer has focus + // To maintain compatibility, we are now hiding the IME when we don't have + // an editor upon refocusing a window. + if (startInputByWinGainedFocus) { + hideCurrentInputLocked(mCurFocusedWindow, 0, null, + SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR); + } + res = startInputUncheckedLocked(cs, inputContext, missingMethods, attribute, + startInputFlags, startInputReason); + } else if (!DebugFlags.FLAG_OPTIMIZE_START_INPUT.value() || (startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0) { res = startInputUncheckedLocked(cs, inputContext, missingMethods, attribute, startInputFlags, startInputReason); @@ -3609,6 +3634,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return res; } + private boolean isImeVisible() { + return (mImeWindowVis & InputMethodService.IME_VISIBLE) != 0; + } + private boolean canShowInputMethodPickerLocked(IInputMethodClient client) { // TODO(yukawa): multi-display support. final int uid = Binder.getCallingUid(); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 03834c348d4b..b7a2eb3c705d 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -6187,7 +6187,7 @@ public class WindowManagerService extends IWindowManager.Stub } if (inputMethodControlTarget != null) { pw.print(" inputMethodControlTarget in display# "); pw.print(displayId); - pw.print(' '); pw.println(inputMethodControlTarget.getWindow()); + pw.print(' '); pw.println(inputMethodControlTarget); } }); pw.print(" mInTouchMode="); pw.println(mInTouchMode); |