0

Reland: Dictation: Show toast when toggling Dictation fails

The original change was reverted because of failures on MSAN try
bots:
https://ci.chromium.org/ui/p/chromium/builders/ci/Linux%20ChromiumOS%20MSan%20Tests/37926/overview

The test passes consistently using many parallel jobs on a local
linux-chromeos-rel build, but I wasn't able to figure out a way to
stabilize the test for MSAN. I will disable the test on MSAN for now,
but added a TODO to address this before launching the new behavior.

Original commit description:

This change implements the behavior described in slide 7 of the UX
mocks [1]. When Dictation fails to toggle because there is no focused
text field, we now show a toast that explains why Dictation failed.
To do this we:

1. Added accessibilityPrivate.showToast(), so that the dictation
extension can request the toast to be shown.
2. Added AccessibilityNotificationController, which manages showing
the toast.

[1] https://docs.google.com/presentation/d/1mRnYcRpyzbY-EjzptCP3KRB5I7v_rM9Kl2zqhhQVZUY/edit#slide=id.g24cce1f4158_0_12

Bug: b:259352600
Change-Id: I3aac7437253aeb8423757038c763aa7ec10f7ccb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4802964
Reviewed-by: Mark Schillaci <mschillaci@google.com>
Reviewed-by: Alex Newcomer <newcomer@chromium.org>
Reviewed-by: Xiyuan Xia <xiyuan@chromium.org>
Commit-Queue: Akihiro Ota <akihiroota@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1186678}
This commit is contained in:
Akihiro Ota
2023-08-22 18:20:25 +00:00
committed by Chromium LUCI CQ
parent 19dcafbc47
commit e145b6bd3e
28 changed files with 353 additions and 19 deletions

@ -79,6 +79,8 @@ component("ash") {
"accessibility/accessibility_delegate.h",
"accessibility/accessibility_event_handler_manager.cc",
"accessibility/accessibility_event_handler_manager.h",
"accessibility/accessibility_notification_controller.cc",
"accessibility/accessibility_notification_controller.h",
"accessibility/accessibility_observer.h",
"accessibility/autoclick/autoclick_controller.cc",
"accessibility/autoclick/autoclick_controller.h",

@ -12,6 +12,7 @@
#include "ash/accelerators/accelerator_controller_impl.h"
#include "ash/accessibility/a11y_feature_type.h"
#include "ash/accessibility/accessibility_notification_controller.h"
#include "ash/accessibility/accessibility_observer.h"
#include "ash/accessibility/autoclick/autoclick_controller.h"
#include "ash/accessibility/dictation_nudge_controller.h"
@ -969,10 +970,14 @@ AccessibilityControllerImpl::AccessibilityControllerImpl()
Shell::Get()->session_controller()->AddObserver(this);
Shell::Get()->tablet_mode_controller()->AddObserver(this);
CreateAccessibilityFeatures();
accessibility_notification_controller_ =
std::make_unique<AccessibilityNotificationController>();
}
AccessibilityControllerImpl::~AccessibilityControllerImpl() {
floating_menu_controller_.reset();
accessibility_notification_controller_.reset();
}
void AccessibilityControllerImpl::CreateAccessibilityFeatures() {
@ -1938,6 +1943,8 @@ void AccessibilityControllerImpl::OnDictationKeyboardDialogDismissed() {
void AccessibilityControllerImpl::ShowDictationLanguageUpgradedNudge(
const std::string& dictation_locale,
const std::string& application_locale) {
// TODO(b:259352600): Move dictation_nudge_controller_ into
// accessibility_notification_controller.
dictation_nudge_controller_ = std::make_unique<DictationNudgeController>(
dictation_locale, application_locale);
dictation_nudge_controller_->ShowNudge();
@ -2925,4 +2932,14 @@ AccessibilityControllerImpl::GetDictationBubbleControllerForTest() {
return dictation_bubble_controller_.get();
}
void AccessibilityControllerImpl::ShowToast(AccessibilityToastType type) {
accessibility_notification_controller_->ShowToast(type);
}
void AccessibilityControllerImpl::AddShowToastCallbackForTesting(
base::RepeatingClosure callback) {
accessibility_notification_controller_->AddShowToastCallbackForTesting(
std::move(callback));
}
} // namespace ash

@ -8,6 +8,7 @@
#include <memory>
#include "ash/accessibility/a11y_feature_type.h"
#include "ash/accessibility/accessibility_notification_controller.h"
#include "ash/ash_export.h"
#include "ash/constants/ash_constants.h"
#include "ash/public/cpp/accessibility_controller.h"
@ -471,6 +472,7 @@ class ASH_EXPORT AccessibilityControllerImpl : public AccessibilityController,
const absl::optional<std::vector<DictationBubbleHintType>>& hints)
override;
void SilenceSpokenFeedback() override;
void ShowToast(AccessibilityToastType type) override;
// A confirmation dialog will be shown the first time an accessibility feature
// is enabled using the specified accelerator key sequence. Only one dialog
@ -534,6 +536,8 @@ class ASH_EXPORT AccessibilityControllerImpl : public AccessibilityController,
OnDictationKeyboardDialogDismissed();
}
void AddShowToastCallbackForTesting(base::RepeatingClosure callback);
private:
// Populate |features_| with the feature of the correct type.
void CreateAccessibilityFeatures();
@ -647,6 +651,10 @@ class ASH_EXPORT AccessibilityControllerImpl : public AccessibilityController,
// Used to control the Dictation bubble UI.
std::unique_ptr<DictationBubbleController> dictation_bubble_controller_;
// Used to control accessibility-related notifications.
std::unique_ptr<AccessibilityNotificationController>
accessibility_notification_controller_;
// True if ChromeVox should enable its volume slide gesture.
bool enable_chromevox_volume_slide_gesture_ = false;

