Commit 8c6ef8bd authored by gogerald's avatar gogerald Committed by Commit Bot

[Autofill Assistant] Add initial accessibility messages

Changes:
1, make init screen focusable so as to read it's content for accessibility
2, announce first run experience is shown and autofill assistant is available
3, announce autofill assistant message
4, do not show autofill assistant bottom bar when showing init screen.
5, move the functions around in controller.cc to match their declaration order.

Bug: 806868
Change-Id: I7376ef905d3e7dc7f9949557f1307cb07ed28c95
Reviewed-on: https://chromium-review.googlesource.com/c/1351649
Commit-Queue: Ganggui Tang <gogerald@chromium.org>
Reviewed-by: default avatarMathias Carlen <mcarlen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611490}
parent 5a42aa21
...@@ -40,15 +40,11 @@ public class AutofillAssistantFacade { ...@@ -40,15 +40,11 @@ public class AutofillAssistantFacade {
AutofillAssistantUiController controller = AutofillAssistantUiController controller =
new AutofillAssistantUiController(activity, parameters); new AutofillAssistantUiController(activity, parameters);
AutofillAssistantUiDelegate uiDelegate = UiDelegateHolder delegateHolder = new UiDelegateHolder(
new AutofillAssistantUiDelegate(activity, controller); controller, new AutofillAssistantUiDelegate(activity, controller));
UiDelegateHolder delegateHolder = new UiDelegateHolder(controller, uiDelegate);
controller.setUiDelegateHolder(delegateHolder);
initTabObservers(activity, delegateHolder); initTabObservers(activity, delegateHolder);
controller.maybeUpdateDetails(Details.makeFromParameters(parameters)); controller.start(delegateHolder, Details.makeFromParameters(parameters));
uiDelegate.startOrSkipInitScreen();
} }
private static void initTabObservers(ChromeActivity activity, UiDelegateHolder delegateHolder) { private static void initTabObservers(ChromeActivity activity, UiDelegateHolder delegateHolder) {
......
...@@ -89,13 +89,17 @@ public class AutofillAssistantUiController implements AutofillAssistantUiDelegat ...@@ -89,13 +89,17 @@ public class AutofillAssistantUiController implements AutofillAssistantUiDelegat
parameters.get(PARAMETER_USER_EMAIL), activity.getInitialIntent().getExtras()); parameters.get(PARAMETER_USER_EMAIL), activity.getInitialIntent().getExtras());
} }
void setUiDelegateHolder(UiDelegateHolder uiDelegateHolder) { void start(UiDelegateHolder uiDelegateHolder, Details details) {
mUiDelegateHolder = uiDelegateHolder; mUiDelegateHolder = uiDelegateHolder;
// Do not show details until 'onInitOk'.
mCurrentDetails = details;
mUiDelegateHolder.startOrSkipInitScreen();
} }
@Override @Override
public void onInitOk() { public void onInitOk() {
assert mUiDelegateHolder != null; assert mUiDelegateHolder != null;
mUiDelegateHolder.performUiOperation(uiDelegate -> uiDelegate.showDetails(mCurrentDetails));
nativeStart(mUiControllerAndroid, mInitialUrl); nativeStart(mUiControllerAndroid, mInitialUrl);
} }
......
...@@ -315,6 +315,7 @@ class AutofillAssistantUiDelegate { ...@@ -315,6 +315,7 @@ class AutofillAssistantUiDelegate {
public void showStatusMessage(@Nullable String message) { public void showStatusMessage(@Nullable String message) {
show(); show();
mStatusMessageView.setText(message); mStatusMessageView.setText(message);
mStatusMessageView.announceForAccessibility(message);
} }
/** /**
...@@ -435,6 +436,10 @@ class AutofillAssistantUiDelegate { ...@@ -435,6 +436,10 @@ class AutofillAssistantUiDelegate {
mActivity.getActivityTab().getWebContents()); mActivity.getActivityTab().getWebContents());
mFullContainer.setVisibility(View.VISIBLE); mFullContainer.setVisibility(View.VISIBLE);
// Announce Autofill Assistant is available for accessibility.
mBottomBar.announceForAccessibility(
mActivity.getString(R.string.autofill_assistant_available_accessibility));
// Set the initial progress. It is OK to make multiple calls to this method as it will // Set the initial progress. It is OK to make multiple calls to this method as it will
// have an effect only on the first one. // have an effect only on the first one.
mProgressBar.maybeIncreaseProgress(PROGRESS_BAR_INITIAL_PROGRESS); mProgressBar.maybeIncreaseProgress(PROGRESS_BAR_INITIAL_PROGRESS);
...@@ -775,6 +780,8 @@ class AutofillAssistantUiDelegate { ...@@ -775,6 +780,8 @@ class AutofillAssistantUiDelegate {
View initView = LayoutInflater.from(mActivity) View initView = LayoutInflater.from(mActivity)
.inflate(R.layout.init_screen, mCoordinatorView) .inflate(R.layout.init_screen, mCoordinatorView)
.findViewById(R.id.init_screen); .findViewById(R.id.init_screen);
// Set focusable for accessibility.
initView.findViewById(R.id.init).setFocusable(true);
// Set default state to checked. // Set default state to checked.
((CheckBox) initView.findViewById(R.id.checkbox_dont_show_init_again)).setChecked(true); ((CheckBox) initView.findViewById(R.id.checkbox_dont_show_init_again)).setChecked(true);
...@@ -782,6 +789,8 @@ class AutofillAssistantUiDelegate { ...@@ -782,6 +789,8 @@ class AutofillAssistantUiDelegate {
.setOnClickListener(unusedView -> onInitClicked(true, initView)); .setOnClickListener(unusedView -> onInitClicked(true, initView));
initView.findViewById(R.id.button_init_not_ok) initView.findViewById(R.id.button_init_not_ok)
.setOnClickListener(unusedView -> onInitClicked(false, initView)); .setOnClickListener(unusedView -> onInitClicked(false, initView));
initView.announceForAccessibility(
mActivity.getString(R.string.autofill_assistant_first_run_accessibility));
} }
private void onInitClicked(boolean accept, View initView) { private void onInitClicked(boolean accept, View initView) {
......
...@@ -35,6 +35,13 @@ class UiDelegateHolder { ...@@ -35,6 +35,13 @@ class UiDelegateHolder {
mUiDelegate = uiDelegate; mUiDelegate = uiDelegate;
} }
/**
* Starts the init screen unless it has been marked to be skipped.
*/
public void startOrSkipInitScreen() {
mUiDelegate.startOrSkipInitScreen();
}
/** /**
* Perform a UI operation: * Perform a UI operation:
* - directly if we are not in a pause state. * - directly if we are not in a pause state.
......
...@@ -142,40 +142,7 @@ Controller::~Controller() { ...@@ -142,40 +142,7 @@ Controller::~Controller() {
} }
} }
void Controller::Start(const GURL& initialUrl) {
DCHECK(initialUrl.is_valid());
GetOrCheckScripts(initialUrl);
if (allow_autostart_) {
auto iter = parameters_->find(kCallerScriptParameterName);
// TODO(crbug.com/806868): Put back an explicit AUTOSTART parameter so we
// don't need to know who calls us.
if (iter != parameters_->end() && iter->second == "1") {
should_fail_after_checking_scripts_ = true;
GetUiController()->ShowOverlay();
GetUiController()->ShowStatusMessage(l10n_util::GetStringFUTF8(
IDS_AUTOFILL_ASSISTANT_LOADING,
base::UTF8ToUTF16(web_contents()->GetVisibleURL().host())));
}
}
touchable_element_area_.SetOnUpdate(base::BindRepeating(
&UiController::UpdateTouchableArea,
// Unretained is safe, since touchable_element_area_ is guaranteed to be
// deleted before the UI controller.
base::Unretained(GetUiController())));
}
void Controller::GetOrCheckScripts(const GURL& url) { void Controller::GetOrCheckScripts(const GURL& url) {
if (IsCookieExperimentEnabled() && !started_) {
GetWebController()->HasCookie(
base::BindOnce(&Controller::OnGetCookie,
// WebController is owned by Controller.
base::Unretained(this), url));
return;
} else {
started_ = true;
}
if (!started_ || script_tracker_->running()) { if (!started_ || script_tracker_->running()) {
return; return;
} }
...@@ -364,11 +331,6 @@ bool Controller::MaybeAutostartScript( ...@@ -364,11 +331,6 @@ bool Controller::MaybeAutostartScript(
return false; return false;
} }
void Controller::OnClickOverlay() {
GetUiController()->HideOverlay();
// TODO(crbug.com/806868): Stop executing scripts.
}
void Controller::OnGetCookie(const GURL& initial_url, bool has_cookie) { void Controller::OnGetCookie(const GURL& initial_url, bool has_cookie) {
if (has_cookie) { if (has_cookie) {
// This code is only active with the experiment parameter. // This code is only active with the experiment parameter.
...@@ -386,38 +348,47 @@ void Controller::OnGetCookie(const GURL& initial_url, bool has_cookie) { ...@@ -386,38 +348,47 @@ void Controller::OnGetCookie(const GURL& initial_url, bool has_cookie) {
void Controller::OnSetCookie(const GURL& initial_url, bool result) { void Controller::OnSetCookie(const GURL& initial_url, bool result) {
DCHECK(result) << "Setting cookie failed"; DCHECK(result) << "Setting cookie failed";
// Failing to set the cookie should not be fatal since it would prevent FinishStart(initial_url);
// checking for available scripts.
started_ = true;
// Kick off another check scripts run since we may have blocked the first one.
GetOrCheckScripts(initial_url);
} }
void Controller::OnScriptSelected(const std::string& script_path) { void Controller::FinishStart(const GURL& initial_url) {
DCHECK(!script_path.empty()); started_ = true;
GetOrCheckScripts(initial_url);
// This is a script selected from the UI, so it should disable autostart. if (allow_autostart_) {
allow_autostart_ = false; auto iter = parameters_->find(kCallerScriptParameterName);
// TODO(crbug.com/806868): Put back an explicit AUTOSTART parameter so we
// don't need to know who calls us.
if (iter != parameters_->end() && iter->second == "1") {
should_fail_after_checking_scripts_ = true;
GetUiController()->ShowOverlay();
GetUiController()->ShowStatusMessage(l10n_util::GetStringFUTF8(
IDS_AUTOFILL_ASSISTANT_LOADING,
base::UTF8ToUTF16(web_contents()->GetVisibleURL().host())));
}
}
ExecuteScript(script_path); touchable_element_area_.SetOnUpdate(base::BindRepeating(
&UiController::UpdateTouchableArea,
// Unretained is safe, since touchable_element_area_ is guaranteed to be
// deleted before the UI controller.
base::Unretained(GetUiController())));
} }
std::string Controller::GetDebugContext() { void Controller::Start(const GURL& initialUrl) {
base::Value dict(base::Value::Type::DICTIONARY); DCHECK(initialUrl.is_valid());
if (IsCookieExperimentEnabled()) {
std::vector<base::Value> parameters_js; GetWebController()->HasCookie(
for (const auto& entry : *parameters_) { base::BindOnce(&Controller::OnGetCookie,
base::Value parameter_js = base::Value(base::Value::Type::DICTIONARY); // WebController is owned by Controller.
parameter_js.SetKey(entry.first, base::Value(entry.second)); base::Unretained(this), initialUrl));
parameters_js.push_back(std::move(parameter_js)); } else {
FinishStart(initialUrl);
} }
dict.SetKey("parameters", base::Value(parameters_js)); }
dict.SetKey("scripts", script_tracker_->GetDebugContext());
std::string output_js; void Controller::OnClickOverlay() {
base::JSONWriter::Write(dict, &output_js); GetUiController()->HideOverlay();
return output_js; // TODO(crbug.com/806868): Stop executing scripts.
} }
void Controller::OnDestroy() { void Controller::OnDestroy() {
...@@ -429,6 +400,15 @@ bool Controller::Terminate() { ...@@ -429,6 +400,15 @@ bool Controller::Terminate() {
return script_tracker_->Terminate(); return script_tracker_->Terminate();
} }
void Controller::OnScriptSelected(const std::string& script_path) {
DCHECK(!script_path.empty());
// This is a script selected from the UI, so it should disable autostart.
allow_autostart_ = false;
ExecuteScript(script_path);
}
void Controller::ScrollBy(float distanceXRatio, float distanceYRatio) { void Controller::ScrollBy(float distanceXRatio, float distanceYRatio) {
GetWebController()->ScrollBy(distanceXRatio, distanceYRatio); GetWebController()->ScrollBy(distanceXRatio, distanceYRatio);
touchable_element_area_.UpdatePositions(); touchable_element_area_.UpdatePositions();
...@@ -438,23 +418,21 @@ void Controller::UpdateTouchableArea() { ...@@ -438,23 +418,21 @@ void Controller::UpdateTouchableArea() {
touchable_element_area_.UpdatePositions(); touchable_element_area_.UpdatePositions();
} }
void Controller::DidAttachInterstitialPage() { std::string Controller::GetDebugContext() {
GetUiController()->Shutdown(); base::Value dict(base::Value::Type::DICTIONARY);
}
void Controller::DidGetUserInteraction(const blink::WebInputEvent::Type type) {
switch (type) {
case blink::WebInputEvent::kTouchStart:
case blink::WebInputEvent::kGestureTapDown:
if (!script_tracker_->running()) {
script_tracker_->CheckScripts(kPeriodicScriptCheckInterval);
StartPeriodicScriptChecks();
}
break;
default: std::vector<base::Value> parameters_js;
break; for (const auto& entry : *parameters_) {
base::Value parameter_js = base::Value(base::Value::Type::DICTIONARY);
parameter_js.SetKey(entry.first, base::Value(entry.second));
parameters_js.push_back(std::move(parameter_js));
} }
dict.SetKey("parameters", base::Value(parameters_js));
dict.SetKey("scripts", script_tracker_->GetDebugContext());
std::string output_js;
base::JSONWriter::Write(dict, &output_js);
return output_js;
} }
void Controller::OnNoRunnableScriptsAnymore() { void Controller::OnNoRunnableScriptsAnymore() {
...@@ -502,8 +480,23 @@ void Controller::OnRunnableScriptsChanged( ...@@ -502,8 +480,23 @@ void Controller::OnRunnableScriptsChanged(
GetUiController()->UpdateScripts(scripts_to_update); GetUiController()->UpdateScripts(scripts_to_update);
} }
void Controller::DocumentAvailableInMainFrame() { void Controller::DidAttachInterstitialPage() {
GetOrCheckScripts(web_contents()->GetLastCommittedURL()); GetUiController()->Shutdown();
}
void Controller::DidGetUserInteraction(const blink::WebInputEvent::Type type) {
switch (type) {
case blink::WebInputEvent::kTouchStart:
case blink::WebInputEvent::kGestureTapDown:
if (!script_tracker_->running()) {
script_tracker_->CheckScripts(kPeriodicScriptCheckInterval);
StartPeriodicScriptChecks();
}
break;
default:
break;
}
} }
void Controller::DidFinishLoad(content::RenderFrameHost* render_frame_host, void Controller::DidFinishLoad(content::RenderFrameHost* render_frame_host,
...@@ -550,6 +543,10 @@ void Controller::DidStartNavigation( ...@@ -550,6 +543,10 @@ void Controller::DidStartNavigation(
} }
} }
void Controller::DocumentAvailableInMainFrame() {
GetOrCheckScripts(web_contents()->GetLastCommittedURL());
}
void Controller::RenderProcessGone(base::TerminationStatus status) { void Controller::RenderProcessGone(base::TerminationStatus status) {
GetUiController()->Shutdown(); GetUiController()->Shutdown();
} }
......
...@@ -97,8 +97,9 @@ class Controller : public ScriptExecutorDelegate, ...@@ -97,8 +97,9 @@ class Controller : public ScriptExecutorDelegate,
// a script terminated with a Stop action. // a script terminated with a Stop action.
void OnGetCookie(const GURL& initial_url, bool has_cookie); void OnGetCookie(const GURL& initial_url, bool has_cookie);
void OnSetCookie(const GURL& initial_url, bool result); void OnSetCookie(const GURL& initial_url, bool result);
void FinishStart(const GURL& initial_url);
// Overrides content::UiDelegate: // Overrides autofill_assistant::UiDelegate:
void Start(const GURL& initialUrl) override; void Start(const GURL& initialUrl) override;
void OnClickOverlay() override; void OnClickOverlay() override;
void OnDestroy() override; void OnDestroy() override;
...@@ -158,6 +159,7 @@ class Controller : public ScriptExecutorDelegate, ...@@ -158,6 +159,7 @@ class Controller : public ScriptExecutorDelegate,
// elements. // elements.
ElementArea touchable_element_area_; ElementArea touchable_element_area_;
// Flag indicates whether it is ready to fetch and execute scripts.
bool started_ = false; bool started_ = false;
base::WeakPtrFactory<Controller> weak_ptr_factory_; base::WeakPtrFactory<Controller> weak_ptr_factory_;
......
...@@ -28,5 +28,11 @@ ...@@ -28,5 +28,11 @@
<message name="IDS_AUTOFILL_ASSISTANT_DETAILS_DIFFER_GO_BACK" desc="Shown on a button allowing going back when details differ." formatter_data="android_java"> <message name="IDS_AUTOFILL_ASSISTANT_DETAILS_DIFFER_GO_BACK" desc="Shown on a button allowing going back when details differ." formatter_data="android_java">
Go back Go back
</message> </message>
<message name="IDS_AUTOFILL_ASSISTANT_FIRST_RUN_ACCESSIBILITY" desc="Accessibility description of Autofill Assistant first run screen is shown." formatter_data="android_java">
Autofill assistant first run screen is shown
</message>
<message name="IDS_AUTOFILL_ASSISTANT_AVAILABLE_ACCESSIBILITY" desc="Accessibility description of Autofill Assistant is available." formatter_data="android_java">
Autofill assistant is available near bottom of the screen
</message>
</if> </if>
</grit-part> </grit-part>
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