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
......@@ -22,18 +22,31 @@ class BluetoothDetailedView : public TrayDetailedView {
~BluetoothDetailedView() override;
void Update();
// Shows/hides the loading indicator below the header.
void ShowLoadingIndicator();
void HideLoadingIndicator();
private:
void CreateItems();
// Shows/hides the container of the message "Bluetooth is disabled". It should
// 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,
bool highlight,
bool checked);
......@@ -47,31 +60,24 @@ class BluetoothDetailedView : public TrayDetailedView {
void UpdateClickedDevice(const std::string& device_id,
views::View* item_container);
void ShowSettings();
std::string GetFocusedDeviceAddress() const;
void FocusDeviceByAddress(const std::string& address) const;
// TrayDetailedView:
void HandleViewClicked(views::View* view) override;
void HandleButtonPressed(views::Button* sender,
const ui::Event& event) 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.
LoginStatus login_;
std::map<views::View*, std::string> device_map_;
BluetoothDeviceList connected_devices_;
BluetoothDeviceList connecting_devices_;
BluetoothDeviceList paired_not_connected_devices_;
BluetoothDeviceList discovered_not_paired_devices_;
views::ToggleButton* toggle_;
views::Button* settings_;
......@@ -80,9 +86,6 @@ class BluetoothDetailedView : public TrayDetailedView {
// be shown instead of Bluetooth device list when Bluetooth is disabled.
views::View* disabled_panel_;
// Timer used to limit the update frequency.
base::OneShotTimer timer_;
DISALLOW_COPY_AND_ASSIGN(BluetoothDetailedView);
};
......
......@@ -7,11 +7,51 @@
#include "ash/session/session_controller.h"
#include "ash/shell.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/unified/unified_detailed_view_delegate.h"
using device::mojom::BluetoothSystem;
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(
UnifiedSystemTrayController* tray_controller)
: detailed_view_delegate_(
......@@ -22,6 +62,12 @@ UnifiedBluetoothDetailedViewController::UnifiedBluetoothDetailedViewController(
UnifiedBluetoothDetailedViewController::
~UnifiedBluetoothDetailedViewController() {
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() {
......@@ -29,16 +75,118 @@ views::View* UnifiedBluetoothDetailedViewController::CreateView() {
view_ = new tray::BluetoothDetailedView(
detailed_view_delegate_.get(),
Shell::Get()->session_controller()->login_status());
view_->Update();
Update();
return view_;
}
void UnifiedBluetoothDetailedViewController::OnBluetoothRefresh() {
view_->Update();
Update();
}
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
......@@ -8,8 +8,10 @@
#include <memory>
#include "ash/system/bluetooth/bluetooth_observer.h"
#include "ash/system/bluetooth/tray_bluetooth_helper.h"
#include "ash/system/unified/detailed_view_controller.h"
#include "base/macros.h"
#include "base/timer/timer.h"
namespace ash {
......@@ -36,10 +38,24 @@ class UnifiedBluetoothDetailedViewController : public DetailedViewController,
void OnBluetoothDiscoveringChanged() override;
private:
void Update();
void DoUpdate();
void BluetoothStartDiscovering();
void UpdateBluetoothDeviceList();
void UpdateDeviceScrollList();
const std::unique_ptr<DetailedViewDelegate> detailed_view_delegate_;
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);
};
......
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