Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: ash/system/tray_accessibility.cc

Issue 2084733002: mash: Move tray accessibility and keyboard to //ash/common (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@typenamespace
Patch Set: rebase Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ash/system/tray_accessibility.h ('k') | ash/sysui/keyboard_ui_mus.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/system/tray_accessibility.h"
6
7 #include "ash/common/accessibility_delegate.h"
8 #include "ash/common/accessibility_types.h"
9 #include "ash/common/session/session_state_delegate.h"
10 #include "ash/common/system/tray/hover_highlight_view.h"
11 #include "ash/common/system/tray/system_tray_delegate.h"
12 #include "ash/common/system/tray/tray_constants.h"
13 #include "ash/common/system/tray/tray_item_more.h"
14 #include "ash/common/system/tray/tray_popup_label_button.h"
15 #include "ash/common/system/tray/wm_system_tray_notifier.h"
16 #include "ash/common/wm_shell.h"
17 #include "ash/system/tray/system_tray.h"
18 #include "ash/system/tray/tray_details_view.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "grit/ash_resources.h"
21 #include "grit/ash_strings.h"
22 #include "ui/base/l10n/l10n_util.h"
23 #include "ui/base/resource/resource_bundle.h"
24 #include "ui/gfx/image/image.h"
25 #include "ui/views/controls/image_view.h"
26 #include "ui/views/controls/label.h"
27 #include "ui/views/layout/box_layout.h"
28 #include "ui/views/widget/widget.h"
29
30 namespace ash {
31 namespace {
32
33 enum AccessibilityState {
34 A11Y_NONE = 0,
35 A11Y_SPOKEN_FEEDBACK = 1 << 0,
36 A11Y_HIGH_CONTRAST = 1 << 1,
37 A11Y_SCREEN_MAGNIFIER = 1 << 2,
38 A11Y_LARGE_CURSOR = 1 << 3,
39 A11Y_AUTOCLICK = 1 << 4,
40 A11Y_VIRTUAL_KEYBOARD = 1 << 5,
41 A11Y_BRAILLE_DISPLAY_CONNECTED = 1 << 6,
42 };
43
44 uint32_t GetAccessibilityState() {
45 AccessibilityDelegate* delegate = WmShell::Get()->GetAccessibilityDelegate();
46 uint32_t state = A11Y_NONE;
47 if (delegate->IsSpokenFeedbackEnabled())
48 state |= A11Y_SPOKEN_FEEDBACK;
49 if (delegate->IsHighContrastEnabled())
50 state |= A11Y_HIGH_CONTRAST;
51 if (delegate->IsMagnifierEnabled())
52 state |= A11Y_SCREEN_MAGNIFIER;
53 if (delegate->IsLargeCursorEnabled())
54 state |= A11Y_LARGE_CURSOR;
55 if (delegate->IsAutoclickEnabled())
56 state |= A11Y_AUTOCLICK;
57 if (delegate->IsVirtualKeyboardEnabled())
58 state |= A11Y_VIRTUAL_KEYBOARD;
59 if (delegate->IsBrailleDisplayConnected())
60 state |= A11Y_BRAILLE_DISPLAY_CONNECTED;
61 return state;
62 }
63
64 LoginStatus GetCurrentLoginStatus() {
65 return WmShell::Get()->system_tray_delegate()->GetUserLoginStatus();
66 }
67
68 } // namespace
69
70 namespace tray {
71
72 class DefaultAccessibilityView : public TrayItemMore {
73 public:
74 explicit DefaultAccessibilityView(SystemTrayItem* owner)
75 : TrayItemMore(owner, true) {
76 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
77 SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_ACCESSIBILITY_DARK).
78 ToImageSkia());
79 base::string16 label = bundle.GetLocalizedString(
80 IDS_ASH_STATUS_TRAY_ACCESSIBILITY);
81 SetLabel(label);
82 SetAccessibleName(label);
83 set_id(test::kAccessibilityTrayItemViewId);
84 }
85
86 ~DefaultAccessibilityView() override {}
87
88 private:
89 DISALLOW_COPY_AND_ASSIGN(DefaultAccessibilityView);
90 };
91
92 ////////////////////////////////////////////////////////////////////////////////
93 // ash::tray::AccessibilityPopupView
94
95 AccessibilityPopupView::AccessibilityPopupView(SystemTrayItem* owner,
96 uint32_t enabled_state_bits)
97 : TrayNotificationView(owner, IDR_AURA_UBER_TRAY_ACCESSIBILITY_DARK),
98 label_(CreateLabel(enabled_state_bits)) {
99 InitView(label_);
100 }
101
102 views::Label* AccessibilityPopupView::CreateLabel(uint32_t enabled_state_bits) {
103 DCHECK((enabled_state_bits &
104 (A11Y_SPOKEN_FEEDBACK | A11Y_BRAILLE_DISPLAY_CONNECTED)) != 0);
105 base::string16 text;
106 if (enabled_state_bits & A11Y_BRAILLE_DISPLAY_CONNECTED) {
107 text.append(l10n_util::GetStringUTF16(
108 IDS_ASH_STATUS_TRAY_BRAILLE_DISPLAY_CONNECTED_BUBBLE));
109 }
110 if (enabled_state_bits & A11Y_SPOKEN_FEEDBACK) {
111 if (!text.empty())
112 text.append(base::ASCIIToUTF16(" "));
113 text.append(l10n_util::GetStringUTF16(
114 IDS_ASH_STATUS_TRAY_SPOKEN_FEEDBACK_ENABLED_BUBBLE));
115 }
116 views::Label* label = new views::Label(text);
117 label->SetMultiLine(true);
118 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
119 return label;
120 }
121
122 ////////////////////////////////////////////////////////////////////////////////
123 // ash::tray::AccessibilityDetailedView
124
125 AccessibilityDetailedView::AccessibilityDetailedView(SystemTrayItem* owner,
126 LoginStatus login)
127 : TrayDetailsView(owner),
128 spoken_feedback_view_(nullptr),
129 high_contrast_view_(nullptr),
130 screen_magnifier_view_(nullptr),
131 large_cursor_view_(nullptr),
132 help_view_(nullptr),
133 settings_view_(nullptr),
134 autoclick_view_(nullptr),
135 virtual_keyboard_view_(nullptr),
136 spoken_feedback_enabled_(false),
137 high_contrast_enabled_(false),
138 screen_magnifier_enabled_(false),
139 large_cursor_enabled_(false),
140 autoclick_enabled_(false),
141 virtual_keyboard_enabled_(false),
142 login_(login) {
143 Reset();
144
145 AppendAccessibilityList();
146 AppendHelpEntries();
147 CreateSpecialRow(IDS_ASH_STATUS_TRAY_ACCESSIBILITY_TITLE, this);
148
149 Layout();
150 }
151
152 void AccessibilityDetailedView::AppendAccessibilityList() {
153 CreateScrollableList();
154 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
155
156 AccessibilityDelegate* delegate = WmShell::Get()->GetAccessibilityDelegate();
157 spoken_feedback_enabled_ = delegate->IsSpokenFeedbackEnabled();
158 spoken_feedback_view_ =
159 AddScrollListItem(bundle.GetLocalizedString(
160 IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SPOKEN_FEEDBACK),
161 spoken_feedback_enabled_, spoken_feedback_enabled_);
162
163 // Large Cursor item is shown only in Login screen.
164 if (login_ == LoginStatus::NOT_LOGGED_IN) {
165 large_cursor_enabled_ = delegate->IsLargeCursorEnabled();
166 large_cursor_view_ =
167 AddScrollListItem(bundle.GetLocalizedString(
168 IDS_ASH_STATUS_TRAY_ACCESSIBILITY_LARGE_CURSOR),
169 large_cursor_enabled_, large_cursor_enabled_);
170 }
171
172 high_contrast_enabled_ = delegate->IsHighContrastEnabled();
173 high_contrast_view_ = AddScrollListItem(
174 bundle.GetLocalizedString(
175 IDS_ASH_STATUS_TRAY_ACCESSIBILITY_HIGH_CONTRAST_MODE),
176 high_contrast_enabled_, high_contrast_enabled_);
177 screen_magnifier_enabled_ = delegate->IsMagnifierEnabled();
178 screen_magnifier_view_ =
179 AddScrollListItem(bundle.GetLocalizedString(
180 IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SCREEN_MAGNIFIER),
181 screen_magnifier_enabled_, screen_magnifier_enabled_);
182
183 // Don't show autoclick option at login screen.
184 if (login_ != LoginStatus::NOT_LOGGED_IN) {
185 autoclick_enabled_ = delegate->IsAutoclickEnabled();
186 autoclick_view_ = AddScrollListItem(
187 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_ACCESSIBILITY_AUTOCLICK),
188 autoclick_enabled_, autoclick_enabled_);
189 }
190
191 virtual_keyboard_enabled_ = delegate->IsVirtualKeyboardEnabled();
192 virtual_keyboard_view_ =
193 AddScrollListItem(bundle.GetLocalizedString(
194 IDS_ASH_STATUS_TRAY_ACCESSIBILITY_VIRTUAL_KEYBOARD),
195 virtual_keyboard_enabled_, virtual_keyboard_enabled_);
196 }
197
198 void AccessibilityDetailedView::AppendHelpEntries() {
199 // Currently the help page requires a browser window.
200 // TODO(yoshiki): show this even on login/lock screen. crbug.com/158286
201 if (login_ == LoginStatus::NOT_LOGGED_IN || login_ == LoginStatus::LOCKED ||
202 WmShell::Get()->GetSessionStateDelegate()->IsInSecondaryLoginScreen())
203 return;
204
205 views::View* bottom_row = new View();
206 views::BoxLayout* layout = new
207 views::BoxLayout(views::BoxLayout::kHorizontal,
208 kTrayMenuBottomRowPadding,
209 kTrayMenuBottomRowPadding,
210 kTrayMenuBottomRowPaddingBetweenItems);
211 layout->SetDefaultFlex(1);
212 bottom_row->SetLayoutManager(layout);
213
214 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
215
216 TrayPopupLabelButton* help = new TrayPopupLabelButton(
217 this,
218 bundle.GetLocalizedString(
219 IDS_ASH_STATUS_TRAY_ACCESSIBILITY_LEARN_MORE));
220 bottom_row->AddChildView(help);
221 help_view_ = help;
222
223 TrayPopupLabelButton* settings = new TrayPopupLabelButton(
224 this,
225 bundle.GetLocalizedString(
226 IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SETTINGS));
227 bottom_row->AddChildView(settings);
228 settings_view_ = settings;
229
230 AddChildView(bottom_row);
231 }
232
233 HoverHighlightView* AccessibilityDetailedView::AddScrollListItem(
234 const base::string16& text,
235 bool highlight,
236 bool checked) {
237 HoverHighlightView* container = new HoverHighlightView(this);
238 container->AddCheckableLabel(text, highlight, checked);
239 scroll_content()->AddChildView(container);
240 return container;
241 }
242
243 void AccessibilityDetailedView::OnViewClicked(views::View* sender) {
244 AccessibilityDelegate* delegate = WmShell::Get()->GetAccessibilityDelegate();
245 if (sender == footer()->content()) {
246 TransitionToDefaultView();
247 } else if (sender == spoken_feedback_view_) {
248 WmShell::Get()->RecordUserMetricsAction(
249 delegate->IsSpokenFeedbackEnabled() ?
250 ash::UMA_STATUS_AREA_DISABLE_SPOKEN_FEEDBACK :
251 ash::UMA_STATUS_AREA_ENABLE_SPOKEN_FEEDBACK);
252 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
253 } else if (sender == high_contrast_view_) {
254 WmShell::Get()->RecordUserMetricsAction(
255 delegate->IsHighContrastEnabled() ?
256 ash::UMA_STATUS_AREA_DISABLE_HIGH_CONTRAST :
257 ash::UMA_STATUS_AREA_ENABLE_HIGH_CONTRAST);
258 delegate->ToggleHighContrast();
259 } else if (sender == screen_magnifier_view_) {
260 WmShell::Get()->RecordUserMetricsAction(
261 delegate->IsMagnifierEnabled() ?
262 ash::UMA_STATUS_AREA_DISABLE_MAGNIFIER :
263 ash::UMA_STATUS_AREA_ENABLE_MAGNIFIER);
264 delegate->SetMagnifierEnabled(!delegate->IsMagnifierEnabled());
265 } else if (large_cursor_view_ && sender == large_cursor_view_) {
266 WmShell::Get()->RecordUserMetricsAction(
267 delegate->IsLargeCursorEnabled() ?
268 ash::UMA_STATUS_AREA_DISABLE_LARGE_CURSOR :
269 ash::UMA_STATUS_AREA_ENABLE_LARGE_CURSOR);
270 delegate->SetLargeCursorEnabled(!delegate->IsLargeCursorEnabled());
271 } else if (autoclick_view_ && sender == autoclick_view_) {
272 WmShell::Get()->RecordUserMetricsAction(
273 delegate->IsAutoclickEnabled() ?
274 ash::UMA_STATUS_AREA_DISABLE_AUTO_CLICK :
275 ash::UMA_STATUS_AREA_ENABLE_AUTO_CLICK);
276 delegate->SetAutoclickEnabled(!delegate->IsAutoclickEnabled());
277 } else if (virtual_keyboard_view_ && sender == virtual_keyboard_view_) {
278 WmShell::Get()->RecordUserMetricsAction(
279 delegate->IsVirtualKeyboardEnabled() ?
280 ash::UMA_STATUS_AREA_DISABLE_VIRTUAL_KEYBOARD :
281 ash::UMA_STATUS_AREA_ENABLE_VIRTUAL_KEYBOARD);
282 delegate->SetVirtualKeyboardEnabled(!delegate->IsVirtualKeyboardEnabled());
283 }
284 }
285
286 void AccessibilityDetailedView::ButtonPressed(views::Button* sender,
287 const ui::Event& event) {
288 SystemTrayDelegate* tray_delegate = WmShell::Get()->system_tray_delegate();
289 if (sender == help_view_)
290 tray_delegate->ShowAccessibilityHelp();
291 else if (sender == settings_view_)
292 tray_delegate->ShowAccessibilitySettings();
293 }
294
295 } // namespace tray
296
297 ////////////////////////////////////////////////////////////////////////////////
298 // ash::TrayAccessibility
299
300 TrayAccessibility::TrayAccessibility(SystemTray* system_tray)
301 : TrayImageItem(system_tray, IDR_AURA_UBER_TRAY_ACCESSIBILITY),
302 default_(NULL),
303 detailed_popup_(NULL),
304 detailed_menu_(NULL),
305 request_popup_view_state_(A11Y_NONE),
306 tray_icon_visible_(false),
307 login_(GetCurrentLoginStatus()),
308 previous_accessibility_state_(GetAccessibilityState()),
309 show_a11y_menu_on_lock_screen_(true) {
310 DCHECK(system_tray);
311 WmShell::Get()->system_tray_notifier()->AddAccessibilityObserver(this);
312 }
313
314 TrayAccessibility::~TrayAccessibility() {
315 WmShell::Get()->system_tray_notifier()->RemoveAccessibilityObserver(this);
316 }
317
318 void TrayAccessibility::SetTrayIconVisible(bool visible) {
319 if (tray_view())
320 tray_view()->SetVisible(visible);
321 tray_icon_visible_ = visible;
322 }
323
324 tray::AccessibilityDetailedView* TrayAccessibility::CreateDetailedMenu() {
325 return new tray::AccessibilityDetailedView(this, login_);
326 }
327
328 bool TrayAccessibility::GetInitialVisibility() {
329 // Shows accessibility icon if any accessibility feature is enabled.
330 // Otherwise, doen't show it.
331 return GetAccessibilityState() != A11Y_NONE;
332 }
333
334 views::View* TrayAccessibility::CreateDefaultView(LoginStatus status) {
335 CHECK(default_ == NULL);
336
337 // Shows accessibility menu if:
338 // - on login screen (not logged in);
339 // - "Enable accessibility menu" on chrome://settings is checked;
340 // - or any of accessibility features is enabled
341 // Otherwise, not shows it.
342 AccessibilityDelegate* delegate = WmShell::Get()->GetAccessibilityDelegate();
343 if (login_ != LoginStatus::NOT_LOGGED_IN &&
344 !delegate->ShouldShowAccessibilityMenu() &&
345 // On login screen, keeps the initial visibility of the menu.
346 (status != LoginStatus::LOCKED || !show_a11y_menu_on_lock_screen_))
347 return NULL;
348
349 CHECK(default_ == NULL);
350 default_ = new tray::DefaultAccessibilityView(this);
351
352 return default_;
353 }
354
355 views::View* TrayAccessibility::CreateDetailedView(LoginStatus status) {
356 CHECK(detailed_popup_ == NULL);
357 CHECK(detailed_menu_ == NULL);
358
359 if (request_popup_view_state_) {
360 detailed_popup_ =
361 new tray::AccessibilityPopupView(this, request_popup_view_state_);
362 request_popup_view_state_ = A11Y_NONE;
363 return detailed_popup_;
364 } else {
365 WmShell::Get()->RecordUserMetricsAction(
366 ash::UMA_STATUS_AREA_DETAILED_ACCESSABILITY);
367 detailed_menu_ = CreateDetailedMenu();
368 return detailed_menu_;
369 }
370 }
371
372 void TrayAccessibility::DestroyDefaultView() {
373 default_ = NULL;
374 }
375
376 void TrayAccessibility::DestroyDetailedView() {
377 detailed_popup_ = NULL;
378 detailed_menu_ = NULL;
379 }
380
381 void TrayAccessibility::UpdateAfterLoginStatusChange(LoginStatus status) {
382 // Stores the a11y feature status on just entering the lock screen.
383 if (login_ != LoginStatus::LOCKED && status == LoginStatus::LOCKED)
384 show_a11y_menu_on_lock_screen_ = (GetAccessibilityState() != A11Y_NONE);
385
386 login_ = status;
387 SetTrayIconVisible(GetInitialVisibility());
388 }
389
390 void TrayAccessibility::OnAccessibilityModeChanged(
391 AccessibilityNotificationVisibility notify) {
392 SetTrayIconVisible(GetInitialVisibility());
393
394 uint32_t accessibility_state = GetAccessibilityState();
395 // We'll get an extra notification if a braille display is connected when
396 // spoken feedback wasn't already enabled. This is because the braille
397 // connection state is already updated when spoken feedback is enabled so
398 // that the notifications can be consolidated into one. Therefore, we
399 // return early if there's no change in the state that we keep track of.
400 if (accessibility_state == previous_accessibility_state_)
401 return;
402 // Contains bits for spoken feedback and braille display connected currently
403 // being enabled.
404 uint32_t being_enabled =
405 (accessibility_state & ~previous_accessibility_state_) &
406 (A11Y_SPOKEN_FEEDBACK | A11Y_BRAILLE_DISPLAY_CONNECTED);
407 if ((notify == A11Y_NOTIFICATION_SHOW) && being_enabled != A11Y_NONE) {
408 // Shows popup if |notify| is true and the spoken feedback is being enabled.
409 request_popup_view_state_ = being_enabled;
410 PopupDetailedView(kTrayPopupAutoCloseDelayForTextInSeconds, false);
411 } else {
412 if (detailed_popup_)
413 detailed_popup_->GetWidget()->Close();
414 if (detailed_menu_)
415 detailed_menu_->GetWidget()->Close();
416 }
417
418 previous_accessibility_state_ = accessibility_state;
419 }
420
421 } // namespace ash
OLDNEW
« no previous file with comments | « ash/system/tray_accessibility.h ('k') | ash/sysui/keyboard_ui_mus.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698