| // 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 CHROME_BROWSER_METRICS_STRUCTURED_ASH_EVENT_STORAGE_H_ |
| #define CHROME_BROWSER_METRICS_STRUCTURED_ASH_EVENT_STORAGE_H_ |
| |
| #include <memory> |
| |
| #include "base/memory/weak_ptr.h" |
| #include "base/time/time.h" |
| #include "chrome/browser/metrics/structured/profile_observer.h" |
| #include "components/metrics/structured/lib/event_storage.h" |
| #include "components/metrics/structured/lib/persistent_proto.h" |
| #include "components/metrics/structured/proto/event_storage.pb.h" |
| #include "third_party/metrics_proto/structured_data.pb.h" |
| |
| namespace metrics::structured { |
| |
| // Storage for Structured Metrics events on Ash. |
| // |
| // Events are stored in a proto called EventsProto. These events are flushed to |
| // disk on a cadence. Before a user has logged in, these events will be stored |
| // in the shared partition. The events after a user has logged in, events will |
| // be stored in the user cryptohome. |
| class AshEventStorage : public EventStorage<StructuredEventProto>, |
| public ProfileObserver { |
| public: |
| // The delay period for the PersistentProto. |
| constexpr static base::TimeDelta kSaveDelay = base::Seconds(1); |
| |
| AshEventStorage(base::TimeDelta write_delay, |
| const base::FilePath& pre_user_event_path); |
| |
| ~AshEventStorage() override; |
| |
| // EventStorage: |
| void OnReady() override; |
| void AddEvent(StructuredEventProto event) override; |
| ::google::protobuf::RepeatedPtrField<StructuredEventProto> TakeEvents() |
| override; |
| int RecordedEventsCount() const override; |
| void Purge() override; |
| void AddBatchEvents( |
| const google::protobuf::RepeatedPtrField<StructuredEventProto>& events) |
| override; |
| |
| // ProfileObserver: |
| void ProfileAdded(const Profile& profile) override; |
| |
| // Populates |proto| with a copy of the events currently recorded across both |
| // |pre_user_events_| and |user_events_|. |
| void CopyEvents(EventsProto* events_proto) const override; |
| |
| private: |
| void OnWrite(const WriteStatus status); |
| void OnRead(const ReadStatus status); |
| void OnProfileRead(const ReadStatus status); |
| |
| EventsProto* pre_user_events() { return pre_user_events_->get(); } |
| const EventsProto* pre_user_events() const { return pre_user_events_->get(); } |
| |
| EventsProto* user_events() { return user_events_->get(); } |
| const EventsProto* user_events() const { return user_events_->get(); } |
| |
| // Retrieves the approproiate event store to write the event. Returns nullptr |
| // if there is no appropriate place to persist the event. |
| PersistentProto<EventsProto>* GetStoreToWriteEvent(); |
| |
| // Callback to be made when profile event storage is ready to record. |
| void OnProfileReady(); |
| |
| bool IsProfileReady() const; |
| bool IsPreUserStorageReadable() const; |
| |
| bool is_initialized_ = false; |
| bool is_user_initialized_ = false; |
| |
| // Delay period for PersistentProto writes. Default value of 1000 ms used if |
| // not specified in ctor. |
| base::TimeDelta write_delay_; |
| |
| // Events captured before a user has logged in. |
| std::unique_ptr<PersistentProto<EventsProto>> pre_user_events_; |
| |
| // On-device storage within the user's cryptohome for unsent logs. |
| std::unique_ptr<PersistentProto<EventsProto>> user_events_; |
| |
| // Storage for events to be stored if they are recorded before the storage is |
| // ready. Should never be used once `OnReady` is called. |
| std::vector<StructuredEventProto> pre_storage_events_; |
| |
| base::WeakPtrFactory<AshEventStorage> weak_factory_{this}; |
| }; |
| |
| } // namespace metrics::structured |
| |
| #endif // CHROME_BROWSER_METRICS_STRUCTURED_ASH_EVENT_STORAGE_H_ |