Merge "Hide soft-keyboard when no editor is focused"

This commit is contained in:
TreeHugger Robot
2022-09-13 10:38:39 +00:00
committed by Android (Google) Code Review
7 changed files with 126 additions and 1 deletions

View File

@@ -2160,10 +2160,15 @@ package android.provider {
field public static final String NAMESPACE_APP_COMPAT_OVERRIDES = "app_compat_overrides";
field public static final String NAMESPACE_CONSTRAIN_DISPLAY_APIS = "constrain_display_apis";
field public static final String NAMESPACE_DEVICE_IDLE = "device_idle";
field public static final String NAMESPACE_INPUT_METHOD_MANAGER = "input_method_manager";
field public static final String NAMESPACE_JOB_SCHEDULER = "jobscheduler";
field public static final String NAMESPACE_SELECTION_TOOLBAR = "selection_toolbar";
}
public interface InputMethodManagerDeviceConfig {
field public static final String KEY_HIDE_IME_WHEN_NO_EDITOR_FOCUS = "hide_ime_when_no_editor_focus";
}
public final class Settings {
field public static final int RESET_MODE_PACKAGE_DEFAULTS = 1; // 0x1
}

View File

@@ -775,6 +775,14 @@ public final class DeviceConfig {
*/
public static final String NAMESPACE_WEAR = "wear";
/**
* Namespace for the input method manager platform features.
*
* @hide
*/
@TestApi
public static final String NAMESPACE_INPUT_METHOD_MANAGER = "input_method_manager";
private static final Object sLock = new Object();
@GuardedBy("sLock")
private static ArrayMap<OnPropertiesChangedListener, Pair<String, Executor>> sListeners =

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.provider;
import android.annotation.TestApi;
/**
* Interface for accessing keys belonging to {@link DeviceConfig#NAMESPACE_INPUT_METHOD_MANAGER}.
* @hide
*/
@TestApi
public interface InputMethodManagerDeviceConfig {
/**
* Whether the IME should be hidden when the window gained focus without an editor focused.
*/
String KEY_HIDE_IME_WHEN_NO_EDITOR_FOCUS = "hide_ime_when_no_editor_focus";
}

View File

@@ -254,6 +254,8 @@ public final class InputMethodDebug {
return "HIDE_SOFT_INPUT_EXTRACT_INPUT_CHANGED";
case SoftInputShowHideReason.HIDE_SOFT_INPUT_IMM_DEPRECATION:
return "HIDE_SOFT_INPUT_IMM_DEPRECATION";
case SoftInputShowHideReason.HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR:
return "HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR";
default:
return "Unknown=" + reason;
}

View File

@@ -63,7 +63,8 @@ import java.lang.annotation.Retention;
SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_BACK_KEY,
SoftInputShowHideReason.HIDE_SOFT_INPUT_IME_TOGGLE_SOFT_INPUT,
SoftInputShowHideReason.HIDE_SOFT_INPUT_EXTRACT_INPUT_CHANGED,
SoftInputShowHideReason.HIDE_SOFT_INPUT_IMM_DEPRECATION})
SoftInputShowHideReason.HIDE_SOFT_INPUT_IMM_DEPRECATION,
SoftInputShowHideReason.HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR})
public @interface SoftInputShowHideReason {
/** Show soft input by {@link android.view.inputmethod.InputMethodManager#showSoftInput}. */
int SHOW_SOFT_INPUT = 0;
@@ -247,4 +248,9 @@ public @interface SoftInputShowHideReason {
* {@link InputMethodManager#hideSoftInputFromInputMethod(IBinder, int)}.
*/
int HIDE_SOFT_INPUT_IMM_DEPRECATION = 31;
/**
* Hide soft input when the window gained focus without an editor from the IME shown window.
*/
int HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR = 32;
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.inputmethod;
import static android.provider.InputMethodManagerDeviceConfig.KEY_HIDE_IME_WHEN_NO_EDITOR_FOCUS;
import android.app.ActivityThread;
import android.provider.DeviceConfig;
/**
* Class for the device-level configuration related to the input method manager
* platform features in {@link DeviceConfig}.
*/
public final class InputMethodDeviceConfigs {
private boolean mHideImeWhenNoEditorFocus;
private final DeviceConfig.OnPropertiesChangedListener mDeviceConfigChangedListener;
public InputMethodDeviceConfigs() {
mDeviceConfigChangedListener = properties -> {
if (!DeviceConfig.NAMESPACE_INPUT_METHOD_MANAGER.equals(properties.getNamespace())) {
return;
}
for (String name : properties.getKeyset()) {
if (KEY_HIDE_IME_WHEN_NO_EDITOR_FOCUS.equals(name)) {
mHideImeWhenNoEditorFocus = properties.getBoolean(name,
true /* defaultValue */);
}
}
};
mHideImeWhenNoEditorFocus = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_INPUT_METHOD_MANAGER,
KEY_HIDE_IME_WHEN_NO_EDITOR_FOCUS, true);
DeviceConfig.addOnPropertiesChangedListener(
DeviceConfig.NAMESPACE_INPUT_METHOD_MANAGER,
ActivityThread.currentApplication().getMainExecutor(),
mDeviceConfigChangedListener);
}
/**
* Whether the IME should be hidden when the window gained focus without an editor focused.
*/
public boolean shouldHideImeWhenNoEditorFocus() {
return mHideImeWhenNoEditorFocus;
}
}

View File

@@ -303,6 +303,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
final PackageManagerInternal mPackageManagerInternal;
final InputManagerInternal mInputManagerInternal;
final ImePlatformCompatUtils mImePlatformCompatUtils;
final InputMethodDeviceConfigs mInputMethodDeviceConfigs;
private final DisplayManagerInternal mDisplayManagerInternal;
final boolean mHasFeature;
private final ArrayMap<String, List<InputMethodSubtype>> mAdditionalSubtypeMap =
@@ -1732,6 +1733,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
mImePlatformCompatUtils = new ImePlatformCompatUtils();
mInputMethodDeviceConfigs = new InputMethodDeviceConfigs();
mImeDisplayValidator = mWindowManagerInternal::getDisplayImePolicy;
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
@@ -3889,6 +3891,18 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR);
}
}
if (!isTextEditor && mInputShown && startInputByWinGainedFocus
&& mInputMethodDeviceConfigs.shouldHideImeWhenNoEditorFocus()) {
// Hide the soft-keyboard when the system do nothing for softInputModeState
// of the window being gained focus without an editor. This behavior benefits
// to resolve some unexpected IME visible cases while that window with following
// configurations being switched from an IME shown window:
// 1) SOFT_INPUT_STATE_UNCHANGED state without an editor
// 2) SOFT_INPUT_STATE_VISIBLE state without an editor
// 3) SOFT_INPUT_STATE_ALWAYS_VISIBLE state without an editor
hideCurrentInputLocked(mCurFocusedWindow, 0, null,
SoftInputShowHideReason.HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR);
}
res = startInputUncheckedLocked(cs, inputContext,
remoteAccessibilityInputConnection, editorInfo, startInputFlags,
startInputReason, unverifiedTargetSdkVersion,