Commit 9d948785 authored by Giovanni Ortuño Urquidi's avatar Giovanni Ortuño Urquidi Committed by Commit Bot

bluetooth: Move controller logic out of BluetoothDetailedView

For the most part, this CL just moves the controller logic out of
BluetoothDetailedView and into UnifiedBluetoothDetailedViewController.

But there are three exceptions:

1. Before, Layout() was called at the end of
   BluetoothDetailedView::DoUpdate(). Now, Layout() is called
   indirectly in UpdateDeviceScrollList() through,
   ShowBluetoothDisabledPanel, HideBluetoothDisabledPanel, and
   BluetoothDetailedView::UpdateDeviceScrollList().

2. BluetoothDetailedView::UpdateDeviceScrollList() used to perform the
   following steps:

   1. Clear the device list
   2. If state is not "powered" show the "bluetooth disabled" panel
      and return.
   3. Otherwise hide the "bluetooth disabled" panel.
   4. Update the device list.

   Now UBDVC::UpdateDeviceScrollList() performs the following steps:

   1. If state is not "powered" then call
      BDV::ShowBluetoothDisabledPanel() and return
     1.1. Clear device list
     1.2. Show "bluetooth disabled" panel
   2. Otherwise call BDV::HideBluetoothDisabledPanel()
     2.1. Hide "bluetooth disabled" panel
   3. Call BDV::UpdateDeviceScrollList()
     3.1. Clear device list
     3.2. Populate device list with current devices.

   Similar set of steps but except that "clear device list" is
   performed by two separate functions.

3. Discovery stops when UnifiedBluetoothDetailedViewController gets
   destroyed. Before, discovery was stopped when BluetoothDetailedView
   was destroyed.


