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 #ifndef COMPONENTS_METRICS_DRIVE_METRICS_PROVIDER_H_ 6 #define COMPONENTS_METRICS_DRIVE_METRICS_PROVIDER_H_ 7 8 #include "base/functional/callback_forward.h" 9 #include "base/gtest_prod_util.h" 10 #include "base/memory/weak_ptr.h" 11 #include "base/sequence_checker.h" 12 #include "components/metrics/metrics_provider.h" 13 #include "third_party/metrics_proto/system_profile.pb.h" 14 15 namespace base { 16 class FilePath; 17 } 18 19 namespace metrics { 20 21 // Provides metrics about the local drives on a user's computer. Currently only 22 // checks to see if they incur a seek-time penalty (e.g. if they're SSDs). 23 class DriveMetricsProvider : public metrics::MetricsProvider { 24 public: 25 explicit DriveMetricsProvider(int local_state_path_key); 26 27 DriveMetricsProvider(const DriveMetricsProvider&) = delete; 28 DriveMetricsProvider& operator=(const DriveMetricsProvider&) = delete; 29 30 ~DriveMetricsProvider() override; 31 32 // metrics::MetricsProvider: 33 void AsyncInit(base::OnceClosure done_callback) override; 34 void ProvideSystemProfileMetrics( 35 metrics::SystemProfileProto* system_profile_proto) override; 36 37 // These values are persisted to logs. Entries should not be renumbered and 38 // numeric values should never be reused. 39 enum class OptionalBoolRecord { 40 kUnknown = 0, 41 kFalse = 1, 42 kTrue = 2, 43 kMaxValue = kTrue, 44 }; 45 46 private: 47 FRIEND_TEST_ALL_PREFIXES(DriveMetricsProviderTest, HasSeekPenalty); 48 49 // A response to querying a drive as to whether it incurs a seek penalty. 50 // |has_seek_penalty| is set if |success| is true. 51 struct SeekPenaltyResponse { 52 SeekPenaltyResponse(); 53 std::optional<bool> has_seek_penalty; 54 std::optional<bool> has_seek_penalty_base; 55 std::optional<bool> is_removable; 56 std::optional<bool> is_usb; 57 }; 58 59 struct DriveMetrics { 60 SeekPenaltyResponse app_drive; 61 SeekPenaltyResponse user_data_drive; 62 }; 63 64 // Determine whether the device that services |path| has a seek penalty. 65 // Returns false if it couldn't be determined (e.g., |path| doesn't exist). 66 static bool HasSeekPenalty(const base::FilePath& path, 67 bool* has_seek_penalty); 68 69 // Gather metrics about various drives. Should be run on a background thread. 70 static DriveMetrics GetDriveMetricsOnBackgroundThread( 71 int local_state_path_key); 72 73 // Tries to determine whether there is a penalty for seeking on the drive that 74 // hosts |path_service_key| (for example: the drive that holds "Local State"). 75 static void QuerySeekPenalty(int path_service_key, 76 SeekPenaltyResponse* response); 77 78 // Called when metrics are done being gathered asynchronously. 79 // |done_callback| is the callback that should be called once all metrics are 80 // gathered. 81 void GotDriveMetrics(base::OnceClosure done_callback, 82 const DriveMetrics& metrics); 83 84 // Fills |drive| with information from successful |response|s. 85 void FillDriveMetrics(const SeekPenaltyResponse& response, 86 metrics::SystemProfileProto::Hardware::Drive* drive); 87 88 // The key to give to base::PathService to obtain the path to local state 89 // (supplied by the embedder). 90 int local_state_path_key_; 91 92 // Information gathered about various important drives. 93 DriveMetrics metrics_; 94 95 SEQUENCE_CHECKER(sequence_checker_); 96 base::WeakPtrFactory<DriveMetricsProvider> weak_ptr_factory_{this}; 97 }; 98 99 } // namespace metrics 100 101 #endif // COMPONENTS_METRICS_DRIVE_METRICS_PROVIDER_H_ 102