123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- // Copyright 2015 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "components/permissions/bluetooth_chooser_controller.h"
- #include <algorithm>
- #include "base/check_op.h"
- #include "base/debug/dump_without_crashing.h"
- #include "base/metrics/histogram_macros.h"
- #include "base/notreached.h"
- #include "base/strings/utf_string_conversions.h"
- #include "components/strings/grit/components_strings.h"
- #include "ui/base/l10n/l10n_util.h"
- namespace permissions {
- namespace {
- void RecordInteractionWithChooser(bool has_null_handler) {
- UMA_HISTOGRAM_BOOLEAN("Bluetooth.Web.ChooserInteraction", has_null_handler);
- }
- } // namespace
- BluetoothChooserController::BluetoothChooserController(
- content::RenderFrameHost* owner,
- const content::BluetoothChooser::EventHandler& event_handler,
- std::u16string title)
- : ChooserController(title), event_handler_(event_handler) {}
- BluetoothChooserController::~BluetoothChooserController() {
- if (event_handler_) {
- event_handler_.Run(content::BluetoothChooserEvent::CANCELLED,
- std::string());
- }
- }
- bool BluetoothChooserController::ShouldShowIconBeforeText() const {
- return true;
- }
- bool BluetoothChooserController::ShouldShowReScanButton() const {
- return true;
- }
- std::u16string BluetoothChooserController::GetNoOptionsText() const {
- return l10n_util::GetStringUTF16(
- IDS_BLUETOOTH_DEVICE_CHOOSER_NO_DEVICES_FOUND_PROMPT);
- }
- std::u16string BluetoothChooserController::GetOkButtonLabel() const {
- return l10n_util::GetStringUTF16(
- IDS_BLUETOOTH_DEVICE_CHOOSER_PAIR_BUTTON_TEXT);
- }
- std::pair<std::u16string, std::u16string>
- BluetoothChooserController::GetThrobberLabelAndTooltip() const {
- return {
- l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_SCANNING_LABEL),
- l10n_util::GetStringUTF16(
- IDS_BLUETOOTH_DEVICE_CHOOSER_SCANNING_LABEL_TOOLTIP)};
- }
- size_t BluetoothChooserController::NumOptions() const {
- return devices_.size();
- }
- int BluetoothChooserController::GetSignalStrengthLevel(size_t index) const {
- return devices_[index].signal_strength_level;
- }
- bool BluetoothChooserController::IsConnected(size_t index) const {
- return devices_[index].is_connected;
- }
- bool BluetoothChooserController::IsPaired(size_t index) const {
- return devices_[index].is_paired;
- }
- std::u16string BluetoothChooserController::GetOption(size_t index) const {
- // Change these back to DCHECKs once https://crbug.com/1292234 is resolved.
- if (index >= devices_.size())
- base::debug::DumpWithoutCrashing();
- const std::string& device_id = devices_[index].id;
- const auto& device_name_it = device_id_to_name_map_.find(device_id);
- if (device_name_it == device_id_to_name_map_.end())
- base::debug::DumpWithoutCrashing();
- const auto& it = device_name_counts_.find(device_name_it->second);
- if (it == device_name_counts_.end())
- base::debug::DumpWithoutCrashing();
- return it->second == 1
- ? device_name_it->second
- : l10n_util::GetStringFUTF16(
- IDS_DEVICE_CHOOSER_DEVICE_NAME_WITH_ID,
- device_name_it->second, base::UTF8ToUTF16(device_id));
- }
- void BluetoothChooserController::RefreshOptions() {
- RecordInteractionWithChooser(event_handler_.is_null());
- if (event_handler_.is_null())
- return;
- ClearAllDevices();
- event_handler_.Run(content::BluetoothChooserEvent::RESCAN, std::string());
- }
- void BluetoothChooserController::Select(const std::vector<size_t>& indices) {
- DCHECK_EQ(1u, indices.size());
- size_t index = indices[0];
- RecordInteractionWithChooser(event_handler_.is_null());
- if (event_handler_.is_null()) {
- return;
- }
- DCHECK_LT(index, devices_.size());
- event_handler_.Run(content::BluetoothChooserEvent::SELECTED,
- devices_[index].id);
- event_handler_.Reset();
- }
- void BluetoothChooserController::Cancel() {
- RecordInteractionWithChooser(event_handler_.is_null());
- if (event_handler_.is_null())
- return;
- event_handler_.Run(content::BluetoothChooserEvent::CANCELLED, std::string());
- event_handler_.Reset();
- }
- void BluetoothChooserController::Close() {
- RecordInteractionWithChooser(event_handler_.is_null());
- if (event_handler_.is_null())
- return;
- event_handler_.Run(content::BluetoothChooserEvent::CANCELLED, std::string());
- event_handler_.Reset();
- }
- void BluetoothChooserController::OnAdapterPresenceChanged(
- content::BluetoothChooser::AdapterPresence presence) {
- ClearAllDevices();
- switch (presence) {
- case content::BluetoothChooser::AdapterPresence::ABSENT:
- NOTREACHED();
- break;
- case content::BluetoothChooser::AdapterPresence::POWERED_OFF:
- if (view()) {
- view()->OnAdapterEnabledChanged(
- false /* Bluetooth adapter is turned off */);
- }
- break;
- case content::BluetoothChooser::AdapterPresence::POWERED_ON:
- if (view()) {
- view()->OnAdapterEnabledChanged(
- true /* Bluetooth adapter is turned on */);
- }
- break;
- case content::BluetoothChooser::AdapterPresence::UNAUTHORIZED:
- if (view()) {
- view()->OnAdapterAuthorizationChanged(/*authorized=*/false);
- }
- break;
- }
- }
- void BluetoothChooserController::OnDiscoveryStateChanged(
- content::BluetoothChooser::DiscoveryState state) {
- switch (state) {
- case content::BluetoothChooser::DiscoveryState::DISCOVERING:
- if (view()) {
- view()->OnRefreshStateChanged(
- true /* Refreshing options is in progress */);
- }
- break;
- case content::BluetoothChooser::DiscoveryState::IDLE:
- case content::BluetoothChooser::DiscoveryState::FAILED_TO_START:
- if (view()) {
- view()->OnRefreshStateChanged(
- false /* Refreshing options is complete */);
- }
- break;
- }
- }
- void BluetoothChooserController::AddOrUpdateDevice(
- const std::string& device_id,
- bool should_update_name,
- const std::u16string& device_name,
- bool is_gatt_connected,
- bool is_paired,
- int signal_strength_level) {
- auto name_it = device_id_to_name_map_.find(device_id);
- if (name_it != device_id_to_name_map_.end()) {
- if (should_update_name) {
- std::u16string previous_device_name = name_it->second;
- name_it->second = device_name;
- const auto& it = device_name_counts_.find(previous_device_name);
- DCHECK(it != device_name_counts_.end());
- DCHECK_GT(it->second, 0);
- if (--(it->second) == 0)
- device_name_counts_.erase(it);
- ++device_name_counts_[device_name];
- }
- auto device_it =
- std::find_if(devices_.begin(), devices_.end(),
- [&device_id](const BluetoothDeviceInfo& device) {
- return device.id == device_id;
- });
- DCHECK(device_it != devices_.end());
- // When Bluetooth device scanning stops, the |signal_strength_level|
- // is -1, and in this case, should still use the previously stored
- // signal strength level value.
- if (signal_strength_level != -1)
- device_it->signal_strength_level = signal_strength_level;
- device_it->is_connected = is_gatt_connected;
- device_it->is_paired = is_paired;
- if (view())
- view()->OnOptionUpdated(device_it - devices_.begin());
- return;
- }
- devices_.push_back(
- {device_id, signal_strength_level, is_gatt_connected, is_paired});
- device_id_to_name_map_.insert({device_id, device_name});
- ++device_name_counts_[device_name];
- if (view())
- view()->OnOptionAdded(devices_.size() - 1);
- }
- void BluetoothChooserController::RemoveDevice(const std::string& device_id) {
- const auto& name_it = device_id_to_name_map_.find(device_id);
- if (name_it == device_id_to_name_map_.end())
- return;
- auto device_it =
- std::find_if(devices_.begin(), devices_.end(),
- [&device_id](const BluetoothDeviceInfo& device) {
- return device.id == device_id;
- });
- if (device_it != devices_.end()) {
- size_t index = device_it - devices_.begin();
- devices_.erase(device_it);
- const auto& it = device_name_counts_.find(name_it->second);
- DCHECK(it != device_name_counts_.end());
- DCHECK_GT(it->second, 0);
- if (--(it->second) == 0)
- device_name_counts_.erase(it);
- device_id_to_name_map_.erase(name_it);
- if (view())
- view()->OnOptionRemoved(index);
- }
- }
- void BluetoothChooserController::ResetEventHandler() {
- event_handler_.Reset();
- }
- base::WeakPtr<BluetoothChooserController>
- BluetoothChooserController::GetWeakPtr() {
- return weak_factory_.GetWeakPtr();
- }
- void BluetoothChooserController::ClearAllDevices() {
- devices_.clear();
- device_id_to_name_map_.clear();
- device_name_counts_.clear();
- }
- } // namespace permissions
|