Commit 7bb34577 authored by Katie D's avatar Katie D Committed by Commit Bot

Adds image label option to the context menus when a screen reader is enabled.

Also adds a bubble to confirm that a user wants the setting on. This copies
the behavior of the spelling suggestions service.

Context menu change is only added when the feature flag is enabled.

Bug: 905419
Change-Id: I171f21a9766d150b113e15a0f95238ed435fda5e
Reviewed-on: https://chromium-review.googlesource.com/c/1404156Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Commit-Queue: Katie Dektar <katie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#622107}
parent 3be571a2
......@@ -278,6 +278,7 @@
#define IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE 50161
#define IDC_CONTENT_CONTEXT_RELOAD_PACKAGED_APP 50162
#define IDC_CONTENT_CONTEXT_RESTART_PACKAGED_APP 50163
#define IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE 50164
// A gap here. Feel free to insert a new ID.
#define IDC_CONTENT_CONTEXT_GENERATEPASSWORD 50166
#define IDC_CONTENT_CONTEXT_EXIT_FULLSCREEN 50167
......
......@@ -904,6 +904,9 @@ Please check your email at <ph name="ACCOUNT_EMAIL">$2<ex>jane.doe@example.com</
</if>
<if expr="not is_android">
<message name="IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_BUBBLE_TEXT" desc="The text of a bubble that confirms users allows integrating the accessibility labels service of Google to Chromium.">
Chromium can recognize images and text in an image by sending page images to Google servers, allowing you to better understand page content.
</message>
<message name="IDS_CONTENT_CONTEXT_SPELLING_BUBBLE_TEXT" desc="The text of a bubble that confirms users allows integrating the spelling service of Google to Chrome.">
Chromium can provide smarter spell-checking by sending what you type in the browser to Google servers, allowing you to use the same spell-checking technology used by Google search.
</message>
......
1f96eb581ed8a4482713741fad615e7dfb8731d3
\ No newline at end of file
......@@ -535,6 +535,15 @@ are declared in tools/grit/grit_rule.gni.
<message name="IDS_CONTENT_CONTEXT_ADD_TO_DICTIONARY" desc="The name of the Add to dictionary command in the content area context menu">
&amp;Add to dictionary
</message>
<message name="IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_SEND" desc="The context-menu item that asks whether to integrate the accessibility image labeling service of Google to Chrome. This text is also used as the title of a bubble which confirms it.">
Get image labels from Google
</message>
<message name="IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_BUBBLE_ENABLE" desc="The button text that allows integrating the accessibility labels service of Google. This should use the same verb as IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_SEND.">
Get labels
</message>
<message name="IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_BUBBLE_DISABLE" desc="The button text that disallows integrating the accessibility labels service of Google.">
Cancel
</message>
<message name="IDS_CONTENT_CONTEXT_SPELLING_ASK_GOOGLE" desc="The context-menu item that asks whether to integrate the spelling service of Google to Chrome. This text is also used as the title of a bubble which confirms it.">
Ask Google for suggestions
</message>
......@@ -759,6 +768,15 @@ are declared in tools/grit/grit_rule.gni.
<message name="IDS_CONTENT_CONTEXT_ADD_TO_DICTIONARY" desc="In Title Case: The name of the Add to dictionary command in the content area context menu">
&amp;Add to Dictionary
</message>
<message name="IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_SEND" desc="The context-menu item that asks whether to integrate the accessibility image labeling service of Google to Chrome. This text is also used as the title of a bubble which confirms it.">
Get Image Labels from Google
</message>
<message name="IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_BUBBLE_ENABLE" desc="The button text that allows integrating the accessibility labels service of Google. This should use the same verb as IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_SEND.">
Get Labels
</message>
<message name="IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_BUBBLE_DISABLE" desc="The button text that disallows integrating the accessibility labels service of Google.">
Cancel
</message>
<message name="IDS_CONTENT_CONTEXT_SPELLING_ASK_GOOGLE" desc="In Title Case: The context-menu item that asks whether to integrate the spelling service of Google to Chrome. This text is also used as the title of a bubble which confirms it.">
Ask Google for Suggestions
</message>
......
1f96eb581ed8a4482713741fad615e7dfb8731d3
\ No newline at end of file
1f96eb581ed8a4482713741fad615e7dfb8731d3
\ No newline at end of file
1f96eb581ed8a4482713741fad615e7dfb8731d3
\ No newline at end of file
......@@ -922,6 +922,9 @@ Please check your email at <ph name="ACCOUNT_EMAIL">$2<ex>jane.doe@example.com</
<!-- content area context menus. Android does not use it -->
<if expr="not is_android">
<message name="IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_BUBBLE_TEXT" desc="The text of a bubble that confirms users allows integrating the accessibility labels service of Google to Chrome.">
Google Chrome can recognize images and text in an image by sending page images to Google servers, allowing you to better understand page content.
</message>
<message name="IDS_CONTENT_CONTEXT_SPELLING_BUBBLE_TEXT" desc="The text of a bubble that confirms users allows integrating the spelling service of Google to Chrome.">
Google Chrome can provide smarter spell-checking by sending what you type in the browser to Google servers, allowing you to use the same spell-checking technology used by Google search.
</message>
......
1f96eb581ed8a4482713741fad615e7dfb8731d3
\ No newline at end of file
......@@ -2876,6 +2876,10 @@ jumbo_split_static_library("browser") {
"profiles/profile_shortcut_manager.h",
"profiles/profile_window.cc",
"profiles/profile_window.h",
"renderer_context_menu/accessibility_labels_bubble_model.cc",
"renderer_context_menu/accessibility_labels_bubble_model.h",
"renderer_context_menu/accessibility_labels_menu_observer.cc",
"renderer_context_menu/accessibility_labels_menu_observer.h",
"renderer_context_menu/render_view_context_menu.cc",
"renderer_context_menu/render_view_context_menu.h",
"renderer_context_menu/spelling_bubble_model.cc",
......
// Copyright 2019 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.
#include "chrome/browser/renderer_context_menu/accessibility_labels_bubble_model.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h"
#include "components/prefs/pref_service.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
using content::OpenURLParams;
using content::Referrer;
using content::WebContents;
AccessibilityLabelsBubbleModel::AccessibilityLabelsBubbleModel(
Profile* profile,
WebContents* web_contents)
: profile_(profile), web_contents_(web_contents) {}
AccessibilityLabelsBubbleModel::~AccessibilityLabelsBubbleModel() {}
base::string16 AccessibilityLabelsBubbleModel::GetTitle() const {
return l10n_util::GetStringUTF16(
IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_SEND);
}
base::string16 AccessibilityLabelsBubbleModel::GetMessageText() const {
return l10n_util::GetStringUTF16(
IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_BUBBLE_TEXT);
}
base::string16 AccessibilityLabelsBubbleModel::GetButtonLabel(
BubbleButton button) const {
return l10n_util::GetStringUTF16(
button == BUTTON_OK
? IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_BUBBLE_ENABLE
: IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_BUBBLE_DISABLE);
}
void AccessibilityLabelsBubbleModel::Accept() {
// TODO(katie): Add logging.
SetPref(true);
}
void AccessibilityLabelsBubbleModel::Cancel() {
// TODO(katie): Add logging.
SetPref(false);
}
base::string16 AccessibilityLabelsBubbleModel::GetLinkText() const {
return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
}
GURL AccessibilityLabelsBubbleModel::GetHelpPageURL() const {
return GURL(chrome::kPrivacyLearnMoreURL);
}
void AccessibilityLabelsBubbleModel::OpenHelpPage() {
// TODO(katie): Link to a specific accessibility labels help page when
// there is one; check with the privacy team.
OpenURLParams params(GetHelpPageURL(), Referrer(),
WindowOpenDisposition::NEW_FOREGROUND_TAB,
ui::PAGE_TRANSITION_LINK, false);
web_contents_->OpenURL(params);
}
void AccessibilityLabelsBubbleModel::SetPref(bool enabled) {
PrefService* pref = profile_->GetPrefs();
DCHECK(pref);
pref->SetBoolean(prefs::kAccessibilityImageLabelsEnabled, enabled);
}
// Copyright 2019 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.
#ifndef CHROME_BROWSER_RENDERER_CONTEXT_MENU_ACCESSIBILITY_LABELS_BUBBLE_MODEL_H_
#define CHROME_BROWSER_RENDERER_CONTEXT_MENU_ACCESSIBILITY_LABELS_BUBBLE_MODEL_H_
#include "base/macros.h"
#include "chrome/browser/ui/confirm_bubble_model.h"
class Profile;
namespace content {
class WebContents;
}
// A class that implements a bubble menu shown when we confirm a user allows
// integrating the accessibility labels service of Google to Chrome.
class AccessibilityLabelsBubbleModel : public ConfirmBubbleModel {
public:
AccessibilityLabelsBubbleModel(Profile* profile,
content::WebContents* web_contents);
~AccessibilityLabelsBubbleModel() override;
// ConfirmBubbleModel implementation.
base::string16 GetTitle() const override;
base::string16 GetMessageText() const override;
base::string16 GetButtonLabel(BubbleButton button) const override;
void Accept() override;
void Cancel() override;
base::string16 GetLinkText() const override;
GURL GetHelpPageURL() const override;
void OpenHelpPage() override;
private:
// Set the profile preferences to enable or disable the feature.
void SetPref(bool enabled);
Profile* profile_;
content::WebContents* web_contents_;
DISALLOW_COPY_AND_ASSIGN(AccessibilityLabelsBubbleModel);
};
#endif // CHROME_BROWSER_RENDERER_CONTEXT_MENU_ACCESSIBILITY_LABELS_BUBBLE_MODEL_H_
// Copyright 2019 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.
#include "chrome/browser/renderer_context_menu/accessibility_labels_menu_observer.h"
#include <utility>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_context_menu/accessibility_labels_bubble_model.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
#include "chrome/browser/ui/confirm_bubble.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/context_menu_params.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/geometry/rect.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
#else
#include "content/public/browser/browser_accessibility_state.h"
#endif // defined(OS_CHROMEOS)
using content::BrowserThread;
AccessibilityLabelsMenuObserver::AccessibilityLabelsMenuObserver(
RenderViewContextMenuProxy* proxy)
: proxy_(proxy) {}
AccessibilityLabelsMenuObserver::~AccessibilityLabelsMenuObserver() {}
void AccessibilityLabelsMenuObserver::InitMenu(
const content::ContextMenuParams& params) {
Profile* profile = Profile::FromBrowserContext(proxy_->GetBrowserContext());
if (ShouldShowLabelsItem()) {
proxy_->AddAccessibilityLabelsServiceItem(profile->GetPrefs()->GetBoolean(
prefs::kAccessibilityImageLabelsEnabled));
}
}
bool AccessibilityLabelsMenuObserver::IsCommandIdSupported(int command_id) {
return command_id == IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE;
}
bool AccessibilityLabelsMenuObserver::IsCommandIdChecked(int command_id) {
DCHECK(IsCommandIdSupported(command_id));
Profile* profile = Profile::FromBrowserContext(proxy_->GetBrowserContext());
if (command_id == IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE) {
return profile->GetPrefs()->GetBoolean(
prefs::kAccessibilityImageLabelsEnabled);
}
return false;
}
bool AccessibilityLabelsMenuObserver::IsCommandIdEnabled(int command_id) {
DCHECK(IsCommandIdSupported(command_id));
if (command_id == IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE) {
return ShouldShowLabelsItem();
}
return false;
}
void AccessibilityLabelsMenuObserver::ExecuteCommand(int command_id) {
// TODO(katie): Add logging.
DCHECK(IsCommandIdSupported(command_id));
Profile* profile = Profile::FromBrowserContext(proxy_->GetBrowserContext());
if (command_id == IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE) {
// When a user enables the accessibility labeling item, we
// show a bubble to confirm it. On the other hand, when a user disables this
// item, we directly update/ the profile and stop integrating the labels
// service immediately.
if (!profile->GetPrefs()->GetBoolean(
prefs::kAccessibilityImageLabelsEnabled)) {
content::RenderViewHost* rvh = proxy_->GetRenderViewHost();
gfx::Rect rect = rvh->GetWidget()->GetView()->GetViewBounds();
std::unique_ptr<AccessibilityLabelsBubbleModel> model(
new AccessibilityLabelsBubbleModel(profile,
proxy_->GetWebContents()));
chrome::ShowConfirmBubble(
proxy_->GetWebContents()->GetTopLevelNativeWindow(),
rvh->GetWidget()->GetView()->GetNativeView(),
gfx::Point(rect.CenterPoint().x(), rect.y()), std::move(model));
} else {
if (profile) {
profile->GetPrefs()->SetBoolean(prefs::kAccessibilityImageLabelsEnabled,
false);
}
}
}
}
bool AccessibilityLabelsMenuObserver::ShouldShowLabelsItem() {
// Hidden behind a feature flag.
base::CommandLine& cmd = *base::CommandLine::ForCurrentProcess();
if (!cmd.HasSwitch(::switches::kEnableExperimentalAccessibilityLabels)) {
return false;
}
// Check if a screen reader is running.
#if defined(OS_CHROMEOS)
return chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled();
#else
// TODO(katie): Can we use AXMode in Chrome OS as well?
ui::AXMode mode =
content::BrowserAccessibilityState::GetInstance()->GetAccessibilityMode();
return mode.has_mode(ui::AXMode::kScreenReader);
#endif // defined(OS_CHROMEOS)
}
// Copyright 2019 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.
#ifndef CHROME_BROWSER_RENDERER_CONTEXT_MENU_ACCESSIBILITY_LABELS_MENU_OBSERVER_H_
#define CHROME_BROWSER_RENDERER_CONTEXT_MENU_ACCESSIBILITY_LABELS_MENU_OBSERVER_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <vector>
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/timer/timer.h"
#include "components/prefs/pref_member.h"
#include "components/renderer_context_menu/render_view_context_menu_observer.h"
class RenderViewContextMenuProxy;
// An observer that listens to events from the RenderViewContextMenu class and
// shows the accessibility labels menu if a screen reader is enabled.
class AccessibilityLabelsMenuObserver : public RenderViewContextMenuObserver {
public:
explicit AccessibilityLabelsMenuObserver(RenderViewContextMenuProxy* proxy);
~AccessibilityLabelsMenuObserver() override;
// RenderViewContextMenuObserver implementation.
void InitMenu(const content::ContextMenuParams& params) override;
bool IsCommandIdSupported(int command_id) override;
bool IsCommandIdChecked(int command_id) override;
bool IsCommandIdEnabled(int command_id) override;
void ExecuteCommand(int command_id) override;
private:
bool ShouldShowLabelsItem();
// The interface to add a context-menu item and update it. This class uses
// this interface to avoid accessing context-menu items directly.
RenderViewContextMenuProxy* proxy_;
DISALLOW_COPY_AND_ASSIGN(AccessibilityLabelsMenuObserver);
};
#endif // CHROME_BROWSER_RENDERER_CONTEXT_MENU_ACCESSIBILITY_LABELS_MENU_OBSERVER_H_
// Copyright 2019 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.
#include "chrome/browser/renderer_context_menu/accessibility_labels_menu_observer.h"
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/renderer_context_menu/mock_render_view_context_menu.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/prefs/pref_service.h"
#include "content/public/common/context_menu_params.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/accessibility/accessibility_switches.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
#else
#include "content/public/browser/browser_accessibility_state.h"
#endif // defined(OS_CHROMEOS)
namespace {
// A test class for accessibility labels. This test should be a browser test
// because it accesses resources.
class AccessibilityLabelsMenuObserverTest : public InProcessBrowserTest {
public:
AccessibilityLabelsMenuObserverTest();
// InProcessBrowserTest overrides:
void SetUpOnMainThread() override { Reset(false); }
void TearDownOnMainThread() override {
observer_.reset();
menu_.reset();
}
void SetUpDefaultCommandLine(base::CommandLine* command_line) override {
base::CommandLine default_command_line(base::CommandLine::NO_PROGRAM);
InProcessBrowserTest::SetUpDefaultCommandLine(&default_command_line);
command_line->AppendSwitch(
switches::kEnableExperimentalAccessibilityLabels);
}
void Reset(bool incognito) {
observer_.reset();
menu_.reset(new MockRenderViewContextMenu(incognito));
observer_.reset(new AccessibilityLabelsMenuObserver(menu_.get()));
menu_->SetObserver(observer_.get());
}
void InitMenu() {
content::ContextMenuParams params;
observer_->InitMenu(params);
}
~AccessibilityLabelsMenuObserverTest() override;
MockRenderViewContextMenu* menu() { return menu_.get(); }
AccessibilityLabelsMenuObserver* observer() { return observer_.get(); }
private:
std::unique_ptr<AccessibilityLabelsMenuObserver> observer_;
std::unique_ptr<MockRenderViewContextMenu> menu_;
DISALLOW_COPY_AND_ASSIGN(AccessibilityLabelsMenuObserverTest);
};
AccessibilityLabelsMenuObserverTest::AccessibilityLabelsMenuObserverTest() {}
AccessibilityLabelsMenuObserverTest::~AccessibilityLabelsMenuObserverTest() {}
} // namespace
// Tests that opening a context menu does not show the menu option if a
// screen reader is not enabled, regardless of the image labels setting.
IN_PROC_BROWSER_TEST_F(AccessibilityLabelsMenuObserverTest,
AccessibilityLabelsNotShownWithoutScreenReader) {
menu()->GetPrefs()->SetBoolean(prefs::kAccessibilityImageLabelsEnabled,
false);
InitMenu();
EXPECT_EQ(0u, menu()->GetMenuSize());
menu()->GetPrefs()->SetBoolean(prefs::kAccessibilityImageLabelsEnabled, true);
InitMenu();
EXPECT_EQ(0u, menu()->GetMenuSize());
}
#if defined(OS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(AccessibilityLabelsMenuObserverTest,
AccessibilityLabelsShowWithChromevoxEnabled) {
chromeos::AccessibilityManager::Get()->EnableSpokenFeedback(true);
menu()->GetPrefs()->SetBoolean(prefs::kAccessibilityImageLabelsEnabled,
false);
InitMenu();
// Shows but is not checked.
ASSERT_EQ(1u, menu()->GetMenuSize());
MockRenderViewContextMenu::MockMenuItem item;
menu()->GetMenuItem(0, &item);
EXPECT_EQ(IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.checked);
EXPECT_FALSE(item.hidden);
Reset(false);
// Shows and is checked when Chromevox and the setting are both on.
menu()->GetPrefs()->SetBoolean(prefs::kAccessibilityImageLabelsEnabled, true);
InitMenu();
ASSERT_EQ(1u, menu()->GetMenuSize());
menu()->GetMenuItem(0, &item);
EXPECT_EQ(IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_TRUE(item.checked);
EXPECT_FALSE(item.hidden);
}
#else
IN_PROC_BROWSER_TEST_F(AccessibilityLabelsMenuObserverTest,
AccessibilityLabelsShowWithScreenReaderEnabled) {
// Spoof a screen reader.
content::BrowserAccessibilityState::GetInstance()->AddAccessibilityModeFlags(
ui::AXMode::kScreenReader);
menu()->GetPrefs()->SetBoolean(prefs::kAccessibilityImageLabelsEnabled,
false);
InitMenu();
// Shows but is not checked.
ASSERT_EQ(1u, menu()->GetMenuSize());
MockRenderViewContextMenu::MockMenuItem item;
menu()->GetMenuItem(0, &item);
EXPECT_EQ(IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.checked);
EXPECT_FALSE(item.hidden);
Reset(false);
// Shows and is checked when a screen reader and the setting are both on.
menu()->GetPrefs()->SetBoolean(prefs::kAccessibilityImageLabelsEnabled, true);
InitMenu();
ASSERT_EQ(1u, menu()->GetMenuSize());
menu()->GetMenuItem(0, &item);
EXPECT_EQ(IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_TRUE(item.checked);
EXPECT_FALSE(item.hidden);
}
#endif // defined(OS_CHROMEOS)
......@@ -147,6 +147,13 @@ void MockRenderViewContextMenu::AddSpellCheckServiceItem(bool is_checked) {
l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_SPELLING_ASK_GOOGLE));
}
void MockRenderViewContextMenu::AddAccessibilityLabelsServiceItem(
bool is_checked) {
AddCheckItem(
IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE,
l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_SEND));
}
content::RenderViewHost* MockRenderViewContextMenu::GetRenderViewHost() const {
return nullptr;
}
......
......@@ -65,6 +65,7 @@ class MockRenderViewContextMenu : public ui::SimpleMenuModel::Delegate,
void RemoveMenuItem(int command_id) override;
void RemoveAdjacentSeparators() override;
void AddSpellCheckServiceItem(bool is_checked) override;
void AddAccessibilityLabelsServiceItem(bool is_checked) override;
content::RenderViewHost* GetRenderViewHost() const override;
content::BrowserContext* GetBrowserContext() const override;
content::WebContents* GetWebContents() const override;
......
......@@ -47,6 +47,7 @@
#include "chrome/browser/profiles/profile_io_data.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_window.h"
#include "chrome/browser/renderer_context_menu/accessibility_labels_menu_observer.h"
#include "chrome/browser/renderer_context_menu/context_menu_content_type_factory.h"
#include "chrome/browser/renderer_context_menu/spelling_menu_observer.h"
#include "chrome/browser/search/search.h"
......@@ -350,11 +351,12 @@ const struct UmaEnumCommandIdPair {
{96, -1, IDC_CONTENT_CONTEXT_START_SMART_SELECTION_ACTION4},
{97, -1, IDC_CONTENT_CONTEXT_START_SMART_SELECTION_ACTION5},
{98, -1, IDC_CONTENT_CONTEXT_LOOK_UP},
{99, -1, IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE},
// Add new items here and use |enum_id| from the next line.
// Also, add new items to RenderViewContextMenuItem enum in
// tools/metrics/histograms/enums.xml.
{99, -1, 0}, // Must be the last. Increment |enum_id| when new IDC
// was added.
{100, -1, 0}, // Must be the last. Increment |enum_id| when new IDC
// was added.
};
// Collapses large ranges of ids before looking for UMA enum.
......@@ -550,6 +552,21 @@ void RenderViewContextMenu::AddSpellCheckServiceItem(ui::SimpleMenuModel* menu,
}
}
// static
void RenderViewContextMenu::AddAccessibilityLabelsServiceItem(
ui::SimpleMenuModel* menu,
bool is_checked) {
if (is_checked) {
menu->AddCheckItemWithStringId(
IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE,
IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_SEND);
} else {
menu->AddItemWithStringId(IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE,
IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_SEND);
AddGoogleIconToLastMenuItem(menu);
}
}
RenderViewContextMenu::RenderViewContextMenu(
content::RenderFrameHost* render_frame_host,
const content::ContextMenuParams& params)
......@@ -869,6 +886,11 @@ void RenderViewContextMenu::InitMenu() {
AppendCurrentExtensionItems();
}
// Accessibility label items are appended to all menus when a screen reader
// is enabled. It can be difficult to open a specific context menu with a
// screen reader, so this is a UX approved solution.
AppendAccessibilityLabelsItems();
if (content_type_->SupportsGroup(
ContextMenuContentType::ITEM_GROUP_DEVELOPER)) {
AppendDeveloperItems();
......@@ -1552,6 +1574,16 @@ void RenderViewContextMenu::AppendSpellingSuggestionItems() {
spelling_suggestions_menu_observer_->InitMenu(params_);
}
void RenderViewContextMenu::AppendAccessibilityLabelsItems() {
menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
if (!accessibility_labels_menu_observer_) {
accessibility_labels_menu_observer_ =
std::make_unique<AccessibilityLabelsMenuObserver>(this);
}
observers_.AddObserver(accessibility_labels_menu_observer_.get());
accessibility_labels_menu_observer_->InitMenu(params_);
}
void RenderViewContextMenu::AppendProtocolHandlerSubMenu() {
const ProtocolHandlerRegistry::ProtocolHandlerList handlers =
GetHandlersForLinkUrl();
......@@ -2137,6 +2169,10 @@ void RenderViewContextMenu::AddSpellCheckServiceItem(bool is_checked) {
AddSpellCheckServiceItem(&menu_model_, is_checked);
}
void RenderViewContextMenu::AddAccessibilityLabelsServiceItem(bool is_checked) {
AddAccessibilityLabelsServiceItem(&menu_model_, is_checked);
}
// static
void RenderViewContextMenu::RegisterMenuShownCallbackForTesting(
base::OnceCallback<void(RenderViewContextMenu*)> cb) {
......
......@@ -32,6 +32,7 @@
#include "chrome/browser/extensions/menu_manager.h"
#endif
class AccessibilityLabelsMenuObserver;
class PrintPreviewContextMenuObserver;
class Profile;
class SpellingMenuObserver;
......@@ -67,12 +68,17 @@ class RenderViewContextMenu : public RenderViewContextMenuBase {
static void AddSpellCheckServiceItem(ui::SimpleMenuModel* menu,
bool is_checked);
// Adds the accessibility labels service item to the context menu.
static void AddAccessibilityLabelsServiceItem(ui::SimpleMenuModel* menu,
bool is_checked);
// RenderViewContextMenuBase:
bool IsCommandIdChecked(int command_id) const override;
bool IsCommandIdVisible(int command_id) const override;
bool IsCommandIdEnabled(int command_id) const override;
void ExecuteCommand(int command_id, int event_flags) override;
void AddSpellCheckServiceItem(bool is_checked) override;
void AddAccessibilityLabelsServiceItem(bool is_checked) override;
// Registers a one-time callback that will be called the next time a context
// menu is shown.
......@@ -166,6 +172,7 @@ class RenderViewContextMenu : public RenderViewContextMenuBase {
void AppendEditableItems();
void AppendLanguageSettings();
void AppendSpellingSuggestionItems();
void AppendAccessibilityLabelsItems();
void AppendSearchProvider();
#if BUILDFLAG(ENABLE_EXTENSIONS)
void AppendAllExtensionItems();
......@@ -243,6 +250,10 @@ class RenderViewContextMenu : public RenderViewContextMenuBase {
// "Ask Google for suggestions" items.
std::unique_ptr<SpellingMenuObserver> spelling_suggestions_menu_observer_;
// An observer that handles accessibility labels items.
std::unique_ptr<AccessibilityLabelsMenuObserver>
accessibility_labels_menu_observer_;
#if !defined(OS_MACOSX)
// An observer that handles the submenu for showing spelling options. This
// submenu lets users select the spelling language, for example.
......
......@@ -775,6 +775,7 @@ test("browser_tests") {
"../browser/profiles/profile_manager_browsertest.cc",
"../browser/push_messaging/push_messaging_browsertest.cc",
"../browser/referrer_policy_browsertest.cc",
"../browser/renderer_context_menu/accessibility_labels_menu_observer_browsertest.cc",
"../browser/renderer_context_menu/mock_render_view_context_menu.cc",
"../browser/renderer_context_menu/mock_render_view_context_menu.h",
"../browser/renderer_context_menu/render_view_context_menu_browsertest.cc",
......
......@@ -106,6 +106,9 @@ class RenderViewContextMenuProxy {
// Add spell check service item to the context menu.
virtual void AddSpellCheckServiceItem(bool is_checked) = 0;
// Add accessibility labels service item to the context menu.
virtual void AddAccessibilityLabelsServiceItem(bool is_checked) = 0;
// Retrieve the given associated objects with a context menu.
virtual content::RenderViewHost* GetRenderViewHost() const = 0;
virtual content::WebContents* GetWebContents() const = 0;
......
......@@ -45284,6 +45284,7 @@ Called by update_net_trust_anchors.py.-->
<int value="96" label="IDC_CONTENT_CONTEXT_START_SMART_SELECTION_ACTION4"/>
<int value="97" label="IDC_CONTENT_CONTEXT_START_SMART_SELECTION_ACTION5"/>
<int value="98" label="IDC_CONTENT_CONTEXT_LOOK_UP"/>
<int value="99" label="IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE"/>
</enum>
<enum name="ReportingHeaderEndpointGroupOutcome">
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