diff options
6 files changed, 76 insertions, 4 deletions
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java index 6dbc09ceef97..bf0e10f993ad 100644 --- a/core/java/android/view/WindowManagerInternal.java +++ b/core/java/android/view/WindowManagerInternal.java @@ -303,13 +303,16 @@ public abstract class WindowManagerInternal { * hidden, no matter how WindowManagerService will react / has reacted * to corresponding API calls. Note that this state is not guaranteed * to be synchronized with state in WindowManagerService. + * @param dismissImeOnBackKeyPressed {@code true} if the software keyboard is shown and the back + * key is expected to dismiss the software keyboard. * @param targetWindowToken token to identify the target window that the IME is associated with. * {@code null} when application, system, or the IME itself decided to * change its window visibility before being associated with any target * window. */ public abstract void updateInputMethodWindowStatus(@NonNull IBinder imeToken, - boolean imeWindowVisible, @Nullable IBinder targetWindowToken); + boolean imeWindowVisible, boolean dismissImeOnBackKeyPressed, + @Nullable IBinder targetWindowToken); /** * Returns true when the hardware keyboard is available. diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index bb6e0eed57cc..030c78b7f4b6 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -1537,6 +1537,18 @@ public interface WindowManagerPolicy { public void setLastInputMethodWindowLw(WindowState ime, WindowState target); /** + * An internal callback (from InputMethodManagerService) to notify a state change regarding + * whether the back key should dismiss the software keyboard (IME) or not. + * + * @param newValue {@code true} if the software keyboard is shown and the back key is expected + * to dismiss the software keyboard. + * @hide + */ + default void setDismissImeOnBackKeyPressed(boolean newValue) { + // Default implementation does nothing. + } + + /** * Show the recents task list app. * @hide */ diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 45dccb6bfe33..6a31e161842b 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -852,6 +852,8 @@ 1 - Go to sleep (doze) 2 - Really go to sleep (don't doze) 3 - Really go to sleep and go home (don't doze) + 4 - Go to home + 5 - Dismiss IME if shown. Otherwise go to home --> <integer name="config_shortPressOnPowerBehavior">1</integer> diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index 39bfedae69d8..8ad3d23648bf 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -49,6 +49,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; +import android.annotation.BinderThread; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -2146,6 +2147,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return mKeyguardManager != null && mKeyguardManager.isKeyguardLocked(); } + @BinderThread @SuppressWarnings("deprecation") @Override public void setImeWindowStatus(IBinder token, IBinder startInputToken, int vis, @@ -2161,9 +2163,23 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mBackDisposition = backDisposition; updateSystemUiLocked(token, vis, backDisposition); } + + final boolean dismissImeOnBackKeyPressed; + switch (backDisposition) { + case InputMethodService.BACK_DISPOSITION_WILL_DISMISS: + dismissImeOnBackKeyPressed = true; + break; + case InputMethodService.BACK_DISPOSITION_WILL_NOT_DISMISS: + dismissImeOnBackKeyPressed = false; + break; + default: + case InputMethodService.BACK_DISPOSITION_DEFAULT: + dismissImeOnBackKeyPressed = ((vis & InputMethodService.IME_VISIBLE) != 0); + break; + } mWindowManagerInternal.updateInputMethodWindowStatus(token, (vis & InputMethodService.IME_VISIBLE) != 0, - info != null ? info.mTargetWindow : null); + dismissImeOnBackKeyPressed, info != null ? info.mTargetWindow : null); } private void updateSystemUi(IBinder token, int vis, int backDisposition) { diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 4f29bfa2829e..bcb4121a6d2f 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -222,9 +222,10 @@ import android.view.accessibility.AccessibilityManager; import android.view.animation.Animation; import android.view.animation.AnimationSet; import android.view.animation.AnimationUtils; +import android.view.inputmethod.InputMethodManagerInternal; import android.widget.ImageView; - import com.android.internal.R; +import com.android.internal.annotations.GuardedBy; import com.android.internal.logging.MetricsLogger; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.policy.IShortcutService; @@ -279,6 +280,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP = 2; static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME = 3; static final int SHORT_PRESS_POWER_GO_HOME = 4; + static final int SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME = 5; static final int LONG_PRESS_POWER_NOTHING = 0; static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1; @@ -407,6 +409,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { PowerManager mPowerManager; ActivityManagerInternal mActivityManagerInternal; InputManagerInternal mInputManagerInternal; + InputMethodManagerInternal mInputMethodManagerInternal; DreamManagerInternal mDreamManagerInternal; PowerManagerInternal mPowerManagerInternal; IStatusBarService mStatusBarService; @@ -494,6 +497,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { WindowState mLastInputMethodWindow = null; WindowState mLastInputMethodTargetWindow = null; + @GuardedBy("mLock") + private boolean mDismissImeOnBackKeyPressed; + // FIXME This state is shared between the input reader and handler thread. // Technically it's broken and buggy but it has been like this for many years // and we have not yet seen any problems. Someday we'll rewrite this logic @@ -1396,6 +1402,27 @@ public class PhoneWindowManager implements WindowManagerPolicy { case SHORT_PRESS_POWER_GO_HOME: launchHomeFromHotKey(true /* awakenFromDreams */, false /*respectKeyguard*/); break; + case SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME: { + final boolean dismissImeOnBackKeyPressed; + // We can be here on both the main thread (via mHandler) and native callback + // thread (from interceptPowerKeyUp via WindowManagerCallbacks). + synchronized (mLock) { + dismissImeOnBackKeyPressed = mDismissImeOnBackKeyPressed; + } + if (dismissImeOnBackKeyPressed) { + if (mInputMethodManagerInternal == null) { + mInputMethodManagerInternal = + LocalServices.getService(InputMethodManagerInternal.class); + } + if (mInputMethodManagerInternal != null) { + mInputMethodManagerInternal.hideCurrentInputMethod(); + } + } else { + launchHomeFromHotKey(true /* awakenFromDreams */, + false /*respectKeyguard*/); + } + break; + } } } } @@ -7955,6 +7982,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override + public void setDismissImeOnBackKeyPressed(boolean newValue) { + synchronized (mLock) { + mDismissImeOnBackKeyPressed = newValue; + } + } + + @Override public int getInputMethodWindowVisibleHeightLw() { return mDockBottom - mCurBottom; } @@ -8170,6 +8204,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { pw.print(prefix); pw.print("mLastInputMethodTargetWindow="); pw.println(mLastInputMethodTargetWindow); } + pw.print(prefix); pw.print("mDismissImeOnBackKeyPressed="); + pw.println(mDismissImeOnBackKeyPressed); if (mStatusBar != null) { pw.print(prefix); pw.print("mStatusBar="); pw.print(mStatusBar); pw.print(" isStatusBarKeyguard="); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 0049585f5c52..252b4d4e0473 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -7267,13 +7267,16 @@ public class WindowManagerService extends IWindowManager.Stub @Override public void updateInputMethodWindowStatus(@NonNull IBinder imeToken, - boolean imeWindowVisible, @Nullable IBinder targetWindowToken) { + boolean imeWindowVisible, boolean dismissImeOnBackKeyPressed, + @Nullable IBinder targetWindowToken) { // TODO (b/34628091): Use this method to address the window animation issue. if (DEBUG_INPUT_METHOD) { Slog.w(TAG_WM, "updateInputMethodWindowStatus: imeToken=" + imeToken + + " dismissImeOnBackKeyPressed=" + dismissImeOnBackKeyPressed + " imeWindowVisible=" + imeWindowVisible + " targetWindowToken=" + targetWindowToken); } + mPolicy.setDismissImeOnBackKeyPressed(dismissImeOnBackKeyPressed); } @Override |