Skip to content

Commit

Permalink
Add Bluetooth feature tile to quick settings for QsRevamp
Browse files Browse the repository at this point in the history
This is a basic version of the feature tile that behaves identically to
the existing Bluetooth feature pod button in legacy quick settings.

https://screenshot.googleplex.com/Bir9sAKT9M3gCyt

Parameterize the existing unit tests by QsRevamp.

NOTE: This tile can cause the QS bubble to be too small. The Bluetooth
tile starts invisible, then becomes visible after an asynchronous query
for Bluetooth state. Because it is invisible during QS bubble
construction, the required height for the feature tiles container is
computed without this tile, and it can be too short. Filed b/262761315
for this issue.

Bug: b:252872600
Test: updated ash_unittests
Change-Id: Ie16039d11a19dd5d6cb4749e18c9114252981ea7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4111777
Reviewed-by: Jiaming Cheng <jiamingc@chromium.org>
Commit-Queue: James Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1084580}
  • Loading branch information
James Cook authored and Chromium LUCI CQ committed Dec 16, 2022
1 parent 10b6699 commit d13b1cc
Show file tree
Hide file tree
Showing 6 changed files with 316 additions and 149 deletions.
100 changes: 88 additions & 12 deletions ash/system/bluetooth/bluetooth_feature_pod_controller.cc
Expand Up @@ -4,14 +4,19 @@

#include "ash/system/bluetooth/bluetooth_feature_pod_controller.h"

#include <string>

#include "ash/constants/ash_features.h"
#include "ash/constants/quick_settings_catalogs.h"
#include "ash/public/cpp/bluetooth_config_service.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/unified/feature_pod_button.h"
#include "ash/system/unified/feature_tile.h"
#include "ash/system/unified/quick_settings_metrics_util.h"
#include "ash/system/unified/unified_system_tray_controller.h"
#include "base/check.h"
#include "base/functional/bind.h"
#include "base/i18n/number_formatting.h"
#include "base/strings/string_number_conversions.h"
#include "chromeos/ash/services/bluetooth_config/public/cpp/cros_bluetooth_config_util.h"
Expand Down Expand Up @@ -48,15 +53,32 @@ FeaturePodButton* BluetoothFeaturePodController::CreateButton() {
return button_;
}

std::unique_ptr<FeatureTile> BluetoothFeaturePodController::CreateTile() {
DCHECK(features::IsQsRevampEnabled());
auto tile = std::make_unique<FeatureTile>(
base::BindRepeating(&BluetoothFeaturePodController::OnIconPressed,
weak_factory_.GetWeakPtr()));
tile_ = tile.get();
tile_->CreateDrillInButton(
base::BindRepeating(&BluetoothFeaturePodController::OnLabelPressed,
weak_factory_.GetWeakPtr()),
l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_BLUETOOTH));
// UpdateTileStateIfExists() will update visibility.
tile_->SetVisible(false);
UpdateTileStateIfExists();
return tile;
}

QsFeatureCatalogName BluetoothFeaturePodController::GetCatalogName() {
return QsFeatureCatalogName::kBluetooth;
}

void BluetoothFeaturePodController::OnIconPressed() {
if (!button_->GetEnabled())
if (!IsButtonEnabled()) {
return;
}

const bool is_toggled = button_->IsToggled();
const bool is_toggled = IsButtonToggled();
remote_cros_bluetooth_config_->SetBluetoothEnabledState(!is_toggled);

if (is_toggled) {
Expand All @@ -69,12 +91,14 @@ void BluetoothFeaturePodController::OnIconPressed() {
}

void BluetoothFeaturePodController::OnLabelPressed() {
if (!button_->GetEnabled())
if (!IsButtonEnabled()) {
return;
}

TrackDiveInUMA();
if (!button_->IsToggled())
if (!IsButtonToggled()) {
remote_cros_bluetooth_config_->SetBluetoothEnabledState(true);
}
tray_controller_->ShowBluetoothDetailedView();
}

Expand All @@ -99,8 +123,9 @@ bool BluetoothFeaturePodController::DoesFirstConnectedDeviceHaveBatteryInfo()

const gfx::VectorIcon& BluetoothFeaturePodController::ComputeButtonIcon()
const {
if (!button_->IsToggled())
if (!IsButtonToggled()) {
return kUnifiedMenuBluetoothDisabledIcon;
}

if (first_connected_device_.has_value())
return kUnifiedMenuBluetoothConnectedIcon;
Expand All @@ -109,10 +134,10 @@ const gfx::VectorIcon& BluetoothFeaturePodController::ComputeButtonIcon()
}

std::u16string BluetoothFeaturePodController::ComputeButtonLabel() const {
if (button_->IsToggled() && first_connected_device_.has_value() &&
connected_device_count_ == 1)
if (IsButtonToggled() && first_connected_device_.has_value() &&
connected_device_count_ == 1) {
return first_connected_device_.value().device_name;

}
return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_BLUETOOTH);
}

Expand Down Expand Up @@ -142,14 +167,14 @@ int BluetoothFeaturePodController::
}

