File: cellular_metrics_logger.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (481 lines) | stat: -rw-r--r-- 18,417 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
// Copyright 2019 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_CELLULAR_METRICS_LOGGER_H_
#define CHROMEOS_ASH_COMPONENTS_NETWORK_CELLULAR_METRICS_LOGGER_H_

#include <optional>

#include "base/component_export.h"
#include "base/containers/flat_map.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.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/managed_network_configuration_handler.h"
#include "chromeos/ash/components/network/network_connection_observer.h"
#include "chromeos/ash/components/network/network_state_handler.h"
#include "chromeos/ash/components/network/network_state_handler_observer.h"

namespace ash {

class CellularESimProfileHandler;
class CellularMetricsLoggerTest;
class ESimFeatureUsageMetrics;
class EnterpriseESimFeatureUsageMetrics;
class NetworkConnectionHandler;
class NetworkState;

// Cellular network SIM types.
enum class SimType {
  kPSim,
  kESim,
};

// Class for tracking cellular network related metrics.
//
// This class adds observers on network state and makes the following
// measurements on cellular networks:
// 1. Time to connected.
// 2. Connected states and non-user initiated disconnections.
// 3. Activation status at login.
// 4. Cellular network usage type.
//
// Note: This class does not start logging metrics until Init() is
// invoked.
class COMPONENT_EXPORT(CHROMEOS_NETWORK) CellularMetricsLogger
    : public NetworkStateHandlerObserver,
      public LoginState::Observer,
      public NetworkConnectionObserver {
 public:
  // Histograms associated with SIM Pin operations.
  static const char kSimPinChangeSuccessHistogram[];
  static const char kManagedSimPinUnblockSuccessHistogram[];
  static const char kManagedSimPinUnlockSuccessHistogram[];
  static const char kSimPinRemoveLockSuccessHistogram[];
  static const char kSimPinRequireLockSuccessHistogram[];
  static const char kRestrictedSimPinUnblockSuccessHistogram[];
  static const char kRestrictedSimPinUnlockSuccessHistogram[];
  static const char kUnmanagedSimPinUnblockSuccessHistogram[];
  static const char kUnmanagedSimPinUnlockSuccessHistogram[];
  static const char kUnrestrictedSimPinUnblockSuccessHistogram[];
  static const char kUnrestrictedSimPinUnlockSuccessHistogram[];
  static const char kChangePinSuccessSimPinLockPolicyHistogram[];
  static const char kRequirePinSuccessSimPinLockPolicyHistogram[];

  // Histograms associated with user initiated connection success.
  static const char kESimUserInitiatedConnectionResultHistogram[];
  static const char kPSimUserInitiatedConnectionResultHistogram[];

  // Histograms associated with all connection success.
  static const char kESimAllConnectionResultHistogram[];
  static const char kESimPolicyAllConnectionResultHistogram[];
  static const char kPSimAllConnectionResultHistogram[];

  // Histograms associated with SIM Lock notification events.
  static const char kSimLockNotificationEventHistogram[];
  static const char kSimLockNotificationLockType[];

  // The amount of time after cellular device is added to device list,
  // after which cellular device is considered initialized.
  static const base::TimeDelta kInitializationTimeout;

  // Histograms associated with SIM Lock status on the active network.
  static const char kUnrestrictedActiveNetworkSIMLockStatus[];
  static const char kRestrictedActiveNetworkSIMLockStatus[];

  // PIN operations that are tracked by metrics.
  enum class SimPinOperation {
    kRequireLock = 0,
    kRemoveLock = 1,
    kUnlock = 2,
    kUnblock = 3,
    kChange = 4,
  };

  // SIM lock notification events
  enum class SimLockNotificationEvent {
    kShown = 0,
    kClicked = 1,
    kDismissed = 2,
    kMaxValue = kDismissed
  };

  // SIM pin lock type.
  enum class SimPinLockType {
    kPinLocked = 0,
    kPukLocked = 1,
    kUnlocked = 2,
    kCarrierLocked = 3,
    kMaxValue = kCarrierLocked
  };

  // Records the result of pin operations performed.
  static void RecordSimPinOperationResult(
      const SimPinOperation& pin_operation,
      const bool allow_cellular_sim_lock,
      const std::optional<std::string>& shill_error_name = std::nullopt);

  // Records the SIM lock notification event.
  static void RecordSimLockNotificationEvent(
      const SimLockNotificationEvent notification_event);

  // Records the SIM lock type when the notification is surfaced.
  static void RecordSimLockNotificationLockType(
      const std::string& sim_lock_type);

  CellularMetricsLogger();

  CellularMetricsLogger(const CellularMetricsLogger&) = delete;
  CellularMetricsLogger& operator=(const CellularMetricsLogger&) = delete;

  ~CellularMetricsLogger() override;

  void Init(NetworkStateHandler* network_state_handler,
            NetworkConnectionHandler* network_connection_handler,
            CellularESimProfileHandler* cellular_esim_profile_handler,
            ManagedNetworkConfigurationHandler*
                managed_network_configuration_handler);

  // LoginState::Observer:
  void LoggedInStateChanged() override;

  // NetworkStateHandlerObserver::
  void DeviceListChanged() override;
  void NetworkListChanged() override;
  void NetworkConnectionStateChanged(const NetworkState* network) override;
  void OnShuttingDown() override;

  // NetworkConnectionObserver::
  void ConnectSucceeded(const std::string& service_path) override;
  void ConnectFailed(const std::string& service_path,
                     const std::string& error_name) override;
  void DisconnectRequested(const std::string& service_path) override;

 private:
  friend class CellularMetricsLoggerTest;
  FRIEND_TEST_ALL_PREFIXES(CellularMetricsLoggerTest,
                           DuplicateCellularServiceGuids);
  FRIEND_TEST_ALL_PREFIXES(CellularMetricsLoggerTest, CellularConnectResult);
  FRIEND_TEST_ALL_PREFIXES(CellularMetricsLoggerTest,
                           CancellationDuringConnecting);
  FRIEND_TEST_ALL_PREFIXES(CellularMetricsLoggerTest,
                           UserInitiatedConnectionResult);
  FRIEND_TEST_ALL_PREFIXES(CellularMetricsLoggerTest,
                           CellularESimProfileStatusAtLoginTest);
  FRIEND_TEST_ALL_PREFIXES(CellularMetricsLoggerTest, CellularUsageCountTest);
  FRIEND_TEST_ALL_PREFIXES(CellularMetricsLoggerTest,
                           CellularUsageCountDongleTest);
  FRIEND_TEST_ALL_PREFIXES(CellularMetricsLoggerTest,
                           CellularPSimActivationStateAtLoginTest);
  FRIEND_TEST_ALL_PREFIXES(CellularMetricsLoggerTest,
                           CellularTimeToConnectedTest);
  FRIEND_TEST_ALL_PREFIXES(CellularMetricsLoggerTest,
                           CellularDisconnectionsTest);
  FRIEND_TEST_ALL_PREFIXES(NetworkDeviceHandlerTest, RequirePin);
  FRIEND_TEST_ALL_PREFIXES(NetworkDeviceHandlerTest, EnterPinOnUnmanagedDevice);
  FRIEND_TEST_ALL_PREFIXES(NetworkDeviceHandlerTest, EnterPinOnManagedDevice);
  FRIEND_TEST_ALL_PREFIXES(NetworkDeviceHandlerTest,
                           UnblockPinOnUnmanagedDevice);
  FRIEND_TEST_ALL_PREFIXES(NetworkDeviceHandlerTest, UnblockPinOnManagedDevice);
  FRIEND_TEST_ALL_PREFIXES(NetworkDeviceHandlerTest, ChangePin);

  // The amount of time after a disconnect request within which any
  // disconnections are considered user initiated.
  static const base::TimeDelta kDisconnectRequestTimeout;

  // Stores connection related information for a cellular network.
  struct ConnectionInfo {
    explicit ConnectionInfo(const std::string& network_guid);
    ConnectionInfo(const std::string& network_guid,
                   bool is_connected,
                   bool is_connecting);
    ~ConnectionInfo();
    const std::string network_guid;
    std::optional<bool> is_connected;
    bool is_connecting = false;
    // Tracks whether a disconnect was requested from chrome on a network that
    // was previously in the connecting state. This field is set back to false
    // when shill connection failures are checked in
    // NetworkConnectionStateChanged().
    bool disconnect_requested = false;
    std::optional<base::TimeTicks> last_disconnect_request_time;
    std::optional<base::TimeTicks> last_connect_start_time;
  };

  // Usage type for cellular network. These values are persisted to logs.
  // Entries should not be renumbered and numeric values should never
  // be reused.
  enum class CellularUsage {
    kConnectedAndOnlyNetwork = 0,
    kConnectedWithOtherNetwork = 1,
    kNotConnected = 2,
    kMaxValue = kNotConnected
  };

  // Activation state for PSim cellular network.
  // These values are persisted to logs. Entries should not be renumbered
  // and numeric values should never be reused.
  enum class PSimActivationState {
    kActivated = 0,
    kActivating = 1,
    kNotActivated = 2,
    kPartiallyActivated = 3,
    kUnknown = 4,
    kMaxValue = kUnknown
  };

  // Profile status for eSIM cellular network.
  // These values are persisted to logs. Entries should not be renumbered
  // and numeric values should never be reused.
  enum class ESimProfileStatus {
    kActive = 0,
    kActiveWithPendingProfiles = 1,
    kPendingProfilesOnly = 2,
    kNoProfiles = 3,
    kMaxValue = kNoProfiles
  };

  // Cellular connection state. These values are persisted to logs.
  // Entries should not be renumbered and numeric values should
  // never be reused.
  enum class ConnectionState {
    kConnected = 0,
    kDisconnected = 1,
    kMaxValue = kDisconnected
  };

  // Result of PIN operations.
  // These values are persisted to logs. Entries should not be renumbered
  // and numeric values should never be reused.
  // Note: With the exception of Success, enums should match the
  // error names listed near the top of NetworkDeviceHandler.
  enum class SimPinOperationResult {
    kSuccess = 0,
    kErrorDeviceMissing = 1,
    kErrorFailure = 2,
    kErrorIncorrectPin = 3,
    kErrorNotFound = 4,
    kErrorNotSupported = 5,
    kErrorPinBlocked = 6,
    kErrorPinRequired = 7,
    kErrorTimeout = 8,
    kErrorUnknown = 9,
    kErrorWrongState = 10,
    kMaxValue = kErrorWrongState,
  };

  // This enum is used to track the connection results from
  // NetworkConnectionHandler. With the exception of kSuccess and kUnknown,
  // these enums are mapped to relevant NetworkConnectionHandler errors
  // associated to user initiated connection errors.
  // These values are persisted to logs. Entries should not be renumbered
  // and numeric values should never be reused.
  enum class ConnectResult {
    kSuccess = 0,
    kUnknown = 1,
    kInvalidGuid = 2,
    kInvalidState = 3,
    kCanceled = 4,
    kNotConfigured = 5,
    kBlocked = 6,
    kCellularInhibitFailure = 7,
    kESimProfileIssue = 8,
    kCellularOutOfCredits = 9,
    kSimPinPukLocked = 10,
    kConnectFailed = 11,
    kNotConnected = 12,
    kActivateFailed = 13,
    kEnabledOrDisabledWhenNotAvailable = 14,
    kErrorCellularDeviceBusy = 15,
    kErrorConnectTimeout = 16,
    kConnectableCellularTimeout = 17,
    kSimCarrierLocked = 18,
    kMaxValue = kSimCarrierLocked,
  };

  // Result of state changes to a cellular network triggered by any connection
  // attempt. With the exception of kSuccess and kUnknown, these enums are
  // mapped directly to Shill errors. These values are persisted to logs.
  // Entries should not be renumbered and numeric values should never be reused.
  enum class ShillConnectResult {
    kSuccess = 0,
    kUnknown = 1,
    kFailedToConnect = 2,
    kDhcpFailure = 3,
    kDnsLookupFailure = 4,
    kEapAuthentication = 5,
    kEapLocalTls = 6,
    kEapRemoteTls = 7,
    kOutOfRange = 8,
    kPinMissing = 9,
    kNoFailure = 10,
    kNotAssociated = 11,
    kNotAuthenticated = 12,
    kTooManySTAs = 13,
    kBadPassphrase = 14,
    kBadWepKey = 15,
    kErrorSimPinPukLocked = 16,
    kErrorNotRegistered = 17,
    kErrorSimCarrierLocked = 18,
    kMaxValue = kErrorSimCarrierLocked,
  };

  // Convert shill error name string to SimPinOperationResult enum.
  static SimPinOperationResult GetSimPinOperationResultForShillError(
      const std::string& shill_error_name);

  // Converts a NetworkConnectionHandler string error to a ConnectResult enum.
  static ConnectResult NetworkConnectionErrorToConnectResult(
      const std::string& error_name);

  // Converts a Shill error string to a ShillConnectResult enum.
  static ShillConnectResult ShillErrorToConnectResult(
      const std::string& error_name);

  static void LogCellularUserInitiatedConnectionSuccessHistogram(
      ConnectResult start_connect_result,
      SimType sim_type);

  // Returns null if there is no network with the given path or if the
  // network is non-cellular.
  const NetworkState* GetCellularNetwork(const std::string& service_path);

  // Convert shill activation state string to PSimActivationState enum
  PSimActivationState PSimActivationStateToEnum(const std::string& state);

  // Helper method to save cellular disconnections histogram.
  void LogCellularDisconnectionsHistogram(ConnectionState connection_state,
                                          SimType sim_type,
                                          bool is_managed_by_policy);

  void LogCellularAllConnectionSuccessHistogram(
      ShillConnectResult start_connect_result,
      SimType sim_type,
      bool is_managed_by_policy);

  void OnInitializationTimeout();

  // Tracks cellular network connection state and logs time to connected.
  void CheckForTimeToConnectedMetric(const NetworkState* network);

  // Tracks current cellular connection status and logs the metric.
  // Current connection can be in one of the three states:
  // (Connected/PIN_Locked/PUK_Blocked). This will be logged when a
  // switch happens from no connection to an active connection or
  // from one connection to another.
  void CheckForSIMStatusMetric(const NetworkState* network);

  // Tracks cellular network connected states and non user initiated
  // disconnections.
  void CheckForConnectionStateMetric(const NetworkState* network);

  // Tracks the activation state of the PSim cellular network if available and
  // if |is_psim_activation_state_logged_| is false.
  void CheckForPSimActivationStateMetric();

  // Tracks the activation state of eSIM cellular networks if available and
  // if |is_esim_profile_status_logged_| is false.
  void CheckForESimProfileStatusMetric();

  // Tracks failed connection attempts.
  void CheckForShillConnectionFailureMetric(const NetworkState* network);

  // This checks the state of connected networks and logs
  // cellular network usage histogram. Histogram is only logged
  // when usage state changes.
  void CheckForCellularUsageMetrics();

  // Tracks how many eSIM profiles are installed on the device and how many pSIM
  // networks are available on the device if |is_service_count_logged_| is true.
  void CheckForCellularServiceCountMetric();

  // Tracks the state of the Allow APN Modification policy at login.
  void CheckForApnPolicyMetric();

  // Handles eSIM Standard Feature Usage Logging metrics when the cellular usage
  // changes for an eSIM network.
  void HandleESimFeatureUsageChange(CellularUsage last_esim_cellular_usage,
                                    CellularUsage current_usage,
                                    bool is_managed_by_policy);

  // Returns the ConnectionInfo for given |cellular_network_guid|.
  ConnectionInfo* GetConnectionInfoForCellularNetwork(
      const std::string& cellular_network_guid);

  // Tracks the last cellular network usage state.
  std::optional<CellularUsage> last_cellular_usage_;

  // Tracks the last PSim cellular network usage state.
  std::optional<CellularUsage> last_psim_cellular_usage_;

  // Tracks the last time the PSim network's cellular usage changed.
  std::optional<base::ElapsedTimer> psim_usage_elapsed_timer_;

  // Tracks the last eSIM cellular network usage state.
  std::optional<CellularUsage> last_esim_cellular_usage_;

  // Tracks the last time eSIM network's cellular usage is managed or not.
  bool last_managed_by_policy_ = false;

  // Tracks the last time the eSIM network's cellular usage changed.
  std::optional<base::ElapsedTimer> esim_usage_elapsed_timer_;

  // Tracks whether cellular device is available or not.
  bool is_cellular_available_ = false;

  raw_ptr<NetworkStateHandler> network_state_handler_ = nullptr;
  base::ScopedObservation<NetworkStateHandler, NetworkStateHandlerObserver>
      network_state_handler_observer_{this};

  raw_ptr<ManagedNetworkConfigurationHandler>
      managed_network_configuration_handler_ = nullptr;

  raw_ptr<NetworkConnectionHandler> network_connection_handler_ = nullptr;

  raw_ptr<CellularESimProfileHandler> cellular_esim_profile_handler_ = nullptr;

  // A timer to wait for cellular initialization. This is useful
  // to avoid tracking intermediate states when cellular network is
  // starting up.
  base::OneShotTimer initialization_timer_;

  // Stores the iccid of the most recently active network.
  std::string last_active_network_iccid_;

  // Tracks whether the PSim activation state is already logged for this
  // session.
  bool is_psim_activation_state_logged_ = false;

  // Tracks whether the eSIM profile status is already logged for this
  // session.
  bool is_esim_profile_status_logged_ = false;

  // Tracks whether service count is already logged for this session.
  bool is_service_count_logged_ = false;

  // Tracks whether apn policy state is already logged for this session.
  bool is_apn_policy_logged_ = false;

  // Stores connection information for all cellular networks.
  base::flat_map<std::string, std::unique_ptr<ConnectionInfo>>
      guid_to_connection_info_map_;

  bool initialized_ = false;

  // Tracks eSIM feature usage for the Standard Feature Usage Logging Framework.
  std::unique_ptr<ESimFeatureUsageMetrics> esim_feature_usage_metrics_;

  // Tracks enterprise eSIM feature usage for the Standard Feature Usage Logging
  // Framework.
  std::unique_ptr<EnterpriseESimFeatureUsageMetrics>
      enterprise_esim_feature_usage_metrics_;
};

}  // namespace ash

#endif  // CHROMEOS_ASH_COMPONENTS_NETWORK_CELLULAR_METRICS_LOGGER_H_