Change-Id: I4727bcdf35e0f84ab16ff0bace8f3d89aefc58de
Reviewed-on: https://chromium-review.googlesource.com/c/1308241
Commit-Queue: Giovanni Ortuño Urquidi <ortuno@chromium.org>
Reviewed-by: default avatarYoshiki Iguchi <yoshiki@chromium.org>
Cr-Commit-Position: refs/heads/master@{#605213}
parent 08ea554f
...@@ -25,40 +25,8 @@ namespace ash { ...@@ -25,40 +25,8 @@ namespace ash {
namespace tray { namespace tray {
namespace { namespace {
const int kUpdateFrequencyMs = 1000;
const int kDisabledPanelLabelBaselineY = 20; const int kDisabledPanelLabelBaselineY = 20;
// Updates bluetooth device |device| in the |list|. If it is new, append to the
// end of the |list|; otherwise, keep it at the same place, but update the data
// with new device info provided by |device|.
void UpdateBluetoothDeviceListHelper(BluetoothDeviceList* list,
const BluetoothDeviceInfo& device) {
for (BluetoothDeviceList::iterator it = list->begin(); it != list->end();
++it) {
if ((*it).address == device.address) {
*it = device;
return;
}
}
list->push_back(device);
}
// Removes the obsolete BluetoothDevices from |list|, if they are not in the
// |new_device_address_list|.
void RemoveObsoleteBluetoothDevicesFromList(
BluetoothDeviceList* device_list,
const std::set<std::string>& new_device_address_list) {
for (BluetoothDeviceList::iterator it = device_list->begin();
it != device_list->end(); ++it) {
if (!new_device_address_list.count((*it).address)) {
it = device_list->erase(it);
if (it == device_list->end())
return;
}
}
}
// Returns corresponding device type icons for given Bluetooth device types and // Returns corresponding device type icons for given Bluetooth device types and
// connection states. // connection states.
const gfx::VectorIcon& GetBluetoothDeviceIcon( const gfx::VectorIcon& GetBluetoothDeviceIcon(
...@@ -136,140 +104,82 @@ BluetoothDetailedView::BluetoothDetailedView(DetailedViewDelegate* delegate, ...@@ -136,140 +104,82 @@ BluetoothDetailedView::BluetoothDetailedView(DetailedViewDelegate* delegate,
CreateItems(); CreateItems();
} }
BluetoothDetailedView::~BluetoothDetailedView() { BluetoothDetailedView::~BluetoothDetailedView() = default;
// Stop discovering bluetooth devices when exiting BT detailed view.
BluetoothStopDiscovering();
}
void BluetoothDetailedView::Update() {
// Update immediately for initial device list and
// when bluetooth is disabled.
if (device_map_.empty() ||
Shell::Get()->tray_bluetooth_helper()->GetBluetoothState() !=
BluetoothSystem::State::kPoweredOn) {
timer_.Stop();
DoUpdate();
return;
}
// Return here since an update is already queued.
if (timer_.IsRunning())
return;
// Update the detailed view after kUpdateFrequencyMs. void BluetoothDetailedView::ShowLoadingIndicator() {
timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kUpdateFrequencyMs), // Setting a value of -1 gives progress_bar an infinite-loading behavior.
this, &BluetoothDetailedView::DoUpdate); ShowProgress(-1, true);
} }
void BluetoothDetailedView::CreateItems() { void BluetoothDetailedView::HideLoadingIndicator() {
CreateScrollableList(); ShowProgress(0, false);
CreateTitleRow(IDS_ASH_STATUS_TRAY_BLUETOOTH);
} }
void BluetoothDetailedView::BluetoothStartDiscovering() { void BluetoothDetailedView::ShowBluetoothDisabledPanel() {
TrayBluetoothHelper* helper = Shell::Get()->tray_bluetooth_helper(); device_map_.clear();
if (helper->HasBluetoothDiscoverySession()) { scroll_content()->RemoveAllChildViews(true);
ShowLoadingIndicator();
return;
}
HideLoadingIndicator();
if (helper->GetBluetoothState() == BluetoothSystem::State::kPoweredOn)
helper->StartBluetoothDiscovering();
}
void BluetoothDetailedView::BluetoothStopDiscovering() { DCHECK(scroller());
TrayBluetoothHelper* helper = Shell::Get()->tray_bluetooth_helper(); if (!disabled_panel_) {
if (helper && helper->HasBluetoothDiscoverySession()) { disabled_panel_ = CreateDisabledPanel();
helper->StopBluetoothDiscovering(); // Insert |disabled_panel_| before the scroller, since the scroller will
HideLoadingIndicator(); // have unnecessary bottom border when it is not the last child.
AddChildViewAt(disabled_panel_, GetIndexOf(scroller()));
// |disabled_panel_| need to fill the remaining space below the title row
// so that the inner contents of |disabled_panel_| are placed properly.
box_layout()->SetFlexForView(disabled_panel_, 1);
} }
disabled_panel_->SetVisible(true);
scroller()->SetVisible(false);
Layout();
} }
void BluetoothDetailedView::UpdateBluetoothDeviceList() { void BluetoothDetailedView::HideBluetoothDisabledPanel() {
std::set<std::string> new_connecting_devices; DCHECK(scroller());
std::set<std::string> new_connected_devices; if (disabled_panel_)
std::set<std::string> new_paired_not_connected_devices; disabled_panel_->SetVisible(false);
std::set<std::string> new_discovered_not_paired_devices; scroller()->SetVisible(true);
BluetoothDeviceList list = Layout();
Shell::Get()->tray_bluetooth_helper()->GetAvailableBluetoothDevices();
for (const auto& device : list) {
if (device.connecting) {
new_connecting_devices.insert(device.address);
UpdateBluetoothDeviceListHelper(&connecting_devices_, device);
} else if (device.connected && device.paired) {
new_connected_devices.insert(device.address);
UpdateBluetoothDeviceListHelper(&connected_devices_, device);
} else if (device.paired) {
new_paired_not_connected_devices.insert(device.address);
UpdateBluetoothDeviceListHelper(&paired_not_connected_devices_, device);
} else {
new_discovered_not_paired_devices.insert(device.address);
UpdateBluetoothDeviceListHelper(&discovered_not_paired_devices_, device);
}
}
RemoveObsoleteBluetoothDevicesFromList(&connecting_devices_,
new_connecting_devices);
RemoveObsoleteBluetoothDevicesFromList(&connected_devices_,
new_connected_devices);
RemoveObsoleteBluetoothDevicesFromList(&paired_not_connected_devices_,
new_paired_not_connected_devices);
RemoveObsoleteBluetoothDevicesFromList(&discovered_not_paired_devices_,
new_discovered_not_paired_devices);
} }
void BluetoothDetailedView::UpdateHeaderEntry() { bool BluetoothDetailedView::IsDeviceScrollListEmpty() const {
const bool is_bluetooth_enabled = return device_map_.empty();
Shell::Get()->tray_bluetooth_helper()->GetBluetoothState() ==
BluetoothSystem::State::kPoweredOn;
if (toggle_)
toggle_->SetIsOn(is_bluetooth_enabled, true);
} }
void BluetoothDetailedView::UpdateDeviceScrollList() { void BluetoothDetailedView::UpdateDeviceScrollList(
const BluetoothDeviceList& connected_devices,
const BluetoothDeviceList& connecting_devices,
const BluetoothDeviceList& paired_not_connected_devices,
const BluetoothDeviceList& discovered_not_paired_devices) {
connecting_devices_ = connecting_devices;
paired_not_connected_devices_ = paired_not_connected_devices;
std::string focused_device_address = GetFocusedDeviceAddress(); std::string focused_device_address = GetFocusedDeviceAddress();
device_map_.clear(); device_map_.clear();
scroll_content()->RemoveAllChildViews(true); scroll_content()->RemoveAllChildViews(true);
TrayBluetoothHelper* helper = Shell::Get()->tray_bluetooth_helper();
const BluetoothSystem::State bluetooth_state = helper->GetBluetoothState();
switch (bluetooth_state) {
case BluetoothSystem::State::kUnsupported:
// Bluetooth is always supported on Chrome OS.
NOTREACHED();
return;
case BluetoothSystem::State::kUnavailable:
case BluetoothSystem::State::kPoweredOff:
case BluetoothSystem::State::kTransitioning:
// If Bluetooth is disabled, show a panel which only indicates that it is
// disabled, instead of the scroller with Bluetooth devices.
ShowDisabledPanel();
return;
case BluetoothSystem::State::kPoweredOn:
HideDisabledPanel();
break;
}
// Add paired devices and their section header to the list. // Add paired devices and their section header to the list.
bool has_paired_devices = !connected_devices_.empty() || bool has_paired_devices = !connected_devices.empty() ||
!connecting_devices_.empty() || !connecting_devices.empty() ||
!paired_not_connected_devices_.empty(); !paired_not_connected_devices.empty();
if (has_paired_devices) { if (has_paired_devices) {
AddScrollListSubHeader(IDS_ASH_STATUS_TRAY_BLUETOOTH_PAIRED_DEVICES); AddScrollListSubHeader(IDS_ASH_STATUS_TRAY_BLUETOOTH_PAIRED_DEVICES);
AppendSameTypeDevicesToScrollList(connected_devices_, true, true); AppendSameTypeDevicesToScrollList(connected_devices, true, true);
AppendSameTypeDevicesToScrollList(connecting_devices_, true, false); AppendSameTypeDevicesToScrollList(connecting_devices, true, false);
AppendSameTypeDevicesToScrollList(paired_not_connected_devices_, false, AppendSameTypeDevicesToScrollList(paired_not_connected_devices, false,
false); false);
} }
// Add unpaired devices to the list. If at least one paired device is // Add unpaired devices to the list. If at least one paired device is
// present, also add a section header above the unpaired devices. // present, also add a section header above the unpaired devices.
if (!discovered_not_paired_devices_.empty()) { if (!discovered_not_paired_devices.empty()) {
if (has_paired_devices) if (has_paired_devices)
AddScrollListSubHeader(IDS_ASH_STATUS_TRAY_BLUETOOTH_UNPAIRED_DEVICES); AddScrollListSubHeader(IDS_ASH_STATUS_TRAY_BLUETOOTH_UNPAIRED_DEVICES);
AppendSameTypeDevicesToScrollList(discovered_not_paired_devices_, false, AppendSameTypeDevicesToScrollList(discovered_not_paired_devices, false,
false); false);
} }
...@@ -284,6 +194,18 @@ void BluetoothDetailedView::UpdateDeviceScrollList() { ...@@ -284,6 +194,18 @@ void BluetoothDetailedView::UpdateDeviceScrollList() {
FocusDeviceByAddress(focused_device_address); FocusDeviceByAddress(focused_device_address);
scroll_content()->InvalidateLayout(); scroll_content()->InvalidateLayout();
Layout();
}
void BluetoothDetailedView::SetToggleIsOn(bool is_on) {
if (toggle_)
toggle_->SetIsOn(is_on, true);
}
void BluetoothDetailedView::CreateItems() {
CreateScrollableList();
CreateTitleRow(IDS_ASH_STATUS_TRAY_BLUETOOTH);
} }
void BluetoothDetailedView::AppendSameTypeDevicesToScrollList( void BluetoothDetailedView::AppendSameTypeDevicesToScrollList(
...@@ -325,6 +247,31 @@ void BluetoothDetailedView::UpdateClickedDevice( ...@@ -325,6 +247,31 @@ void BluetoothDetailedView::UpdateClickedDevice(
} }
} }
void BluetoothDetailedView::ShowSettings() {
if (TrayPopupUtils::CanOpenWebUISettings()) {
Shell::Get()->system_tray_model()->client_ptr()->ShowBluetoothSettings();
CloseBubble();
}
}
std::string BluetoothDetailedView::GetFocusedDeviceAddress() const {
for (const auto& view_and_address : device_map_) {
if (view_and_address.first->HasFocus())
return view_and_address.second;
}
return std::string();
}
void BluetoothDetailedView::FocusDeviceByAddress(
const std::string& address) const {
for (auto& view_and_address : device_map_) {
if (view_and_address.second == address) {
view_and_address.first->RequestFocus();
return;
}
}
}
void BluetoothDetailedView::HandleViewClicked(views::View* view) { void BluetoothDetailedView::HandleViewClicked(views::View* view) {
TrayBluetoothHelper* helper = Shell::Get()->tray_bluetooth_helper(); TrayBluetoothHelper* helper = Shell::Get()->tray_bluetooth_helper();
if (helper->GetBluetoothState() != BluetoothSystem::State::kPoweredOn) if (helper->GetBluetoothState() != BluetoothSystem::State::kPoweredOn)
...@@ -375,71 +322,5 @@ void BluetoothDetailedView::CreateExtraTitleRowButtons() { ...@@ -375,71 +322,5 @@ void BluetoothDetailedView::CreateExtraTitleRowButtons() {
tri_view()->AddView(TriView::Container::END, settings_); tri_view()->AddView(TriView::Container::END, settings_);
} }
void BluetoothDetailedView::ShowSettings() {
if (TrayPopupUtils::CanOpenWebUISettings()) {
Shell::Get()->system_tray_model()->client_ptr()->ShowBluetoothSettings();
CloseBubble();
}
}
void BluetoothDetailedView::ShowLoadingIndicator() {
// Setting a value of -1 gives progress_bar an infinite-loading behavior.
ShowProgress(-1, true);
}
void BluetoothDetailedView::HideLoadingIndicator() {
ShowProgress(0, false);
}
void BluetoothDetailedView::ShowDisabledPanel() {
DCHECK(scroller());
if (!disabled_panel_) {
disabled_panel_ = CreateDisabledPanel();
// Insert |disabled_panel_| before the scroller, since the scroller will
// have unnecessary bottom border when it is not the last child.
AddChildViewAt(disabled_panel_, GetIndexOf(scroller()));
// |disabled_panel_| need to fill the remaining space below the title row
// so that the inner contents of |disabled_panel_| are placed properly.
box_layout()->SetFlexForView(disabled_panel_, 1);
}
disabled_panel_->SetVisible(true);
scroller()->SetVisible(false);
}
void BluetoothDetailedView::HideDisabledPanel() {
DCHECK(scroller());
if (disabled_panel_)
disabled_panel_->SetVisible(false);
scroller()->SetVisible(true);
}
std::string BluetoothDetailedView::GetFocusedDeviceAddress() const {
for (auto& view_and_address : device_map_) {
if (view_and_address.first->HasFocus())
return view_and_address.second;
}
return std::string();
}
void BluetoothDetailedView::FocusDeviceByAddress(
const std::string& address) const {
for (auto& view_and_address : device_map_) {
if (view_and_address.second == address) {
view_and_address.first->RequestFocus();
return;
}
}
}
void BluetoothDetailedView::DoUpdate() {
BluetoothStartDiscovering();
UpdateBluetoothDeviceList();
// Update UI.
UpdateDeviceScrollList();
UpdateHeaderEntry();
Layout();
}
} // namespace tray } // namespace tray
} // namespace ash } // namespace ash
...@@ -22,18 +22,31 @@ class BluetoothDetailedView : public TrayDetailedView { ...@@ -22,18 +22,31 @@ class BluetoothDetailedView : public TrayDetailedView {
~BluetoothDetailedView() override; ~BluetoothDetailedView() override;
void Update(); // Shows/hides the loading indicator below the header.
void ShowLoadingIndicator();
void HideLoadingIndicator();
private: // Shows/hides the container of the message "Bluetooth is disabled". It should
void CreateItems(); // be shown instead of the device list when Bluetooth is disabled.
void ShowBluetoothDisabledPanel();
void HideBluetoothDisabledPanel();
// Returns true if the device list has any devices, false otherwise.
bool IsDeviceScrollListEmpty() const;
void BluetoothStartDiscovering(); // Updates the device list.
void UpdateDeviceScrollList(
const BluetoothDeviceList& connected_devices,
const BluetoothDeviceList& connecting_devices,
const BluetoothDeviceList& paired_not_connected_devices,
const BluetoothDeviceList& discovered_not_paired_devices);
void BluetoothStopDiscovering(); // Sets the state of the toggle in the header.
void SetToggleIsOn(bool is_on);
private:
void CreateItems();
void UpdateBluetoothDeviceList();
void UpdateHeaderEntry();
void UpdateDeviceScrollList();
void AppendSameTypeDevicesToScrollList(const BluetoothDeviceList& list, void AppendSameTypeDevicesToScrollList(const BluetoothDeviceList& list,
bool highlight, bool highlight,
bool checked); bool checked);
...@@ -47,31 +60,24 @@ class BluetoothDetailedView : public TrayDetailedView { ...@@ -47,31 +60,24 @@ class BluetoothDetailedView : public TrayDetailedView {
void UpdateClickedDevice(const std::string& device_id, void UpdateClickedDevice(const std::string& device_id,
views::View* item_container); views::View* item_container);
void ShowSettings();
std::string GetFocusedDeviceAddress() const;
void FocusDeviceByAddress(const std::string& address) const;
// TrayDetailedView: // TrayDetailedView:
void HandleViewClicked(views::View* view) override; void HandleViewClicked(views::View* view) override;
void HandleButtonPressed(views::Button* sender, void HandleButtonPressed(views::Button* sender,
const ui::Event& event) override; const ui::Event& event) override;
void CreateExtraTitleRowButtons() override; void CreateExtraTitleRowButtons() override;
void ShowSettings();
void ShowLoadingIndicator();
void HideLoadingIndicator();
void ShowDisabledPanel();
void HideDisabledPanel();
std::string GetFocusedDeviceAddress() const;
void FocusDeviceByAddress(const std::string& address) const;
void DoUpdate();
// TODO(jamescook): Don't cache this. // TODO(jamescook): Don't cache this.
LoginStatus login_; LoginStatus login_;
std::map<views::View*, std::string> device_map_; std::map<views::View*, std::string> device_map_;
BluetoothDeviceList connected_devices_;
BluetoothDeviceList connecting_devices_; BluetoothDeviceList connecting_devices_;
BluetoothDeviceList paired_not_connected_devices_; BluetoothDeviceList paired_not_connected_devices_;
BluetoothDeviceList discovered_not_paired_devices_;
views::ToggleButton* toggle_; views::ToggleButton* toggle_;
views::Button* settings_; views::Button* settings_;
...@@ -80,9 +86,6 @@ class BluetoothDetailedView : public TrayDetailedView { ...@@ -80,9 +86,6 @@ class BluetoothDetailedView : public TrayDetailedView {
// be shown instead of Bluetooth device list when Bluetooth is disabled. // be shown instead of Bluetooth device list when Bluetooth is disabled.
views::View* disabled_panel_; views::View* disabled_panel_;
// Timer used to limit the update frequency.
base::OneShotTimer timer_;
DISALLOW_COPY_AND_ASSIGN(BluetoothDetailedView); DISALLOW_COPY_AND_ASSIGN(BluetoothDetailedView);
}; };
......
...@@ -7,11 +7,51 @@ ...@@ -7,11 +7,51 @@
#include "ash/session/session_controller.h" #include "ash/session/session_controller.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/system/bluetooth/bluetooth_detailed_view.h" #include "ash/system/bluetooth/bluetooth_detailed_view.h"
#include "ash/system/bluetooth/tray_bluetooth_helper.h"
#include "ash/system/tray/system_tray_notifier.h" #include "ash/system/tray/system_tray_notifier.h"
#include "ash/system/unified/unified_detailed_view_delegate.h" #include "ash/system/unified/unified_detailed_view_delegate.h"
using device::mojom::BluetoothSystem;
namespace ash { namespace ash {
const int kUpdateFrequencyMs = 1000;
namespace {
// Updates bluetooth device |device| in the |list|. If it is new, append to the
// end of the |list|; otherwise, keep it at the same place, but update the data
// with new device info provided by |device|.
void UpdateBluetoothDeviceListHelper(BluetoothDeviceList* list,
const BluetoothDeviceInfo& device) {
for (BluetoothDeviceList::iterator it = list->begin(); it != list->end();
++it) {
if ((*it).address == device.address) {
*it = device;
return;
}
}
list->push_back(device);
}
// Removes the obsolete BluetoothDevices from |list|, if they are not in the
// |new_device_address_list|.
void RemoveObsoleteBluetoothDevicesFromList(
BluetoothDeviceList* device_list,
const std::set<std::string>& new_device_address_list) {
for (BluetoothDeviceList::iterator it = device_list->begin();
it != device_list->end(); ++it) {
if (!new_device_address_list.count((*it).address)) {
it = device_list->erase(it);
if (it == device_list->end())
return;
}
}
}
} // namespace
UnifiedBluetoothDetailedViewController::UnifiedBluetoothDetailedViewController( UnifiedBluetoothDetailedViewController::UnifiedBluetoothDetailedViewController(
UnifiedSystemTrayController* tray_controller) UnifiedSystemTrayController* tray_controller)
: detailed_view_delegate_( : detailed_view_delegate_(
...@@ -22,6 +62,12 @@ UnifiedBluetoothDetailedViewController::UnifiedBluetoothDetailedViewController( ...@@ -22,6 +62,12 @@ UnifiedBluetoothDetailedViewController::UnifiedBluetoothDetailedViewController(
UnifiedBluetoothDetailedViewController:: UnifiedBluetoothDetailedViewController::
~UnifiedBluetoothDetailedViewController() { ~UnifiedBluetoothDetailedViewController() {
Shell::Get()->system_tray_notifier()->RemoveBluetoothObserver(this); Shell::Get()->system_tray_notifier()->RemoveBluetoothObserver(this);
// Stop discovering bluetooth devices when exiting BT detailed view.
TrayBluetoothHelper* helper = Shell::Get()->tray_bluetooth_helper();
if (helper && helper->HasBluetoothDiscoverySession()) {
helper->StopBluetoothDiscovering();
view_->HideLoadingIndicator();
}
} }
views::View* UnifiedBluetoothDetailedViewController::CreateView() { views::View* UnifiedBluetoothDetailedViewController::CreateView() {
...@@ -29,16 +75,118 @@ views::View* UnifiedBluetoothDetailedViewController::CreateView() { ...@@ -29,16 +75,118 @@ views::View* UnifiedBluetoothDetailedViewController::CreateView() {
view_ = new tray::BluetoothDetailedView( view_ = new tray::BluetoothDetailedView(
detailed_view_delegate_.get(), detailed_view_delegate_.get(),
Shell::Get()->session_controller()->login_status()); Shell::Get()->session_controller()->login_status());
view_->Update(); Update();
return view_; return view_;
} }
void UnifiedBluetoothDetailedViewController::OnBluetoothRefresh() { void UnifiedBluetoothDetailedViewController::OnBluetoothRefresh() {
view_->Update(); Update();
} }
void UnifiedBluetoothDetailedViewController::OnBluetoothDiscoveringChanged() { void UnifiedBluetoothDetailedViewController::OnBluetoothDiscoveringChanged() {
view_->Update(); Update();
}
void UnifiedBluetoothDetailedViewController::Update() {
// Update immediately for initial device list and
// when bluetooth is disabled.
if (view_->IsDeviceScrollListEmpty() ||
Shell::Get()->tray_bluetooth_helper()->GetBluetoothState() !=
BluetoothSystem::State::kPoweredOn) {
timer_.Stop();
DoUpdate();
return;
}
// Return here since an update is already queued.
if (timer_.IsRunning())
return;
// Update the detailed view after kUpdateFrequencyMs.
timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kUpdateFrequencyMs),
this, &UnifiedBluetoothDetailedViewController::DoUpdate);
}
void UnifiedBluetoothDetailedViewController::DoUpdate() {
BluetoothStartDiscovering();
UpdateBluetoothDeviceList();
// Update UI
view_->SetToggleIsOn(
Shell::Get()->tray_bluetooth_helper()->GetBluetoothState() ==
BluetoothSystem::State::kPoweredOn);
UpdateDeviceScrollList();
}
void UnifiedBluetoothDetailedViewController::BluetoothStartDiscovering() {
TrayBluetoothHelper* helper = Shell::Get()->tray_bluetooth_helper();
if (helper->HasBluetoothDiscoverySession()) {
view_->ShowLoadingIndicator();
return;
}
view_->HideLoadingIndicator();
if (helper->GetBluetoothState() == BluetoothSystem::State::kPoweredOn)
helper->StartBluetoothDiscovering();
}
void UnifiedBluetoothDetailedViewController::UpdateBluetoothDeviceList() {
std::set<std::string> new_connecting_devices;
std::set<std::string> new_connected_devices;
std::set<std::string> new_paired_not_connected_devices;
std::set<std::string> new_discovered_not_paired_devices;
BluetoothDeviceList list =
Shell::Get()->tray_bluetooth_helper()->GetAvailableBluetoothDevices();
for (const auto& device : list) {
if (device.connecting) {
new_connecting_devices.insert(device.address);
UpdateBluetoothDeviceListHelper(&connecting_devices_, device);
} else if (device.connected && device.paired) {
new_connected_devices.insert(device.address);
UpdateBluetoothDeviceListHelper(&connected_devices_, device);
} else if (device.paired) {
new_paired_not_connected_devices.insert(device.address);
UpdateBluetoothDeviceListHelper(&paired_not_connected_devices_, device);
} else {
new_discovered_not_paired_devices.insert(device.address);
UpdateBluetoothDeviceListHelper(&discovered_not_paired_devices_, device);
}
}
RemoveObsoleteBluetoothDevicesFromList(&connecting_devices_,
new_connecting_devices);
RemoveObsoleteBluetoothDevicesFromList(&connected_devices_,
new_connected_devices);
RemoveObsoleteBluetoothDevicesFromList(&paired_not_connected_devices_,
new_paired_not_connected_devices);
RemoveObsoleteBluetoothDevicesFromList(&discovered_not_paired_devices_,
new_discovered_not_paired_devices);
}
void UnifiedBluetoothDetailedViewController::UpdateDeviceScrollList() {
const BluetoothSystem::State bluetooth_state =
Shell::Get()->tray_bluetooth_helper()->GetBluetoothState();
switch (bluetooth_state) {
case BluetoothSystem::State::kUnsupported:
// Bluetooth is always supported on Chrome OS.
NOTREACHED();
return;
case BluetoothSystem::State::kUnavailable:
case BluetoothSystem::State::kPoweredOff:
case BluetoothSystem::State::kTransitioning:
// If Bluetooth is disabled, show a panel which only indicates that it is
// disabled, instead of the scroller with Bluetooth devices.
view_->ShowBluetoothDisabledPanel();
return;
case BluetoothSystem::State::kPoweredOn:
break;
}
view_->HideBluetoothDisabledPanel();
view_->UpdateDeviceScrollList(connected_devices_, connecting_devices_,
paired_not_connected_devices_,
discovered_not_paired_devices_);
} }
} // namespace ash } // namespace ash
...@@ -8,8 +8,10 @@ ...@@ -8,8 +8,10 @@
#include <memory> #include <memory>
#include "ash/system/bluetooth/bluetooth_observer.h" #include "ash/system/bluetooth/bluetooth_observer.h"
#include "ash/system/bluetooth/tray_bluetooth_helper.h"
#include "ash/system/unified/detailed_view_controller.h" #include "ash/system/unified/detailed_view_controller.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/timer/timer.h"
namespace ash { namespace ash {
...@@ -36,10 +38,24 @@ class UnifiedBluetoothDetailedViewController : public DetailedViewController, ...@@ -36,10 +38,24 @@ class UnifiedBluetoothDetailedViewController : public DetailedViewController,
void OnBluetoothDiscoveringChanged() override; void OnBluetoothDiscoveringChanged() override;
private: private:
void Update();
void DoUpdate();
void BluetoothStartDiscovering();
void UpdateBluetoothDeviceList();
void UpdateDeviceScrollList();
const std::unique_ptr<DetailedViewDelegate> detailed_view_delegate_; const std::unique_ptr<DetailedViewDelegate> detailed_view_delegate_;
tray::BluetoothDetailedView* view_ = nullptr; tray::BluetoothDetailedView* view_ = nullptr;
BluetoothDeviceList connected_devices_;
BluetoothDeviceList connecting_devices_;
BluetoothDeviceList paired_not_connected_devices_;
BluetoothDeviceList discovered_not_paired_devices_;
// Timer used to limit the update frequency.
base::OneShotTimer timer_;
DISALLOW_COPY_AND_ASSIGN(UnifiedBluetoothDetailedViewController); DISALLOW_COPY_AND_ASSIGN(UnifiedBluetoothDetailedViewController);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment