PageRenderTime 47ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/external/chromium_org/ash/system/tray_accessibility.cc

https://gitlab.com/brian0218/rk3188_rk3066_r-box_android4.4.2_sdk
C++ | 355 lines | 281 code | 54 blank | 20 comment | 52 complexity | 467efeaacaa72cfb9906af7a6dc67ee6 MD5 | raw file
  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. #include "ash/system/tray_accessibility.h"
  5. #include "ash/shell.h"
  6. #include "ash/shell_delegate.h"
  7. #include "ash/system/tray/hover_highlight_view.h"
  8. #include "ash/system/tray/system_tray.h"
  9. #include "ash/system/tray/system_tray_delegate.h"
  10. #include "ash/system/tray/system_tray_notifier.h"
  11. #include "ash/system/tray/tray_constants.h"
  12. #include "ash/system/tray/tray_details_view.h"
  13. #include "ash/system/tray/tray_item_more.h"
  14. #include "ash/system/tray/tray_notification_view.h"
  15. #include "ash/system/tray/tray_popup_label_button.h"
  16. #include "grit/ash_resources.h"
  17. #include "grit/ash_strings.h"
  18. #include "ui/base/l10n/l10n_util.h"
  19. #include "ui/base/resource/resource_bundle.h"
  20. #include "ui/gfx/image/image.h"
  21. #include "ui/views/controls/image_view.h"
  22. #include "ui/views/controls/label.h"
  23. #include "ui/views/layout/box_layout.h"
  24. #include "ui/views/widget/widget.h"
  25. namespace ash {
  26. namespace internal {
  27. namespace {
  28. const int kPaddingAroundBottomRow = 5;
  29. enum AccessibilityState {
  30. A11Y_NONE = 0,
  31. A11Y_SPOKEN_FEEDBACK = 1 << 0,
  32. A11Y_HIGH_CONTRAST = 1 << 1,
  33. A11Y_SCREEN_MAGNIFIER = 1 << 2,
  34. A11Y_LARGE_CURSOR = 1 << 3,
  35. };
  36. uint32 GetAccessibilityState() {
  37. ShellDelegate* shell_delegate = Shell::GetInstance()->delegate();
  38. uint32 state = A11Y_NONE;
  39. if (shell_delegate->IsSpokenFeedbackEnabled())
  40. state |= A11Y_SPOKEN_FEEDBACK;
  41. if (shell_delegate->IsHighContrastEnabled())
  42. state |= A11Y_HIGH_CONTRAST;
  43. if (shell_delegate->IsMagnifierEnabled())
  44. state |= A11Y_SCREEN_MAGNIFIER;
  45. if (shell_delegate->IsLargeCursorEnabled())
  46. state |= A11Y_LARGE_CURSOR;
  47. return state;
  48. }
  49. user::LoginStatus GetCurrentLoginStatus() {
  50. return Shell::GetInstance()->system_tray_delegate()->GetUserLoginStatus();
  51. }
  52. } // namespace
  53. namespace tray {
  54. class DefaultAccessibilityView : public TrayItemMore {
  55. public:
  56. explicit DefaultAccessibilityView(SystemTrayItem* owner)
  57. : TrayItemMore(owner, true) {
  58. ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
  59. SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_ACCESSIBILITY_DARK).
  60. ToImageSkia());
  61. base::string16 label = bundle.GetLocalizedString(
  62. IDS_ASH_STATUS_TRAY_ACCESSIBILITY);
  63. SetLabel(label);
  64. SetAccessibleName(label);
  65. }
  66. virtual ~DefaultAccessibilityView() {
  67. }
  68. private:
  69. DISALLOW_COPY_AND_ASSIGN(DefaultAccessibilityView);
  70. };
  71. class AccessibilityPopupView : public TrayNotificationView {
  72. public:
  73. AccessibilityPopupView(SystemTrayItem* owner)
  74. : TrayNotificationView(owner, IDR_AURA_UBER_TRAY_ACCESSIBILITY_DARK) {
  75. InitView(GetLabel());
  76. }
  77. private:
  78. views::Label* GetLabel() {
  79. views::Label* label = new views::Label(
  80. l10n_util::GetStringUTF16(
  81. IDS_ASH_STATUS_TRAY_SPOKEN_FEEDBACK_ENABLED_BUBBLE));
  82. label->SetMultiLine(true);
  83. label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
  84. return label;
  85. }
  86. DISALLOW_COPY_AND_ASSIGN(AccessibilityPopupView);
  87. };
  88. ////////////////////////////////////////////////////////////////////////////////
  89. // ash::internal::tray::AccessibilityDetailedView
  90. AccessibilityDetailedView::AccessibilityDetailedView(
  91. SystemTrayItem* owner, user::LoginStatus login) :
  92. TrayDetailsView(owner),
  93. spoken_feedback_view_(NULL),
  94. high_contrast_view_(NULL),
  95. screen_magnifier_view_(NULL),
  96. large_cursor_view_(NULL),
  97. help_view_(NULL),
  98. settings_view_(NULL),
  99. spoken_feedback_enabled_(false),
  100. high_contrast_enabled_(false),
  101. screen_magnifier_enabled_(false),
  102. large_cursor_enabled_(false),
  103. login_(login) {
  104. Reset();
  105. AppendAccessibilityList();
  106. AppendHelpEntries();
  107. CreateSpecialRow(IDS_ASH_STATUS_TRAY_ACCESSIBILITY_TITLE, this);
  108. Layout();
  109. }
  110. void AccessibilityDetailedView::AppendAccessibilityList() {
  111. CreateScrollableList();
  112. ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
  113. ShellDelegate* shell_delegate = Shell::GetInstance()->delegate();
  114. spoken_feedback_enabled_ = shell_delegate->IsSpokenFeedbackEnabled();
  115. spoken_feedback_view_ = AddScrollListItem(
  116. bundle.GetLocalizedString(
  117. IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SPOKEN_FEEDBACK),
  118. spoken_feedback_enabled_ ? gfx::Font::BOLD : gfx::Font::NORMAL,
  119. spoken_feedback_enabled_);
  120. // Large Cursor item is shown only in Login screen.
  121. if (login_ == user::LOGGED_IN_NONE) {
  122. large_cursor_enabled_ = shell_delegate->IsLargeCursorEnabled();
  123. large_cursor_view_ = AddScrollListItem(
  124. bundle.GetLocalizedString(
  125. IDS_ASH_STATUS_TRAY_ACCESSIBILITY_LARGE_CURSOR),
  126. large_cursor_enabled_ ? gfx::Font::BOLD : gfx::Font::NORMAL,
  127. large_cursor_enabled_);
  128. }
  129. high_contrast_enabled_ = shell_delegate->IsHighContrastEnabled();
  130. high_contrast_view_ = AddScrollListItem(
  131. bundle.GetLocalizedString(
  132. IDS_ASH_STATUS_TRAY_ACCESSIBILITY_HIGH_CONTRAST_MODE),
  133. high_contrast_enabled_ ? gfx::Font::BOLD : gfx::Font::NORMAL,
  134. high_contrast_enabled_);
  135. screen_magnifier_enabled_ = shell_delegate->IsMagnifierEnabled();
  136. screen_magnifier_view_ = AddScrollListItem(
  137. bundle.GetLocalizedString(
  138. IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SCREEN_MAGNIFIER),
  139. screen_magnifier_enabled_ ? gfx::Font::BOLD : gfx::Font::NORMAL,
  140. screen_magnifier_enabled_);
  141. }
  142. void AccessibilityDetailedView::AppendHelpEntries() {
  143. // Currently the help page requires a browser window.
  144. // TODO(yoshiki): show this even on login/lock screen. crbug.com/158286
  145. if (login_ == user::LOGGED_IN_NONE ||
  146. login_ == user::LOGGED_IN_LOCKED)
  147. return;
  148. views::View* bottom_row = new View();
  149. views::BoxLayout* layout = new
  150. views::BoxLayout(views::BoxLayout::kHorizontal,
  151. kTrayMenuBottomRowPadding,
  152. kTrayMenuBottomRowPadding,
  153. kTrayMenuBottomRowPaddingBetweenItems);
  154. layout->set_spread_blank_space(true);
  155. bottom_row->SetLayoutManager(layout);
  156. ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
  157. TrayPopupLabelButton* help = new TrayPopupLabelButton(
  158. this,
  159. bundle.GetLocalizedString(
  160. IDS_ASH_STATUS_TRAY_ACCESSIBILITY_LEARN_MORE));
  161. bottom_row->AddChildView(help);
  162. help_view_ = help;
  163. TrayPopupLabelButton* settings = new TrayPopupLabelButton(
  164. this,
  165. bundle.GetLocalizedString(
  166. IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SETTINGS));
  167. bottom_row->AddChildView(settings);
  168. settings_view_ = settings;
  169. AddChildView(bottom_row);
  170. }
  171. HoverHighlightView* AccessibilityDetailedView::AddScrollListItem(
  172. const base::string16& text,
  173. gfx::Font::FontStyle style,
  174. bool checked) {
  175. HoverHighlightView* container = new HoverHighlightView(this);
  176. container->AddCheckableLabel(text, style, checked);
  177. scroll_content()->AddChildView(container);
  178. return container;
  179. }
  180. void AccessibilityDetailedView::OnViewClicked(views::View* sender) {
  181. ShellDelegate* shell_delegate = Shell::GetInstance()->delegate();
  182. if (sender == footer()->content()) {
  183. owner()->system_tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
  184. } else if (sender == spoken_feedback_view_) {
  185. shell_delegate->ToggleSpokenFeedback(ash::A11Y_NOTIFICATION_NONE);
  186. } else if (sender == high_contrast_view_) {
  187. shell_delegate->ToggleHighContrast();
  188. } else if (sender == screen_magnifier_view_) {
  189. shell_delegate->SetMagnifierEnabled(!shell_delegate->IsMagnifierEnabled());
  190. } else if (large_cursor_view_ && sender == large_cursor_view_) {
  191. shell_delegate->
  192. SetLargeCursorEnabled(!shell_delegate->IsLargeCursorEnabled());
  193. }
  194. }
  195. void AccessibilityDetailedView::ButtonPressed(views::Button* sender,
  196. const ui::Event& event) {
  197. SystemTrayDelegate* tray_delegate =
  198. Shell::GetInstance()->system_tray_delegate();
  199. if (sender == help_view_)
  200. tray_delegate->ShowAccessibilityHelp();
  201. else if (sender == settings_view_)
  202. tray_delegate->ShowAccessibilitySettings();
  203. }
  204. } // namespace tray
  205. ////////////////////////////////////////////////////////////////////////////////
  206. // ash::internal::TrayAccessibility
  207. TrayAccessibility::TrayAccessibility(SystemTray* system_tray)
  208. : TrayImageItem(system_tray, IDR_AURA_UBER_TRAY_ACCESSIBILITY),
  209. default_(NULL),
  210. detailed_popup_(NULL),
  211. detailed_menu_(NULL),
  212. request_popup_view_(false),
  213. tray_icon_visible_(false),
  214. login_(GetCurrentLoginStatus()),
  215. previous_accessibility_state_(GetAccessibilityState()),
  216. show_a11y_menu_on_lock_screen_(true) {
  217. DCHECK(Shell::GetInstance()->delegate());
  218. DCHECK(system_tray);
  219. Shell::GetInstance()->system_tray_notifier()->AddAccessibilityObserver(this);
  220. }
  221. TrayAccessibility::~TrayAccessibility() {
  222. Shell::GetInstance()->system_tray_notifier()->
  223. RemoveAccessibilityObserver(this);
  224. }
  225. void TrayAccessibility::SetTrayIconVisible(bool visible) {
  226. if (tray_view())
  227. tray_view()->SetVisible(visible);
  228. tray_icon_visible_ = visible;
  229. }
  230. tray::AccessibilityDetailedView* TrayAccessibility::CreateDetailedMenu() {
  231. return new tray::AccessibilityDetailedView(this, login_);
  232. }
  233. bool TrayAccessibility::GetInitialVisibility() {
  234. // Shows accessibility icon if any accessibility feature is enabled.
  235. // Otherwise, doen't show it.
  236. return GetAccessibilityState() != A11Y_NONE;
  237. }
  238. views::View* TrayAccessibility::CreateDefaultView(user::LoginStatus status) {
  239. CHECK(default_ == NULL);
  240. // Shows accessibility menu if:
  241. // - on login screen (not logged in);
  242. // - "Enable accessibility menu" on chrome://settings is checked;
  243. // - or any of accessibility features is enabled
  244. // Otherwise, not shows it.
  245. ShellDelegate* delegate = Shell::GetInstance()->delegate();
  246. if (login_ != user::LOGGED_IN_NONE &&
  247. !delegate->ShouldAlwaysShowAccessibilityMenu() &&
  248. // On login screen, keeps the initial visivility of the menu.
  249. (status != user::LOGGED_IN_LOCKED || !show_a11y_menu_on_lock_screen_) &&
  250. GetAccessibilityState() == A11Y_NONE)
  251. return NULL;
  252. CHECK(default_ == NULL);
  253. default_ = new tray::DefaultAccessibilityView(this);
  254. return default_;
  255. }
  256. views::View* TrayAccessibility::CreateDetailedView(user::LoginStatus status) {
  257. CHECK(detailed_popup_ == NULL);
  258. CHECK(detailed_menu_ == NULL);
  259. if (request_popup_view_) {
  260. detailed_popup_ = new tray::AccessibilityPopupView(this);
  261. request_popup_view_ = false;
  262. return detailed_popup_;
  263. } else {
  264. detailed_menu_ = CreateDetailedMenu();
  265. return detailed_menu_;
  266. }
  267. }
  268. void TrayAccessibility::DestroyDefaultView() {
  269. default_ = NULL;
  270. }
  271. void TrayAccessibility::DestroyDetailedView() {
  272. detailed_popup_ = NULL;
  273. detailed_menu_ = NULL;
  274. }
  275. void TrayAccessibility::UpdateAfterLoginStatusChange(user::LoginStatus status) {
  276. // Stores the a11y feature status on just entering the lock screen.
  277. if (login_ != user::LOGGED_IN_LOCKED && status == user::LOGGED_IN_LOCKED)
  278. show_a11y_menu_on_lock_screen_ = (GetAccessibilityState() != A11Y_NONE);
  279. login_ = status;
  280. SetTrayIconVisible(GetInitialVisibility());
  281. }
  282. void TrayAccessibility::OnAccessibilityModeChanged(
  283. AccessibilityNotificationVisibility notify) {
  284. SetTrayIconVisible(GetInitialVisibility());
  285. uint32 accessibility_state = GetAccessibilityState();
  286. if ((notify == ash::A11Y_NOTIFICATION_SHOW)&&
  287. !(previous_accessibility_state_ & A11Y_SPOKEN_FEEDBACK) &&
  288. (accessibility_state & A11Y_SPOKEN_FEEDBACK)) {
  289. // Shows popup if |notify| is true and the spoken feedback is being enabled.
  290. request_popup_view_ = true;
  291. PopupDetailedView(kTrayPopupAutoCloseDelayForTextInSeconds, false);
  292. } else {
  293. if (detailed_popup_)
  294. detailed_popup_->GetWidget()->Close();
  295. if (detailed_menu_)
  296. detailed_menu_->GetWidget()->Close();
  297. }
  298. previous_accessibility_state_ = accessibility_state;
  299. }
  300. } // namespace internal
  301. } // namespace ash