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

Side by Side Diff: ash/system/chromeos/bluetooth/tray_bluetooth.cc

Issue 2108403004: mash: Move several chromeos system tray items to //ash/common (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@audio
Patch Set: Rebase Created 4 years, 5 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
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/chromeos/bluetooth/tray_bluetooth.h"
6
7 #include "ash/common/session/session_state_delegate.h"
8 #include "ash/common/system/tray/fixed_sized_scroll_view.h"
9 #include "ash/common/system/tray/hover_highlight_view.h"
10 #include "ash/common/system/tray/system_tray_delegate.h"
11 #include "ash/common/system/tray/system_tray_notifier.h"
12 #include "ash/common/system/tray/throbber_view.h"
13 #include "ash/common/system/tray/tray_constants.h"
14 #include "ash/common/system/tray/tray_details_view.h"
15 #include "ash/common/system/tray/tray_item_more.h"
16 #include "ash/common/system/tray/tray_popup_header_button.h"
17 #include "ash/common/system/tray/view_click_listener.h"
18 #include "ash/common/wm_shell.h"
19 #include "ash/system/tray/system_tray.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
29 namespace ash {
30 namespace tray {
31 namespace {
32
33 // Updates bluetooth device |device| in the |list|. If it is new, append to the
34 // end of the |list|; otherwise, keep it at the same place, but update the data
35 // with new device info provided by |device|.
36 void UpdateBluetoothDeviceListHelper(BluetoothDeviceList* list,
37 const BluetoothDeviceInfo& device) {
38 for (BluetoothDeviceList::iterator it = list->begin(); it != list->end();
39 ++it) {
40 if ((*it).address == device.address) {
41 *it = device;
42 return;
43 }
44 }
45
46 list->push_back(device);
47 }
48
49 // Removes the obsolete BluetoothDevices from |list|, if they are not in the
50 // |new_list|.
51 void RemoveObsoleteBluetoothDevicesFromList(
52 BluetoothDeviceList* list,
53 const std::set<std::string>& new_list) {
54 for (BluetoothDeviceList::iterator it = list->begin(); it != list->end();
55 ++it) {
56 if (new_list.find((*it).address) == new_list.end()) {
57 it = list->erase(it);
58 if (it == list->end())
59 return;
60 }
61 }
62 }
63
64 } // namespace
65
66 class BluetoothDefaultView : public TrayItemMore {
67 public:
68 BluetoothDefaultView(SystemTrayItem* owner, bool show_more)
69 : TrayItemMore(owner, show_more) {
70 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
71 SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_BLUETOOTH).ToImageSkia());
72 UpdateLabel();
73 }
74
75 ~BluetoothDefaultView() override {}
76
77 void UpdateLabel() {
78 SystemTrayDelegate* delegate = WmShell::Get()->system_tray_delegate();
79 if (delegate->GetBluetoothAvailable()) {
80 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
81 const base::string16 label =
82 rb.GetLocalizedString(delegate->GetBluetoothEnabled()
83 ? IDS_ASH_STATUS_TRAY_BLUETOOTH_ENABLED
84 : IDS_ASH_STATUS_TRAY_BLUETOOTH_DISABLED);
85 SetLabel(label);
86 SetAccessibleName(label);
87 SetVisible(true);
88 } else {
89 SetVisible(false);
90 }
91 }
92
93 private:
94 DISALLOW_COPY_AND_ASSIGN(BluetoothDefaultView);
95 };
96
97 class BluetoothDetailedView : public TrayDetailsView,
98 public ViewClickListener,
99 public views::ButtonListener {
100 public:
101 BluetoothDetailedView(SystemTrayItem* owner, LoginStatus login)
102 : TrayDetailsView(owner),
103 login_(login),
104 manage_devices_(NULL),
105 toggle_bluetooth_(NULL),
106 enable_bluetooth_(NULL) {
107 CreateItems();
108 }
109
110 ~BluetoothDetailedView() override {
111 // Stop discovering bluetooth devices when exiting BT detailed view.
112 BluetoothStopDiscovering();
113 }
114
115 void Update() {
116 BluetoothStartDiscovering();
117 UpdateBluetoothDeviceList();
118
119 // Update UI.
120 UpdateDeviceScrollList();
121 UpdateHeaderEntry();
122 Layout();
123 }
124
125 private:
126 void CreateItems() {
127 CreateScrollableList();
128 AppendSettingsEntries();
129 AppendHeaderEntry();
130 }
131
132 void BluetoothStartDiscovering() {
133 SystemTrayDelegate* delegate = WmShell::Get()->system_tray_delegate();
134 bool bluetooth_enabled = delegate->GetBluetoothEnabled();
135 bool bluetooth_discovering = delegate->GetBluetoothDiscovering();
136 if (bluetooth_discovering) {
137 throbber_->Start();
138 return;
139 }
140 throbber_->Stop();
141 if (bluetooth_enabled) {
142 delegate->BluetoothStartDiscovering();
143 }
144 }
145
146 void BluetoothStopDiscovering() {
147 SystemTrayDelegate* delegate = WmShell::Get()->system_tray_delegate();
148 if (delegate && delegate->GetBluetoothDiscovering()) {
149 delegate->BluetoothStopDiscovering();
150 throbber_->Stop();
151 }
152 }
153
154 void UpdateBluetoothDeviceList() {
155 std::set<std::string> new_connecting_devices;
156 std::set<std::string> new_connected_devices;
157 std::set<std::string> new_paired_not_connected_devices;
158 std::set<std::string> new_discovered_not_paired_devices;
159
160 BluetoothDeviceList list;
161 WmShell::Get()->system_tray_delegate()->GetAvailableBluetoothDevices(&list);
162 for (size_t i = 0; i < list.size(); ++i) {
163 if (list[i].connecting) {
164 list[i].display_name = l10n_util::GetStringFUTF16(
165 IDS_ASH_STATUS_TRAY_BLUETOOTH_CONNECTING, list[i].display_name);
166 new_connecting_devices.insert(list[i].address);
167 UpdateBluetoothDeviceListHelper(&connecting_devices_, list[i]);
168 } else if (list[i].connected && list[i].paired) {
169 new_connected_devices.insert(list[i].address);
170 UpdateBluetoothDeviceListHelper(&connected_devices_, list[i]);
171 } else if (list[i].paired) {
172 new_paired_not_connected_devices.insert(list[i].address);
173 UpdateBluetoothDeviceListHelper(&paired_not_connected_devices_,
174 list[i]);
175 } else {
176 new_discovered_not_paired_devices.insert(list[i].address);
177 UpdateBluetoothDeviceListHelper(&discovered_not_paired_devices_,
178 list[i]);
179 }
180 }
181 RemoveObsoleteBluetoothDevicesFromList(&connecting_devices_,
182 new_connecting_devices);
183 RemoveObsoleteBluetoothDevicesFromList(&connected_devices_,
184 new_connected_devices);
185 RemoveObsoleteBluetoothDevicesFromList(&paired_not_connected_devices_,
186 new_paired_not_connected_devices);
187 RemoveObsoleteBluetoothDevicesFromList(&discovered_not_paired_devices_,
188 new_discovered_not_paired_devices);
189 }
190
191 void AppendHeaderEntry() {
192 CreateSpecialRow(IDS_ASH_STATUS_TRAY_BLUETOOTH, this);
193
194 if (login_ == LoginStatus::LOCKED)
195 return;
196
197 throbber_ = new ThrobberView;
198 throbber_->SetTooltipText(
199 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCOVERING));
200 footer()->AddView(throbber_, false /* separator */);
201
202 // Do not allow toggling bluetooth in the lock screen.
203 SystemTrayDelegate* delegate = WmShell::Get()->system_tray_delegate();
204 toggle_bluetooth_ =
205 new TrayPopupHeaderButton(this, IDR_AURA_UBER_TRAY_BLUETOOTH_ENABLED,
206 IDR_AURA_UBER_TRAY_BLUETOOTH_DISABLED,
207 IDR_AURA_UBER_TRAY_BLUETOOTH_ENABLED_HOVER,
208 IDR_AURA_UBER_TRAY_BLUETOOTH_DISABLED_HOVER,
209 IDS_ASH_STATUS_TRAY_BLUETOOTH);
210 toggle_bluetooth_->SetToggled(!delegate->GetBluetoothEnabled());
211 toggle_bluetooth_->SetTooltipText(
212 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISABLE_BLUETOOTH));
213 toggle_bluetooth_->SetToggledTooltipText(
214 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ENABLE_BLUETOOTH));
215 toggle_bluetooth_->EnableCanvasFlippingForRTLUI(false);
216 footer()->AddButton(toggle_bluetooth_);
217 }
218
219 void UpdateHeaderEntry() {
220 if (toggle_bluetooth_) {
221 toggle_bluetooth_->SetToggled(
222 !WmShell::Get()->system_tray_delegate()->GetBluetoothEnabled());
223 }
224 }
225
226 void UpdateDeviceScrollList() {
227 device_map_.clear();
228 scroll_content()->RemoveAllChildViews(true);
229 enable_bluetooth_ = NULL;
230
231 SystemTrayDelegate* delegate = WmShell::Get()->system_tray_delegate();
232 bool bluetooth_enabled = delegate->GetBluetoothEnabled();
233 bool blueooth_available = delegate->GetBluetoothAvailable();
234 if (blueooth_available && !bluetooth_enabled && toggle_bluetooth_) {
235 enable_bluetooth_ = AddScrollListItem(
236 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ENABLE_BLUETOOTH),
237 false /* highlight */, false /* checked */, true /* enabled */);
238 }
239
240 AppendSameTypeDevicesToScrollList(connected_devices_, true, true,
241 bluetooth_enabled);
242 AppendSameTypeDevicesToScrollList(connecting_devices_, true, false,
243 bluetooth_enabled);
244 AppendSameTypeDevicesToScrollList(paired_not_connected_devices_, false,
245 false, bluetooth_enabled);
246 if (discovered_not_paired_devices_.size() > 0)
247 AddScrollSeparator();
248 AppendSameTypeDevicesToScrollList(discovered_not_paired_devices_, false,
249 false, bluetooth_enabled);
250
251 // Show user Bluetooth state if there is no bluetooth devices in list.
252 if (device_map_.size() == 0) {
253 if (blueooth_available && bluetooth_enabled) {
254 AddScrollListItem(l10n_util::GetStringUTF16(
255 IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCOVERING),
256 false /* highlight */, false /* checked */,
257 true /* enabled */);
258 }
259 }
260
261 scroll_content()->SizeToPreferredSize();
262 }
263
264 void AppendSameTypeDevicesToScrollList(const BluetoothDeviceList& list,
265 bool highlight,
266 bool checked,
267 bool enabled) {
268 for (size_t i = 0; i < list.size(); ++i) {
269 HoverHighlightView* container =
270 AddScrollListItem(list[i].display_name, highlight, checked, enabled);
271 device_map_[container] = list[i].address;
272 }
273 }
274
275 HoverHighlightView* AddScrollListItem(const base::string16& text,
276 bool highlight,
277 bool checked,
278 bool enabled) {
279 HoverHighlightView* container = new HoverHighlightView(this);
280 views::Label* label =
281 container->AddCheckableLabel(text, highlight, checked);
282 label->SetEnabled(enabled);
283 scroll_content()->AddChildView(container);
284 return container;
285 }
286
287 // Add settings entries.
288 void AppendSettingsEntries() {
289 if (!WmShell::Get()->system_tray_delegate()->ShouldShowSettings())
290 return;
291
292 // Add bluetooth device requires a browser window, hide it for non logged in
293 // user.
294 if (login_ == LoginStatus::NOT_LOGGED_IN || login_ == LoginStatus::LOCKED ||
295 WmShell::Get()->GetSessionStateDelegate()->IsInSecondaryLoginScreen()) {
296 return;
297 }
298
299 SystemTrayDelegate* delegate = WmShell::Get()->system_tray_delegate();
300 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
301 HoverHighlightView* container = new HoverHighlightView(this);
302 container->AddLabel(
303 rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_BLUETOOTH_MANAGE_DEVICES),
304 gfx::ALIGN_LEFT, false /* highlight */);
305 container->SetEnabled(delegate->GetBluetoothAvailable());
306 AddChildView(container);
307 manage_devices_ = container;
308 }
309
310 // Returns true if the device with |device_id| is found in |device_list|,
311 // and the display_name of the device will be returned in |display_name| if
312 // it's not NULL.
313 bool FoundDevice(const std::string& device_id,
314 const BluetoothDeviceList& device_list,
315 base::string16* display_name) {
316 for (size_t i = 0; i < device_list.size(); ++i) {
317 if (device_list[i].address == device_id) {
318 if (display_name)
319 *display_name = device_list[i].display_name;
320 return true;
321 }
322 }
323 return false;
324 }
325
326 // Updates UI of the clicked bluetooth device to show it is being connected
327 // or disconnected if such an operation is going to be performed underway.
328 void UpdateClickedDevice(const std::string& device_id,
329 views::View* item_container) {
330 base::string16 display_name;
331 if (FoundDevice(device_id, paired_not_connected_devices_, &display_name)) {
332 display_name = l10n_util::GetStringFUTF16(
333 IDS_ASH_STATUS_TRAY_BLUETOOTH_CONNECTING, display_name);
334
335 item_container->RemoveAllChildViews(true);
336 static_cast<HoverHighlightView*>(item_container)
337 ->AddCheckableLabel(display_name, true /* highlight */, false);
338 scroll_content()->SizeToPreferredSize();
339 static_cast<views::View*>(scroller())->Layout();
340 }
341 }
342
343 // Overridden from ViewClickListener.
344 void OnViewClicked(views::View* sender) override {
345 SystemTrayDelegate* delegate = WmShell::Get()->system_tray_delegate();
346 if (sender == footer()->content()) {
347 TransitionToDefaultView();
348 } else if (sender == manage_devices_) {
349 delegate->ManageBluetoothDevices();
350 } else if (sender == enable_bluetooth_) {
351 WmShell::Get()->RecordUserMetricsAction(
352 delegate->GetBluetoothEnabled() ? UMA_STATUS_AREA_BLUETOOTH_DISABLED
353 : UMA_STATUS_AREA_BLUETOOTH_ENABLED);
354 delegate->ToggleBluetooth();
355 } else {
356 if (!delegate->GetBluetoothEnabled())
357 return;
358 std::map<views::View*, std::string>::iterator find;
359 find = device_map_.find(sender);
360 if (find == device_map_.end())
361 return;
362 const std::string device_id = find->second;
363 if (FoundDevice(device_id, connecting_devices_, NULL))
364 return;
365 UpdateClickedDevice(device_id, sender);
366 delegate->ConnectToBluetoothDevice(device_id);
367 }
368 }
369
370 // Overridden from ButtonListener.
371 void ButtonPressed(views::Button* sender, const ui::Event& event) override {
372 SystemTrayDelegate* delegate = WmShell::Get()->system_tray_delegate();
373 if (sender == toggle_bluetooth_)
374 delegate->ToggleBluetooth();
375 else
376 NOTREACHED();
377 }
378
379 LoginStatus login_;
380
381 std::map<views::View*, std::string> device_map_;
382 views::View* manage_devices_;
383 ThrobberView* throbber_;
384 TrayPopupHeaderButton* toggle_bluetooth_;
385 HoverHighlightView* enable_bluetooth_;
386 BluetoothDeviceList connected_devices_;
387 BluetoothDeviceList connecting_devices_;
388 BluetoothDeviceList paired_not_connected_devices_;
389 BluetoothDeviceList discovered_not_paired_devices_;
390
391 DISALLOW_COPY_AND_ASSIGN(BluetoothDetailedView);
392 };
393
394 } // namespace tray
395
396 TrayBluetooth::TrayBluetooth(SystemTray* system_tray)
397 : SystemTrayItem(system_tray), default_(NULL), detailed_(NULL) {
398 WmShell::Get()->system_tray_notifier()->AddBluetoothObserver(this);
399 }
400
401 TrayBluetooth::~TrayBluetooth() {
402 WmShell::Get()->system_tray_notifier()->RemoveBluetoothObserver(this);
403 }
404
405 views::View* TrayBluetooth::CreateTrayView(LoginStatus status) {
406 return NULL;
407 }
408
409 views::View* TrayBluetooth::CreateDefaultView(LoginStatus status) {
410 CHECK(default_ == NULL);
411 default_ =
412 new tray::BluetoothDefaultView(this, status != LoginStatus::LOCKED);
413 return default_;
414 }
415
416 views::View* TrayBluetooth::CreateDetailedView(LoginStatus status) {
417 if (!WmShell::Get()->system_tray_delegate()->GetBluetoothAvailable())
418 return NULL;
419 WmShell::Get()->RecordUserMetricsAction(
420 UMA_STATUS_AREA_DETAILED_BLUETOOTH_VIEW);
421 CHECK(detailed_ == NULL);
422 detailed_ = new tray::BluetoothDetailedView(this, status);
423 detailed_->Update();
424 return detailed_;
425 }
426
427 void TrayBluetooth::DestroyTrayView() {}
428
429 void TrayBluetooth::DestroyDefaultView() {
430 default_ = NULL;
431 }
432
433 void TrayBluetooth::DestroyDetailedView() {
434 detailed_ = NULL;
435 }
436
437 void TrayBluetooth::UpdateAfterLoginStatusChange(LoginStatus status) {}
438
439 void TrayBluetooth::OnBluetoothRefresh() {
440 if (default_)
441 default_->UpdateLabel();
442 else if (detailed_)
443 detailed_->Update();
444 }
445
446 void TrayBluetooth::OnBluetoothDiscoveringChanged() {
447 if (!detailed_)
448 return;
449 detailed_->Update();
450 }
451
452 } // namespace ash
OLDNEW
« no previous file with comments | « ash/system/chromeos/bluetooth/tray_bluetooth.h ('k') | ash/system/chromeos/enterprise/tray_enterprise.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698