@ -7,6 +7,7 @@
#include "ash/accelerators/accelerator_controller_impl.h"
#include "ash/accessibility/accessibility_controller_impl.h"
#include "ash/shell.h"
#include "base/functional/callback.h"
namespace ash {
@ -52,6 +53,12 @@ void AccessibilityControllerTestApiImpl::DismissDictationKeyboardDialog() {
->DismissDictationKeyboardDialogForTesting(); // IN-TEST
}
void AccessibilityControllerTestApiImpl::AddShowToastCallbackForTesting(
base::RepeatingClosure callback) const {
GetController()->AddShowToastCallbackForTesting(
std::move(callback)); // IN-TEST
}
// static
std::unique_ptr<AccessibilityControllerTestApi>
AccessibilityControllerTestApi::Create() {

@ -6,6 +6,7 @@
#define ASH_ACCESSIBILITY_ACCESSIBILITY_CONTROLLER_TEST_API_IMPL_H_
#include "ash/public/cpp/test/accessibility_controller_test_api.h"
#include "base/functional/callback_forward.h"
namespace ash {
@ -14,12 +15,10 @@ class AccessibilityControllerTestApiImpl
: public AccessibilityControllerTestApi {
public:
AccessibilityControllerTestApiImpl();
AccessibilityControllerTestApiImpl(
const AccessibilityControllerTestApiImpl&) = delete;
AccessibilityControllerTestApiImpl& operator=(
const AccessibilityControllerTestApiImpl&) = delete;
~AccessibilityControllerTestApiImpl() override;
// AccessibilityControllerTestApi:
@ -29,6 +28,8 @@ class AccessibilityControllerTestApiImpl
bool IsDictationKeboardDialogShowing() const override;
void AcceptDictationKeyboardDialog() override;
void DismissDictationKeyboardDialog() override;
void AddShowToastCallbackForTesting(
base::RepeatingClosure callback) const override;
};
} // namespace ash

@ -0,0 +1,56 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/accessibility/accessibility_notification_controller.h"
#include "ash/public/cpp/accessibility_controller_enums.h"
#include "ash/public/cpp/system/toast_data.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/toast/toast_manager_impl.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/base/l10n/l10n_util.h"
namespace ash {
namespace {
const std::string kAccessibilityToastId = "AccessibilityToast";
ToastData GetToastData(AccessibilityToastType type) {
switch (type) {
case AccessibilityToastType::kDictationNoFocusedTextField:
return {/*id=*/kAccessibilityToastId,
/*catalog_name=*/ToastCatalogName::kDictationNoFocusedTextField,
/*text=*/
l10n_util::GetStringUTF16(
IDS_ASH_ACCESSIBILITY_NUDGE_DICTATION_NO_FOCUSED_TEXT_FIELD)};
}
}
} // namespace
AccessibilityNotificationController::AccessibilityNotificationController() =
default;
AccessibilityNotificationController::~AccessibilityNotificationController() =
default;
void AccessibilityNotificationController::ShowToast(
AccessibilityToastType type) {
if (!::features::IsAccessibilityDictationKeyboardImprovementsEnabled()) {
return;
}
Shell::Get()->toast_manager()->Show(GetToastData(type));
if (show_anchored_nudge_callback_for_testing_) {
show_anchored_nudge_callback_for_testing_.Run();
}
}
void AccessibilityNotificationController::AddShowToastCallbackForTesting(
base::RepeatingClosure callback) {
show_anchored_nudge_callback_for_testing_ = std::move(callback);
}
} // namespace ash

@ -0,0 +1,33 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_ACCESSIBILITY_ACCESSIBILITY_NOTIFICATION_CONTROLLER_H_
#define ASH_ACCESSIBILITY_ACCESSIBILITY_NOTIFICATION_CONTROLLER_H_
#include "ash/ash_export.h"
#include "ash/public/cpp/accessibility_controller_enums.h"
#include "base/functional/callback.h"
namespace ash {
// Class that manages showing notifications for accessibility.
class ASH_EXPORT AccessibilityNotificationController {
public:
AccessibilityNotificationController();
AccessibilityNotificationController(
const AccessibilityNotificationController&) = delete;
AccessibilityNotificationController& operator=(
const AccessibilityNotificationController&) = delete;
~AccessibilityNotificationController();
void ShowToast(AccessibilityToastType type);
void AddShowToastCallbackForTesting(base::RepeatingClosure callback);
private:
base::RepeatingClosure show_anchored_nudge_callback_for_testing_;
};
} // namespace ash
#endif // ASH_ACCESSIBILITY_ACCESSIBILITY_NOTIFICATION_CONTROLLER_H_

@ -1333,6 +1333,11 @@ Style notes:
With dictation, you can type using your voice. Press the dictation key or select the microphone icon at the bottom of the screen when youre on a text field. Your dictation language is set to <ph name="language">$1<ex>English (United States)</ex></ph>. Speech is sent to Google for processing. You can change the dictation language anytime in Settings > Accessibility.
</message>
<!-- Accessibility nudges -->
<message name="IDS_ASH_ACCESSIBILITY_NUDGE_DICTATION_NO_FOCUSED_TEXT_FIELD" desc="Displayed in a nudge when Dictation is stopped automatically because there is no focused text field.">
Go to a text field to use Dictation
</message>
<message name="IDS_ASH_STATUS_TRAY_ACCESSIBILITY_VIRTUAL_KEYBOARD" desc="The label used in the accessibility menu of the system tray to toggle on/off the onscreen keyboard.">
On-screen keyboard
</message>

@ -0,0 +1 @@
cc8d39b5868c8f202c7edc14eedd27e7e64855dd

@ -273,7 +273,8 @@ enum class ToastCatalogName {
kCopyGifToClipboardAction = 42,
// [Deprecated] kVideoConferenceTrayUseWhileDisabled = 43,
kBatterySaverDisabled = 44,
kMaxValue = kBatterySaverDisabled
kDictationNoFocusedTextField = 45,
kMaxValue = kDictationNoFocusedTextField
};
} // namespace ash

@ -210,6 +210,9 @@ class ASH_PUBLIC_EXPORT AccessibilityController {
// Cancels all of spoken feedback's current and queued speech immediately.
virtual void SilenceSpokenFeedback() = 0;
// Shows an accessibility-related toast.
virtual void ShowToast(AccessibilityToastType type) = 0;
protected:
AccessibilityController();
virtual ~AccessibilityController();

@ -232,6 +232,12 @@ enum class DictationNotificationType {
kOnlyPumpkinDownloaded,
};
// The types of accessibility-related toasts. This enum should be kept in sync
// with chrome.accessibilityPrivate.ToastType.
enum class AccessibilityToastType {
kDictationNoFocusedTextField,
};
} // namespace ash
#endif // ASH_PUBLIC_CPP_ACCESSIBILITY_CONTROLLER_ENUMS_H_

@ -8,6 +8,7 @@
#include <memory>
#include "ash/ash_export.h"
#include "base/functional/callback_forward.h"
namespace ash {
@ -27,6 +28,8 @@ class ASH_EXPORT AccessibilityControllerTestApi {
virtual bool IsDictationKeboardDialogShowing() const = 0;
virtual void AcceptDictationKeyboardDialog() = 0;
virtual void DismissDictationKeyboardDialog() = 0;
virtual void AddShowToastCallbackForTesting(
base::RepeatingClosure callback) const = 0;
};
} // namespace ash

@ -67,6 +67,17 @@ namespace {
namespace accessibility_private = ::extensions::api::accessibility_private;
using ::ash::AccessibilityManager;
ash::AccessibilityToastType ConvertToastType(
accessibility_private::ToastType type) {
switch (type) {
case accessibility_private::ToastType::
TOAST_TYPE_DICTATIONNOFOCUSEDTEXTFIELD:
return ash::AccessibilityToastType::kDictationNoFocusedTextField;
case accessibility_private::ToastType::TOAST_TYPE_NONE:
NOTREACHED_NORETURN();
}
}
ash::DictationBubbleHintType ConvertDictationHintType(
accessibility_private::DictationBubbleHintType hint_type) {
switch (hint_type) {
@ -782,6 +793,15 @@ AccessibilityPrivateSetVirtualKeyboardVisibleFunction::Run() {
return RespondNow(NoArguments());
}
ExtensionFunction::ResponseAction AccessibilityPrivateShowToastFunction::Run() {
absl::optional<accessibility_private::ShowToast::Params> params(
accessibility_private::ShowToast::Params::Create(args()));
EXTENSION_FUNCTION_VALIDATE(params);
ash::AccessibilityController::Get()->ShowToast(
ConvertToastType(params->type));
return RespondNow(NoArguments());
}
ExtensionFunction::ResponseAction
AccessibilityPrivateShowConfirmationDialogFunction::Run() {
absl::optional<accessibility_private::ShowConfirmationDialog::Params> params =

@ -240,6 +240,14 @@ class AccessibilityPrivateSetVirtualKeyboardVisibleFunction
ACCESSIBILITY_PRIVATE_SETVIRTUALKEYBOARDVISIBLE)
};
// API function that displays an accessibility-related toast.
class AccessibilityPrivateShowToastFunction : public ExtensionFunction {
~AccessibilityPrivateShowToastFunction() override = default;
ResponseAction Run() override;
DECLARE_EXTENSION_FUNCTION("accessibilityPrivate.showToast",
ACCESSIBILITY_PRIVATE_SHOWTOAST)
};
// API function that shows a confirmation dialog, with callbacks for
// confirm/cancel.
class AccessibilityPrivateShowConfirmationDialogFunction

@ -8,6 +8,7 @@
#include "ash/constants/ash_pref_names.h"
#include "ash/public/cpp/system_tray_test_api.h"
#include "ash/public/cpp/test/accessibility_controller_test_api.h"
#include "ash/root_window_controller.h"
#include "ash/shell.h"
#include "ash/system/accessibility/dictation_button_tray.h"
@ -316,6 +317,8 @@ class DictationTestBase : public InProcessBrowserTest,
utils_->set_wait_for_accessibility_common_extension_load_(use);
}
DictationTestUtils* utils() { return utils_.get(); }
private:
std::unique_ptr<DictationTestUtils> utils_;
base::test::ScopedFeatureList scoped_feature_list_;
@ -2240,4 +2243,109 @@ IN_PROC_BROWSER_TEST_P(DictationFormattedContentEditableTest,
SendFinalResultAndWaitForEditableValue("was one", "This was one test");
}
class AccessibilityToastCallbackManager {
public:
void OnToastShown() { run_loop_.Quit(); }
void WaitForToastShown() { run_loop_.Run(); }
private:
base::RunLoop run_loop_;
};
class DictationKeyboardImprovementsTest : public DictationTestBase {
public:
DictationKeyboardImprovementsTest() = default;
~DictationKeyboardImprovementsTest() override = default;
DictationKeyboardImprovementsTest(const DictationKeyboardImprovementsTest&) =
delete;
DictationKeyboardImprovementsTest& operator=(
const DictationKeyboardImprovementsTest&) = delete;
protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
DictationTestBase::SetUpCommandLine(command_line);
std::vector<base::test::FeatureRef> enabled_features{
::features::kAccessibilityDictationKeyboardImprovements};
scoped_feature_list_.InitWithFeatures(
enabled_features, std::vector<base::test::FeatureRef>());
}
void SetUpOnMainThread() override {
DictationTestBase::SetUpOnMainThread();
test_api_ = AccessibilityControllerTestApi::Create();
callback_manager_ = std::make_unique<AccessibilityToastCallbackManager>();
test_api_->AddShowToastCallbackForTesting(
base::BindRepeating(&AccessibilityToastCallbackManager::OnToastShown,
base::Unretained(callback_manager_.get())));
// Tab away from the editable.
ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
/*window=*/nullptr, /*key=*/ui::KeyboardCode::VKEY_TAB,
/*control=*/false,
/*shift=*/false, /*alt=*/false, /*command=*/false)));
// Reduce the no focused IME timeout so that the nudge will be shown
// promptly.
ExecuteAccessibilityCommonScript(
"testSupport.setNoFocusedImeTimeout(500);");
}
void WaitForToastShown() { callback_manager_->WaitForToastShown(); }
private:
std::unique_ptr<AccessibilityControllerTestApi> test_api_;
std::unique_ptr<AccessibilityToastCallbackManager> callback_manager_;
base::test::ScopedFeatureList scoped_feature_list_;
};
INSTANTIATE_TEST_SUITE_P(
NetworkDictationKeyboardImprovementsTest,
DictationKeyboardImprovementsTest,
::testing::Values(TestConfig(speech::SpeechRecognitionType::kNetwork,
EditableType::kInput)));
// Verifies that a nudge is shown in the system UI when Dictation is toggled
// when there is no focused editable.
IN_PROC_BROWSER_TEST_P(DictationKeyboardImprovementsTest,
ToggledWithNoFocusShowsNudge) {
// Disable the console observer because toggling Dictation in the following
// manner will cause an error to be emitted to the console.
utils()->DisableConsoleObserver();
ToggleDictationWithKeystroke();
WaitForToastShown();
WaitForRecognitionStopped();
}
// Verifies that ChromeVox announces a message when when Dictation is toggled
// when there is no focused editable.
// TODO(b:259352600): Re-enable this test on MSAN.
#if defined(MEMORY_SANITIZER)
#define MAYBE_ToggledWithNoFocusTriggersSpeech \
DISABLED_ToggledWithNoFocusTriggersSpeech
#else
#define MAYBE_ToggledWithNoFocusTriggersSpeech ToggledWithNoFocusTriggersSpeech
#endif
IN_PROC_BROWSER_TEST_P(DictationKeyboardImprovementsTest,
MAYBE_ToggledWithNoFocusTriggersSpeech) {
// Setup ChromeVox.
test::SpeechMonitor sm;
EXPECT_FALSE(GetManager()->IsSpokenFeedbackEnabled());
extensions::ExtensionHostTestHelper host_helper(
browser()->profile(), extension_misc::kChromeVoxExtensionId);
EnableChromeVox();
host_helper.WaitForHostCompletedFirstLoad();
EXPECT_TRUE(GetManager()->IsSpokenFeedbackEnabled());
// Disable the console observer because toggling Dictation in the following
// manner will cause an error to be emitted to the console.
utils()->DisableConsoleObserver();
ToggleDictationWithKeystroke();
WaitForToastShown();
WaitForRecognitionStopped();
// Assert speech from ChromeVox.
sm.ExpectSpeechPattern("*Go to a text field to use Dictation*");
sm.Replay();
}
} // namespace ash

