Commit 38f6dc3b authored by gogerald's avatar gogerald Committed by Commit Bot

[Autofill Assistant] Introduce basic UI

Will style it more in the upcoming CLs

Screenshot
https://drive.google.com/file/d/1h50bgzIvVkZMjsjbYDel97P1JrBfWDj4/view?usp=sharing

Bug: 806868
Change-Id: Ib6ba1d040302b90f36bcd16726fca833b1f1b167
Reviewed-on: https://chromium-review.googlesource.com/1234020
Commit-Queue: Ganggui Tang <gogerald@chromium.org>
Reviewed-by: default avatarTheresa <twellington@chromium.org>
Cr-Commit-Position: refs/heads/master@{#592873}
parent 9a92e396
<?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. -->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:gravity="center_vertical"
android:minHeight="40dp"
android:singleLine="true"
android:background="@drawable/chip_bg" />
<?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"
android:id="@+id/autofill_assistant"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible"
android:gravity="bottom">
<LinearLayout
android:id="@+id/overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:clickable="true"
android:focusable="false"
android:orientation="vertical">
<ProgressBar
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="16dp"
android:indeterminate="true" />
<TextView
android:id="@+id/overlay_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_horizontal" />
</LinearLayout>
<LinearLayout
android:id="@+id/bottombar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@drawable/popup_bg_bottom"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_marginTop="8dp"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:orientation="horizontal">
<android.support.v7.widget.AppCompatImageView
android:layout_width="24dp"
android:layout_height="24dp"
app:srcCompat="@drawable/chrome_sync_logo" />
<TextView
android:id="@+id/status_message"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:paddingStart="24dp"
android:maxLines="1"
android:layout_weight="1.0"/>
<ImageButton
android:id="@+id/feedback_button"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="12dp"
android:src="@drawable/help_outline"
android:tint="@color/modern_grey_400"
android:background="?attr/selectableItemBackground"
android:contentDescription="@string/menu_send_feedback" />
<ImageButton
android:id="@+id/close_button"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/btn_delete_24dp"
android:tint="@color/modern_grey_400"
android:background="?attr/selectableItemBackground"
android:contentDescription="@string/close" />
</LinearLayout>
<ViewStub
android:id="@+id/details"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:scrollbars="none">
<LinearLayout
android:id="@+id/carousel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:gravity="center_vertical"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
</FrameLayout>
...@@ -26,13 +26,13 @@ import java.util.Map; ...@@ -26,13 +26,13 @@ import java.util.Map;
* Autofill Assistant related UIs and forward UI events to native side. * Autofill Assistant related UIs and forward UI events to native side.
*/ */
@JNINamespace("autofill_assistant") @JNINamespace("autofill_assistant")
public class AutofillAssistantUiController implements BottomBarController.Client { public class AutofillAssistantUiController implements AutofillAssistantUiDelegate.Client {
/** Prefix for Intent extras relevant to this feature. */ /** Prefix for Intent extras relevant to this feature. */
private static final String INTENT_EXTRA_PREFIX = private static final String INTENT_EXTRA_PREFIX =
"org.chromium.chrome.browser.autofill_assistant."; "org.chromium.chrome.browser.autofill_assistant.";
private final long mUiControllerAndroid; private final long mUiControllerAndroid;
private final BottomBarController mBottomBarController; private final AutofillAssistantUiDelegate mUiDelegate;
/** /**
* Construct Autofill Assistant UI controller. * Construct Autofill Assistant UI controller.
...@@ -40,7 +40,6 @@ public class AutofillAssistantUiController implements BottomBarController.Client ...@@ -40,7 +40,6 @@ public class AutofillAssistantUiController implements BottomBarController.Client
* @param activity The CustomTabActivity of the controller associated with. * @param activity The CustomTabActivity of the controller associated with.
*/ */
public AutofillAssistantUiController(CustomTabActivity activity) { public AutofillAssistantUiController(CustomTabActivity activity) {
// TODO(crbug.com/806868): Implement corresponding UI.
Tab activityTab = activity.getActivityTab(); Tab activityTab = activity.getActivityTab();
Map<String, String> parameters = extractParameters(activity.getInitialIntent().getExtras()); Map<String, String> parameters = extractParameters(activity.getInitialIntent().getExtras());
...@@ -77,7 +76,12 @@ public class AutofillAssistantUiController implements BottomBarController.Client ...@@ -77,7 +76,12 @@ public class AutofillAssistantUiController implements BottomBarController.Client
} }
}); });
mBottomBarController = new BottomBarController(activity, this); mUiDelegate = new AutofillAssistantUiDelegate(activity, this);
}
@Override
public void onDismiss() {
nativeDestroy(mUiControllerAndroid);
} }
@Override @Override
...@@ -96,29 +100,35 @@ public class AutofillAssistantUiController implements BottomBarController.Client ...@@ -96,29 +100,35 @@ public class AutofillAssistantUiController implements BottomBarController.Client
return result; return result;
} }
@Override
public void onClickOverlay() {
// TODO(crbug.com/806868): Notify native side.
}
@CalledByNative @CalledByNative
private void onShowStatusMessage(String message) { private void onShowStatusMessage(String message) {
mBottomBarController.showStatusMessage(message); mUiDelegate.showStatusMessage(message);
} }
@CalledByNative @CalledByNative
private void onShowOverlay() { private void onShowOverlay() {
// TODO(crbug.com/806868): Implement corresponding UI. mUiDelegate.showOverlay();
} }
@CalledByNative @CalledByNative
private void onHideOverlay() { private void onHideOverlay() {
// TODO(crbug.com/806868): Implement corresponding UI. mUiDelegate.hideOverlay();
} }
@CalledByNative @CalledByNative
private void onUpdateScripts(String[] scriptNames, String[] scriptPaths) { private void onUpdateScripts(String[] scriptNames, String[] scriptPaths) {
List<BottomBarController.ScriptHandle> scriptHandles = new ArrayList<>(); List<AutofillAssistantUiDelegate.ScriptHandle> scriptHandles = new ArrayList<>();
// Note that scriptNames and scriptPaths are one-on-one matched by index. // Note that scriptNames and scriptPaths are one-on-one matched by index.
for (int i = 0; i < scriptNames.length; i++) { for (int i = 0; i < scriptNames.length; i++) {
scriptHandles.add(new BottomBarController.ScriptHandle(scriptNames[i], scriptPaths[i])); scriptHandles.add(
new AutofillAssistantUiDelegate.ScriptHandle(scriptNames[i], scriptPaths[i]));
} }
mBottomBarController.updateScripts(scriptHandles); mUiDelegate.updateScripts(scriptHandles);
} }
// native methods. // native methods.
......
...@@ -5,12 +5,9 @@ ...@@ -5,12 +5,9 @@
package org.chromium.chrome.browser.autofill_assistant; package org.chromium.chrome.browser.autofill_assistant;
import android.app.Activity; import android.app.Activity;
import android.graphics.Color; import android.view.LayoutInflater;
import android.support.design.widget.CoordinatorLayout; import android.view.View;
import android.view.Gravity;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
...@@ -20,15 +17,15 @@ import java.util.List; ...@@ -20,15 +17,15 @@ import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;
/** Controller to interact with the bottom bar. */ /** Delegate to interact with the assistant UI. */
class BottomBarController { class AutofillAssistantUiDelegate {
private static final String SCRIPTS_STATUS_MESSAGE = "Scripts";
private final Activity mActivity; private final Activity mActivity;
private final Client mClient; private final Client mClient;
private final View mFullContainer;
private final View mOverlay;
private final LinearLayout mBottomBar; private final LinearLayout mBottomBar;
private ViewGroup mScriptsViewContainer; private final ViewGroup mScriptsViewContainer;
private TextView mStatusMessageView; private final TextView mStatusMessageView;
/** /**
* This is a client interface that relays interactions from the UI. * This is a client interface that relays interactions from the UI.
...@@ -36,6 +33,16 @@ class BottomBarController { ...@@ -36,6 +33,16 @@ class BottomBarController {
* Java version of the native autofill_assistant::UiDelegate. * Java version of the native autofill_assistant::UiDelegate.
*/ */
public interface Client { public interface Client {
/**
* Called when clicking on the overlay.
*/
void onClickOverlay();
/**
* Called when the bottom bar is dismissing.
*/
void onDismiss();
/** /**
* Called when a script has been selected. * Called when a script has been selected.
* *
...@@ -71,23 +78,46 @@ class BottomBarController { ...@@ -71,23 +78,46 @@ class BottomBarController {
} }
/** /**
* Constructs a bottom bar. * Constructs an assistant UI delegate.
* *
* @param activity The Activity * @param activity The Activity
* @param client The client to forward events to * @param client The client to forward events to
*/ */
public BottomBarController(Activity activity, Client client) { public AutofillAssistantUiDelegate(Activity activity, Client client) {
mActivity = activity; mActivity = activity;
mClient = client; mClient = client;
mBottomBar = createBottomBar(); mFullContainer = LayoutInflater.from(mActivity)
((ViewGroup) mActivity.findViewById(R.id.coordinator)).addView(mBottomBar); .inflate(R.layout.autofill_assistant_sheet,
((ViewGroup) mActivity.findViewById(R.id.coordinator)))
CoordinatorLayout.LayoutParams params = .findViewById(R.id.autofill_assistant);
(CoordinatorLayout.LayoutParams) mBottomBar.getLayoutParams(); // TODO(crbug.com/806868): Set hint text on overlay.
params.gravity = Gravity.BOTTOM; mOverlay = mFullContainer.findViewById(R.id.overlay);
mOverlay.setOnClickListener(new View.OnClickListener() {
showStatusMessage(SCRIPTS_STATUS_MESSAGE); @Override
public void onClick(View v) {
mClient.onClickOverlay();
}
});
mBottomBar = mFullContainer.findViewById(R.id.bottombar);
mBottomBar.findViewById(R.id.close_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mFullContainer.setVisibility(View.GONE);
mClient.onDismiss();
}
});
mBottomBar.findViewById(R.id.feedback_button)
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO(crbug.com/806868): Send feedback.
}
});
mScriptsViewContainer = mBottomBar.findViewById(R.id.carousel);
mStatusMessageView = mBottomBar.findViewById(R.id.status_message);
// TODO(crbug.com/806868): Listen for contextual search shown so as to hide this UI.
} }
/** /**
...@@ -96,6 +126,8 @@ class BottomBarController { ...@@ -96,6 +126,8 @@ class BottomBarController {
* @param message Message to display. * @param message Message to display.
*/ */
public void showStatusMessage(@Nullable String message) { public void showStatusMessage(@Nullable String message) {
if (!mFullContainer.isShown()) mFullContainer.setVisibility(View.VISIBLE);
mStatusMessageView.setText(message); mStatusMessageView.setText(message);
} }
...@@ -106,71 +138,30 @@ class BottomBarController { ...@@ -106,71 +138,30 @@ class BottomBarController {
*/ */
public void updateScripts(List<ScriptHandle> scriptHandles) { public void updateScripts(List<ScriptHandle> scriptHandles) {
mScriptsViewContainer.removeAllViews(); mScriptsViewContainer.removeAllViews();
if (scriptHandles.isEmpty()) { if (scriptHandles.isEmpty()) {
return; return;
} }
for (ScriptHandle scriptHandle : scriptHandles) { for (ScriptHandle scriptHandle : scriptHandles) {
TextView scriptView = createScriptView(scriptHandle.getName()); TextView scriptView = (TextView) (LayoutInflater.from(mActivity).inflate(
R.layout.autofill_assistant_chip, null));
scriptView.setText(scriptHandle.getName());
scriptView.setOnClickListener( scriptView.setOnClickListener(
(unusedView) -> { mClient.onScriptSelected(scriptHandle.getPath()); }); (unusedView) -> { mClient.onScriptSelected(scriptHandle.getPath()); });
mScriptsViewContainer.addView(scriptView); mScriptsViewContainer.addView(scriptView);
} }
}
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() { if (!mFullContainer.isShown()) mFullContainer.setVisibility(View.VISIBLE);
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) { /** Called to show overlay. */
LinearLayout layout = new LinearLayout(mActivity); public void showOverlay() {
layout.setLayoutParams(layoutParams); mOverlay.setVisibility(View.VISIBLE);
layout.setOrientation(orientation);
return layout;
} }
private TextView createScriptView(String text) { /** Called to hide overlay. */
TextView scriptView = new TextView(mActivity); public void hideOverlay() {
scriptView.setPadding(20, 20, 20, 20); mOverlay.setVisibility(View.GONE);
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;
} }
} }
...@@ -114,7 +114,7 @@ chrome_java_sources = [ ...@@ -114,7 +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/PasswordAccessorySheetCoordinator.java",
"java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetViewBinder.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/AutofillAssistantUiController.java",
"java/src/org/chromium/chrome/browser/autofill_assistant/BottomBarController.java", "java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.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",
......
...@@ -57,7 +57,6 @@ Controller::Controller( ...@@ -57,7 +57,6 @@ Controller::Controller(
memory_(std::make_unique<ClientMemory>()), memory_(std::make_unique<ClientMemory>()),
allow_autostart_(true) { allow_autostart_(true) {
GetUiController()->SetUiDelegate(this); GetUiController()->SetUiDelegate(this);
GetUiController()->ShowOverlay();
if (!web_contents->IsLoading()) { if (!web_contents->IsLoading()) {
GetOrCheckScripts(web_contents->GetLastCommittedURL()); GetOrCheckScripts(web_contents->GetLastCommittedURL());
} }
......
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