Loading services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java +44 −46 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import static android.view.WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVI import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED; import static android.view.WindowManager.LayoutParams.SoftInputModeFlags; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static com.android.internal.inputmethod.InputMethodDebug.softInputModeToString; import static com.android.internal.inputmethod.SoftInputShowHideReason.REMOVE_IME_SCREENSHOT_FROM_IMMS; Loading Loading @@ -59,7 +58,6 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.inputmethod.SoftInputShowHideReason; import com.android.server.LocalServices; import com.android.server.wm.ImeTargetChangeListener; import com.android.server.wm.WindowManagerInternal; import java.io.PrintWriter; Loading @@ -76,6 +74,9 @@ public final class ImeVisibilityStateComputer { private static final boolean DEBUG = InputMethodManagerService.DEBUG; @UserIdInt private final int mUserId; private final InputMethodManagerService mService; private final WindowManagerInternal mWindowManagerInternal; Loading Loading @@ -184,57 +185,51 @@ public final class ImeVisibilityStateComputer { */ private final ImeVisibilityPolicy mPolicy; public ImeVisibilityStateComputer(@NonNull InputMethodManagerService service) { public ImeVisibilityStateComputer(@NonNull InputMethodManagerService service, @UserIdInt int userId) { this(service, LocalServices.getService(WindowManagerInternal.class), LocalServices.getService(WindowManagerInternal.class)::getDisplayImePolicy, new ImeVisibilityPolicy()); new ImeVisibilityPolicy(), userId); } @VisibleForTesting public ImeVisibilityStateComputer(@NonNull InputMethodManagerService service, @NonNull Injector injector) { this(service, injector.getWmService(), injector.getImeValidator(), new ImeVisibilityPolicy()); new ImeVisibilityPolicy(), injector.getUserId()); } interface Injector { default WindowManagerInternal getWmService() { return null; } @NonNull WindowManagerInternal getWmService(); default InputMethodManagerService.ImeDisplayValidator getImeValidator() { return null; } @NonNull InputMethodManagerService.ImeDisplayValidator getImeValidator(); @UserIdInt int getUserId(); } private ImeVisibilityStateComputer(InputMethodManagerService service, WindowManagerInternal wmService, InputMethodManagerService.ImeDisplayValidator imeDisplayValidator, ImeVisibilityPolicy imePolicy) { ImeVisibilityPolicy imePolicy, @UserIdInt int userId) { mUserId = userId; mService = service; mWindowManagerInternal = wmService; mImeDisplayValidator = imeDisplayValidator; mPolicy = imePolicy; mWindowManagerInternal.setInputMethodTargetChangeListener(new ImeTargetChangeListener() { @Override public void onImeTargetOverlayVisibilityChanged(@NonNull IBinder overlayWindowToken, @WindowManager.LayoutParams.WindowType int windowType, boolean visible, boolean removed, int displayId) { // Ignoring the starting window since it's ok to cover the IME target // window in temporary without affecting the IME visibility. final boolean hasOverlay = visible && !removed && windowType != TYPE_APPLICATION_STARTING; synchronized (ImfLock.class) { mHasVisibleImeLayeringOverlay = hasOverlay; } @GuardedBy("ImfLock.class") void setHasVisibleImeLayeringOverlay(boolean hasVisibleOverlay) { mHasVisibleImeLayeringOverlay = hasVisibleOverlay; } @Override public void onImeInputTargetVisibilityChanged(IBinder imeInputTarget, boolean visibleRequested, boolean removed, int displayId) { final boolean visibleAndNotRemoved = visibleRequested && !removed; synchronized (ImfLock.class) { @GuardedBy("ImfLock.class") void onImeInputTargetVisibilityChanged(@NonNull IBinder imeInputTarget, boolean visibleAndNotRemoved) { if (visibleAndNotRemoved) { mCurVisibleImeInputTarget = imeInputTarget; return; Loading @@ -245,13 +240,10 @@ public final class ImeVisibilityStateComputer { final var statsToken = ImeTracker.forLogging().onStart(ImeTracker.TYPE_HIDE, ImeTracker.ORIGIN_SERVER, reason, false /* fromUser */); mService.onApplyImeVisibilityFromComputerLocked(imeInputTarget, statsToken, new ImeVisibilityResult(STATE_HIDE_IME_EXPLICIT, reason)); new ImeVisibilityResult(STATE_HIDE_IME_EXPLICIT, reason), mUserId); } mCurVisibleImeInputTarget = null; } } }); } /** * Called when {@link InputMethodManagerService} is processing the show IME request. Loading Loading @@ -631,6 +623,12 @@ public final class ImeVisibilityStateComputer { return mWindowManagerInternal.shouldRestoreImeVisibility(getWindowTokenFrom(state)); } @UserIdInt @VisibleForTesting int getUserId() { return mUserId; } @GuardedBy("ImfLock.class") boolean isInputShown() { return mInputShown; Loading services/core/java/com/android/server/inputmethod/InputMethodBindingController.java +2 −1 Original line number Diff line number Diff line Loading @@ -463,7 +463,8 @@ final class InputMethodBindingController { // should now try to restart the service for us. mLastBindTime = SystemClock.uptimeMillis(); clearCurMethodAndSessions(); mService.mVisibilityStateComputer.setInputShown(false); final var userData = mService.getUserData(mUserId); userData.mVisibilityStateComputer.setInputShown(false); mService.unbindCurrentClientLocked(UnbindReason.DISCONNECT_IME, mUserId); } } Loading services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +122 −66 File changed.Preview size limit exceeded, changes collapsed. Show changes services/core/java/com/android/server/inputmethod/UserData.java +6 −1 Original line number Diff line number Diff line Loading @@ -66,6 +66,9 @@ final class UserData { final HardwareKeyboardShortcutController mHardwareKeyboardShortcutController = new HardwareKeyboardShortcutController(); @NonNull final ImeVisibilityStateComputer mVisibilityStateComputer; /** * Have we called mCurMethod.bindInput()? */ Loading Loading @@ -155,9 +158,11 @@ final class UserData { * Intended to be instantiated only from this file. */ UserData(@UserIdInt int userId, @NonNull InputMethodBindingController bindingController) { @NonNull InputMethodBindingController bindingController, @NonNull ImeVisibilityStateComputer stateComputer) { mUserId = userId; mBindingController = bindingController; mVisibilityStateComputer = stateComputer; } @Override Loading services/core/java/com/android/server/inputmethod/UserDataRepository.java +8 −3 Original line number Diff line number Diff line Loading @@ -30,7 +30,10 @@ final class UserDataRepository { @NonNull private volatile ImmutableSparseArray<UserData> mUserData = ImmutableSparseArray.empty(); @NonNull private final IntFunction<InputMethodBindingController> mBindingControllerFactory; @NonNull private final IntFunction<ImeVisibilityStateComputer> mVisibilityStateComputerFactory; @AnyThread @NonNull Loading @@ -42,7 +45,8 @@ final class UserDataRepository { } // Note that the below line can be called concurrently. Here we assume that // instantiating UserData for the same user multiple times would have no side effect. final var newUserData = new UserData(userId, mBindingControllerFactory.apply(userId)); final var newUserData = new UserData(userId, mBindingControllerFactory.apply(userId), mVisibilityStateComputerFactory.apply(userId)); synchronized (mMutationLock) { mUserData = mUserData.cloneWithPutOrSelf(userId, newUserData); return newUserData; Loading @@ -54,9 +58,10 @@ final class UserDataRepository { mUserData.forEach(consumer); } UserDataRepository( @NonNull IntFunction<InputMethodBindingController> bindingControllerFactory) { UserDataRepository(@NonNull IntFunction<InputMethodBindingController> bindingControllerFactory, @NonNull IntFunction<ImeVisibilityStateComputer> visibilityStateComputerFactory) { mBindingControllerFactory = bindingControllerFactory; mVisibilityStateComputerFactory = visibilityStateComputerFactory; } @AnyThread Loading Loading
services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java +44 −46 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import static android.view.WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVI import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED; import static android.view.WindowManager.LayoutParams.SoftInputModeFlags; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static com.android.internal.inputmethod.InputMethodDebug.softInputModeToString; import static com.android.internal.inputmethod.SoftInputShowHideReason.REMOVE_IME_SCREENSHOT_FROM_IMMS; Loading Loading @@ -59,7 +58,6 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.inputmethod.SoftInputShowHideReason; import com.android.server.LocalServices; import com.android.server.wm.ImeTargetChangeListener; import com.android.server.wm.WindowManagerInternal; import java.io.PrintWriter; Loading @@ -76,6 +74,9 @@ public final class ImeVisibilityStateComputer { private static final boolean DEBUG = InputMethodManagerService.DEBUG; @UserIdInt private final int mUserId; private final InputMethodManagerService mService; private final WindowManagerInternal mWindowManagerInternal; Loading Loading @@ -184,57 +185,51 @@ public final class ImeVisibilityStateComputer { */ private final ImeVisibilityPolicy mPolicy; public ImeVisibilityStateComputer(@NonNull InputMethodManagerService service) { public ImeVisibilityStateComputer(@NonNull InputMethodManagerService service, @UserIdInt int userId) { this(service, LocalServices.getService(WindowManagerInternal.class), LocalServices.getService(WindowManagerInternal.class)::getDisplayImePolicy, new ImeVisibilityPolicy()); new ImeVisibilityPolicy(), userId); } @VisibleForTesting public ImeVisibilityStateComputer(@NonNull InputMethodManagerService service, @NonNull Injector injector) { this(service, injector.getWmService(), injector.getImeValidator(), new ImeVisibilityPolicy()); new ImeVisibilityPolicy(), injector.getUserId()); } interface Injector { default WindowManagerInternal getWmService() { return null; } @NonNull WindowManagerInternal getWmService(); default InputMethodManagerService.ImeDisplayValidator getImeValidator() { return null; } @NonNull InputMethodManagerService.ImeDisplayValidator getImeValidator(); @UserIdInt int getUserId(); } private ImeVisibilityStateComputer(InputMethodManagerService service, WindowManagerInternal wmService, InputMethodManagerService.ImeDisplayValidator imeDisplayValidator, ImeVisibilityPolicy imePolicy) { ImeVisibilityPolicy imePolicy, @UserIdInt int userId) { mUserId = userId; mService = service; mWindowManagerInternal = wmService; mImeDisplayValidator = imeDisplayValidator; mPolicy = imePolicy; mWindowManagerInternal.setInputMethodTargetChangeListener(new ImeTargetChangeListener() { @Override public void onImeTargetOverlayVisibilityChanged(@NonNull IBinder overlayWindowToken, @WindowManager.LayoutParams.WindowType int windowType, boolean visible, boolean removed, int displayId) { // Ignoring the starting window since it's ok to cover the IME target // window in temporary without affecting the IME visibility. final boolean hasOverlay = visible && !removed && windowType != TYPE_APPLICATION_STARTING; synchronized (ImfLock.class) { mHasVisibleImeLayeringOverlay = hasOverlay; } @GuardedBy("ImfLock.class") void setHasVisibleImeLayeringOverlay(boolean hasVisibleOverlay) { mHasVisibleImeLayeringOverlay = hasVisibleOverlay; } @Override public void onImeInputTargetVisibilityChanged(IBinder imeInputTarget, boolean visibleRequested, boolean removed, int displayId) { final boolean visibleAndNotRemoved = visibleRequested && !removed; synchronized (ImfLock.class) { @GuardedBy("ImfLock.class") void onImeInputTargetVisibilityChanged(@NonNull IBinder imeInputTarget, boolean visibleAndNotRemoved) { if (visibleAndNotRemoved) { mCurVisibleImeInputTarget = imeInputTarget; return; Loading @@ -245,13 +240,10 @@ public final class ImeVisibilityStateComputer { final var statsToken = ImeTracker.forLogging().onStart(ImeTracker.TYPE_HIDE, ImeTracker.ORIGIN_SERVER, reason, false /* fromUser */); mService.onApplyImeVisibilityFromComputerLocked(imeInputTarget, statsToken, new ImeVisibilityResult(STATE_HIDE_IME_EXPLICIT, reason)); new ImeVisibilityResult(STATE_HIDE_IME_EXPLICIT, reason), mUserId); } mCurVisibleImeInputTarget = null; } } }); } /** * Called when {@link InputMethodManagerService} is processing the show IME request. Loading Loading @@ -631,6 +623,12 @@ public final class ImeVisibilityStateComputer { return mWindowManagerInternal.shouldRestoreImeVisibility(getWindowTokenFrom(state)); } @UserIdInt @VisibleForTesting int getUserId() { return mUserId; } @GuardedBy("ImfLock.class") boolean isInputShown() { return mInputShown; Loading
services/core/java/com/android/server/inputmethod/InputMethodBindingController.java +2 −1 Original line number Diff line number Diff line Loading @@ -463,7 +463,8 @@ final class InputMethodBindingController { // should now try to restart the service for us. mLastBindTime = SystemClock.uptimeMillis(); clearCurMethodAndSessions(); mService.mVisibilityStateComputer.setInputShown(false); final var userData = mService.getUserData(mUserId); userData.mVisibilityStateComputer.setInputShown(false); mService.unbindCurrentClientLocked(UnbindReason.DISCONNECT_IME, mUserId); } } Loading
services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +122 −66 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/core/java/com/android/server/inputmethod/UserData.java +6 −1 Original line number Diff line number Diff line Loading @@ -66,6 +66,9 @@ final class UserData { final HardwareKeyboardShortcutController mHardwareKeyboardShortcutController = new HardwareKeyboardShortcutController(); @NonNull final ImeVisibilityStateComputer mVisibilityStateComputer; /** * Have we called mCurMethod.bindInput()? */ Loading Loading @@ -155,9 +158,11 @@ final class UserData { * Intended to be instantiated only from this file. */ UserData(@UserIdInt int userId, @NonNull InputMethodBindingController bindingController) { @NonNull InputMethodBindingController bindingController, @NonNull ImeVisibilityStateComputer stateComputer) { mUserId = userId; mBindingController = bindingController; mVisibilityStateComputer = stateComputer; } @Override Loading
services/core/java/com/android/server/inputmethod/UserDataRepository.java +8 −3 Original line number Diff line number Diff line Loading @@ -30,7 +30,10 @@ final class UserDataRepository { @NonNull private volatile ImmutableSparseArray<UserData> mUserData = ImmutableSparseArray.empty(); @NonNull private final IntFunction<InputMethodBindingController> mBindingControllerFactory; @NonNull private final IntFunction<ImeVisibilityStateComputer> mVisibilityStateComputerFactory; @AnyThread @NonNull Loading @@ -42,7 +45,8 @@ final class UserDataRepository { } // Note that the below line can be called concurrently. Here we assume that // instantiating UserData for the same user multiple times would have no side effect. final var newUserData = new UserData(userId, mBindingControllerFactory.apply(userId)); final var newUserData = new UserData(userId, mBindingControllerFactory.apply(userId), mVisibilityStateComputerFactory.apply(userId)); synchronized (mMutationLock) { mUserData = mUserData.cloneWithPutOrSelf(userId, newUserData); return newUserData; Loading @@ -54,9 +58,10 @@ final class UserDataRepository { mUserData.forEach(consumer); } UserDataRepository( @NonNull IntFunction<InputMethodBindingController> bindingControllerFactory) { UserDataRepository(@NonNull IntFunction<InputMethodBindingController> bindingControllerFactory, @NonNull IntFunction<ImeVisibilityStateComputer> visibilityStateComputerFactory) { mBindingControllerFactory = bindingControllerFactory; mVisibilityStateComputerFactory = visibilityStateComputerFactory; } @AnyThread Loading