Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1166)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/omnibox/KeyboardHideHelper.java

Issue 2821793002: Defocus omnibox on back if keyboard hides. (Closed)
Patch Set: Add comments Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/android/java/src/org/chromium/chrome/browser/omnibox/KeyboardHideHelper.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/KeyboardHideHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/KeyboardHideHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..673472c6f9ebfcc9646a0ac5cfa3123b41bd0954
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/KeyboardHideHelper.java
@@ -0,0 +1,119 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.omnibox;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.WindowManager;
+
+import org.chromium.base.VisibleForTesting;
+import org.chromium.chrome.browser.WindowDelegate;
+
+/**
+ * Helps to detect whether the virtual keyboard was hidden to allow unfocusing of the omnibox.
+ * <p>
+ * There are no Android APIs to determine the visibility of a soft keyboard, so this class
+ * aggressively detects signals that might indicate the keyboard has been hidden.
+ */
+class KeyboardHideHelper implements ViewTreeObserver.OnGlobalLayoutListener {
+ private static final long SOFT_KEYBOARD_HIDDEN_TIMEOUT_MS = 1000;
+
+ private final View mView;
+ private final Runnable mOnHideCallback;
+ private final Runnable mClearListenerDelayedTask;
+ private final Rect mTempRect;
+
+ private WindowDelegate mWindowDelegate;
+ private boolean mIsLayoutListenerAttached;
+ private int mInitialViewportHeight;
+
+ /**
+ * Constructs the helper for hiding the keyboard.
+ *
+ * @param view The view the keyboard is shown for.
+ * @param onHideCallback The callback to be triggered when the keyboard is detected as hidden.
+ */
+ public KeyboardHideHelper(View view, Runnable onHideCallback) {
+ mView = view;
+ mOnHideCallback = onHideCallback;
+ mClearListenerDelayedTask = new Runnable() {
+ @Override
+ public void run() {
+ cleanUp();
+ }
+ };
+ mTempRect = new Rect();
+ }
+
+ /**
+ * Initialize the delegate that allows interaction with the Window.
+ */
+ public void setWindowDelegate(WindowDelegate windowDelegate) {
+ mWindowDelegate = windowDelegate;
+ }
+
+ /**
+ * Begin monitoring for keyboard hidden and defocuses the omnibox if it is detected.
+ * <p>
+ * Only call this method once a strong signal arrives that indicates the keyboard likely will
+ * be hidden (i.e. KeyEvent.KEYCODE_BACK in View#onKeyPreIme). Any increase in window size will
+ * trigger the hide callback to be notified after this is called. This is meant to be a "good"
+ * approximation for user intent to dimiss the keyboard to compensate for the lack of a proper
+ * signal from the system.
+ */
+ public void monitorForKeyboardHidden() {
+ cleanUp();
+
+ // If a hardware keyboard is attached, they might be hiding the virtual keyboard, but
+ // attempting to continue typing with the hardware keyboard. Disable unfocusing the
+ // omnibox automatically if we detect this case might be possible.
+ if (mView.getResources().getConfiguration().keyboard == Configuration.KEYBOARD_QWERTY) {
+ return;
+ }
+
+ if (mWindowDelegate != null) {
+ assert mWindowDelegate.getWindowSoftInputMode()
+ != WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING
+ : "SOFT_INPUT_ADJUST_NOTHING prevents detecting window size changes.";
+ }
+
+ mView.getViewTreeObserver().addOnGlobalLayoutListener(this);
+ mIsLayoutListenerAttached = true;
+
+ mInitialViewportHeight = availableWindowHeight();
+ mView.postDelayed(mClearListenerDelayedTask, SOFT_KEYBOARD_HIDDEN_TIMEOUT_MS);
+ }
+
+ @Override
+ public void onGlobalLayout() {
+ if (availableWindowHeight() > mInitialViewportHeight) {
+ mOnHideCallback.run();
+ cleanUp();
+ }
+ }
+
+ @VisibleForTesting
+ boolean isMonitoringForLayoutChanges() {
+ return mIsLayoutListenerAttached;
+ }
+
+ private int availableWindowHeight() {
+ if (mWindowDelegate == null) {
+ return mView.getRootView().getHeight();
+ }
+
+ mWindowDelegate.getWindowVisibleDisplayFrame(mTempRect);
+ return Math.min(mTempRect.height(), mWindowDelegate.getDecorViewHeight());
+ }
+
+ private void cleanUp() {
+ if (!mIsLayoutListenerAttached) return;
+ mView.removeCallbacks(mClearListenerDelayedTask);
+ mView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ mIsLayoutListenerAttached = false;
+ }
+}
« no previous file with comments | « no previous file | chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698