Commit fc7b1de5 authored by Ernest Galbrun's avatar Ernest Galbrun Committed by Commit Bot

Create an init screen that shows up the first time autofill is enabled.

Before: autofill assistant would trigger automatically.
After: Autofill assistant shows the init screen first, and the "ok"
button must be clicked for autofill to proceed. The init screen can be
deactivated by checking the dont_show_init_screen checkbox.

https://screenshot.googleplex.com/8sRtJSAqVjG

Binary-Size: Increase is due to adding new images for the background of the onboarding screen.
Bug: 806868
Change-Id: I9b2aa8a537698cdc2d36dd5a1b0fa37aa87091b9
Reviewed-on: https://chromium-review.googlesource.com/c/1296501
Commit-Queue: Ernest Galbrun <galbrun@google.com>
Reviewed-by: default avatarTheresa <twellington@chromium.org>
Reviewed-by: default avatarMathias Carlen <mcarlen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#606065}
parent 9c575941
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2018 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. -->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/init_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="100dp"
android:background="@drawable/autofill_assistant_bottombar_bg"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_marginTop="16dp"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<android.support.v7.widget.AppCompatImageView
android:layout_width="24dp"
android:layout_height="24dp"
app:srcCompat="@drawable/ic_autofill_assistant_24dp" />
<Space
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="1"/>
<ImageButton
android:id="@+id/close_button"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/btn_delete_24dp"
android:tint="@color/light_icon_color"
android:background="?attr/selectableItemBackground"
android:contentDescription="@string/close" />
</LinearLayout>
<LinearLayout
android:id="@+id/init"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingStart="50dp"
android:paddingEnd="50dp"
android:paddingBottom="15dp"
android:paddingTop="100dp">
<ImageView
tools:ignore="contentDescription"
android:layout_width="250dp"
android:layout_height="170dp"
android:scaleType="centerCrop"
android:src="@drawable/onboarding_background"
android:paddingStart="50dp"/>
<TextView
android:textColor="@color/default_text_color"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textAppearance="@style/BlackTitle2"
android:text="@string/autofill_assistant_onboarding_title" />
<TextView
android:textColor="@color/default_text_color"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingTop="40dp"
android:textAppearance="@style/BlackBodyDefault"
android:gravity="center"
android:text="@string/autofill_assistant_init_message" />
<Space
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<CheckBox
android:id="@+id/checkbox_dont_show_init_again"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/BlackBodyDefault"
android:paddingStart="25dp"
android:text="@string/dont_display_again"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="20dp"
android:paddingBottom="8dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/chip_init_not_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="36dp"
android:minWidth="120dp"
android:singleLine="true"
android:gravity="center"
android:textAppearance="@style/TextAppearance.AutofillAssistantButtonHairline"
android:background="@drawable/autofill_assistant_button_hairline_bg"
android:paddingStart="24dp"
android:paddingEnd="24dp"
android:paddingTop="9dp"
android:paddingBottom="9dp"
android:text="@string/no_thanks"/>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/chip_init_ok"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:textAppearance="@style/TextAppearance.AutofillAssistantFilledButton"
android:minHeight="36dp"
android:minWidth="120dp"
android:singleLine="true"
android:background="@drawable/autofill_assistant_button_filled_bg"
android:textColor="@color/modern_grey_50"
android:paddingStart="24dp"
android:paddingEnd="24dp"
android:paddingTop="9dp"
android:paddingBottom="9dp"
android:text="@string/init_ok" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
...@@ -20,4 +20,10 @@ ...@@ -20,4 +20,10 @@
<item name="android:textColor">@color/modern_blue_600</item> <item name="android:textColor">@color/modern_blue_600</item>
<item name="android:textSize">@dimen/text_size_medium</item> <item name="android:textSize">@dimen/text_size_medium</item>
</style> </style>
<style
name="TextAppearance.AutofillAssistantFilledButton"
parent="RobotoMediumStyle">
<item name="android:textColor">@color/modern_grey_50</item>
<item name="android:textSize">@dimen/text_size_medium</item>
</style>
</resources> </resources>
...@@ -66,8 +66,13 @@ public class AutofillAssistantUiController implements AutofillAssistantUiDelegat ...@@ -66,8 +66,13 @@ public class AutofillAssistantUiController implements AutofillAssistantUiDelegat
private static final String RFC_3339_FORMAT = "yyyy'-'MM'-'dd'T'HH':'mm':'ssZ"; private static final String RFC_3339_FORMAT = "yyyy'-'MM'-'dd'T'HH':'mm':'ssZ";
private final WebContents mWebContents; private final WebContents mWebContents;
private final long mUiControllerAndroid;
private final UiDelegateHolder mUiDelegateHolder; private final UiDelegateHolder mUiDelegateHolder;
private final String mInitialUrl;
/**
* Native pointer to the UIController.
*/
private final long mUiControllerAndroid;
private AutofillAssistantPaymentRequest mAutofillAssistantPaymentRequest; private AutofillAssistantPaymentRequest mAutofillAssistantPaymentRequest;
...@@ -97,7 +102,12 @@ public class AutofillAssistantUiController implements AutofillAssistantUiDelegat ...@@ -97,7 +102,12 @@ public class AutofillAssistantUiController implements AutofillAssistantUiDelegat
&& !VariationsAssociatedData.getVariationParamValue(STUDY_NAME, URL_PARAMETER_NAME) && !VariationsAssociatedData.getVariationParamValue(STUDY_NAME, URL_PARAMETER_NAME)
.isEmpty() .isEmpty()
&& ContextUtils.getAppSharedPreferences().getBoolean( && ContextUtils.getAppSharedPreferences().getBoolean(
AutofillAssistantPreferences.PREF_AUTOFILL_ASSISTANT_SWITCH, false); AutofillAssistantPreferences.PREF_AUTOFILL_ASSISTANT_SWITCH, true);
}
@Override
public void onInitOk() {
nativeStart(mUiControllerAndroid, mInitialUrl);
} }
/** /**
...@@ -122,10 +132,13 @@ public class AutofillAssistantUiController implements AutofillAssistantUiDelegat ...@@ -122,10 +132,13 @@ public class AutofillAssistantUiController implements AutofillAssistantUiDelegat
Tab activityTab = activity.getActivityTab(); Tab activityTab = activity.getActivityTab();
mWebContents = activityTab.getWebContents(); mWebContents = activityTab.getWebContents();
mInitialUrl = activity.getInitialIntent().getDataString();
mUiControllerAndroid = mUiControllerAndroid =
nativeInit(mWebContents, parameters.keySet().toArray(new String[parameters.size()]), nativeInit(mWebContents, parameters.keySet().toArray(new String[parameters.size()]),
parameters.values().toArray(new String[parameters.size()]), parameters.values().toArray(new String[parameters.size()]));
activity.getInitialIntent().getDataString());
mUiDelegateHolder.performUiOperation(uiDelegate -> uiDelegate.startOrSkipInitScreen());
// Shut down Autofill Assistant when the tab is detached from the activity. // Shut down Autofill Assistant when the tab is detached from the activity.
activityTab.addObserver(new EmptyTabObserver() { activityTab.addObserver(new EmptyTabObserver() {
...@@ -557,8 +570,9 @@ public class AutofillAssistantUiController implements AutofillAssistantUiDelegat ...@@ -557,8 +570,9 @@ public class AutofillAssistantUiController implements AutofillAssistantUiDelegat
} }
// native methods. // native methods.
private native long nativeInit(WebContents webContents, String[] parameterNames, private native long nativeInit(
String[] parameterValues, String initialUrl); WebContents webContents, String[] parameterNames, String[] parameterValues);
private native void nativeStart(long nativeUiControllerAndroid, String initialUrl);
private native void nativeDestroy(long nativeUiControllerAndroid); private native void nativeDestroy(long nativeUiControllerAndroid);
private native void nativeGiveUp(long nativeUiControllerAndroid); private native void nativeGiveUp(long nativeUiControllerAndroid);
private native void nativeOnScriptSelected(long nativeUiControllerAndroid, String scriptPath); private native void nativeOnScriptSelected(long nativeUiControllerAndroid, String scriptPath);
......
...@@ -20,6 +20,7 @@ import android.view.Gravity; ...@@ -20,6 +20,7 @@ import android.view.Gravity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.HorizontalScrollView; import android.widget.HorizontalScrollView;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
...@@ -58,6 +59,7 @@ class AutofillAssistantUiDelegate { ...@@ -58,6 +59,7 @@ class AutofillAssistantUiDelegate {
private final ChromeActivity mActivity; private final ChromeActivity mActivity;
private final Client mClient; private final Client mClient;
private final ViewGroup mCoordinatorView;
private final View mFullContainer; private final View mFullContainer;
private final View mOverlay; private final View mOverlay;
private final LinearLayout mBottomBar; private final LinearLayout mBottomBar;
...@@ -109,6 +111,11 @@ class AutofillAssistantUiDelegate { ...@@ -109,6 +111,11 @@ class AutofillAssistantUiDelegate {
* @param guid The GUID of the selected card. * @param guid The GUID of the selected card.
*/ */
void onCardSelected(String guid); void onCardSelected(String guid);
/**
* Called when the init was successful.
*/
void onInitOk();
} }
/** /**
...@@ -210,9 +217,9 @@ class AutofillAssistantUiDelegate { ...@@ -210,9 +217,9 @@ class AutofillAssistantUiDelegate {
mActivity = activity; mActivity = activity;
mClient = client; mClient = client;
mCoordinatorView = (ViewGroup) mActivity.findViewById(R.id.coordinator);
mFullContainer = LayoutInflater.from(mActivity) mFullContainer = LayoutInflater.from(mActivity)
.inflate(R.layout.autofill_assistant_sheet, .inflate(R.layout.autofill_assistant_sheet, mCoordinatorView)
((ViewGroup) mActivity.findViewById(R.id.coordinator)))
.findViewById(R.id.autofill_assistant); .findViewById(R.id.autofill_assistant);
// TODO(crbug.com/806868): Set hint text on overlay. // TODO(crbug.com/806868): Set hint text on overlay.
mOverlay = mFullContainer.findViewById(R.id.overlay); mOverlay = mFullContainer.findViewById(R.id.overlay);
...@@ -581,6 +588,39 @@ class AutofillAssistantUiDelegate { ...@@ -581,6 +588,39 @@ class AutofillAssistantUiDelegate {
show(); show();
} }
/**
* Starts the init screen unless it has been marked to be skipped.
*/
public void startOrSkipInitScreen() {
if (InitScreenController.skip()) {
mClient.onInitOk();
return;
}
showInitScreen(new InitScreenController(mClient));
}
/**
* Shows the init screen and launch the autofill assistant when it succeeds.
*/
public void showInitScreen(InitScreenController controller) {
View initView = LayoutInflater.from(mActivity)
.inflate(R.layout.init_screen, mCoordinatorView)
.findViewById(R.id.init_screen);
initView.findViewById(R.id.close_button)
.setOnClickListener(unusedView -> onInitClicked(controller, false, initView));
initView.findViewById(R.id.chip_init_ok)
.setOnClickListener(unusedView -> onInitClicked(controller, true, initView));
initView.findViewById(R.id.chip_init_not_ok)
.setOnClickListener(unusedView -> onInitClicked(controller, false, initView));
}
private void onInitClicked(InitScreenController controller, Boolean initOk, View initView) {
CheckBox checkBox = initView.findViewById(R.id.checkbox_dont_show_init_again);
controller.onInitFinished(initOk, checkBox.isChecked());
mCoordinatorView.removeView(initView);
}
private Promise<Bitmap> downloadImage(String url) { private Promise<Bitmap> downloadImage(String url) {
Promise<Bitmap> promise = new Promise<>(); Promise<Bitmap> promise = new Promise<>();
new DownloadImageTask(promise).execute(url); new DownloadImageTask(promise).execute(url);
......
// Copyright 2018 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.autofill_assistant;
import org.chromium.base.ContextUtils;
import org.chromium.chrome.browser.preferences.autofill_assistant.AutofillAssistantPreferences;
/**
* Init screen controller, responsible for starting the native autofill assistant after init has
* been confirmed.
*/
public class InitScreenController {
/**
* Name of the shared parameter entry keeping track of whether the
* first screen should be skipped on startup.
*/
private static final String AUTOFILL_ASSISTANT_SKIP_INIT_SCREEN =
"AUTOFILL_ASSISTANT_SKIP_INIT_SCREEN";
public static boolean skip() {
return ContextUtils.getAppSharedPreferences().getBoolean(
AUTOFILL_ASSISTANT_SKIP_INIT_SCREEN, false);
}
private final AutofillAssistantUiDelegate.Client mClient;
/**
* Constructs an Init screen.
*
* @param activity The parent activity.
*/
public InitScreenController(AutofillAssistantUiDelegate.Client client) {
mClient = client;
}
/**
* The main callback method providing the result of the init, and the status
* of the "don't show me again" checkbox.
*/
public void onInitFinished(boolean initOk, boolean dontShowAgain) {
if (initOk) {
if (dontShowAgain) {
ContextUtils.getAppSharedPreferences()
.edit()
.putBoolean(AUTOFILL_ASSISTANT_SKIP_INIT_SCREEN, true)
.apply();
}
mClient.onInitOk();
return;
}
if (dontShowAgain) {
ContextUtils.getAppSharedPreferences()
.edit()
.putBoolean(AutofillAssistantPreferences.PREF_AUTOFILL_ASSISTANT_SWITCH, false)
.apply();
}
}
}
...@@ -3926,9 +3926,21 @@ However, you aren’t invisible. Going private doesn’t hide your browsing from ...@@ -3926,9 +3926,21 @@ However, you aren’t invisible. Going private doesn’t hide your browsing from
</message> </message>
<!-- Autofill Assistant --> <!-- Autofill Assistant -->
<message name="IDS_AUTOFILL_ASSISTANT_ONBOARDING_TITLE" desc="Onboarding title for the autofill assistant.">
Fast checkout
</message>
<message name="IDS_AUTOFILL_ASSISTANT_STOPPED" desc="Text label that is shown when stopping the Autofill Assistant. DURATION_SECONDS is a number representing a duration in seconds, which is why it is appended with 's'."> <message name="IDS_AUTOFILL_ASSISTANT_STOPPED" desc="Text label that is shown when stopping the Autofill Assistant. DURATION_SECONDS is a number representing a duration in seconds, which is why it is appended with 's'.">
Autofill Assistant will stop in <ph name="DURATION_SECONDS">%1$s<ex>3</ex></ph>s… Autofill Assistant will stop in <ph name="DURATION_SECONDS">%1$s<ex>3</ex></ph>s…
</message> </message>
<message name="IDS_INIT_OK" desc="Init screen confirmation text.">
Let's go
</message>
<message name="IDS_DONT_DISPLAY_AGAIN" desc="Description for the checkbox that prevents the screen to be displayed again.">
Don't display again
</message>
<message name="IDS_AUTOFILL_ASSISTANT_INIT_MESSAGE" desc="Onboarding message describing autofill assistant's capability.">
Google Assistant can help you get things done faster and easier on the web
</message>
<!-- Autofill Assistant preferences --> <!-- Autofill Assistant preferences -->
<message name="IDS_PREFS_AUTOFILL_ASSISTANT_TITLE" desc="Title for the Autofill Assistant preferences screen. [CHAR-LIMIT=32]"> <message name="IDS_PREFS_AUTOFILL_ASSISTANT_TITLE" desc="Title for the Autofill Assistant preferences screen. [CHAR-LIMIT=32]">
Autofill Assistant Autofill Assistant
...@@ -3936,7 +3948,6 @@ However, you aren’t invisible. Going private doesn’t hide your browsing from ...@@ -3936,7 +3948,6 @@ However, you aren’t invisible. Going private doesn’t hide your browsing from
<message name="IDS_PREFS_AUTOFILL_ASSISTANT_SWITCH" desc="Title for the switch toggling whether Autofill Assistant is enabled. [CHAR-LIMIT=32]"> <message name="IDS_PREFS_AUTOFILL_ASSISTANT_SWITCH" desc="Title for the switch toggling whether Autofill Assistant is enabled. [CHAR-LIMIT=32]">
Automate Automate
</message> </message>
</messages> </messages>
</release> </release>
</grit> </grit>
...@@ -120,6 +120,7 @@ chrome_java_sources = [ ...@@ -120,6 +120,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/autofill_assistant/AnimatedProgressBar.java", "java/src/org/chromium/chrome/browser/autofill_assistant/AnimatedProgressBar.java",
"java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java", "java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java",
"java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java", "java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java",
"java/src/org/chromium/chrome/browser/autofill_assistant/InitScreenController.java",
"java/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTask.java", "java/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTask.java",
"java/src/org/chromium/chrome/browser/banners/AppBannerManager.java", "java/src/org/chromium/chrome/browser/banners/AppBannerManager.java",
"java/src/org/chromium/chrome/browser/banners/AppBannerUiDelegateAndroid.java", "java/src/org/chromium/chrome/browser/banners/AppBannerUiDelegateAndroid.java",
......
...@@ -66,8 +66,7 @@ UiControllerAndroid::UiControllerAndroid( ...@@ -66,8 +66,7 @@ UiControllerAndroid::UiControllerAndroid(
jobject jcaller, jobject jcaller,
const JavaParamRef<jobject>& webContents, const JavaParamRef<jobject>& webContents,
const JavaParamRef<jobjectArray>& parameterNames, const JavaParamRef<jobjectArray>& parameterNames,
const JavaParamRef<jobjectArray>& parameterValues, const JavaParamRef<jobjectArray>& parameterValues)
const JavaParamRef<jstring>& initialUrlString)
: ui_delegate_(nullptr) { : ui_delegate_(nullptr) {
java_autofill_assistant_ui_controller_.Reset(env, jcaller); java_autofill_assistant_ui_controller_.Reset(env, jcaller);
...@@ -75,17 +74,22 @@ UiControllerAndroid::UiControllerAndroid( ...@@ -75,17 +74,22 @@ UiControllerAndroid::UiControllerAndroid(
content::WebContents::FromJavaWebContents(webContents); content::WebContents::FromJavaWebContents(webContents);
DCHECK(web_contents); DCHECK(web_contents);
browser_context_ = web_contents->GetBrowserContext(); browser_context_ = web_contents->GetBrowserContext();
GURL initialUrl = Controller::CreateForWebContents(
GURL(base::android::ConvertJavaStringToUTF8(env, initialUrlString));
Controller::CreateAndStartForWebContents(
web_contents, base::WrapUnique(this), web_contents, base::WrapUnique(this),
BuildParametersFromJava(env, parameterNames, parameterValues), BuildParametersFromJava(env, parameterNames, parameterValues));
initialUrl);
DCHECK(ui_delegate_); DCHECK(ui_delegate_);
} }
UiControllerAndroid::~UiControllerAndroid() {} UiControllerAndroid::~UiControllerAndroid() {}
void UiControllerAndroid::Start(JNIEnv* env,
const JavaParamRef<jobject>& jcaller,
const JavaParamRef<jstring>& initialUrlString) {
GURL initialUrl =
GURL(base::android::ConvertJavaStringToUTF8(env, initialUrlString));
ui_delegate_->Start(initialUrl);
}
void UiControllerAndroid::SetUiDelegate(UiDelegate* ui_delegate) { void UiControllerAndroid::SetUiDelegate(UiDelegate* ui_delegate) {
ui_delegate_ = ui_delegate; ui_delegate_ = ui_delegate;
} }
...@@ -372,11 +376,9 @@ static jlong JNI_AutofillAssistantUiController_Init( ...@@ -372,11 +376,9 @@ static jlong JNI_AutofillAssistantUiController_Init(
const JavaParamRef<jobject>& jcaller, const JavaParamRef<jobject>& jcaller,
const JavaParamRef<jobject>& webContents, const JavaParamRef<jobject>& webContents,
const JavaParamRef<jobjectArray>& parameterNames, const JavaParamRef<jobjectArray>& parameterNames,
const JavaParamRef<jobjectArray>& parameterValues, const JavaParamRef<jobjectArray>& parameterValues) {
const JavaParamRef<jstring>& initialUrlString) {
auto* ui_controller_android = new autofill_assistant::UiControllerAndroid( auto* ui_controller_android = new autofill_assistant::UiControllerAndroid(
env, jcaller, webContents, parameterNames, parameterValues, env, jcaller, webContents, parameterNames, parameterValues);
initialUrlString);
return reinterpret_cast<intptr_t>(ui_controller_android); return reinterpret_cast<intptr_t>(ui_controller_android);
} }
......
...@@ -30,8 +30,7 @@ class UiControllerAndroid : public UiController, ...@@ -30,8 +30,7 @@ class UiControllerAndroid : public UiController,
jobject jcaller, jobject jcaller,
const base::android::JavaParamRef<jobject>& webContents, const base::android::JavaParamRef<jobject>& webContents,
const base::android::JavaParamRef<jobjectArray>& parameterNames, const base::android::JavaParamRef<jobjectArray>& parameterNames,
const base::android::JavaParamRef<jobjectArray>& parameterValues, const base::android::JavaParamRef<jobjectArray>& parameterValues);
const base::android::JavaParamRef<jstring>& initialUrlString);
~UiControllerAndroid() override; ~UiControllerAndroid() override;
// Overrides UiController: // Overrides UiController:
...@@ -69,6 +68,9 @@ class UiControllerAndroid : public UiController, ...@@ -69,6 +68,9 @@ class UiControllerAndroid : public UiController,
void InvalidateAccessToken(const std::string& access_token) override; void InvalidateAccessToken(const std::string& access_token) override;
// Called by Java. // Called by Java.
void Start(JNIEnv* env,
const base::android::JavaParamRef<jobject>& jcaller,
const base::android::JavaParamRef<jstring>& initialUrlString);
void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
void GiveUp(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); void GiveUp(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
void OnScriptSelected( void OnScriptSelected(
......
...@@ -40,11 +40,10 @@ static const char* const kCallerScriptParameterName = "CALLER"; ...@@ -40,11 +40,10 @@ static const char* const kCallerScriptParameterName = "CALLER";
} // namespace } // namespace
// static // static
void Controller::CreateAndStartForWebContents( void Controller::CreateForWebContents(
content::WebContents* web_contents, content::WebContents* web_contents,
std::unique_ptr<Client> client, std::unique_ptr<Client> client,
std::unique_ptr<std::map<std::string, std::string>> parameters, std::unique_ptr<std::map<std::string, std::string>> parameters) {
const GURL& initialUrl) {
// Get the key early since |client| will be invalidated when moved below. // Get the key early since |client| will be invalidated when moved below.
GURL server_url(client->GetServerUrl()); GURL server_url(client->GetServerUrl());
DCHECK(server_url.is_valid()); DCHECK(server_url.is_valid());
...@@ -53,7 +52,7 @@ void Controller::CreateAndStartForWebContents( ...@@ -53,7 +52,7 @@ void Controller::CreateAndStartForWebContents(
client->GetAccessTokenFetcher()); client->GetAccessTokenFetcher());
new Controller(web_contents, std::move(client), new Controller(web_contents, std::move(client),
WebController::CreateForWebContents(web_contents), WebController::CreateForWebContents(web_contents),
std::move(service), std::move(parameters), initialUrl); std::move(service), std::move(parameters));
} }
Service* Controller::GetService() { Service* Controller::GetService() {
...@@ -89,8 +88,7 @@ Controller::Controller( ...@@ -89,8 +88,7 @@ Controller::Controller(
std::unique_ptr<Client> client, std::unique_ptr<Client> client,
std::unique_ptr<WebController> web_controller, std::unique_ptr<WebController> web_controller,
std::unique_ptr<Service> service, std::unique_ptr<Service> service,
std::unique_ptr<std::map<std::string, std::string>> parameters, std::unique_ptr<std::map<std::string, std::string>> parameters)
const GURL& initialUrl)
: content::WebContentsObserver(web_contents), : content::WebContentsObserver(web_contents),
client_(std::move(client)), client_(std::move(client)),
web_controller_(std::move(web_controller)), web_controller_(std::move(web_controller)),
...@@ -113,6 +111,16 @@ Controller::Controller( ...@@ -113,6 +111,16 @@ Controller::Controller(
} }
GetUiController()->SetUiDelegate(this); GetUiController()->SetUiDelegate(this);
}
Controller::~Controller() {
if (clear_web_contents_delegate_) {
web_contents()->SetDelegate(nullptr);
}
}
void Controller::Start(const GURL& initialUrl) {
started_ = true;
if (initialUrl.is_valid()) if (initialUrl.is_valid())
GetOrCheckScripts(initialUrl); GetOrCheckScripts(initialUrl);
...@@ -127,18 +135,15 @@ Controller::Controller( ...@@ -127,18 +135,15 @@ Controller::Controller(
// domain in the "Loading..." message. // domain in the "Loading..." message.
GetUiController()->ShowStatusMessage(l10n_util::GetStringFUTF8( GetUiController()->ShowStatusMessage(l10n_util::GetStringFUTF8(
IDS_AUTOFILL_ASSISTANT_LOADING, IDS_AUTOFILL_ASSISTANT_LOADING,
base::UTF8ToUTF16(web_contents->GetVisibleURL().host()))); base::UTF8ToUTF16(web_contents()->GetVisibleURL().host())));
} }
} }
} }
Controller::~Controller() {
if (clear_web_contents_delegate_) {
web_contents()->SetDelegate(nullptr);
}
}
void Controller::GetOrCheckScripts(const GURL& url) { void Controller::GetOrCheckScripts(const GURL& url) {
if (!started_) {
return;
}
if (script_tracker_->running()) if (script_tracker_->running())
return; return;
......
...@@ -39,11 +39,10 @@ class Controller : public ScriptExecutorDelegate, ...@@ -39,11 +39,10 @@ class Controller : public ScriptExecutorDelegate,
private content::WebContentsObserver, private content::WebContentsObserver,
private content::WebContentsDelegate { private content::WebContentsDelegate {
public: public:
static void CreateAndStartForWebContents( static void CreateForWebContents(
content::WebContents* web_contents, content::WebContents* web_contents,
std::unique_ptr<Client> client, std::unique_ptr<Client> client,
std::unique_ptr<std::map<std::string, std::string>> parameters, std::unique_ptr<std::map<std::string, std::string>> parameters);
const GURL& initialUrl);
// Overrides ScriptExecutorDelegate: // Overrides ScriptExecutorDelegate:
Service* GetService() override; Service* GetService() override;
...@@ -61,8 +60,7 @@ class Controller : public ScriptExecutorDelegate, ...@@ -61,8 +60,7 @@ class Controller : public ScriptExecutorDelegate,
std::unique_ptr<Client> client, std::unique_ptr<Client> client,
std::unique_ptr<WebController> web_controller, std::unique_ptr<WebController> web_controller,
std::unique_ptr<Service> service, std::unique_ptr<Service> service,
std::unique_ptr<std::map<std::string, std::string>> parameters, std::unique_ptr<std::map<std::string, std::string>> parameters);
const GURL& initialUrl);
~Controller() override; ~Controller() override;
void GetOrCheckScripts(const GURL& url); void GetOrCheckScripts(const GURL& url);
...@@ -81,6 +79,7 @@ class Controller : public ScriptExecutorDelegate, ...@@ -81,6 +79,7 @@ class Controller : public ScriptExecutorDelegate,
void OnPeriodicScriptCheck(); void OnPeriodicScriptCheck();
// Overrides content::UiDelegate: // Overrides content::UiDelegate:
void Start(const GURL& initialUrl) override;
void OnClickOverlay() override; void OnClickOverlay() override;
void OnDestroy() override; void OnDestroy() override;
void OnGiveUp() override; void OnGiveUp() override;
...@@ -132,6 +131,8 @@ class Controller : public ScriptExecutorDelegate, ...@@ -132,6 +131,8 @@ class Controller : public ScriptExecutorDelegate,
// unsuccessful round of preconditions checking. // unsuccessful round of preconditions checking.
bool should_fail_after_checking_scripts_ = false; bool should_fail_after_checking_scripts_ = false;
bool started_ = false;
base::WeakPtrFactory<Controller> weak_ptr_factory_; base::WeakPtrFactory<Controller> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(Controller); DISALLOW_COPY_AND_ASSIGN(Controller);
......
...@@ -64,11 +64,10 @@ class ControllerTest : public content::RenderViewHostTestHarness { ...@@ -64,11 +64,10 @@ class ControllerTest : public content::RenderViewHostTestHarness {
std::unique_ptr<Client> client, std::unique_ptr<Client> client,
std::unique_ptr<WebController> web_controller, std::unique_ptr<WebController> web_controller,
std::unique_ptr<Service> service, std::unique_ptr<Service> service,
std::unique_ptr<std::map<std::string, std::string>> parameters, std::unique_ptr<std::map<std::string, std::string>> parameters) {
const GURL& initialUrl) {
return new Controller(web_contents, std::move(client), return new Controller(web_contents, std::move(client),
std::move(web_controller), std::move(service), std::move(web_controller), std::move(service),
std::move(parameters), initialUrl); std::move(parameters));
} }
static void DestroyController(Controller* controller) { static void DestroyController(Controller* controller) {
...@@ -90,8 +89,9 @@ class ControllerTest : public content::RenderViewHostTestHarness { ...@@ -90,8 +89,9 @@ class ControllerTest : public content::RenderViewHostTestHarness {
controller_ = new Controller( controller_ = new Controller(
web_contents(), std::make_unique<FakeClient>(std::move(ui_controller)), web_contents(), std::make_unique<FakeClient>(std::move(ui_controller)),
std::move(web_controller), std::move(service), std::move(parameters), std::move(web_controller), std::move(service), std::move(parameters));
initialUrl);
GetUiDelegate()->Start(initialUrl);
// Fetching scripts succeeds for all URLs, but return nothing. // Fetching scripts succeeds for all URLs, but return nothing.
ON_CALL(*mock_service_, OnGetScriptsForUrl(_, _, _)) ON_CALL(*mock_service_, OnGetScriptsForUrl(_, _, _))
...@@ -364,6 +364,22 @@ TEST_F(ControllerTest, LoadProgressChanged) { ...@@ -364,6 +364,22 @@ TEST_F(ControllerTest, LoadProgressChanged) {
SimulateProgressChanged(0.4); SimulateProgressChanged(0.4);
} }
TEST_F(ControllerTest, InitialUrlLoadsDoesntStartByDefault) {
GURL initialUrl("http://a.example.com/path");
auto service = std::make_unique<NiceMock<MockService>>();
EXPECT_CALL(*service.get(), OnGetScriptsForUrl(Eq(initialUrl), _, _))
.Times(0);
Controller* controller = ControllerTest::CreateController(
web_contents(),
std::make_unique<FakeClient>(
std::make_unique<NiceMock<MockUiController>>()),
std::make_unique<NiceMock<MockWebController>>(), std::move(service),
std::make_unique<std::map<std::string, std::string>>());
ControllerTest::DestroyController(controller);
}
TEST_F(ControllerTest, InitialUrlLoads) { TEST_F(ControllerTest, InitialUrlLoads) {
GURL initialUrl("http://a.example.com/path"); GURL initialUrl("http://a.example.com/path");
auto service = std::make_unique<NiceMock<MockService>>(); auto service = std::make_unique<NiceMock<MockService>>();
...@@ -376,7 +392,8 @@ TEST_F(ControllerTest, InitialUrlLoads) { ...@@ -376,7 +392,8 @@ TEST_F(ControllerTest, InitialUrlLoads) {
std::make_unique<FakeClient>( std::make_unique<FakeClient>(
std::make_unique<NiceMock<MockUiController>>()), std::make_unique<NiceMock<MockUiController>>()),
std::make_unique<NiceMock<MockWebController>>(), std::move(service), std::make_unique<NiceMock<MockWebController>>(), std::move(service),
std::make_unique<std::map<std::string, std::string>>(), initialUrl); std::make_unique<std::map<std::string, std::string>>());
dynamic_cast<UiDelegate*>(controller)->Start(initialUrl);
ControllerTest::DestroyController(controller); ControllerTest::DestroyController(controller);
} }
......
...@@ -13,6 +13,9 @@ class UiDelegate { ...@@ -13,6 +13,9 @@ class UiDelegate {
public: public:
virtual ~UiDelegate() = default; virtual ~UiDelegate() = default;
// Called when autofill assistant can start executing scripts.
virtual void Start(const GURL& initialUrl) = 0;
// Called when the overlay has been clicked. // Called when the overlay has been clicked.
virtual void OnClickOverlay() = 0; virtual void OnClickOverlay() = 0;
......
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