@ -179,7 +179,7 @@ void DictationTestUtils::EnableDictation(Browser* browser) {
// Increase Dictation's NO_FOCUSED_IME timeout to reduce flakiness on slower
// builds.
std::string script = "testSupport.increaseNoFocusedImeTimeout();";
std::string script = "testSupport.setNoFocusedImeTimeout(20 * 1000);";
ExecuteAccessibilityCommonScript(script);
// Dictation will request a Pumpkin install when it starts up. Wait for

@ -94,6 +94,10 @@ class DictationTestUtils {
int GetCommitTextCallCount();
void WaitForCommitText(const std::u16string& value);
// TODO(b:259352600): Instead of disabling the observer, change this to
// allow specific messages.
void DisableConsoleObserver() { console_observer_.reset(); }
// Sets whether or not we should wait for the accessibility common extension
// to load when enabling Dictation. This should be true in almost all cases.
// However, there are times when we don't want to wait for accessibility

@ -202,7 +202,7 @@ export class Dictation {
}
this.setStopTimeout_(
Dictation.Timeouts.NO_FOCUSED_IME_MS,
'Dictation stopped automatically: No focused IME');
Dictation.StopReason.NO_FOCUSED_IME);
this.inputController_.connect(() => this.maybeStartSpeechRecognition_());
}
@ -262,18 +262,21 @@ export class Dictation {
/**
* Sets the timeout to stop Dictation.
* @param {number} durationMs
* @param {string=} debugInfo Optional debugging information for why Dictation
* @param {Dictation.StopReason=} reason Optional reason for why Dictation
* stopped automatically.
* @private
*/
setStopTimeout_(durationMs, debugInfo) {
setStopTimeout_(durationMs, reason) {
if (this.stopTimeoutId_ !== null) {
clearTimeout(this.stopTimeoutId_);
}
this.stopTimeoutId_ = setTimeout(() => {
this.stopDictation_(/*notify=*/ true);
if (debugInfo) {
console.log(debugInfo);
if (reason === Dictation.StopReason.NO_FOCUSED_IME) {
chrome.accessibilityPrivate.showToast(
chrome.accessibilityPrivate.ToastType
.DICTATION_NO_FOCUSED_TEXT_FIELD);
}
}, durationMs);
}
@ -540,12 +543,9 @@ export class Dictation {
InputController.IME_ENGINE_ID);
}
/**
* Used to increase the NO_FOCUSED_IME_MS timeout to reduce the flakiness of
* Dictation tests on slower builds. For testing purposes only.
*/
increaseNoFocusedImeTimeoutForTesting() {
Dictation.Timeouts.NO_FOCUSED_IME_MS = 20 * 1000;
/** Used to set the NO_FOCUSED_IME_MS timeout for testing purposes only. */
setNoFocusedImeTimeoutForTesting(duration) {
Dictation.Timeouts.NO_FOCUSED_IME_MS = duration;
}
/**
@ -628,3 +628,8 @@ Dictation.Timeouts = {
NO_NEW_SPEECH_MS: 5 * 1000,
NO_FOCUSED_IME_MS: 1000,
};
/** @enum {string} */
Dictation.StopReason = {
NO_FOCUSED_IME: 'Dictation stopped automatically: No focused IME',
};

@ -116,7 +116,7 @@ DictationE2ETestBase = class extends E2ETestBase {
accessibilityCommon.dictation_.disablePumpkinForTesting();
// Increase Dictation's NO_FOCUSED_IME timeout to reduce flakiness on slower
// builds.
accessibilityCommon.dictation_.increaseNoFocusedImeTimeoutForTesting();
accessibilityCommon.dictation_.setNoFocusedImeTimeoutForTesting(20 * 1000);
}
/** @override */

@ -20,9 +20,9 @@ class DictationTestSupport {
domAutomationController.send('ready');
}
/** Increases Dictation timeouts for test stability. */
increaseNoFocusedImeTimeout() {
this.dictation_.increaseNoFocusedImeTimeoutForTesting();
/** Sets Dictation timeouts for test stability. */
setNoFocusedImeTimeout(duration) {
this.dictation_.setNoFocusedImeTimeoutForTesting(duration);
this.notifyCcTests_();
}

@ -73,6 +73,10 @@ class MockAccessibilityPrivate {
this.SyntheticKeyboardEventType = {KEYDOWN: 'keydown', KEYUP: 'keyup'};
this.ToastType = {
DICTATION_NO_FOCUSED_TEXT_FIELD: 'dictationNoFocusedTextField',
};
/** @private {function<number, number>} */
this.boundsListener_ = null;
@ -484,4 +488,7 @@ class MockAccessibilityPrivate {
await getFileBytes(`${pumpkinDir}/es_es/pumpkin_config.binarypb`);
MockAccessibilityPrivate.pumpkinData_ = data;
}
/** @param {!chrome.accessibilityPrivate.ToastType} type */
showToast(type) {}
}

@ -117,3 +117,5 @@ void FakeAccessibilityController::UpdateDictationBubble(
const absl::optional<std::vector<ash::DictationBubbleHintType>>& hints) {}
void FakeAccessibilityController::SilenceSpokenFeedback() {}
void FakeAccessibilityController::ShowToast(ash::AccessibilityToastType type) {}

@ -77,6 +77,7 @@ class FakeAccessibilityController : ash::AccessibilityController {
const absl::optional<std::vector<ash::DictationBubbleHintType>>& hints)
override;
void SilenceSpokenFeedback() override;
void ShowToast(ash::AccessibilityToastType type) override;
private:
bool was_client_set_ = false;

@ -292,6 +292,13 @@
}
}
},
{
"id": "ToastType",
"type": "string",
"enum": [
"dictationNoFocusedTextField"
]
},
{
"id": "DlcType",
"type": "string",
@ -894,6 +901,16 @@
}
]
}
},
{
"name": "showToast",
"type": "function",
"description": "Displays an accessibility-related toast.",
"parameters": [{
"name": "type",
"$ref": "ToastType",
"description": "The type of toast to show."
}]
}
],
"events": [

@ -1880,6 +1880,7 @@ enum HistogramValue {
OS_DIAGNOSTICS_RUNBLUETOOTHSCANNINGROUTINE = 1818,
OS_DIAGNOSTICS_RUNBLUETOOTHPAIRINGROUTINE = 1819,
FILEMANAGERPRIVATE_DISMISSIOTASK = 1820,
ACCESSIBILITY_PRIVATE_SHOWTOAST = 1821,
// Last entry: Add new entries above, then run:
// tools/metrics/histograms/update_extension_histograms.py
ENUM_BOUNDARY

@ -339,6 +339,13 @@ chrome.accessibilityPrivate.DictationBubbleHintType = {
*/
chrome.accessibilityPrivate.DictationBubbleProperties;
/**
* @enum {string}
*/
chrome.accessibilityPrivate.ToastType = {
DICTATION_NO_FOCUSED_TEXT_FIELD: 'dictationNoFocusedTextField',
};
/**
* @enum {string}
*/
@ -657,6 +664,13 @@ chrome.accessibilityPrivate.getDlcContents = function(dlc, callback) {};
*/
chrome.accessibilityPrivate.isLacrosPrimary = function(callback) {};
/**
* Displays an accessibility-related toast.
* @param {!chrome.accessibilityPrivate.ToastType} type The type of toast to
* show.
*/
chrome.accessibilityPrivate.showToast = function(type) {};
/**
* Fired whenever ChromeVox should output introduction.
* @type {!ChromeEvent}

@ -37589,6 +37589,7 @@ Called by update_extension_histograms.py.-->
<int value="1818" label="OS_DIAGNOSTICS_RUNBLUETOOTHSCANNINGROUTINE"/>
<int value="1819" label="OS_DIAGNOSTICS_RUNBLUETOOTHPAIRINGROUTINE"/>
<int value="1820" label="FILEMANAGERPRIVATE_DISMISSIOTASK"/>
<int value="1821" label="ACCESSIBILITY_PRIVATE_SHOWTOAST"/>
</enum>
<enum name="ExtensionIconState">
@ -77776,6 +77777,8 @@ Called by update_net_trust_anchors.py.-->
<int value="18" label="Scalable IPH Bubble"/>
<int value="19"
label="Video Conference Tray Camera And Microphone Use While Disabled"/>
<int value="20" label="Multitask Menu Clamshell"/>
<int value="21" label="Multitask Menu Tablet"/>
</enum>
<enum name="NukeProfileResult">
@ -104470,6 +104473,7 @@ would be helpful to identify which type is being sent.
<int value="41" label="Video Conference Tray Speak-On-Mute Detected"/>
<int value="42" label="Copy Gif To Clipboard Action"/>
<int value="44" label="Battery Saver Disabled"/>
<int value="45" label="Dictation No Focused Text Field"/>
</enum>
<enum name="TokenBinding.KeyMatch">