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)14TestKeyDataProvider::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)17TestKeyDataProvider::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()25TestKeyDataProvider::~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)32std::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)66std::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)90KeyData* 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()127bool TestKeyDataProvider::IsReady() { 128 return device_key_data_->IsReady(); 129 } 130 OnProfileAdded(const base::FilePath & profile_path)131void 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()144void 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()154void TestKeyDataProvider::OnKeyReady() { 155 // Notifies observers both when device and profile keys are ready. 156 NotifyKeyReady(); 157 } 158 159 } // namespace metrics::structured 160