// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/ash/settings/pages/bluetooth/bluetooth_section.h"
#include "ash/constants/ash_features.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/webui/settings/public/constants/routes.mojom.h"
#include "ash/webui/settings/public/constants/setting.mojom.h"
#include "base/functional/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/no_destructor.h"
#include "chrome/browser/ui/webui/ash/bluetooth/bluetooth_shared_load_time_data_provider.h"
#include "chrome/browser/ui/webui/ash/settings/pages/bluetooth/bluetooth_handler.h"
#include "chrome/browser/ui/webui/ash/settings/pages/bluetooth/fast_pair_saved_devices_handler.h"
#include "chrome/browser/ui/webui/ash/settings/pages/bluetooth/fast_pair_software_scanning_handler.h"
#include "chrome/browser/ui/webui/ash/settings/search/mojom/search.mojom.h"
#include "chrome/browser/ui/webui/ash/settings/search/mojom/search_result_icon.mojom.h"
#include "chrome/browser/ui/webui/ash/settings/search/search_tag_registry.h"
#include "chrome/browser/ui/webui/webui_util.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "chromeos/strings/grit/chromeos_strings.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/web_ui_data_source.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/chromeos/bluetooth_utils.h"
#include "device/bluetooth/dbus/bluez_dbus_manager.h"
#include "device/bluetooth/floss/floss_dbus_manager.h"
#include "device/bluetooth/floss/floss_features.h"
#include "device/bluetooth/strings/grit/bluetooth_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/webui/web_ui_util.h"
namespace ash::settings {
namespace mojom {
using ::chromeos::settings::mojom::kBluetoothDeviceDetailSubpagePath;
using ::chromeos::settings::mojom::kBluetoothDevicesSubpagePath;
using ::chromeos::settings::mojom::kBluetoothSavedDevicesSubpagePath;
using ::chromeos::settings::mojom::kBluetoothSectionPath;
using ::chromeos::settings::mojom::Section;
using ::chromeos::settings::mojom::Setting;
using ::chromeos::settings::mojom::Subpage;
} // namespace mojom
namespace {
const std::vector<SearchConcept>& GetBluetoothSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_BLUETOOTH,
mojom::kBluetoothDevicesSubpagePath,
mojom::SearchResultIcon::kBluetooth,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kBluetoothDevices}},
});
return *tags;
}
const std::vector<SearchConcept>& GetBluetoothOnSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_BLUETOOTH_TURN_OFF,
mojom::kBluetoothDevicesSubpagePath,
mojom::SearchResultIcon::kBluetooth,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kBluetoothOnOff},
{IDS_OS_SETTINGS_TAG_BLUETOOTH_TURN_OFF_ALT1,
SearchConcept::kAltTagEnd}},
});
return *tags;
}
const std::vector<SearchConcept>& GetBluetoothOffSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_BLUETOOTH_TURN_ON,
mojom::kBluetoothDevicesSubpagePath,
mojom::SearchResultIcon::kBluetooth,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kBluetoothOnOff},
{IDS_OS_SETTINGS_TAG_BLUETOOTH_TURN_ON_ALT1, SearchConcept::kAltTagEnd}},
});
return *tags;
}
const std::vector<SearchConcept>& GetBluetoothPairableSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_BLUETOOTH_PAIR,
mojom::kBluetoothDevicesSubpagePath,
mojom::SearchResultIcon::kBluetooth,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kBluetoothPairDevice}},
});
return *tags;
}
const std::vector<SearchConcept>& GetFastPairOffSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_FAST_PAIR_TURN_ON,
mojom::kBluetoothDevicesSubpagePath,
mojom::SearchResultIcon::kBluetooth,
mojom::SearchResultDefaultRank::kLow,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kFastPairOnOff},
{IDS_OS_SETTINGS_TAG_FAST_PAIR_TURN_ON_ALT1, SearchConcept::kAltTagEnd}},
});
return *tags;
}
const std::vector<SearchConcept>& GetFastPairOnSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_FAST_PAIR_TURN_OFF,
mojom::kBluetoothDevicesSubpagePath,
mojom::SearchResultIcon::kBluetooth,
mojom::SearchResultDefaultRank::kLow,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kFastPairOnOff},
{IDS_OS_SETTINGS_TAG_FAST_PAIR_TURN_OFF_ALT1,
SearchConcept::kAltTagEnd}},
});
return *tags;
}
const std::vector<SearchConcept>& GetFastPairSavedDevicesSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_FAST_PAIR_SAVED_DEVICES,
mojom::kBluetoothSavedDevicesSubpagePath,
mojom::SearchResultIcon::kBluetooth,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kFastPairSavedDevices}},
});
return *tags;
}
} // namespace
BluetoothSection::BluetoothSection(Profile* profile,
SearchTagRegistry* search_tag_registry,
PrefService* pref_service)
: OsSettingsSection(profile, search_tag_registry),
pref_service_(pref_service),
pref_change_registrar_(std::make_unique<PrefChangeRegistrar>()) {
bool is_initialized = false;
if (floss::features::IsFlossEnabled()) {
is_initialized = floss::FlossDBusManager::IsInitialized();
} else {
is_initialized = bluez::BluezDBusManager::IsInitialized();
}
// Note: May be uninitialized in tests.
if (is_initialized) {
device::BluetoothAdapterFactory::Get()->GetAdapter(
base::BindOnce(&BluetoothSection::OnFetchBluetoothAdapter,
weak_ptr_factory_.GetWeakPtr()));
}
if (ash::features::IsFastPairEnabled()) {
pref_change_registrar_->Init(pref_service_);
pref_change_registrar_->Add(
prefs::kFastPairEnabled,
base::BindRepeating(&BluetoothSection::OnFastPairEnabledChanged,
base::Unretained(this)));
}
}
BluetoothSection::~BluetoothSection() {
if (bluetooth_adapter_) {
bluetooth_adapter_->RemoveObserver(this);
}
}
void BluetoothSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"bluetoothConnected", IDS_SETTINGS_BLUETOOTH_CONNECTED},
{"bluetoothConnecting", IDS_SETTINGS_BLUETOOTH_CONNECTING},
{"bluetoothConnect", IDS_SETTINGS_BLUETOOTH_CONNECT},
{"bluetoothDisconnect", IDS_SETTINGS_BLUETOOTH_DISCONNECT},
{"bluetoothDeviceDetailConnected",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_CONNECTED},
{"bluetoothDeviceDetailDisconnected",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_DISCONNECTED},
{"bluetoothDeviceDetailForget",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_FORGET},
{"bluetoothDeviceDetailForgetA11yLabel",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_FORGET_A11Y_LABEL},
{"bluetoothDeviceDetailHIDMessageConnected",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_HID_MESSAGE_CONNECTED},
{"bluetoothDeviceDetailHIDMessageDisconnected",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_HID_MESSAGE_DISCONNECTED},
{"bluetoothDeviceDetailName", IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_NAME},
{"bluetoothDeviceDetailChangeNameDialogNewName",
IDS_SETTINGS_BLUETOOTH_CHANGE_DEVICE_NAME_DIALOG_NEW_NAME},
{"bluetoothDeviceDetailChangeNameDialogCancel",
IDS_SETTINGS_BLUETOOTH_CHANGE_DEVICE_NAME_DIALOG_CANCEL},
{"bluetoothDeviceDetailChangeNameDialogDone",
IDS_SETTINGS_BLUETOOTH_CHANGE_DEVICE_NAME_DIALOG_DONE},
{"bluetoothDeviceDetailChangeDeviceSettingsKeyboard",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_CHANGE_DEVICE_SETTINGS_KEYBOARD},
{"bluetoothDeviceDetailChangeDeviceSettingsMouse",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_CHANGE_DEVICE_SETTINGS_MOUSE},
{"bluetoothDeviceDetailChangeDeviceName",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_CHANGE_DEVICE_NAME},
{"bluetoothDeviceDetailBatteryPercentageA11yLabel",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_BATTERY_PERCENTAGE_A11Y_LABEL},
{"bluetoothDeviceDetailConnectedA11yLabel",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_CONNECTED_A11Y_LABEL},
{"bluetoothDeviceDetailConnectingA11yLabel",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_CONNECTING_A11Y_LABEL},
{"bluetoothDeviceDetailConnectionFailureA11yLabel",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_CONNECTION_FAILURE_A11Y_LABEL},
{"bluetoothDeviceDetailLeftBudBatteryPercentageA11yLabel",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_LEFT_BUD_BATTERY_PERCENTAGE_A11Y_LABEL},
{"bluetoothDeviceDetailCaseBatteryPercentageA11yLabel",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_CASE_BATTERY_PERCENTAGE_A11Y_LABEL},
{"bluetoothDeviceDetailRightBudBatteryPercentageA11yLabel",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_RIGHT_BUD_BATTERY_PERCENTAGE_A11Y_LABEL},
{"bluetoothTrueWirelessLeftBudLabel",
IDS_SETTINGS_BLUETOOTH_TRUE_WIRELESS_LEFT_BUD_LABEL},
{"bluetoothTrueWirelessCaseLabel",
IDS_SETTINGS_BLUETOOTH_TRUE_WIRELESS_CASE_LABEL},
{"bluetoothTrueWirelessRightBudLabel",
IDS_SETTINGS_BLUETOOTH_TRUE_WIRELESS_RIGHT_BUD_LABEL},
{"bluetoothDeviceDetailConnectionFailureLabel",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_CONNECTION_FAILURE_LABEL},
{"bluetoothDeviceDetailDisconnectedA11yLabel",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_DISCONNECTED_A11Y_LABEL},
{"bluetoothChangeNameDialogInputA11yLabel",
IDS_SETTINGS_BLUETOOTH_CHANGE_DEVICE_NAME_DIALOG_INPUT_A11Y_LABEL},
{"bluetoothChangeNameDialogInputSubtitle",
IDS_SETTINGS_BLUETOOTH_CHANGE_DEVICE_NAME_DIALOG_INPUT_SUBTITLE},
{"bluetoothChangeNameDialogInputCharCount",
IDS_SETTINGS_BLUETOOTH_CHANGE_DEVICE_NAME_DIALOG_INPUT_CHARACTER_COUNT},
{"bluetoothDeviceDetailChangeDeviceNameBtnA11yLabel",
IDS_SETTINGS_BLUETOOTH_DEVICE_DETAIL_CHANGE_DEVICE_NAME_BTN_A11Y_LABEL},
{"bluetoothToggleA11yLabel",
IDS_SETTINGS_BLUETOOTH_TOGGLE_ACCESSIBILITY_LABEL},
{"bluetoothExpandA11yLabel",
IDS_SETTINGS_BLUETOOTH_EXPAND_ACCESSIBILITY_LABEL},
{"bluetoothPageTitle", IDS_SETTINGS_BLUETOOTH},
{"bluetoothSummaryPageConnectedA11yOneDevice",
IDS_SETTINGS_BLUETOOTH_SUMMARY_PAGE_CONNECTED_A11Y_ONE_DEVICE},
{"bluetoothSummaryPageConnectedA11yTwoDevices",
IDS_SETTINGS_BLUETOOTH_SUMMARY_PAGE_CONNECTED_A11Y_TWO_DEVICES},
{"bluetoothSummaryPageConnectedA11yTwoOrMoreDevices",
IDS_SETTINGS_BLUETOOTH_SUMMARY_PAGE_CONNECTED_A11Y_TWO_OR_MORE_DEVICES},
{"bluetoothSummaryPageTwoOrMoreDevicesDescription",
IDS_SETTINGS_BLUETOOTH_SUMMARY_PAGE_TWO_OR_MORE_DEVICES_DESCRIPTION},
{"bluetoothSummaryPageTwoDevicesDescription",
IDS_SETTINGS_BLUETOOTH_SUMMARY_PAGE_TWO_DEVICES_DESCRIPTION},
{"bluetoothSummaryPageOff", IDS_SETTINGS_BLUETOOTH_SUMMARY_PAGE_OFF},
{"bluetoothSummaryPageOn", IDS_SETTINGS_BLUETOOTH_SUMMARY_PAGE_ON},
{"bluetoothA11yDeviceTypeUnknown",
IDS_BLUETOOTH_A11Y_DEVICE_TYPE_UNKNOWN},
{"bluetoothA11yDeviceTypeComputer",
IDS_BLUETOOTH_A11Y_DEVICE_TYPE_COMPUTER},
{"bluetoothA11yDeviceTypePhone", IDS_BLUETOOTH_A11Y_DEVICE_TYPE_PHONE},
{"bluetoothA11yDeviceTypeHeadset",
IDS_BLUETOOTH_A11Y_DEVICE_TYPE_HEADSET},
{"bluetoothA11yDeviceTypeVideoCamera",
IDS_BLUETOOTH_A11Y_DEVICE_TYPE_VIDEO_CAMERA},
{"bluetoothA11yDeviceTypeGameController",
IDS_BLUETOOTH_A11Y_DEVICE_TYPE_GAME_CONTROLLER},
{"bluetoothA11yDeviceTypeKeyboard",
IDS_BLUETOOTH_A11Y_DEVICE_TYPE_KEYBOARD},
{"bluetoothA11yDeviceTypeKeyboardMouseCombo",
IDS_BLUETOOTH_A11Y_DEVICE_TYPE_KEYBOARD_MOUSE_COMBO},
{"bluetoothA11yDeviceTypeMouse", IDS_BLUETOOTH_A11Y_DEVICE_TYPE_MOUSE},
{"bluetoothA11yDeviceTypeMouse", IDS_BLUETOOTH_A11Y_DEVICE_TYPE_MOUSE},
{"bluetoothA11yDeviceTypeTablet", IDS_BLUETOOTH_A11Y_DEVICE_TYPE_TABLET},
{"bluetoothA11yDeviceConnectionStateConnected",
IDS_BLUETOOTH_A11Y_DEVICE_CONNECTION_STATE_CONNECTED},
{"bluetoothA11yDeviceConnectionStateConnecting",
IDS_BLUETOOTH_A11Y_DEVICE_CONNECTION_STATE_CONNECTING},
{"bluetoothA11yDeviceConnectionStateNotConnected",
IDS_BLUETOOTH_A11Y_DEVICE_CONNECTION_STATE_NOT_CONNECTED},
{"bluetoothA11yDeviceBatteryInfo",
IDS_BLUETOOTH_A11Y_DEVICE_BATTERY_INFO},
{"bluetoothA11yDeviceNamedBatteryInfoLeftBud",
IDS_BLUETOOTH_A11Y_DEVICE_NAMED_BATTERY_INFO_LEFT_BUD},
{"bluetoothA11yDeviceNamedBatteryInfoCase",
IDS_BLUETOOTH_A11Y_DEVICE_NAMED_BATTERY_INFO_CASE},
{"bluetoothA11yDeviceNamedBatteryInfoRightBud",
IDS_BLUETOOTH_A11Y_DEVICE_NAMED_BATTERY_INFO_RIGHT_BUD},
{"bluetoothA11yDeviceName", IDS_BLUETOOTH_A11Y_DEVICE_NAME},
{"bluetoothRemove", IDS_SETTINGS_BLUETOOTH_REMOVE},
{"bluetoothManaged", IDS_SETTINGS_BLUETOOTH_MANAGED},
{"enableFastPairLabel", IDS_BLUETOOTH_ENABLE_FAST_PAIR_LABEL},
{"enableFastPairSubtitle", IDS_BLUETOOTH_ENABLE_FAST_PAIR_SUBTITLE},
{"savedDevicesLabel", IDS_BLUETOOTH_SAVED_DEVICES_LABEL},
{"savedDevicesSubtitle", IDS_BLUETOOTH_SAVED_DEVICES_SUBTITLE},
{"savedDevicesPageName", IDS_SETTINGS_BLUETOOTH_SAVED_DEVICES},
{"savedDevicesRemove", IDS_BLUETOOTH_SAVED_DEVICES_REMOVE},
{"savedDevicesDialogRemove",
IDS_SETTINGS_REMOVE_SAVED_DEVICE_DIALOG_REMOVE},
{"savedDevicesDialogCancel",
IDS_SETTINGS_REMOVE_SAVED_DEVICE_DIALOG_CANCEL},
{"savedDevicesDialogLabel",
IDS_SETTINGS_REMOVE_SAVED_DEVICE_DIALOG_LABEL},
{"bluetoothDevicesDialogForget",
IDS_SETTINGS_FORGET_DEVICE_DIALOG_FORGET},
{"bluetoothDevicesDialogCancel",
IDS_SETTINGS_FORGET_DEVICE_DIALOG_CANCEL},
{"bluetoothDevicesDialogLabel", IDS_SETTINGS_FORGET_DEVICE_DIALOG_LABEL},
{"bluetoothDevicesDialogTitle", IDS_SETTINGS_FORGET_DEVICE_DIALOG_TITLE},
{"bluetoothPrimaryUserControlled",
IDS_SETTINGS_BLUETOOTH_PRIMARY_USER_CONTROLLED},
{"bluetoothDeviceListCurrentlyConnected",
IDS_BLUETOOTH_DEVICE_LIST_CURRENTLY_CONNECTED},
{"bluetoothDeviceListPreviouslyConnected",
IDS_BLUETOOTH_DEVICE_LIST_PREVIOUSLY_CONNECTED},
{"bluetoothDeviceListNoConnectedDevices",
IDS_BLUETOOTH_DEVICE_LIST_NO_CONNECTED_DEVICES},
{"bluetoothEnabledA11YLabel", IDS_SETTINGS_BLUETOOTH_ENABLED_A11Y_LABEL},
{"bluetoothDisabledA11YLabel",
IDS_SETTINGS_BLUETOOTH_DISABLED_A11Y_LABEL},
{"savedDeviceItemA11yLabel", IDS_SAVED_DEVICE_ITEM_A11Y_LABEL},
{"savedDeviceItemButtonA11yLabel",
IDS_SAVED_DEVICE_LIST_ITEM_BUTTON_A11Y_LABEL},
{"bluetoothMenuItemDescriptionMultipleDevicesConnected",
IDS_OS_SETTINGS_BLUETOOTH_MENU_ITEM_DESCRIPTION_MULTIPLE_DEVICES_CONNECTED},
};
html_source->AddLocalizedStrings(kLocalizedStrings);
html_source->AddBoolean("enableFastPairFlag", features::IsFastPairEnabled());
html_source->AddBoolean("enableSavedDevicesFlag",
features::IsFastPairSavedDevicesEnabled());
html_source->AddBoolean(
"bluetoothRevampHatsSurveyFlag",
base::FeatureList::IsEnabled(
::features::kHappinessTrackingSystemBluetoothRevamp));
html_source->AddBoolean("bluetoothDisconnectWarningFlag",
features::IsBluetoothDisconnectWarningEnabled());
bluetooth::AddLoadTimeData(html_source);
}
void BluetoothSection::AddHandlers(content::WebUI* web_ui) {
web_ui->AddMessageHandler(std::make_unique<BluetoothHandler>());
if (features::IsFastPairEnabled() &&
features::IsFastPairSavedDevicesEnabled()) {
web_ui->AddMessageHandler(std::make_unique<FastPairSavedDevicesHandler>());
}
if (features::IsFastPairSoftwareScanningSupportEnabled()) {
web_ui->AddMessageHandler(std::make_unique<FastPairSoftwareScanningHandler>(
std::make_unique<quick_pair::BatterySaverActiveProvider>(),
std::make_unique<quick_pair::HardwareOffloadingSupportedProvider>()));
}
}
int BluetoothSection::GetSectionNameMessageId() const {
return IDS_SETTINGS_BLUETOOTH;
}
mojom::Section BluetoothSection::GetSection() const {
return mojom::Section::kBluetooth;
}
mojom::SearchResultIcon BluetoothSection::GetSectionIcon() const {
return mojom::SearchResultIcon::kBluetooth;
}
const char* BluetoothSection::GetSectionPath() const {
return mojom::kBluetoothSectionPath;
}
bool BluetoothSection::LogMetric(mojom::Setting setting,
base::Value& value) const {
switch (setting) {
case mojom::Setting::kBluetoothOnOff:
base::UmaHistogramBoolean("ChromeOS.Settings.Bluetooth.BluetoothOnOff",
value.GetBool());
return true;
default:
return false;
}
}
void BluetoothSection::RegisterHierarchy(HierarchyGenerator* generator) const {
generator->RegisterTopLevelSubpage(IDS_SETTINGS_BLUETOOTH,
mojom::Subpage::kBluetoothDevices,
mojom::SearchResultIcon::kBluetooth,
mojom::SearchResultDefaultRank::kMedium,
mojom::kBluetoothDevicesSubpagePath);
static constexpr mojom::Setting kBluetoothDevicesSettings[] = {
mojom::Setting::kBluetoothOnOff, mojom::Setting::kBluetoothPairDevice,
mojom::Setting::kBluetoothUnpairDevice, mojom::Setting::kFastPairOnOff,
mojom::Setting::kFastPairSavedDevices};
RegisterNestedSettingBulk(mojom::Subpage::kBluetoothDevices,
kBluetoothDevicesSettings, generator);
generator->RegisterTopLevelAltSetting(mojom::Setting::kBluetoothOnOff);
generator->RegisterNestedSubpage(IDS_SETTINGS_BLUETOOTH_DEVICE_DETAILS,
mojom::Subpage::kBluetoothDeviceDetail,
mojom::Subpage::kBluetoothDevices,
mojom::SearchResultIcon::kBluetooth,
mojom::SearchResultDefaultRank::kMedium,
mojom::kBluetoothDeviceDetailSubpagePath);
generator->RegisterNestedSubpage(IDS_SETTINGS_BLUETOOTH_SAVED_DEVICES,
mojom::Subpage::kBluetoothSavedDevices,
mojom::Subpage::kBluetoothDevices,
mojom::SearchResultIcon::kBluetooth,
mojom::SearchResultDefaultRank::kMedium,
mojom::kBluetoothSavedDevicesSubpagePath);
}
void BluetoothSection::AdapterPresentChanged(device::BluetoothAdapter* adapter,
bool present) {
UpdateSearchTags();
}
void BluetoothSection::AdapterPoweredChanged(device::BluetoothAdapter* adapter,
bool powered) {
UpdateSearchTags();
}
void BluetoothSection::DeviceAdded(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) {
UpdateSearchTags();
}
void BluetoothSection::DeviceChanged(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) {
UpdateSearchTags();
}
void BluetoothSection::DeviceRemoved(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) {
UpdateSearchTags();
}
void BluetoothSection::OnFetchBluetoothAdapter(
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter) {
bluetooth_adapter_ = bluetooth_adapter;
bluetooth_adapter_->AddObserver(this);
UpdateSearchTags();
}
void BluetoothSection::OnFastPairEnabledChanged() {
UpdateSearchTags();
}
void BluetoothSection::UpdateSearchTags() {
SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
// Start with no search tags, then add them below if appropriate.
updater.RemoveSearchTags(GetBluetoothSearchConcepts());
updater.RemoveSearchTags(GetBluetoothOnSearchConcepts());
updater.RemoveSearchTags(GetBluetoothOffSearchConcepts());
updater.RemoveSearchTags(GetFastPairOnSearchConcepts());
updater.RemoveSearchTags(GetFastPairOffSearchConcepts());
updater.RemoveSearchTags(GetFastPairSavedDevicesSearchConcepts());
updater.RemoveSearchTags(GetBluetoothPairableSearchConcepts());
if (!bluetooth_adapter_->IsPresent()) {
return;
}
updater.AddSearchTags(GetBluetoothSearchConcepts());
if (features::IsFastPairEnabled() &&
features::IsCrossDeviceFeatureSuiteAllowed()) {
if (pref_service_->GetBoolean(ash::prefs::kFastPairEnabled)) {
updater.AddSearchTags(GetFastPairOnSearchConcepts());
} else {
updater.AddSearchTags(GetFastPairOffSearchConcepts());
}
if (features::IsFastPairSavedDevicesEnabled()) {
updater.AddSearchTags(GetFastPairSavedDevicesSearchConcepts());
}
}
if (!bluetooth_adapter_->IsPowered()) {
updater.AddSearchTags(GetBluetoothOffSearchConcepts());
return;
}
updater.AddSearchTags(GetBluetoothOnSearchConcepts());
updater.AddSearchTags(GetBluetoothPairableSearchConcepts());
}
} // namespace ash::settings