Skip to content

Commit

Permalink
[Autofill Assistant] Introduce a simple bar to show scripts.
Browse files Browse the repository at this point in the history
R=gogerald@chromium.org

Bug: 806868
Change-Id: I1b7503c801916fb7bd7e0bcde2361f0bfd15d7cf
Reviewed-on: https://chromium-review.googlesource.com/1202205
Commit-Queue: Ganggui Tang <gogerald@chromium.org>
Reviewed-by: Ganggui Tang <gogerald@chromium.org>
Cr-Commit-Position: refs/heads/master@{#589703}
  • Loading branch information
Mathias Carlen authored and Commit Bot committed Sep 7, 2018
1 parent c2fffce commit e8ca310
Show file tree
Hide file tree
Showing 12 changed files with 186 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
@JNINamespace("autofill_assistant")
public class AutofillAssistantUiController {
private final long mUiControllerAndroid;
private final BottomBarController mBottomBarController;

/**
* Construct Autofill Assistant UI controller.
Expand Down Expand Up @@ -56,11 +57,13 @@ public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) {
// selected Tab.
}
});

mBottomBarController = new BottomBarController(activity);
}

@CalledByNative
private void onShowStatusMessage(String message) {
// TODO(crbug.com/806868): Implement corresponding UI.
mBottomBarController.showStatusMessage(message);
}

@CalledByNative
Expand All @@ -73,6 +76,13 @@ private void onHideOverlay() {
// TODO(crbug.com/806868): Implement corresponding UI.
}

@CalledByNative
private void onUpdateScripts(String[] scripts) {
// TODO(crbug.com/806868): Pass a Script handle instead of a string so that we can report
// back what script got selected.
mBottomBarController.updateScripts(scripts);
}

// native methods.
private native long nativeInit(WebContents webContents);
private native void nativeDestroy(long nativeUiControllerAndroid);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// 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 android.app.Activity;
import android.graphics.Color;
import android.support.design.widget.CoordinatorLayout;
import android.view.Gravity;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;

import org.chromium.chrome.R;

import javax.annotation.Nullable;

/** Controller to interact with the bottom bar. */
class BottomBarController {
private static final String SCRIPTS_STATUS_MESSAGE = "Scripts";

private final Activity mActivity;
private final LinearLayout mBottomBar;
private ViewGroup mScriptsViewContainer;
private TextView mStatusMessageView;

/**
* Constructs a bottom bar.
*
* @param activity The Activity
*/
public BottomBarController(Activity activity) {
mActivity = activity;

mBottomBar = createBottomBar();
((ViewGroup) mActivity.findViewById(R.id.coordinator)).addView(mBottomBar);

CoordinatorLayout.LayoutParams params =
(CoordinatorLayout.LayoutParams) mBottomBar.getLayoutParams();
params.gravity = Gravity.BOTTOM;

showStatusMessage(SCRIPTS_STATUS_MESSAGE);
}

/**
* Shows a message in the status bar.
*
* @param message Message to display.
*/
public void showStatusMessage(@Nullable String message) {
mStatusMessageView.setText(message);
}

/**
* Updates the list of scripts in the bar.
*
* @param scripts List of scripts to show.
*/
public void updateScripts(String[] scripts) {
mScriptsViewContainer.removeAllViews();
if (scripts.length == 0) {
return;
}

for (String script : scripts) {
mScriptsViewContainer.addView(createScriptView(script));
}
}

private LinearLayout createBottomBar() {
LinearLayout bottomBar = createContainer();
mStatusMessageView = createTextView();
bottomBar.addView(mStatusMessageView);
bottomBar.addView(createScrollView());
return bottomBar;
}

private LinearLayout createContainer() {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
LinearLayout layout = createLinearLayout(params, LinearLayout.VERTICAL);
layout.setBackgroundColor(Color.parseColor("#f0f0f0"));
layout.setPadding(10, 10, 10, 10);
return layout;
}

private TextView createTextView() {
TextView textView = new TextView(mActivity);
textView.setLayoutParams(
new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
textView.setGravity(Gravity.CENTER_HORIZONTAL);
return textView;
}

private HorizontalScrollView createScrollView() {
HorizontalScrollView scrollView = new HorizontalScrollView(mActivity);
scrollView.setLayoutParams(
new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
scrollView.setHorizontalScrollBarEnabled(false);
mScriptsViewContainer = createLinearLayout(
new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT),
LinearLayout.HORIZONTAL);
scrollView.addView(mScriptsViewContainer);
return scrollView;
}

private LinearLayout createLinearLayout(LayoutParams layoutParams, int orientation) {
LinearLayout layout = new LinearLayout(mActivity);
layout.setLayoutParams(layoutParams);
layout.setOrientation(orientation);
return layout;
}

private TextView createScriptView(String text) {
TextView scriptView = new TextView(mActivity);
scriptView.setPadding(20, 20, 20, 20);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(10, 10, 10, 10);
scriptView.setLayoutParams(layoutParams);
scriptView.setMaxLines(1);
scriptView.setText(text);
scriptView.setBackgroundColor(Color.parseColor("#e0e0e0"));
return scriptView;
}
}
1 change: 1 addition & 0 deletions chrome/android/java_sources.gni
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetCoordinator.java",
"java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetViewBinder.java",
"java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java",
"java/src/org/chromium/chrome/browser/autofill_assistant/BottomBarController.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/AppBannerUiDelegateAndroid.java",
Expand Down
15 changes: 15 additions & 0 deletions chrome/browser/android/autofill_assistant/ui_controller_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "chrome/browser/android/autofill_assistant/ui_controller_android.h"

#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/command_line.h"
#include "chrome/common/channel_info.h"
Expand Down Expand Up @@ -60,6 +61,20 @@ void UiControllerAndroid::HideOverlay() {
AttachCurrentThread(), java_autofill_assistant_ui_controller_);
}

void UiControllerAndroid::UpdateScripts(
const std::vector<ScriptHandle>& scripts) {
// TODO(crbug.com/806868): Pass the handles directly instead of the path.
std::vector<std::string> script_paths;
for (const auto& script : scripts) {
script_paths.emplace_back(script.path);
}

JNIEnv* env = AttachCurrentThread();
auto jscripts = base::android::ToJavaArrayOfStrings(env, script_paths);
Java_AutofillAssistantUiController_onUpdateScripts(
env, java_autofill_assistant_ui_controller_, jscripts);
}

void UiControllerAndroid::ChooseAddress(
base::OnceCallback<void(const std::string&)> callback) {
// TODO(crbug.com/806868): Implement ChooseAddress.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class UiControllerAndroid : public UiController, public Client {
void ShowStatusMessage(const std::string& message) override;
void ShowOverlay() override;
void HideOverlay() override;
void UpdateScripts(const std::vector<ScriptHandle>& scripts) override;
void ChooseAddress(
base::OnceCallback<void(const std::string&)> callback) override;
void ChooseCard(
Expand Down
11 changes: 8 additions & 3 deletions components/autofill_assistant/browser/controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,14 @@ void Controller::OnDestroy() {
delete this;
}

void Controller::OnRunnableScriptsChanged() {
// TODO(crbug.com/806868): Take the set of runnable script from the tracker
// and make them available for selection. Run the selected script.
void Controller::OnRunnableScriptsChanged(
const std::vector<ScriptHandle>& runnable_scripts) {
// Script selection is disabled when a script is already running. We will
// check again and maybe update when the current script has finished.
if (script_tracker_->running())
return;

GetUiController()->UpdateScripts(runnable_scripts);
}

void Controller::DidFinishLoad(content::RenderFrameHost* render_frame_host,
Expand Down
3 changes: 2 additions & 1 deletion components/autofill_assistant/browser/controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ class Controller : public ScriptExecutorDelegate,
void OnDestroy() override;

// Overrides ScriptTracker::Listener:
void OnRunnableScriptsChanged() override;
void OnRunnableScriptsChanged(
const std::vector<ScriptHandle>& runnable_scripts) override;

// Overrides content::WebContentsObserver:
void DidFinishLoad(content::RenderFrameHost* render_frame_host,
Expand Down
2 changes: 2 additions & 0 deletions components/autofill_assistant/browser/mock_ui_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_MOCK_UI_CONTROLLER_H_

#include "base/callback.h"
#include "components/autofill_assistant/browser/script.h"
#include "components/autofill_assistant/browser/ui_controller.h"
#include "testing/gmock/include/gmock/gmock.h"

Expand All @@ -20,6 +21,7 @@ class MockUiController : public UiController {
MOCK_METHOD1(ShowStatusMessage, void(const std::string& message));
MOCK_METHOD0(ShowOverlay, void());
MOCK_METHOD0(HideOverlay, void());
MOCK_METHOD1(UpdateScripts, void(const std::vector<ScriptHandle>& scripts));

void ChooseAddress(
base::OnceCallback<void(const std::string&)> callback) override {
Expand Down
2 changes: 1 addition & 1 deletion components/autofill_assistant/browser/script_tracker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ void ScriptTracker::UpdateRunnableScriptsIfNecessary() {
pending_runnable_scripts_.clear();

if (runnables_changed)
listener_->OnRunnableScriptsChanged();
listener_->OnRunnableScriptsChanged(runnable_scripts_);
}

bool ScriptTracker::RunnablesHaveChanged() {
Expand Down
12 changes: 4 additions & 8 deletions components/autofill_assistant/browser/script_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ class ScriptTracker {
public:
virtual ~Listener() = default;

// Called when the set of runnable scripts have changed.
virtual void OnRunnableScriptsChanged() = 0;
// Called when the set of runnable scripts have changed. |runnable_scripts|
// are the new runnable scripts.
virtual void OnRunnableScriptsChanged(
const std::vector<ScriptHandle>& runnable_scripts) = 0;
};

// |delegate| and |listener| should outlive this object and should not be
Expand Down Expand Up @@ -66,12 +68,6 @@ class ScriptTracker {
private:
friend ScriptTrackerTest;

// Returns a set of scripts that can be run, according to the last round of
// checks.
const std::vector<ScriptHandle>& runnable_scripts() const {
return runnable_scripts_;
}

void OnScriptRun(base::OnceCallback<void(bool)> original_callback,
bool success);
void UpdateRunnableScriptsIfNecessary();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ class ScriptTrackerTest : public testing::Test,
ClientMemory* GetClientMemory() override { return &client_memory_; }

// Overrides ScriptTracker::Listener
void OnRunnableScriptsChanged() override { runnable_scripts_changed_++; }
void OnRunnableScriptsChanged(
const std::vector<ScriptHandle>& runnable_scripts) override {
runnable_scripts_changed_++;
runnable_scripts_ = runnable_scripts;
}

void SetAndCheckScripts(const SupportsScriptResponseProto& response) {
std::string response_str;
Expand All @@ -77,7 +81,7 @@ class ScriptTrackerTest : public testing::Test,
}

const std::vector<ScriptHandle>& runnable_scripts() {
return tracker_.runnable_scripts();
return runnable_scripts_;
}

NiceMock<MockService> mock_service_;
Expand All @@ -87,6 +91,7 @@ class ScriptTrackerTest : public testing::Test,

// Number of times OnRunnableScriptsChanged was called.
int runnable_scripts_changed_;
std::vector<ScriptHandle> runnable_scripts_;
ScriptTracker tracker_;
};

Expand Down
5 changes: 5 additions & 0 deletions components/autofill_assistant/browser/ui_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "base/callback_forward.h"

namespace autofill_assistant {
struct ScriptHandle;

// Controller to control autofill assistant UI.
class UiController {
public:
Expand All @@ -29,6 +31,9 @@ class UiController {
// Hide the overlay.
virtual void HideOverlay() = 0;

// Update the list of scripts in the UI.
virtual void UpdateScripts(const std::vector<ScriptHandle>& scripts) = 0;

// Show UI to ask user to choose an address in personal data manager. GUID of
// the chosen address will be returned through callback if succeed, otherwise
// empty string is returned.
Expand Down

0 comments on commit e8ca310

Please sign in to comment.