1 // Copyright 2023 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_STRUCTURED_LIB_KEY_DATA_FILE_DELEGATE_H_ 6 #define COMPONENTS_METRICS_STRUCTURED_LIB_KEY_DATA_FILE_DELEGATE_H_ 7 8 #include <memory> 9 #include <string> 10 11 #include "base/functional/callback.h" 12 #include "base/memory/scoped_refptr.h" 13 #include "base/memory/weak_ptr.h" 14 #include "base/sequence_checker.h" 15 #include "components/metrics/structured/lib/key_data.h" 16 #include "components/metrics/structured/lib/persistent_proto.h" 17 #include "components/metrics/structured/lib/proto/key.pb.h" 18 19 namespace base { 20 21 class FilePath; 22 class TimeDelta; 23 24 } // namespace base 25 26 namespace metrics::structured { 27 28 // File-backed KeyData::StorageDelegate implementation using PersistentProto, 29 // stored at the path given to the constructor that will persist any changes on 30 // |save_delay| cadence. 31 class KeyDataFileDelegate : public KeyData::StorageDelegate { 32 public: 33 // Stores a file at |path| that updates every |save_delay|. Once the keys have 34 // been loaded from |path|, callback |on_initialized_callback| will be called. 35 KeyDataFileDelegate(const base::FilePath& path, 36 base::TimeDelta save_delay, 37 base::OnceClosure on_initialized_callback); 38 ~KeyDataFileDelegate() override; 39 40 // KeyData::StorageDelegate: 41 bool IsReady() const override; 42 const KeyProto* GetKey(uint64_t project_name_hash) const override; 43 void UpsertKey(uint64_t project_name_hash, 44 base::TimeDelta last_key_rotation, 45 base::TimeDelta key_rotation_period) override; 46 void Purge() override; 47 48 private: 49 friend class KeyDataFileDelegateTest; 50 51 // Flushes immediately for tests that need to read the file immediately. 52 void WriteNowForTesting(); 53 54 // Callback made when |proto_| is initially read. 55 void OnRead(ReadStatus status); 56 57 // Callback made when there is a write to |proto_|. 58 void OnWrite(WriteStatus status); 59 60 // Whether this instance has finished reading from disk. 61 bool is_initialized_ = false; 62 63 // Callback made once |proto_| has been read and loaded into memory. 64 base::OnceClosure on_initialized_callback_; 65 66 // File-backed storage for keys. 67 std::unique_ptr<PersistentProto<KeyDataProto>> proto_; 68 69 SEQUENCE_CHECKER(sequence_checker_); 70 71 base::WeakPtrFactory<KeyDataFileDelegate> weak_factory_{this}; 72 }; 73 74 } // namespace metrics::structured 75 76 #endif // COMPONENTS_METRICS_STRUCTURED_LIB_KEY_DATA_FILE_DELEGATE_H_ 77