• 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   auto maybe_project_validator =
37       validator::Validators::Get()->GetProjectValidator(project_name);
38   const auto* project_validator = maybe_project_validator.value();
39 
40   switch (project_validator->id_scope()) {
41     case IdScope::kPerProfile: {
42       if (profile_key_data_) {
43         return profile_key_data_->GetId(project_name);
44       }
45       break;
46     }
47     case IdScope::kPerDevice: {
48       if (project_validator->event_type() ==
49           StructuredEventProto_EventType_SEQUENCE) {
50         if (!profile_key_data_) {
51           return std::nullopt;
52         }
53         return profile_key_data_->GetId(project_name);
54       } else if (device_key_data_) {
55         return device_key_data_->GetId(project_name);
56       }
57       break;
58     }
59     default:
60       NOTREACHED();
61       break;
62   }
63   return std::nullopt;
64 }
65 
GetSecondaryId(const std::string & project_name)66 std::optional<uint64_t> TestKeyDataProvider::GetSecondaryId(
67     const std::string& project_name) {
68   auto maybe_project_validator =
69       validator::Validators::Get()->GetProjectValidator(project_name);
70   if (!maybe_project_validator.has_value()) {
71     return std::nullopt;
72   }
73 
74   const auto* project_validator = maybe_project_validator.value();
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 absl::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   auto maybe_project_validator =
94       validator::Validators::Get()->GetProjectValidator(project_name);
95   if (!maybe_project_validator.has_value()) {
96     return nullptr;
97   }
98   const auto* project_validator = maybe_project_validator.value();
99 
100   switch (project_validator->id_scope()) {
101     case IdScope::kPerProfile: {
102       if (profile_key_data_) {
103         return profile_key_data_->GetKeyData(project_name);
104       }
105       break;
106     }
107     case IdScope::kPerDevice: {
108       if (project_validator->event_type() ==
109           StructuredEventProto_EventType_SEQUENCE) {
110         if (!profile_key_data_) {
111           return nullptr;
112         }
113         return profile_key_data_->GetKeyData(project_name);
114       } else if (device_key_data_) {
115         return device_key_data_->GetKeyData(project_name);
116       }
117       break;
118     }
119     default:
120       NOTREACHED();
121       break;
122   }
123 
124   return nullptr;
125 }
126 
IsReady()127 bool TestKeyDataProvider::IsReady() {
128   return device_key_data_->IsReady();
129 }
130 
OnProfileAdded(const base::FilePath & profile_path)131 void TestKeyDataProvider::OnProfileAdded(const base::FilePath& profile_path) {
132   // If the profile path has not been set, then set it here.
133   if (profile_key_path_.empty()) {
134     profile_key_path_ = profile_path;
135   }
136 
137   DCHECK(!profile_key_path_.empty());
138 
139   profile_key_data_ = std::make_unique<KeyDataProviderFile>(
140       profile_key_path_, base::Milliseconds(0));
141   profile_key_data_->AddObserver(this);
142 }
143 
Purge()144 void TestKeyDataProvider::Purge() {
145   if (profile_key_data_->IsReady()) {
146     profile_key_data_->Purge();
147   }
148 
149   if (device_key_data_->IsReady()) {
150     device_key_data_->Purge();
151   }
152 }
153 
OnKeyReady()154 void TestKeyDataProvider::OnKeyReady() {
155   // Notifies observers both when device and profile keys are ready.
156   NotifyKeyReady();
157 }
158 
159 }  // namespace metrics::structured
160