15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/bluetooth/tray_bluetooth.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ash/session/session_state_delegate.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/fixed_sized_scroll_view.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/hover_highlight_view.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/system_tray.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/system_tray_delegate.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/system_tray_notifier.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/throbber_view.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_constants.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_details_view.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_item_more.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/system/tray/tray_popup_header_button.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_resources.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_strings.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/image_view.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/box_layout.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace tray {
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace {
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Updates bluetooth device |device| in the |list|. If it is new, append to the
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// end of the |list|; otherwise, keep it at the same place, but update the data
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// with new device info provided by |device|.
35e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid UpdateBluetoothDeviceListHelper(BluetoothDeviceList* list,
36e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                     const BluetoothDeviceInfo& device) {
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (BluetoothDeviceList::iterator it = list->begin(); it != list->end();
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       ++it) {
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if ((*it).address == device.address) {
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      *it = device;
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  list->push_back(device);
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Removes the obsolete BluetoothDevices from |list|, if they are not in the
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// |new_list|.
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void RemoveObsoleteBluetoothDevicesFromList(
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    BluetoothDeviceList* list,
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::set<std::string>& new_list) {
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (BluetoothDeviceList::iterator it = list->begin(); it != list->end();
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       ++it) {
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (new_list.find((*it).address) == new_list.end()) {
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      it = list->erase(it);
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (it == list->end())
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        return;
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BluetoothDefaultView : public TrayItemMore {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BluetoothDefaultView(SystemTrayItem* owner, bool show_more)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : TrayItemMore(owner, show_more) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_BLUETOOTH).ToImageSkia());
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateLabel();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~BluetoothDefaultView() {}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateLabel() {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ash::SystemTrayDelegate* delegate =
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate();
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate->GetBluetoothAvailable()) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const base::string16 label =
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          rb.GetLocalizedString(delegate->GetBluetoothEnabled() ?
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              IDS_ASH_STATUS_TRAY_BLUETOOTH_ENABLED :
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              IDS_ASH_STATUS_TRAY_BLUETOOTH_DISABLED);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetLabel(label);
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetAccessibleName(label);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetVisible(true);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetVisible(false);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BluetoothDefaultView);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BluetoothDetailedView : public TrayDetailsView,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              public ViewClickListener,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              public views::ButtonListener {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BluetoothDetailedView(SystemTrayItem* owner, user::LoginStatus login)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : TrayDetailsView(owner),
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        login_(login),
104a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        manage_devices_(NULL),
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        toggle_bluetooth_(NULL),
106e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        enable_bluetooth_(NULL) {
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateItems();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~BluetoothDetailedView() {
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Stop discovering bluetooth devices when exiting BT detailed view.
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BluetoothStopDiscovering();
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Update() {
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BluetoothStartDiscovering();
117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    UpdateBluetoothDeviceList();
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Update UI.
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateDeviceScrollList();
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateHeaderEntry();
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Layout();
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CreateItems() {
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateScrollableList();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppendSettingsEntries();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppendHeaderEntry();
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void BluetoothStartDiscovering() {
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ash::SystemTrayDelegate* delegate =
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate();
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool bluetooth_enabled = delegate->GetBluetoothEnabled();
136e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    bool bluetooth_discovering = delegate->GetBluetoothDiscovering();
137e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (bluetooth_discovering) {
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      throbber_->Start();
139e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      return;
140e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    }
141e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    throbber_->Stop();
142e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (bluetooth_enabled) {
143e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      delegate->BluetoothStartDiscovering();
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void BluetoothStopDiscovering() {
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ash::SystemTrayDelegate* delegate =
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate();
150e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (delegate && delegate->GetBluetoothDiscovering()) {
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delegate->BluetoothStopDiscovering();
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      throbber_->Stop();
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
156e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  void UpdateBluetoothDeviceList() {
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::set<std::string> new_connecting_devices;
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::set<std::string> new_connected_devices;
15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::set<std::string> new_paired_not_connected_devices;
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::set<std::string> new_discovered_not_paired_devices;
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BluetoothDeviceList list;
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Shell::GetInstance()->system_tray_delegate()->
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GetAvailableBluetoothDevices(&list);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < list.size(); ++i) {
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (list[i].connecting) {
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        list[i].display_name = l10n_util::GetStringFUTF16(
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            IDS_ASH_STATUS_TRAY_BLUETOOTH_CONNECTING, list[i].display_name);
16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        new_connecting_devices.insert(list[i].address);
170e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        UpdateBluetoothDeviceListHelper(&connecting_devices_, list[i]);
17158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch      } else if (list[i].connected && list[i].paired) {
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        new_connected_devices.insert(list[i].address);
173e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        UpdateBluetoothDeviceListHelper(&connected_devices_, list[i]);
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else if (list[i].paired) {
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        new_paired_not_connected_devices.insert(list[i].address);
176e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        UpdateBluetoothDeviceListHelper(
177e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            &paired_not_connected_devices_, list[i]);
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else {
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        new_discovered_not_paired_devices.insert(list[i].address);
180e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        UpdateBluetoothDeviceListHelper(
181e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch            &discovered_not_paired_devices_, list[i]);
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RemoveObsoleteBluetoothDevicesFromList(&connecting_devices_,
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           new_connecting_devices);
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RemoveObsoleteBluetoothDevicesFromList(&connected_devices_,
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           new_connected_devices);
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RemoveObsoleteBluetoothDevicesFromList(&paired_not_connected_devices_,
18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           new_paired_not_connected_devices);
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RemoveObsoleteBluetoothDevicesFromList(&discovered_not_paired_devices_,
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           new_discovered_not_paired_devices);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AppendHeaderEntry() {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateSpecialRow(IDS_ASH_STATUS_TRAY_BLUETOOTH, this);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (login_ == user::LOGGED_IN_LOCKED)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    throbber_ = new ThrobberView;
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    throbber_->SetTooltipText(
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCOVERING));
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    footer()->AddThrobber(throbber_);
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Do not allow toggling bluetooth in the lock screen.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ash::SystemTrayDelegate* delegate =
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate();
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    toggle_bluetooth_ = new TrayPopupHeaderButton(this,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IDR_AURA_UBER_TRAY_BLUETOOTH_ENABLED,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IDR_AURA_UBER_TRAY_BLUETOOTH_DISABLED,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IDR_AURA_UBER_TRAY_BLUETOOTH_ENABLED_HOVER,
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IDR_AURA_UBER_TRAY_BLUETOOTH_DISABLED_HOVER,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IDS_ASH_STATUS_TRAY_BLUETOOTH);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    toggle_bluetooth_->SetToggled(!delegate->GetBluetoothEnabled());
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    toggle_bluetooth_->SetTooltipText(
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISABLE_BLUETOOTH));
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    toggle_bluetooth_->SetToggledTooltipText(
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ENABLE_BLUETOOTH));
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    footer()->AddButton(toggle_bluetooth_);
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateHeaderEntry() {
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (toggle_bluetooth_) {
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      toggle_bluetooth_->SetToggled(
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          !ash::Shell::GetInstance()->system_tray_delegate()->
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetBluetoothEnabled());
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateDeviceScrollList() {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    device_map_.clear();
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scroll_content()->RemoveAllChildViews(true);
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    enable_bluetooth_ = NULL;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ash::SystemTrayDelegate* delegate =
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate();
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool bluetooth_enabled = delegate->GetBluetoothEnabled();
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool blueooth_available = delegate->GetBluetoothAvailable();
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (blueooth_available && !bluetooth_enabled &&
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        toggle_bluetooth_) {
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      enable_bluetooth_ =
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          AddScrollListItem(
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ENABLE_BLUETOOTH),
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              gfx::Font::NORMAL, false, true);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendSameTypeDevicesToScrollList(
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        connected_devices_, true, true, bluetooth_enabled);
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendSameTypeDevicesToScrollList(
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        connecting_devices_, true, false, bluetooth_enabled);
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    AppendSameTypeDevicesToScrollList(
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        paired_not_connected_devices_, false, false, bluetooth_enabled);
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (discovered_not_paired_devices_.size() > 0)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AddScrollSeparator();
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendSameTypeDevicesToScrollList(
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        discovered_not_paired_devices_, false, false, bluetooth_enabled);
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Show user Bluetooth state if there is no bluetooth devices in list.
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (device_map_.size() == 0) {
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (blueooth_available && bluetooth_enabled) {
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        AddScrollListItem(
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            l10n_util::GetStringUTF16(
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCOVERING),
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            gfx::Font::NORMAL, false, true);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scroll_content()->SizeToPreferredSize();
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    static_cast<views::View*>(scroller())->Layout();
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendSameTypeDevicesToScrollList(const BluetoothDeviceList& list,
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool bold,
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool checked,
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool enabled) {
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < list.size(); ++i) {
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HoverHighlightView* container = AddScrollListItem(
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          list[i].display_name,
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          bold? gfx::Font::BOLD : gfx::Font::NORMAL,
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          checked, enabled);
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_map_[container] = list[i].address;
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HoverHighlightView* AddScrollListItem(const base::string16& text,
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        gfx::Font::FontStyle style,
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        bool checked,
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        bool enabled) {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HoverHighlightView* container = new HoverHighlightView(this);
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    views::Label* label = container->AddCheckableLabel(text, style, checked);
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    label->SetEnabled(enabled);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scroll_content()->AddChildView(container);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return container;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add settings entries.
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AppendSettingsEntries() {
298c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (!ash::Shell::GetInstance()->
299c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            system_tray_delegate()->ShouldShowSettings()) {
300c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      return;
301c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
302c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Add bluetooth device requires a browser window, hide it for non logged in
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // user.
3056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    bool userAddingRunning = ash::Shell::GetInstance()
3066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                 ->session_state_delegate()
3076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                 ->IsInSecondaryLoginScreen();
3086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (login_ == user::LOGGED_IN_NONE || login_ == user::LOGGED_IN_LOCKED ||
3106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        userAddingRunning)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ash::SystemTrayDelegate* delegate =
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate();
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HoverHighlightView* container = new HoverHighlightView(this);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    container->AddLabel(
318a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_BLUETOOTH_MANAGE_DEVICES),
319a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        gfx::ALIGN_LEFT,
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Font::NORMAL);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    container->SetEnabled(delegate->GetBluetoothAvailable());
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddChildView(container);
323a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    manage_devices_ = container;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if the device with |device_id| is found in |device_list|,
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // and the display_name of the device will be returned in |display_name| if
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // it's not NULL.
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool FoundDevice(const std::string& device_id,
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   const BluetoothDeviceList& device_list,
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::string16* display_name) {
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < device_list.size(); ++i) {
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (device_list[i].address == device_id) {
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (display_name)
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          *display_name = device_list[i].display_name;
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return true;
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Updates UI of the clicked bluetooth device to show it is being connected
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // or disconnected if such an operation is going to be performed underway.
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateClickedDevice(std::string device_id, views::View* item_container) {
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::string16 display_name;
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (FoundDevice(device_id, paired_not_connected_devices_,
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           &display_name)) {
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      display_name = l10n_util::GetStringFUTF16(
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          IDS_ASH_STATUS_TRAY_BLUETOOTH_CONNECTING, display_name);
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      item_container->RemoveAllChildViews(true);
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<HoverHighlightView*>(item_container)->
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          AddCheckableLabel(display_name, gfx::Font::BOLD, false);
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scroll_content()->SizeToPreferredSize();
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<views::View*>(scroller())->Layout();
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from ViewClickListener.
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnViewClicked(views::View* sender) OVERRIDE {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ash::SystemTrayDelegate* delegate =
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate();
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sender == footer()->content()) {
364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      TransitionToDefaultView();
365a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    } else if (sender == manage_devices_) {
366a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      delegate->ManageBluetoothDevices();
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (sender == enable_bluetooth_) {
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Shell::GetInstance()->metrics()->RecordUserMetricsAction(
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          delegate->GetBluetoothEnabled() ?
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          ash::UMA_STATUS_AREA_BLUETOOTH_DISABLED :
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          ash::UMA_STATUS_AREA_BLUETOOTH_ENABLED);
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delegate->ToggleBluetooth();
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (!delegate->GetBluetoothEnabled())
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::map<views::View*, std::string>::iterator find;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      find = device_map_.find(sender);
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (find == device_map_.end())
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return;
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::string device_id = find->second;
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (FoundDevice(device_id, connecting_devices_, NULL))
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return;
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      UpdateClickedDevice(device_id, sender);
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      delegate->ConnectToBluetoothDevice(device_id);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from ButtonListener.
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ButtonPressed(views::Button* sender,
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const ui::Event& event) OVERRIDE {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ash::SystemTrayDelegate* delegate =
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate();
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sender == toggle_bluetooth_)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate->ToggleBluetooth();
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  user::LoginStatus login_;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<views::View*, std::string> device_map_;
402a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  views::View* manage_devices_;
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ThrobberView* throbber_;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TrayPopupHeaderButton* toggle_bluetooth_;
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HoverHighlightView* enable_bluetooth_;
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BluetoothDeviceList connected_devices_;
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDeviceList connecting_devices_;
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BluetoothDeviceList paired_not_connected_devices_;
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BluetoothDeviceList discovered_not_paired_devices_;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BluetoothDetailedView);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace tray
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TrayBluetooth::TrayBluetooth(SystemTray* system_tray)
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : SystemTrayItem(system_tray),
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default_(NULL),
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      detailed_(NULL) {
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->system_tray_notifier()->AddBluetoothObserver(this);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TrayBluetooth::~TrayBluetooth() {
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->system_tray_notifier()->RemoveBluetoothObserver(this);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayBluetooth::CreateTrayView(user::LoginStatus status) {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayBluetooth::CreateDefaultView(user::LoginStatus status) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(default_ == NULL);
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  default_ = new tray::BluetoothDefaultView(
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      this, status != user::LOGGED_IN_LOCKED);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return default_;
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayBluetooth::CreateDetailedView(user::LoginStatus status) {
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!Shell::GetInstance()->system_tray_delegate()->GetBluetoothAvailable())
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Shell::GetInstance()->metrics()->RecordUserMetricsAction(
4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ash::UMA_STATUS_AREA_DETAILED_BLUETOOTH_VIEW);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(detailed_ == NULL);
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  detailed_ = new tray::BluetoothDetailedView(this, status);
445e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  detailed_->Update();
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return detailed_;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayBluetooth::DestroyTrayView() {
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayBluetooth::DestroyDefaultView() {
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  default_ = NULL;
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayBluetooth::DestroyDetailedView() {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  detailed_ = NULL;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayBluetooth::UpdateAfterLoginStatusChange(user::LoginStatus status) {
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayBluetooth::OnBluetoothRefresh() {
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (default_)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default_->UpdateLabel();
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (detailed_)
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    detailed_->Update();
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayBluetooth::OnBluetoothDiscoveringChanged() {
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!detailed_)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  detailed_->Update();
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
477