std::u16string BluetoothFeaturePodController::ComputeButtonSubLabel() const {
if (!button_->IsToggled())
if (!IsButtonToggled()) {
return l10n_util::GetStringUTF16(
IDS_ASH_STATUS_TRAY_BLUETOOTH_DISABLED_SHORT);

if (!first_connected_device_.has_value())
}
if (!first_connected_device_.has_value()) {
return l10n_util::GetStringUTF16(
IDS_ASH_STATUS_TRAY_BLUETOOTH_ENABLED_SHORT);

}
if (connected_device_count_ == 1) {
if (DoesFirstConnectedDeviceHaveBatteryInfo()) {
return l10n_util::GetStringFUTF16(
Expand Down Expand Up @@ -189,6 +214,16 @@ std::u16string BluetoothFeaturePodController::ComputeTooltip() const {
base::FormatNumber(connected_device_count_));
}

bool BluetoothFeaturePodController::IsButtonEnabled() const {
return features::IsQsRevampEnabled() ? tile_->GetEnabled()
: button_->GetEnabled();
}

bool BluetoothFeaturePodController::IsButtonToggled() const {
return features::IsQsRevampEnabled() ? tile_->IsToggled()
: button_->IsToggled();
}

void BluetoothFeaturePodController::UpdateButtonStateIfExists() {
// Check |button_| here so that calling functions don't need to.
if (!button_)
Expand Down Expand Up @@ -226,6 +261,46 @@ void BluetoothFeaturePodController::UpdateButtonStateIfExists() {
}
}

void BluetoothFeaturePodController::UpdateTileStateIfExists() {
if (!tile_) {
return;
}
if (system_state_ == BluetoothSystemState::kUnavailable) {
tile_->SetVisible(false);
tile_->SetEnabled(false);
return;
}

// If the button's visibility changes from invisible to visible, log its
// visibility.
if (!tile_->GetVisible()) {
TrackVisibilityUMA();
}
tile_->SetEnabled(modification_state_ ==
BluetoothModificationState::kCanModifyBluetooth);
tile_->SetToggled(
bluetooth_config::IsBluetoothEnabledOrEnabling(system_state_));
tile_->SetVisible(true);
tile_->SetVectorIcon(ComputeButtonIcon());
tile_->SetLabel(ComputeButtonLabel());
tile_->SetSubLabel(ComputeButtonSubLabel());

if (!tile_->IsToggled()) {
std::u16string tooltip = l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_BLUETOOTH_TOGGLE_TOOLTIP,
l10n_util::GetStringUTF16(
IDS_ASH_STATUS_TRAY_BLUETOOTH_DISABLED_TOOLTIP));
tile_->SetTooltipText(tooltip);
tile_->SetDrillInButtonTooltipText(tooltip);
return;
}
std::u16string tooltip_core = ComputeTooltip();
tile_->SetTooltipText(l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_BLUETOOTH_TOGGLE_TOOLTIP, tooltip_core));
tile_->SetDrillInButtonTooltipText(l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_BLUETOOTH_SETTINGS_TOOLTIP, tooltip_core));
}

void BluetoothFeaturePodController::OnPropertiesUpdated(
BluetoothSystemPropertiesPtr properties) {
connected_device_count_ = 0;
Expand All @@ -248,6 +323,7 @@ void BluetoothFeaturePodController::OnPropertiesUpdated(
modification_state_ = properties->modification_state;
system_state_ = properties->system_state;
UpdateButtonStateIfExists();
UpdateTileStateIfExists();
}

} // namespace ash
18 changes: 17 additions & 1 deletion ash/system/bluetooth/bluetooth_feature_pod_controller.h
Expand Up @@ -9,6 +9,7 @@

#include "ash/constants/quick_settings_catalogs.h"
#include "ash/system/unified/feature_pod_controller_base.h"
#include "base/memory/weak_ptr.h"
#include "chromeos/ash/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
Expand Down Expand Up @@ -36,6 +37,7 @@ class ASH_EXPORT BluetoothFeaturePodController

// FeaturePodControllerBase:
FeaturePodButton* CreateButton() override;
std::unique_ptr<FeatureTile> CreateTile() override;
QsFeatureCatalogName GetCatalogName() override;
void OnIconPressed() override;
void OnLabelPressed() override;
Expand All @@ -60,9 +62,20 @@ class ASH_EXPORT BluetoothFeaturePodController
std::u16string ComputeButtonSubLabel() const;
std::u16string ComputeTooltip() const;

// Returns true if `button_` or `tile_` is enabled, depending on feature
// QsRevamp.
bool IsButtonEnabled() const;

// Returns true if `button_` or `tile_` is toggled, depending on feature
// QsRevamp.
bool IsButtonToggled() const;

// Updates |button_| state to reflect the cached Bluetooth state.
void UpdateButtonStateIfExists();

// Updates `tile_` state to reflect the cached Bluetooth state.
void UpdateTileStateIfExists();

// bluetooth_config::mojom::SystemPropertiesObserver
void OnPropertiesUpdated(bluetooth_config::mojom::BluetoothSystemPropertiesPtr
properties) override;
Expand All @@ -79,8 +92,11 @@ class ASH_EXPORT BluetoothFeaturePodController
kCannotModifyBluetooth;
bluetooth_config::mojom::BluetoothSystemState system_state_ =
bluetooth_config::mojom::BluetoothSystemState::kUnavailable;
FeaturePodButton* button_ = nullptr;
FeaturePodButton* button_ = nullptr; // Owned by views hierarchy.
FeatureTile* tile_ = nullptr; // Owned by views hierarchy.
UnifiedSystemTrayController* tray_controller_;

base::WeakPtrFactory<BluetoothFeaturePodController> weak_factory_{this};
};

} // namespace ash
Expand Down

0 comments on commit d13b1cc

Please sign in to comment.