Index: content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java |
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java |
index 4f54ff25e4455c47fa5d73073115f644e5a12b0f..6766dca7757baeadf386d2a3945f00f0447faaf0 100644 |
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java |
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java |
@@ -112,8 +112,7 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Displa |
// and remove from it in removeJavaScriptInterface(). The annotation class is stored for |
// the purpose of migrating injected objects from one instance of CVC to another, which |
// is used by Android WebView to support WebChromeClient.onCreateWindow scenario. |
- private final Map<String, Pair<Object, Class>> mJavaScriptInterfaces = |
- new HashMap<String, Pair<Object, Class>>(); |
+ private final Map<String, Pair<Object, Class>> mJavaScriptInterfaces = new HashMap<>(); |
aelias_OOO_until_Jul13
2017/03/30 02:06:55
I assume you made these changes because of a presu
mthiesse
2017/03/30 14:51:51
My editor automatically makes these changes, and I
|
// Additionally, we keep track of all Java bound JS objects that are in use on the |
// current page to ensure that they are not garbage collected until the page is |
@@ -121,7 +120,7 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Displa |
// via the removeJavaScriptInterface API and transient objects returned from methods |
// on the interface object. Note we use HashSet rather than Set as the native side |
// expects HashSet (no bindings for interfaces). |
- private final HashSet<Object> mRetainedJavaScriptObjects = new HashSet<Object>(); |
+ private final HashSet<Object> mRetainedJavaScriptObjects = new HashSet<>(); |
/** |
* A {@link WebContentsObserver} that listens to frame navigation events. |
@@ -132,7 +131,7 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Displa |
ContentViewWebContentsObserver(ContentViewCore contentViewCore) { |
super(contentViewCore.getWebContents()); |
- mWeakContentViewCore = new WeakReference<ContentViewCore>(contentViewCore); |
+ mWeakContentViewCore = new WeakReference<>(contentViewCore); |
} |
@Override |
@@ -371,6 +370,11 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Displa |
// ResultReceiver in the InputMethodService (IME app) gets gc'ed. |
private ShowKeyboardResultReceiver mShowKeyboardResultReceiver; |
+ // Whether this ContentViewCore has view focus. |
+ private boolean mHasViewFocus; |
+ // Whether this ContentViewCore has window focus. |
+ private boolean mHasWindowFocus; |
+ |
// The list of observers that are notified when ContentViewCore changes its WindowAndroid. |
private final ObserverList<WindowAndroidChangedObserver> mWindowAndroidChangedObservers; |
@@ -396,10 +400,10 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Displa |
mAccessibilityManager = (AccessibilityManager) |
getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); |
mSystemCaptioningBridge = CaptioningBridgeFactory.getSystemCaptioningBridge(mContext); |
- mGestureStateListeners = new ObserverList<GestureStateListener>(); |
+ mGestureStateListeners = new ObserverList<>(); |
mGestureStateListenersIterator = mGestureStateListeners.rewindableIterator(); |
- mWindowAndroidChangedObservers = new ObserverList<WindowAndroidChangedObserver>(); |
+ mWindowAndroidChangedObservers = new ObserverList<>(); |
} |
/** |
@@ -676,6 +680,8 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Displa |
} |
mContainerView = containerView; |
+ onFocusChangedInternal(getRealWindowFocusedState(), containerView.hasFocus(), |
+ false /* hideKeyboardOnBlur */); |
mContainerView.setClickable(true); |
if (mSelectionPopupController != null) { |
mSelectionPopupController.setContainerView(containerView); |
@@ -685,6 +691,20 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Displa |
} |
} |
+ /** |
+ * Note: We don't use View#hasWindowFocus() because it returns incorrect values when the View |
+ * doesn't have View focus. |
+ * @return Whether the containerView actually has Window focus. |
+ */ |
+ private boolean getRealWindowFocusedState() { |
+ boolean hasWindowFocus = false; |
+ int[] states = mContainerView.getDrawableState(); |
+ for (int state : states) { |
+ if ((state & android.R.attr.state_window_focused) != 0) hasWindowFocus = true; |
+ } |
+ return hasWindowFocus; |
+ } |
+ |
@CalledByNative |
private void onNativeContentViewCoreDestroyed(long nativeContentViewCore) { |
assert nativeContentViewCore == mNativeContentViewCore; |
@@ -1334,23 +1354,37 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Displa |
* @see View#onWindowFocusChanged(boolean) |
*/ |
public void onWindowFocusChanged(boolean hasWindowFocus) { |
+ if (mHasWindowFocus == hasWindowFocus) return; |
mImeAdapter.onWindowFocusChanged(hasWindowFocus); |
if (!hasWindowFocus) resetGestureDetection(); |
mSelectionPopupController.onWindowFocusChanged(hasWindowFocus); |
for (mGestureStateListenersIterator.rewind(); mGestureStateListenersIterator.hasNext();) { |
mGestureStateListenersIterator.next().onWindowFocusChanged(hasWindowFocus); |
} |
+ onFocusChangedInternal(hasWindowFocus, mHasViewFocus, true /* hideKeyboardOnBlur */); |
} |
public void onFocusChanged(boolean gainFocus, boolean hideKeyboardOnBlur) { |
aelias_OOO_until_Jul13
2017/03/30 02:06:55
Please rename "gainFocus" to "hasViewFocus"
mthiesse
2017/03/30 14:51:51
Done.
|
- mImeAdapter.onViewFocusChanged(gainFocus, hideKeyboardOnBlur); |
+ if (mHasViewFocus == gainFocus) return; |
+ onFocusChangedInternal(mHasWindowFocus, gainFocus, hideKeyboardOnBlur); |
+ } |
+ |
+ @VisibleForTesting |
+ public void onFocusChangedInternal( |
+ boolean hasWindowFocus, boolean hasViewFocus, boolean hideKeyboardOnBlur) { |
+ boolean hadInputFocus = mHasWindowFocus && mHasViewFocus; |
+ boolean hasInputFocus = hasWindowFocus && hasViewFocus; |
+ mHasWindowFocus = hasWindowFocus; |
+ mHasViewFocus = hasViewFocus; |
+ if (hasInputFocus == hadInputFocus) return; |
aelias_OOO_until_Jul13
2017/03/30 02:06:55
This early-return seems to do nothing given the ot
mthiesse
2017/03/30 14:51:51
It doesn't do nothing - it stops us from doing wor
|
+ mImeAdapter.onViewFocusChanged(hasInputFocus, hideKeyboardOnBlur); |
// Used in test that bypasses initialize(). |
if (mJoystickScrollProvider != null) { |
- mJoystickScrollProvider.setEnabled(gainFocus && !isFocusedNodeEditable()); |
+ mJoystickScrollProvider.setEnabled(hasInputFocus && !isFocusedNodeEditable()); |
} |
- if (gainFocus) { |
+ if (hasInputFocus) { |
restoreSelectionPopupsIfNecessary(); |
} else { |
cancelRequestToScrollFocusedEditableNodeIntoView(); |
@@ -1365,7 +1399,7 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Displa |
clearSelection(); |
} |
} |
- if (mNativeContentViewCore != 0) nativeSetFocus(mNativeContentViewCore, gainFocus); |
+ if (mNativeContentViewCore != 0) nativeSetFocus(mNativeContentViewCore, hasInputFocus); |
} |
/** |
@@ -1822,7 +1856,7 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Displa |
assert mNativeSelectPopupSourceFrame == 0 : "Zombie popup did not clear the frame source"; |
assert items.length == enabled.length; |
- List<SelectPopupItem> popupItems = new ArrayList<SelectPopupItem>(); |
+ List<SelectPopupItem> popupItems = new ArrayList<>(); |
for (int i = 0; i < items.length; i++) { |
popupItems.add(new SelectPopupItem(items[i], enabled[i])); |
} |