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 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)68std::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)90KeyData* 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()125bool TestKeyDataProvider::IsReady() { 126 return device_key_data_->IsReady(); 127 } 128 OnProfileAdded(const base::FilePath & profile_path)129void 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()142void 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()152void TestKeyDataProvider::OnKeyReady() { 153 // Notifies observers both when device and profile keys are ready. 154 NotifyKeyReady(); 155 } 156 157 } // namespace metrics::structured 158