123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- // Copyright 2021 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 "ash/components/peripheral_notification/peripheral_notification_manager.h"
- #include "ash/constants/ash_features.h"
- #include "base/callback_helpers.h"
- #include "base/files/file_path.h"
- #include "base/files/file_util.h"
- #include "base/metrics/histogram_functions.h"
- #include "base/task/task_traits.h"
- #include "base/task/thread_pool.h"
- #include "services/device/public/mojom/usb_device.mojom.h"
- #include "third_party/cros_system_api/dbus/typecd/dbus-constants.h"
- namespace ash {
- namespace {
- PeripheralNotificationManager* g_instance = nullptr;
- const int kBillboardDeviceClassCode = 17;
- constexpr char thunderbolt_file_path[] = "/sys/bus/thunderbolt/devices/0-0";
- void RecordConnectivityMetric(
- PeripheralNotificationManager::PeripheralConnectivityResults results) {
- base::UmaHistogramEnumeration("Ash.Peripheral.ConnectivityResults", results);
- }
- // Checks if the board supports Thunderbolt.
- bool CheckIfThunderboltFilepathExists(std::string root_prefix) {
- return base::PathExists(base::FilePath(root_prefix + thunderbolt_file_path));
- }
- } // namespace
- PeripheralNotificationManager::PeripheralNotificationManager(
- bool is_guest_profile,
- bool is_pcie_tunneling_allowed)
- : is_guest_profile_(is_guest_profile),
- is_pcie_tunneling_allowed_(is_pcie_tunneling_allowed) {
- DCHECK(TypecdClient::Get());
- DCHECK(PciguardClient::Get());
- TypecdClient::Get()->AddObserver(this);
- PciguardClient::Get()->AddObserver(this);
- }
- PeripheralNotificationManager::~PeripheralNotificationManager() {
- TypecdClient::Get()->RemoveObserver(this);
- PciguardClient::Get()->RemoveObserver(this);
- CHECK_EQ(this, g_instance);
- g_instance = nullptr;
- }
- void PeripheralNotificationManager::AddObserver(Observer* observer) {
- observer_list_.AddObserver(observer);
- }
- void PeripheralNotificationManager::RemoveObserver(Observer* observer) {
- observer_list_.RemoveObserver(observer);
- }
- void PeripheralNotificationManager::
- NotifyLimitedPerformancePeripheralReceived() {
- // Show no notifications if PCIe tunneling is allowed.
- if (is_pcie_tunneling_allowed_)
- return;
- for (auto& observer : observer_list_)
- observer.OnLimitedPerformancePeripheralReceived();
- }
- void PeripheralNotificationManager::NotifyGuestModeNotificationReceived(
- bool is_thunderbolt_only) {
- for (auto& observer : observer_list_)
- observer.OnGuestModeNotificationReceived(is_thunderbolt_only);
- }
- void PeripheralNotificationManager::NotifyPeripheralBlockedReceived() {
- for (auto& observer : observer_list_)
- observer.OnPeripheralBlockedReceived();
- }
- void PeripheralNotificationManager::OnBillboardDeviceConnected(
- bool billboard_is_supported) {
- if (!features::IsPcieBillboardNotificationEnabled()) {
- return;
- }
- if (!billboard_is_supported) {
- for (auto& observer : observer_list_)
- observer.OnBillboardDeviceConnected();
- RecordConnectivityMetric(PeripheralConnectivityResults::kBillboardDevice);
- }
- }
- void PeripheralNotificationManager::OnThunderboltDeviceConnected(
- bool is_thunderbolt_only) {
- if (is_guest_profile_) {
- NotifyGuestModeNotificationReceived(is_thunderbolt_only);
- RecordConnectivityMetric(
- is_thunderbolt_only
- ? PeripheralConnectivityResults::kTBTOnlyAndBlockedInGuestSession
- : PeripheralConnectivityResults::kAltModeFallbackInGuestSession);
- return;
- }
- // Only show notifications if the peripheral is operating at limited
- // performance.
- if (!is_pcie_tunneling_allowed_) {
- NotifyLimitedPerformancePeripheralReceived();
- RecordConnectivityMetric(
- is_thunderbolt_only
- ? PeripheralConnectivityResults::kTBTOnlyAndBlockedByPciguard
- : PeripheralConnectivityResults::kAltModeFallbackDueToPciguard);
- return;
- }
- RecordConnectivityMetric(
- PeripheralConnectivityResults::kTBTSupportedAndAllowed);
- }
- void PeripheralNotificationManager::OnBlockedThunderboltDeviceConnected(
- const std::string& name) {
- // Currently the device name is not shown in the notification.
- NotifyPeripheralBlockedReceived();
- RecordConnectivityMetric(PeripheralConnectivityResults::kPeripheralBlocked);
- }
- void PeripheralNotificationManager::OnCableWarning(
- typecd::CableWarningType cable_warning_type) {
- // Decode cable warnging signal.
- switch (cable_warning_type) {
- case typecd::CableWarningType::kInvalidDpCable:
- NotifyInvalidDpCable();
- RecordConnectivityMetric(PeripheralConnectivityResults::kInvalidDpCable);
- break;
- case typecd::CableWarningType::kInvalidUSB4ValidTBTCable:
- NotifyInvalidUSB4ValidTBTCableWarning();
- RecordConnectivityMetric(
- PeripheralConnectivityResults::kInvalidUSB4ValidTBTCable);
- break;
- case typecd::CableWarningType::kInvalidUSB4Cable:
- NotifyInvalidUSB4CableWarning();
- RecordConnectivityMetric(
- PeripheralConnectivityResults::kInvalidUSB4Cable);
- break;
- case typecd::CableWarningType::kInvalidTBTCable:
- NotifyInvalidTBTCableWarning();
- RecordConnectivityMetric(PeripheralConnectivityResults::kInvalidTBTCable);
- break;
- case typecd::CableWarningType::kSpeedLimitingCable:
- NotifySpeedLimitingCableWarning();
- RecordConnectivityMetric(
- PeripheralConnectivityResults::kSpeedLimitingCable);
- break;
- default:
- break;
- }
- }
- void PeripheralNotificationManager::NotifyInvalidDpCable() {
- for (auto& observer : observer_list_)
- observer.OnInvalidDpCableWarning();
- }
- void PeripheralNotificationManager::NotifyInvalidUSB4ValidTBTCableWarning() {
- for (auto& observer : observer_list_)
- observer.OnInvalidUSB4ValidTBTCableWarning();
- }
- void PeripheralNotificationManager::NotifyInvalidUSB4CableWarning() {
- for (auto& observer : observer_list_)
- observer.OnInvalidUSB4CableWarning();
- }
- void PeripheralNotificationManager::NotifyInvalidTBTCableWarning() {
- for (auto& observer : observer_list_)
- observer.OnInvalidTBTCableWarning();
- }
- void PeripheralNotificationManager::NotifySpeedLimitingCableWarning() {
- for (auto& observer : observer_list_)
- observer.OnSpeedLimitingCableWarning();
- }
- void PeripheralNotificationManager::OnDeviceConnected(
- device::mojom::UsbDeviceInfo* device) {
- if (device->class_code == kBillboardDeviceClassCode) {
- // PathExist is a blocking call. PostTask it and wait on the result.
- base::ThreadPool::PostTaskAndReplyWithResult(
- FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
- base::BindOnce(&CheckIfThunderboltFilepathExists, root_prefix_),
- base::BindOnce(
- &PeripheralNotificationManager::OnBillboardDeviceConnected,
- weak_ptr_factory_.GetWeakPtr()));
- }
- }
- void PeripheralNotificationManager::SetPcieTunnelingAllowedState(
- bool is_pcie_tunneling_allowed) {
- is_pcie_tunneling_allowed_ = is_pcie_tunneling_allowed;
- }
- void PeripheralNotificationManager::SetRootPrefixForTesting(
- const std::string& prefix) {
- root_prefix_ = prefix;
- }
- // static
- void PeripheralNotificationManager::Initialize(bool is_guest_profile,
- bool is_pcie_tunneling_allowed) {
- CHECK(!g_instance);
- g_instance = new PeripheralNotificationManager(is_guest_profile,
- is_pcie_tunneling_allowed);
- }
- // static
- void PeripheralNotificationManager::Shutdown() {
- CHECK(g_instance);
- delete g_instance;
- g_instance = NULL;
- }
- // static
- PeripheralNotificationManager* PeripheralNotificationManager::Get() {
- CHECK(g_instance);
- return g_instance;
- }
- // static
- bool PeripheralNotificationManager::IsInitialized() {
- return g_instance;
- }
- } // namespace ash
|