• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/metrics/drive_metrics_provider.h"
6 
7 #include "base/base_paths.h"
8 #include "base/check_op.h"
9 #include "base/files/drive_info.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/functional/bind.h"
13 #include "base/functional/callback.h"
14 #include "base/location.h"
15 #include "base/metrics/histogram_functions.h"
16 #include "base/path_service.h"
17 #include "base/task/task_traits.h"
18 #include "base/task/thread_pool.h"
19 #include "base/threading/scoped_blocking_call.h"
20 
21 namespace metrics {
22 
23 namespace {
RecordTriStateMetric(const char * name,std::optional<bool> sample)24 void RecordTriStateMetric(const char* name, std::optional<bool> sample) {
25   base::UmaHistogramEnumeration(
26       name, !sample.has_value()
27                 ? DriveMetricsProvider::OptionalBoolRecord::kUnknown
28                 : (*sample ? DriveMetricsProvider::OptionalBoolRecord::kTrue
29                            : DriveMetricsProvider::OptionalBoolRecord::kFalse));
30 }
31 }  // namespace
32 
DriveMetricsProvider(int local_state_path_key)33 DriveMetricsProvider::DriveMetricsProvider(int local_state_path_key)
34     : local_state_path_key_(local_state_path_key) {}
35 
36 DriveMetricsProvider::~DriveMetricsProvider() = default;
37 
ProvideSystemProfileMetrics(metrics::SystemProfileProto * system_profile_proto)38 void DriveMetricsProvider::ProvideSystemProfileMetrics(
39     metrics::SystemProfileProto* system_profile_proto) {
40   auto* hardware = system_profile_proto->mutable_hardware();
41   FillDriveMetrics(metrics_.app_drive, hardware->mutable_app_drive());
42   FillDriveMetrics(metrics_.user_data_drive,
43                    hardware->mutable_user_data_drive());
44 }
45 
AsyncInit(base::OnceClosure done_callback)46 void DriveMetricsProvider::AsyncInit(base::OnceClosure done_callback) {
47   base::ThreadPool::PostTaskAndReplyWithResult(
48       FROM_HERE,
49       {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
50        base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
51       base::BindOnce(&DriveMetricsProvider::GetDriveMetricsOnBackgroundThread,
52                      local_state_path_key_),
53       base::BindOnce(&DriveMetricsProvider::GotDriveMetrics,
54                      weak_ptr_factory_.GetWeakPtr(), std::move(done_callback)));
55 }
56 
57 DriveMetricsProvider::SeekPenaltyResponse::SeekPenaltyResponse() = default;
58 
59 // static
60 DriveMetricsProvider::DriveMetrics
GetDriveMetricsOnBackgroundThread(int local_state_path_key)61 DriveMetricsProvider::GetDriveMetricsOnBackgroundThread(
62     int local_state_path_key) {
63   base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
64                                                 base::BlockingType::WILL_BLOCK);
65 
66   DriveMetricsProvider::DriveMetrics metrics;
67   QuerySeekPenalty(base::FILE_EXE, &metrics.app_drive);
68   QuerySeekPenalty(local_state_path_key, &metrics.user_data_drive);
69   return metrics;
70 }
71 
72 // static
QuerySeekPenalty(int path_service_key,DriveMetricsProvider::SeekPenaltyResponse * response)73 void DriveMetricsProvider::QuerySeekPenalty(
74     int path_service_key,
75     DriveMetricsProvider::SeekPenaltyResponse* response) {
76   DCHECK(response);
77 
78   base::FilePath path;
79   if (!base::PathService::Get(path_service_key, &path))
80     return;
81 
82   bool has_seek_penalty;
83   bool have_value = HasSeekPenalty(path, &has_seek_penalty);
84   if (have_value) {
85     response->has_seek_penalty = has_seek_penalty;
86   }
87   std::optional<base::DriveInfo> drive_info = base::GetFileDriveInfo(path);
88   if (drive_info.has_value()) {
89     response->has_seek_penalty_base = drive_info->has_seek_penalty;
90 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
91     response->is_removable = drive_info->is_removable;
92     response->is_usb = drive_info->is_usb;
93 #endif
94   }
95 }
96 
GotDriveMetrics(base::OnceClosure done_callback,const DriveMetricsProvider::DriveMetrics & metrics)97 void DriveMetricsProvider::GotDriveMetrics(
98     base::OnceClosure done_callback,
99     const DriveMetricsProvider::DriveMetrics& metrics) {
100   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
101   metrics_ = metrics;
102   std::move(done_callback).Run();
103 }
104 
FillDriveMetrics(const DriveMetricsProvider::SeekPenaltyResponse & response,metrics::SystemProfileProto::Hardware::Drive * drive)105 void DriveMetricsProvider::FillDriveMetrics(
106     const DriveMetricsProvider::SeekPenaltyResponse& response,
107     metrics::SystemProfileProto::Hardware::Drive* drive) {
108   if (response.has_seek_penalty.has_value()) {
109     drive->set_has_seek_penalty(*response.has_seek_penalty);
110   }
111 
112   RecordTriStateMetric("UMA.SeekPenaltyResult.Provider",
113                        response.has_seek_penalty);
114   RecordTriStateMetric("UMA.SeekPenaltyResult.Base",
115                        response.has_seek_penalty_base);
116 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
117   RecordTriStateMetric("UMA.DriveIsRemovableResult", response.is_removable);
118   RecordTriStateMetric("UMA.DriveIsUSBResult", response.is_usb);
119 #endif
120 }
121 
122 }  // namespace metrics
123