| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_HOTSPOT_METRICS_HELPER_H_ |
| #define CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_HOTSPOT_METRICS_HELPER_H_ |
| |
| #include "base/component_export.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/time/time.h" |
| #include "base/timer/elapsed_timer.h" |
| #include "base/timer/timer.h" |
| #include "chromeos/ash/components/login/login_state/login_state.h" |
| #include "chromeos/ash/components/network/hotspot_capabilities_provider.h" |
| #include "chromeos/ash/components/network/hotspot_enabled_state_notifier.h" |
| #include "chromeos/ash/components/network/hotspot_state_handler.h" |
| #include "chromeos/ash/services/hotspot_config/public/mojom/cros_hotspot_config.mojom.h" |
| #include "mojo/public/cpp/bindings/receiver.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| |
| namespace ash { |
| |
| class EnterpriseManagedMetadataStore; |
| class HotspotConfigurationHandler; |
| class HotspotController; |
| |
| // This class is used to track the hotspot capabilities and status update and |
| // emits UMA metrics to the related histogram. |
| class COMPONENT_EXPORT(CHROMEOS_NETWORK) HotspotMetricsHelper |
| : public LoginState::Observer, |
| public HotspotCapabilitiesProvider::Observer, |
| public HotspotStateHandler::Observer, |
| public hotspot_config::mojom::HotspotEnabledStateObserver { |
| public: |
| // Emits enable/disable hotspot operation result to related UMA histogram. |
| static void RecordSetTetheringEnabledResult( |
| bool enabled, |
| hotspot_config::mojom::HotspotControlResult result); |
| |
| // Emits check tethering readiness operation result to related UMA histogram. |
| static void RecordCheckTetheringReadinessResult( |
| HotspotCapabilitiesProvider::CheckTetheringReadinessResult result); |
| |
| // Emits set hotspot configuration operation result to related UMA histogram. |
| static void RecordSetHotspotConfigResult( |
| hotspot_config::mojom::SetHotspotConfigResult result); |
| |
| // Emits hotspot enable operation latency to related UMA histogram. |
| static void RecordEnableHotspotLatency(const base::TimeDelta& latency); |
| |
| HotspotMetricsHelper(); |
| HotspotMetricsHelper(const HotspotMetricsHelper&) = delete; |
| HotspotMetricsHelper& operator=(const HotspotMetricsHelper&) = delete; |
| ~HotspotMetricsHelper() override; |
| |
| void Init(EnterpriseManagedMetadataStore* enterprise_managed_metadata_store, |
| HotspotCapabilitiesProvider* hotspot_capabilities_provider, |
| HotspotStateHandler* hotspot_state_handler, |
| HotspotController* hotspot_controller, |
| HotspotConfigurationHandler* hotspot_configuration_handler, |
| HotspotEnabledStateNotifier* hotspot_enabled_state_notifier, |
| NetworkStateHandler* network_state_handler); |
| |
| private: |
| friend class HotspotMetricsHelperTest; |
| FRIEND_TEST_ALL_PREFIXES(HotspotMetricsHelperTest, |
| HotspotAllowStatusHistogram); |
| FRIEND_TEST_ALL_PREFIXES(HotspotMetricsHelperTest, |
| HotspotUsageConfigHistogram); |
| FRIEND_TEST_ALL_PREFIXES(HotspotMetricsHelperTest, |
| HotspotUsageDurationHistogram); |
| FRIEND_TEST_ALL_PREFIXES(HotspotMetricsHelperTest, |
| HotspotMaxClientCountHistogram); |
| FRIEND_TEST_ALL_PREFIXES(HotspotMetricsHelperTest, |
| HotspotIsDeviceManagedHistogram); |
| FRIEND_TEST_ALL_PREFIXES(HotspotMetricsHelperTest, |
| HotspotEnabledUpstreamStatusHistogram); |
| FRIEND_TEST_ALL_PREFIXES(HotspotMetricsHelperTest, |
| HotspotDisableReasonHistogram); |
| FRIEND_TEST_ALL_PREFIXES(HotspotControllerTest, EnableTetheringSuccess); |
| FRIEND_TEST_ALL_PREFIXES(HotspotControllerTest, |
| EnableTetheringReadinessCheckFailure); |
| FRIEND_TEST_ALL_PREFIXES(HotspotControllerTest, |
| EnableTetheringNetworkSetupFailure); |
| FRIEND_TEST_ALL_PREFIXES(HotspotControllerTest, DisableTetheringSuccess); |
| FRIEND_TEST_ALL_PREFIXES(HotspotConfigurationHandlerTest, |
| SetAndGetHotspotConfig); |
| FRIEND_TEST_ALL_PREFIXES(HotspotCapabilitiesProviderTest, |
| CheckTetheringReadiness); |
| |
| enum class HotspotMetricsSetEnabledResult; |
| enum class HotspotMetricsSetConfigResult; |
| enum class HotspotMetricsCheckReadinessResult; |
| enum class HotspotMetricsDisableReason; |
| |
| static const char kHotspotAllowStatusHistogram[]; |
| static const char kHotspotAllowStatusAtLoginHistogram[]; |
| static const char kHotspotEnableResultHistogram[]; |
| static const char kHotspotDisableResultHistogram[]; |
| static const char kHotspotSetConfigResultHistogram[]; |
| static const char kHotspotCheckReadinessResultHistogram[]; |
| static const char kHotspotUsageConfigAutoDisable[]; |
| static const char kHotspotUsageConfigMAR[]; |
| static const char kHotspotUsageConfigCompatibilityMode[]; |
| static const char kHotspotUsageDuration[]; |
| static const char kHotspotMaxClientCount[]; |
| static const char kHotspotIsDeviceManaged[]; |
| static const char kHotspotEnableLatency[]; |
| static const char kHotspotUpstreamStatusWhenEnabled[]; |
| static const char kHotspotDisableReasonHistogram[]; |
| static const base::TimeDelta kLogAllowStatusAtLoginTimeout; |
| |
| static HotspotMetricsCheckReadinessResult GetCheckReadinessMetricsResult( |
| const HotspotCapabilitiesProvider::CheckTetheringReadinessResult& result); |
| static HotspotMetricsSetEnabledResult GetSetEnabledMetricsResult( |
| const hotspot_config::mojom::HotspotControlResult& result); |
| static HotspotMetricsSetConfigResult GetSetConfigMetricsResult( |
| const hotspot_config::mojom::SetHotspotConfigResult& result); |
| static HotspotMetricsDisableReason GetMetricsDisableReason( |
| const hotspot_config::mojom::DisableReason& reason); |
| |
| // Represents the hotspot allow status on device. Note: |
| // kDisallowNoCellularUpstream is not logged in the metric because it means |
| // the device is not cellular capable, and it would drown out the metric by |
| // adding the bucket. These values are persisted to logs. Entries should not |
| // be renumbered and numeric values should never be reused. |
| enum class HotspotMetricsAllowStatus { |
| kAllowed = 0, |
| kDisallowedWiFiDownstreamNotSupported = 1, |
| kDisallowedNoWiFiSecurityModes = 2, |
| kDisallowedNoMobileData = 3, |
| kDisallowedReadinessCheckFail = 4, |
| kDisallowedByPolicy = 5, |
| kMaxValue = kDisallowedByPolicy, |
| }; |
| |
| // Represents the operation result of set hotspot configuration used for |
| // related UMA histogram. These values are persisted to logs. Entries should |
| // not be renumbered and numeric values should never be reused. |
| enum class HotspotMetricsSetConfigResult { |
| kSuccess = 0, |
| kFailedNotLogin = 1, |
| kFailedInvalidConfiguration = 2, |
| kMaxValue = kFailedInvalidConfiguration, |
| }; |
| |
| // Represents the operation result of check tethering readiness used for |
| // related UMA histogram. These values are persisted to logs. Entries should |
| // not be renumbered and numeric values should never be reused. |
| enum class HotspotMetricsCheckReadinessResult { |
| kReady = 0, |
| kNotAllowed = 1, |
| kUpstreamNetworkNotAvailable = 2, |
| kShillOperationFailed = 3, |
| kUnknownResult = 4, |
| kMaxValue = kUnknownResult, |
| }; |
| |
| // Represents the operation result of enable/disable hotspot used for related |
| // UMA histograms. These values are persisted to logs. Entries should not be |
| // renumbered and numeric values should never be reused. |
| enum class HotspotMetricsSetEnabledResult { |
| kSuccess = 0, |
| kNotAllowed = 1, |
| kReadinessCheckFailure = 2, |
| kDisableWifiFailure = 3, |
| kInvalidConfiguration = 4, |
| kUpstreamNotAvailable = 5, |
| kNetworkSetupFailure = 6, |
| kWifiDriverFailure = 7, |
| kCellularAttachFailure = 8, |
| kShillOperationFailure = 9, |
| kUnknownFailure = 10, |
| kAlreadyFulfilled = 11, |
| kMaxValue = kAlreadyFulfilled, |
| }; |
| |
| // Represents the upstream status when hotspot is enabled. These values are |
| // persisted to logs. Entries should not be renumbered and numeric values |
| // should never be reused. |
| enum class HotspotMetricsUpstreamStatus { |
| kWifiWithCellularConnected = 0, |
| kWifiWithCellularNotConnected = 1, |
| kMaxValue = kWifiWithCellularNotConnected, |
| }; |
| |
| // Represents the hotspot disable reason. These values are persisted to logs. |
| // Entries should not be renumbered and numeric values should never be used. |
| enum class HotspotMetricsDisableReason { |
| kAutoDisabled = 0, |
| kInternalError = 1, |
| kUserInitiated = 2, |
| kWifiEnabled = 3, |
| kProhibitedByPolicy = 4, |
| kUpstreamNetworkNotAvailable = 5, |
| kSuspended = 6, |
| kRestart = 7, |
| kMaxValue = kRestart, |
| }; |
| |
| // HotspotCapabilitiesProvider::Observer: |
| void OnHotspotCapabilitiesChanged() override; |
| |
| // HotspotStateHandler::Observer: |
| void OnHotspotStatusChanged() override; |
| |
| // LoginState::Observer: |
| void LoggedInStateChanged() override; |
| |
| // hotspot_config::mojom::HotspotEnabledStateObserver: |
| void OnHotspotTurnedOn(bool wifi_turned_off) override; |
| void OnHotspotTurnedOff(hotspot_config::mojom::DisableReason reason) override; |
| |
| void LogAllowStatus(); |
| void LogAllowStatusAtLogin(); |
| void LogUsageConfig(); |
| void LogUsageDuration(); |
| void LogMaxClientCount(); |
| void LogIsDeviceManaged(); |
| void LogUpstreamStatus(); |
| void LogDisableReason(const hotspot_config::mojom::DisableReason& reason); |
| |
| // Retrieves the latest hotspot allow status and converts to |
| // HotspotMetricsAllowStatus enum. Return absl::nullopt if it is disallowed |
| // due to device is not cellular capable. |
| absl::optional<HotspotMetricsAllowStatus> GetMetricsAllowStatus(); |
| |
| raw_ptr<EnterpriseManagedMetadataStore, ExperimentalAsh> |
| enterprise_managed_metadata_store_ = nullptr; |
| raw_ptr<HotspotCapabilitiesProvider, ExperimentalAsh> |
| hotspot_capabilities_provider_ = nullptr; |
| raw_ptr<HotspotStateHandler, ExperimentalAsh> hotspot_state_handler_ = |
| nullptr; |
| raw_ptr<HotspotConfigurationHandler, ExperimentalAsh> |
| hotspot_configuration_handler_ = nullptr; |
| raw_ptr<HotspotEnabledStateNotifier, ExperimentalAsh> |
| hotspot_enabled_state_notifier_ = nullptr; |
| raw_ptr<NetworkStateHandler, ExperimentalAsh> network_state_handler_ = |
| nullptr; |
| |
| // A timer to wait for user connecting to their upstream cellular network |
| // after login. |
| base::OneShotTimer timer_; |
| |
| // Tracks the maximum connected client count per hotspot session. |
| size_t max_client_count_ = 0; |
| |
| // Tracks whether the metrics are already logged for this session. |
| bool is_metrics_logged_ = false; |
| |
| // Tracks whether the hotspot is active. |
| bool is_hotspot_active_ = false; |
| |
| // Tracks the usage time for each hotspot session. |
| absl::optional<base::ElapsedTimer> usage_timer_; |
| |
| // Tracks if the device is enterprise managed or not. |
| bool is_enterprise_managed_ = false; |
| |
| mojo::Receiver<hotspot_config::mojom::HotspotEnabledStateObserver> |
| hotspot_enabled_state_notifier_receiver_{this}; |
| }; |
| |
| } // namespace ash |
| |
| #endif // CHROMEOS_ASH_COMPONENTS_NETWORK_METRICS_HOTSPOT_METRICS_HELPER_H_ |