Commit ec943409 authored by Colin Blundell's avatar Colin Blundell Committed by Commit Bot

[WebLayer] Fix autofill integration

In WebLayer, both TabImpl and ContentView currently hold on to a
reference to the AutofillProviderImpl instance that should be used to
talk to the Autofill Service. TabImpl updates its reference when an
updateFromBrowser() call is received, and ContentView has its reference
set to that of the Tab by BrowserViewController on the Tab becoming the
active tab. However, this setup is brittle, as if
Tab#updateFromBrowser() is called after the Tab becomes the active Tab,
ContentView's reference will become stale.

Such a call has indeed crept in, as Tab#updateFromBrowser() is now
called from BrowserImpl#onFragmentStart(). This means that autofill no
longer works in the initial tab. This CL makes this setup more robust
by localizing interaction with AutofillProviderImpl inside TabImpl and
having ContentView go through TabImpl as necessary.

Bug: 1070296
Change-Id: I1c26ab8e5d8e9decfdcc3155e2577b1dbeda32b2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2149432Reviewed-by: default avatarTobias Sargeant <tobiasjs@chromium.org>
Commit-Queue: Colin Blundell <blundell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#759232}
parent e3ea14cc
......@@ -132,15 +132,7 @@ public final class BrowserViewController
mGestureStateTracker =
new WebContentsGestureStateTracker(mContentView, webContents, this);
}
mContentView.setWebContents(webContents);
if (mTab != null) {
// Now that |mContentView| is associated with this Tab's WebContents,
// associate |mContentView| with this Tab's AutofillProvider as well.
mContentView.setAutofillProvider(mTab.getAutofillProvider());
} else {
mContentView.setAutofillProvider(null);
}
mContentView.setTab(mTab);
mContentViewRenderView.setWebContents(webContents);
mTopControlsContainerView.setWebContents(webContents);
......
......@@ -27,7 +27,6 @@ import android.widget.RelativeLayout;
import org.chromium.base.ObserverList;
import org.chromium.base.TraceEvent;
import org.chromium.base.compat.ApiHelperForO;
import org.chromium.components.autofill.AutofillProvider;
import org.chromium.content_public.browser.ImeAdapter;
import org.chromium.content_public.browser.RenderCoordinates;
import org.chromium.content_public.browser.SmartClipProvider;
......@@ -50,8 +49,8 @@ public class ContentView extends RelativeLayout
public static final int DEFAULT_MEASURE_SPEC =
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
private TabImpl mTab;
private WebContents mWebContents;
private AutofillProvider mAutofillProvider;
private final ObserverList<OnHierarchyChangeListener> mHierarchyChangeListeners =
new ObserverList<>();
private final ObserverList<OnSystemUiVisibilityChangeListener> mSystemUiChangeListeners =
......@@ -127,27 +126,24 @@ public class ContentView extends RelativeLayout
: null;
}
protected AutofillProvider getAutofillProvider() {
return mAutofillProvider;
protected TabImpl getTab() {
return mTab;
}
public void setWebContents(WebContents webContents) {
public void setTab(TabImpl tab) {
mTab = tab;
boolean wasFocused = isFocused();
boolean wasWindowFocused = hasWindowFocus();
boolean wasAttached = isAttachedToWindow();
if (wasFocused) onFocusChanged(false, View.FOCUS_FORWARD, null);
if (wasWindowFocused) onWindowFocusChanged(false);
if (wasAttached) onDetachedFromWindow();
mWebContents = webContents;
mWebContents = mTab != null ? mTab.getWebContents() : null;
if (wasFocused) onFocusChanged(true, View.FOCUS_FORWARD, null);
if (wasWindowFocused) onWindowFocusChanged(true);
if (wasAttached) onAttachedToWindow();
}
public void setAutofillProvider(AutofillProvider autofillProvider) {
mAutofillProvider = autofillProvider;
}
@Override
public boolean performAccessibilityAction(int action, Bundle arguments) {
WebContentsAccessibility wcax = getWebContentsAccessibility();
......@@ -522,21 +518,21 @@ public class ContentView extends RelativeLayout
public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) {
// A new (virtual) View has been entered, and the autofill system-level
// infrastructure wants us to populate |structure| with the autofill structure of the
// (virtual) View. Forward this on to AutofillProvider to accomplish.
AutofillProvider autofillProvider = getAutofillProvider();
if (autofillProvider != null) {
autofillProvider.onProvideAutoFillVirtualStructure(structure, flags);
// (virtual) View. Forward this on to TabImpl to accomplish.
TabImpl tab = getTab();
if (tab != null) {
tab.onProvideAutofillVirtualStructure(structure, flags);
}
}
@Override
public void autofill(final SparseArray<AutofillValue> values) {
// The autofill system-level infrastructure has information that we can use to
// autofill the current (virtual) View. Forward this on to AutofillProvider to
// autofill the current (virtual) View. Forward this on to TabImpl to
// accomplish.
AutofillProvider autofillProvider = getAutofillProvider();
if (autofillProvider != null) {
autofillProvider.autofill(values);
TabImpl tab = getTab();
if (tab != null) {
tab.autofill(values);
}
}
}
......
......@@ -9,8 +9,11 @@ import android.os.Build;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.AndroidRuntimeException;
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.ViewStructure;
import android.view.autofill.AutofillValue;
import android.webkit.ValueCallback;
import org.chromium.base.Callback;
......@@ -236,6 +239,16 @@ public final class TabImpl extends ITab.Stub {
}
}
public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) {
if (mAutofillProvider == null) return;
mAutofillProvider.onProvideAutoFillVirtualStructure(structure, flags);
}
public void autofill(final SparseArray<AutofillValue> values) {
if (mAutofillProvider == null) return;
mAutofillProvider.autofill(values);
}
public BrowserImpl getBrowser() {
return mBrowser;
}
......@@ -311,10 +324,6 @@ public final class TabImpl extends ITab.Stub {
return mWebContents;
}
public AutofillProvider getAutofillProvider() {
return mAutofillProvider;
}
long getNativeTab() {
return mNativeTab;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment