tray_bluetooth.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/fixed_sized_scroll_view.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/hover_highlight_view.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/system_tray.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/system_tray_delegate.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/system_tray_notifier.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/throbber_view.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_constants.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_details_view.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_item_more.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/system/tray/tray_popup_header_button.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_resources.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_strings.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/image_view.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/box_layout.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace tray {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace {
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Updates bluetooth device |device| in the |list|. If it is new, append to the
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// end of the |list|; otherwise, keep it at the same place, but update the data
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// with new device info provided by |device|.
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void UpdateBluetoothDeviceList(BluetoothDeviceList* list,
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               const BluetoothDeviceInfo& device) {
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (BluetoothDeviceList::iterator it = list->begin(); it != list->end();
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       ++it) {
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if ((*it).address == device.address) {
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      *it = device;
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  list->push_back(device);
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Removes the obsolete BluetoothDevices from |list|, if they are not in the
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// |new_list|.
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void RemoveObsoleteBluetoothDevicesFromList(
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    BluetoothDeviceList* list,
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::set<std::string>& new_list) {
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (BluetoothDeviceList::iterator it = list->begin(); it != list->end();
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       ++it) {
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (new_list.find((*it).address) == new_list.end()) {
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      it = list->erase(it);
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (it == list->end())
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        return;
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BluetoothDefaultView : public TrayItemMore {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BluetoothDefaultView(SystemTrayItem* owner, bool show_more)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : TrayItemMore(owner, show_more) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_BLUETOOTH).ToImageSkia());
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateLabel();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~BluetoothDefaultView() {}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateLabel() {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ash::SystemTrayDelegate* delegate =
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate->GetBluetoothAvailable()) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const base::string16 label =
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          rb.GetLocalizedString(delegate->GetBluetoothEnabled() ?
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              IDS_ASH_STATUS_TRAY_BLUETOOTH_ENABLED :
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              IDS_ASH_STATUS_TRAY_BLUETOOTH_DISABLED);
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetLabel(label);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetAccessibleName(label);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetVisible(true);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetVisible(false);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BluetoothDefaultView);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BluetoothDetailedView : public TrayDetailsView,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              public ViewClickListener,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              public views::ButtonListener {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BluetoothDetailedView(SystemTrayItem* owner, user::LoginStatus login)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : TrayDetailsView(owner),
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        login_(login),
106a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        manage_devices_(NULL),
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        toggle_bluetooth_(NULL),
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        enable_bluetooth_(NULL),
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        bluetooth_discovering_(false) {
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateItems();
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Update();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~BluetoothDetailedView() {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Stop discovering bluetooth devices when exiting BT detailed view.
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BluetoothStopDiscovering();
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Update() {
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BluetoothStartDiscovering();
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateBlueToothDeviceList();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Update UI.
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateDeviceScrollList();
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateHeaderEntry();
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Layout();
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CreateItems() {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateScrollableList();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppendSettingsEntries();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppendHeaderEntry();
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void BluetoothStartDiscovering() {
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ash::SystemTrayDelegate* delegate =
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate();
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool bluetooth_enabled = delegate->GetBluetoothEnabled();
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!bluetooth_discovering_ && bluetooth_enabled) {
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      bluetooth_discovering_ = true;
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delegate->BluetoothStartDiscovering();
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      throbber_->Start();
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if(!bluetooth_enabled) {
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      bluetooth_discovering_ = false;
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      throbber_->Stop();
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void BluetoothStopDiscovering() {
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ash::SystemTrayDelegate* delegate =
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate();
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (delegate && bluetooth_discovering_) {
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bluetooth_discovering_ = false;
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delegate->BluetoothStopDiscovering();
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      throbber_->Stop();
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateBlueToothDeviceList() {
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::set<std::string> new_connecting_devices;
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::set<std::string> new_connected_devices;
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::set<std::string> new_paired_not_connected_devices;
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::set<std::string> new_discovered_not_paired_devices;
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BluetoothDeviceList list;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Shell::GetInstance()->system_tray_delegate()->
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GetAvailableBluetoothDevices(&list);
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < list.size(); ++i) {
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (list[i].connecting) {
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        list[i].display_name = l10n_util::GetStringFUTF16(
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            IDS_ASH_STATUS_TRAY_BLUETOOTH_CONNECTING, list[i].display_name);
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        new_connecting_devices.insert(list[i].address);
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        UpdateBluetoothDeviceList(&connecting_devices_, list[i]);
17558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch      } else if (list[i].connected && list[i].paired) {
17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        new_connected_devices.insert(list[i].address);
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        UpdateBluetoothDeviceList(&connected_devices_, list[i]);
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else if (list[i].paired) {
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        new_paired_not_connected_devices.insert(list[i].address);
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        UpdateBluetoothDeviceList(&paired_not_connected_devices_, list[i]);
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else {
18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        new_discovered_not_paired_devices.insert(list[i].address);
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        UpdateBluetoothDeviceList(&discovered_not_paired_devices_, list[i]);
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RemoveObsoleteBluetoothDevicesFromList(&connecting_devices_,
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           new_connecting_devices);
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RemoveObsoleteBluetoothDevicesFromList(&connected_devices_,
18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           new_connected_devices);
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RemoveObsoleteBluetoothDevicesFromList(&paired_not_connected_devices_,
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           new_paired_not_connected_devices);
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RemoveObsoleteBluetoothDevicesFromList(&discovered_not_paired_devices_,
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           new_discovered_not_paired_devices);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AppendHeaderEntry() {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateSpecialRow(IDS_ASH_STATUS_TRAY_BLUETOOTH, this);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (login_ == user::LOGGED_IN_LOCKED)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    throbber_ = new ThrobberView;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    throbber_->SetTooltipText(
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCOVERING));
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    footer()->AddThrobber(throbber_);
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Do not allow toggling bluetooth in the lock screen.
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ash::SystemTrayDelegate* delegate =
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate();
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    toggle_bluetooth_ = new TrayPopupHeaderButton(this,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IDR_AURA_UBER_TRAY_BLUETOOTH_ENABLED,
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IDR_AURA_UBER_TRAY_BLUETOOTH_DISABLED,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IDR_AURA_UBER_TRAY_BLUETOOTH_ENABLED_HOVER,
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IDR_AURA_UBER_TRAY_BLUETOOTH_DISABLED_HOVER,
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IDS_ASH_STATUS_TRAY_BLUETOOTH);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    toggle_bluetooth_->SetToggled(!delegate->GetBluetoothEnabled());
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    toggle_bluetooth_->SetTooltipText(
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISABLE_BLUETOOTH));
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    toggle_bluetooth_->SetToggledTooltipText(
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ENABLE_BLUETOOTH));
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    footer()->AddButton(toggle_bluetooth_);
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateHeaderEntry() {
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (toggle_bluetooth_) {
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      toggle_bluetooth_->SetToggled(
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          !ash::Shell::GetInstance()->system_tray_delegate()->
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetBluetoothEnabled());
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateDeviceScrollList() {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    device_map_.clear();
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scroll_content()->RemoveAllChildViews(true);
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    enable_bluetooth_ = NULL;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ash::SystemTrayDelegate* delegate =
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate();
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool bluetooth_enabled = delegate->GetBluetoothEnabled();
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool blueooth_available = delegate->GetBluetoothAvailable();
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (blueooth_available && !bluetooth_enabled &&
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        toggle_bluetooth_) {
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      enable_bluetooth_ =
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          AddScrollListItem(
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ENABLE_BLUETOOTH),
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              gfx::Font::NORMAL, false, true);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendSameTypeDevicesToScrollList(
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        connected_devices_, true, true, bluetooth_enabled);
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendSameTypeDevicesToScrollList(
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        connecting_devices_, true, false, bluetooth_enabled);
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    AppendSameTypeDevicesToScrollList(
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        paired_not_connected_devices_, false, false, bluetooth_enabled);
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (discovered_not_paired_devices_.size() > 0)
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AddScrollSeparator();
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendSameTypeDevicesToScrollList(
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        discovered_not_paired_devices_, false, false, bluetooth_enabled);
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Show user Bluetooth state if there is no bluetooth devices in list.
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (device_map_.size() == 0) {
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (blueooth_available && bluetooth_enabled) {
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        AddScrollListItem(
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            l10n_util::GetStringUTF16(
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCOVERING),
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            gfx::Font::NORMAL, false, true);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scroll_content()->SizeToPreferredSize();
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    static_cast<views::View*>(scroller())->Layout();
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendSameTypeDevicesToScrollList(const BluetoothDeviceList& list,
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool bold,
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool checked,
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool enabled) {
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < list.size(); ++i) {
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HoverHighlightView* container = AddScrollListItem(
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          list[i].display_name,
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          bold? gfx::Font::BOLD : gfx::Font::NORMAL,
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          checked, enabled);
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_map_[container] = list[i].address;
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HoverHighlightView* AddScrollListItem(const base::string16& text,
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        gfx::Font::FontStyle style,
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        bool checked,
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        bool enabled) {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HoverHighlightView* container = new HoverHighlightView(this);
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    views::Label* label = container->AddCheckableLabel(text, style, checked);
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    label->SetEnabled(enabled);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scroll_content()->AddChildView(container);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return container;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add settings entries.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AppendSettingsEntries() {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Add bluetooth device requires a browser window, hide it for non logged in
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // user.
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (login_ == user::LOGGED_IN_NONE ||
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        login_ == user::LOGGED_IN_LOCKED)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ash::SystemTrayDelegate* delegate =
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate();
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HoverHighlightView* container = new HoverHighlightView(this);
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    container->AddLabel(
311a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_BLUETOOTH_MANAGE_DEVICES),
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Font::NORMAL);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    container->SetEnabled(delegate->GetBluetoothAvailable());
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddChildView(container);
315a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    manage_devices_ = container;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if the device with |device_id| is found in |device_list|,
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // and the display_name of the device will be returned in |display_name| if
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // it's not NULL.
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool FoundDevice(const std::string& device_id,
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   const BluetoothDeviceList& device_list,
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::string16* display_name) {
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < device_list.size(); ++i) {
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (device_list[i].address == device_id) {
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (display_name)
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          *display_name = device_list[i].display_name;
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return true;
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Updates UI of the clicked bluetooth device to show it is being connected
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // or disconnected if such an operation is going to be performed underway.
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateClickedDevice(std::string device_id, views::View* item_container) {
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::string16 display_name;
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (FoundDevice(device_id, paired_not_connected_devices_,
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           &display_name)) {
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      display_name = l10n_util::GetStringFUTF16(
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          IDS_ASH_STATUS_TRAY_BLUETOOTH_CONNECTING, display_name);
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      item_container->RemoveAllChildViews(true);
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<HoverHighlightView*>(item_container)->
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          AddCheckableLabel(display_name, gfx::Font::BOLD, false);
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scroll_content()->SizeToPreferredSize();
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<views::View*>(scroller())->Layout();
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from ViewClickListener.
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnViewClicked(views::View* sender) OVERRIDE {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ash::SystemTrayDelegate* delegate =
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate();
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sender == footer()->content()) {
356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      TransitionToDefaultView();
357a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    } else if (sender == manage_devices_) {
358a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      delegate->ManageBluetoothDevices();
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (sender == enable_bluetooth_) {
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Shell::GetInstance()->metrics()->RecordUserMetricsAction(
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          delegate->GetBluetoothEnabled() ?
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          ash::UMA_STATUS_AREA_BLUETOOTH_DISABLED :
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          ash::UMA_STATUS_AREA_BLUETOOTH_ENABLED);
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delegate->ToggleBluetooth();
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (!delegate->GetBluetoothEnabled())
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::map<views::View*, std::string>::iterator find;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      find = device_map_.find(sender);
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (find == device_map_.end())
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return;
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::string device_id = find->second;
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (FoundDevice(device_id, connecting_devices_, NULL))
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return;
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      UpdateClickedDevice(device_id, sender);
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      delegate->ConnectToBluetoothDevice(device_id);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from ButtonListener.
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ButtonPressed(views::Button* sender,
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const ui::Event& event) OVERRIDE {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ash::SystemTrayDelegate* delegate =
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate();
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sender == toggle_bluetooth_)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate->ToggleBluetooth();
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  user::LoginStatus login_;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<views::View*, std::string> device_map_;
394a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  views::View* manage_devices_;
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ThrobberView* throbber_;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TrayPopupHeaderButton* toggle_bluetooth_;
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HoverHighlightView* enable_bluetooth_;
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BluetoothDeviceList connected_devices_;
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDeviceList connecting_devices_;
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BluetoothDeviceList paired_not_connected_devices_;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BluetoothDeviceList discovered_not_paired_devices_;
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool bluetooth_discovering_;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BluetoothDetailedView);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace tray
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TrayBluetooth::TrayBluetooth(SystemTray* system_tray)
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : SystemTrayItem(system_tray),
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default_(NULL),
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      detailed_(NULL) {
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->system_tray_notifier()->AddBluetoothObserver(this);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TrayBluetooth::~TrayBluetooth() {
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->system_tray_notifier()->RemoveBluetoothObserver(this);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayBluetooth::CreateTrayView(user::LoginStatus status) {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayBluetooth::CreateDefaultView(user::LoginStatus status) {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(default_ == NULL);
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  default_ = new tray::BluetoothDefaultView(
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      this, status != user::LOGGED_IN_LOCKED);
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return default_;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayBluetooth::CreateDetailedView(user::LoginStatus status) {
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!Shell::GetInstance()->system_tray_delegate()->GetBluetoothAvailable())
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Shell::GetInstance()->metrics()->RecordUserMetricsAction(
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ash::UMA_STATUS_AREA_DETAILED_BLUETOOTH_VIEW);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(detailed_ == NULL);
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  detailed_ = new tray::BluetoothDetailedView(this, status);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return detailed_;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayBluetooth::DestroyTrayView() {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayBluetooth::DestroyDefaultView() {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  default_ = NULL;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayBluetooth::DestroyDetailedView() {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  detailed_ = NULL;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayBluetooth::UpdateAfterLoginStatusChange(user::LoginStatus status) {
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayBluetooth::OnBluetoothRefresh() {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (default_)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default_->UpdateLabel();
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (detailed_)
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    detailed_->Update();
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayBluetooth::OnBluetoothDiscoveringChanged() {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!detailed_)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  detailed_->Update();
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
470