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 break; 65 } 66 return std::nullopt; 67 } 68 GetSecondaryId(const std::string & project_name)69std::optional<uint64_t> TestKeyDataProvider::GetSecondaryId( 70 const std::string& project_name) { 71 const auto* project_validator = 72 validator::Validators::Get()->GetProjectValidator(project_name); 73 if (!project_validator) { 74 return std::nullopt; 75 } 76 77 // Only SEQUENCE types have secondary ids. 78 if (project_validator->event_type() != 79 StructuredEventProto_EventType_SEQUENCE) { 80 return std::nullopt; 81 } 82 83 DCHECK(device_key_data_); 84 if (device_key_data_ && device_key_data_->IsReady()) { 85 return device_key_data_->GetId(project_name); 86 } 87 88 return std::nullopt; 89 } 90 GetKeyData(const std::string & project_name)91KeyData* TestKeyDataProvider::GetKeyData(const std::string& project_name) { 92 // Validates the event. If valid, retrieve the metadata associated 93 // with the event. 94 const auto* project_validator = 95 validator::Validators::Get()->GetProjectValidator(project_name); 96 if (!project_validator) { 97 return nullptr; 98 } 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