• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "components/metrics/structured/test/test_key_data_provider.h"
6 
7 #include "base/check.h"
8 #include "base/time/time.h"
9 #include "components/metrics/structured/key_data_provider_file.h"
10 #include "components/metrics/structured/structured_metrics_validator.h"
11 
12 namespace metrics::structured {
13 
TestKeyDataProvider(const base::FilePath & device_key_path)14 TestKeyDataProvider::TestKeyDataProvider(const base::FilePath& device_key_path)
15     : TestKeyDataProvider(device_key_path, base::FilePath()) {}
16 
TestKeyDataProvider(const base::FilePath & device_key_path,const base::FilePath & profile_key_path)17 TestKeyDataProvider::TestKeyDataProvider(const base::FilePath& device_key_path,
18                                          const base::FilePath& profile_key_path)
19     : device_key_path_(device_key_path), profile_key_path_(profile_key_path) {
20   device_key_data_ = std::make_unique<KeyDataProviderFile>(
21       device_key_path_, base::Milliseconds(0));
22   device_key_data_->AddObserver(this);
23 }
24 
~TestKeyDataProvider()25 TestKeyDataProvider::~TestKeyDataProvider() {
26   device_key_data_->RemoveObserver(this);
27   if (profile_key_data_) {
28     profile_key_data_->RemoveObserver(this);
29   }
30 }
31 
GetId(const std::string & project_name)32 std::optional<uint64_t> TestKeyDataProvider::GetId(
33     const std::string& project_name) {
34   // Validates the event. If valid, retrieve the metadata associated
35   // with the event.
36   const auto* project_validator =
37       validator::Validators::Get()->GetProjectValidator(project_name);
38 
39   if (!project_validator) {
40     return std::nullopt;
41   }
42 
43   switch (project_validator->id_scope()) {
44     case IdScope::kPerProfile: {
45       if (profile_key_data_) {
46         return profile_key_data_->GetId(project_name);
47       }
48       break;
49     }
50     case IdScope::kPerDevice: {
51       if (project_validator->event_type() ==
52           StructuredEventProto_EventType_SEQUENCE) {
53         if (!profile_key_data_) {
54           return std::nullopt;
55         }
56         return profile_key_data_->GetId(project_name);
57       } else if (device_key_data_) {
58         return device_key_data_->GetId(project_name);
59       }
60       break;
61     }
62     default:
63       NOTREACHED();
64   }
65   return std::nullopt;
66 }
67 
GetSecondaryId(const std::string & project_name)68 std::optional<uint64_t> TestKeyDataProvider::GetSecondaryId(
69     const std::string& project_name) {
70   const auto* project_validator =
71       validator::Validators::Get()->GetProjectValidator(project_name);
72   if (!project_validator) {
73     return std::nullopt;
74   }
75 
76   // Only SEQUENCE types have secondary ids.
77   if (project_validator->event_type() !=
78       StructuredEventProto_EventType_SEQUENCE) {
79     return std::nullopt;
80   }
81 
82   DCHECK(device_key_data_);
83   if (device_key_data_ && device_key_data_->IsReady()) {
84     return device_key_data_->GetId(project_name);
85   }
86 
87   return std::nullopt;
88 }
89 
GetKeyData(const std::string & project_name)90 KeyData* TestKeyDataProvider::GetKeyData(const std::string& project_name) {
91   // Validates the event. If valid, retrieve the metadata associated
92   // with the event.
93   const auto* project_validator =
94       validator::Validators::Get()->GetProjectValidator(project_name);
95   if (!project_validator) {
96     return nullptr;
97   }
98 
99   switch (project_validator->id_scope()) {
100     case IdScope::kPerProfile: {
101       if (profile_key_data_) {
102         return profile_key_data_->GetKeyData(project_name);
103       }
104       break;
105     }
106     case IdScope::kPerDevice: {
107       if (project_validator->event_type() ==
108           StructuredEventProto_EventType_SEQUENCE) {
109         if (!profile_key_data_) {
110           return nullptr;
111         }
112         return profile_key_data_->GetKeyData(project_name);
113       } else if (device_key_data_) {
114         return device_key_data_->GetKeyData(project_name);
115       }
116       break;
117     }
118     default:
119       NOTREACHED();
120   }
121 
122   return nullptr;
123 }
124 
IsReady()125 bool TestKeyDataProvider::IsReady() {
126   return device_key_data_->IsReady();
127 }
128 
OnProfileAdded(const base::FilePath & profile_path)129 void TestKeyDataProvider::OnProfileAdded(const base::FilePath& profile_path) {
130   // If the profile path has not been set, then set it here.
131   if (profile_key_path_.empty()) {
132     profile_key_path_ = profile_path;
133   }
134 
135   DCHECK(!profile_key_path_.empty());
136 
137   profile_key_data_ = std::make_unique<KeyDataProviderFile>(
138       profile_key_path_, base::Milliseconds(0));
139   profile_key_data_->AddObserver(this);
140 }
141 
Purge()142 void TestKeyDataProvider::Purge() {
143   if (profile_key_data_->IsReady()) {
144     profile_key_data_->Purge();
145   }
146 
147   if (device_key_data_->IsReady()) {
148     device_key_data_->Purge();
149   }
150 }
151 
OnKeyReady()152 void TestKeyDataProvider::OnKeyReady() {
153   // Notifies observers both when device and profile keys are ready.
154   NotifyKeyReady();
155 }
156 
157 }  // namespace metrics::structured
158