[go: nahoru, domu]

blob: 15fc42f78a2b7aea959b1b15c04e0724145df6cb [file] [log] [blame]
Guido Urdaneta9f831c22023-06-22 13:44:341// 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/media_device_salt/media_device_salt_service.h"
6
Guido Urdanetafcee7ad2023-07-18 00:04:207#include <utility>
8
9#include "base/containers/cxx20_erase_vector.h"
10#include "base/feature_list.h"
11#include "base/functional/bind.h"
12#include "base/system/system_monitor.h"
13#include "base/task/sequenced_task_runner.h"
14#include "base/task/task_traits.h"
15#include "base/task/thread_pool.h"
16#include "base/threading/sequence_bound.h"
17#include "base/time/time.h"
18#include "base/unguessable_token.h"
Guido Urdaneta9f831c22023-06-22 13:44:3419#include "components/media_device_salt/media_device_id_salt.h"
Guido Urdanetafcee7ad2023-07-18 00:04:2020#include "components/media_device_salt/media_device_salt_database.h"
Guido Urdaneta32e581992023-07-21 12:52:0121#include "third_party/blink/public/common/storage_key/storage_key.h"
Guido Urdaneta9f831c22023-06-22 13:44:3422
23namespace media_device_salt {
24
Guido Urdanetafcee7ad2023-07-18 00:04:2025BASE_FEATURE(kMediaDeviceIdPartitioning,
26 "MediaDeviceIdPartitioning",
Guido Urdanetaac024d7562023-07-31 18:40:3527 base::FEATURE_ENABLED_BY_DEFAULT);
Guido Urdanetafcee7ad2023-07-18 00:04:2028BASE_FEATURE(kMediaDeviceIdRandomSaltsPerStorageKey,
29 "MediaDeviceIdRandomSaltsPerStorageKey",
Guido Urdanetac9acf992023-10-03 20:51:5130 base::FEATURE_ENABLED_BY_DEFAULT);
Guido Urdanetafcee7ad2023-07-18 00:04:2031
32namespace {
33
34scoped_refptr<base::SequencedTaskRunner> CreateDatabaseTaskRunner() {
35 // We use a SequencedTaskRunner so that there is a global ordering to a
36 // storage key's directory operations.
37 return base::ThreadPool::CreateSequencedTaskRunner({
38 base::MayBlock(), // For File I/O
39 base::TaskPriority::USER_VISIBLE,
40 base::TaskShutdownBehavior::BLOCK_SHUTDOWN, // To allow clean shutdown
41 });
42}
43
44} // namespace
45
46MediaDeviceSaltService::MediaDeviceSaltService(PrefService* pref_service,
47 const base::FilePath& path)
48 : fallback_salt_(CreateRandomSalt()),
49 fallback_salt_creation_time_(base::Time::Now()),
50 media_device_id_salt_(
Guido Urdaneta9f831c22023-06-22 13:44:3451 base::MakeRefCounted<MediaDeviceIDSalt>(pref_service)),
Guido Urdanetafcee7ad2023-07-18 00:04:2052 pref_service_(pref_service),
53 db_(base::FeatureList::IsEnabled(kMediaDeviceIdPartitioning)
54 ? base::SequenceBound<MediaDeviceSaltDatabase>(
55 CreateDatabaseTaskRunner(),
56 path)
57 : base::SequenceBound<MediaDeviceSaltDatabase>()) {}
Guido Urdaneta9f831c22023-06-22 13:44:3458
59MediaDeviceSaltService::~MediaDeviceSaltService() = default;
60
61void MediaDeviceSaltService::GetSalt(
Guido Urdanetafcee7ad2023-07-18 00:04:2062 const blink::StorageKey& storage_key,
Guido Urdaneta9f831c22023-06-22 13:44:3463 base::OnceCallback<void(const std::string&)> callback) {
Guido Urdanetafcee7ad2023-07-18 00:04:2064 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
65 if (!base::FeatureList::IsEnabled(kMediaDeviceIdPartitioning)) {
Guido Urdaneta40bd3122023-07-19 06:01:1766 std::move(callback).Run(GetGlobalSalt());
Guido Urdanetafcee7ad2023-07-18 00:04:2067 return;
68 }
69
70 if (storage_key.origin().opaque()) {
71 std::move(callback).Run(fallback_salt_);
72 return;
73 }
74
Arthur Sonzognic571efb2024-01-26 20:26:1875 std::optional<std::string> candidate_salt;
Guido Urdanetafcee7ad2023-07-18 00:04:2076 if (!base::FeatureList::IsEnabled(kMediaDeviceIdRandomSaltsPerStorageKey)) {
77 candidate_salt = GetGlobalSalt();
78 }
79
80 db_.AsyncCall(&MediaDeviceSaltDatabase::GetOrInsertSalt)
81 .WithArgs(storage_key, candidate_salt)
82 .Then(base::BindOnce(&MediaDeviceSaltService::FinalizeGetSalt,
83 weak_factory_.GetWeakPtr(), std::move(callback)));
Guido Urdaneta9f831c22023-06-22 13:44:3484}
85
Guido Urdanetafcee7ad2023-07-18 00:04:2086void MediaDeviceSaltService::FinalizeGetSalt(
87 base::OnceCallback<void(const std::string&)> callback,
Arthur Sonzognic571efb2024-01-26 20:26:1888 std::optional<std::string> salt) {
Guido Urdanetafcee7ad2023-07-18 00:04:2089 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
90 std::move(callback).Run(salt.has_value() ? *salt : fallback_salt_);
91}
92
Guido Urdanetafcee7ad2023-07-18 00:04:2093void MediaDeviceSaltService::DeleteSalts(
94 base::Time delete_begin,
95 base::Time delete_end,
96 content::StoragePartition::StorageKeyMatcherFunction matcher,
97 base::OnceClosure done_closure) {
98 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
99 if (matcher) {
100 if (!base::FeatureList::IsEnabled(kMediaDeviceIdPartitioning)) {
101 std::move(done_closure).Run();
102 return;
103 }
104 } else {
105 if (!base::FeatureList::IsEnabled(kMediaDeviceIdRandomSaltsPerStorageKey) ||
106 !base::FeatureList::IsEnabled(kMediaDeviceIdPartitioning)) {
107 ResetGlobalSalt();
108 }
109 if (!base::FeatureList::IsEnabled(kMediaDeviceIdPartitioning)) {
Guido Urdaneta62ddc2512023-07-18 12:53:18110 FinalizeDeleteSalts(std::move(done_closure));
Guido Urdanetafcee7ad2023-07-18 00:04:20111 return;
112 }
113
114 // Reset the fallback key if the deletion period includes its creation time.
115 if (delete_begin <= fallback_salt_creation_time_ &&
116 fallback_salt_creation_time_ <= delete_end) {
117 fallback_salt_ = CreateRandomSalt();
118 fallback_salt_creation_time_ = base::Time::Now();
119 }
120 }
121
122 db_.AsyncCall(&MediaDeviceSaltDatabase::DeleteEntries)
123 .WithArgs(delete_begin, delete_end, std::move(matcher))
124 .Then(base::BindOnce(&MediaDeviceSaltService::FinalizeDeleteSalts,
125 weak_factory_.GetWeakPtr(),
126 std::move(done_closure)));
127}
128
129void MediaDeviceSaltService::FinalizeDeleteSalts(
130 base::OnceClosure done_closure) {
131 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
132 // Propagate device change notifications, for anything currently using devices
133 // which will now have new IDs.
134 if (base::SystemMonitor* monitor = base::SystemMonitor::Get()) {
135 monitor->ProcessDevicesChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
136 monitor->ProcessDevicesChanged(base::SystemMonitor::DEVTYPE_AUDIO);
137 }
138 std::move(done_closure).Run();
139}
140
Guido Urdaneta32e581992023-07-21 12:52:01141void MediaDeviceSaltService::DeleteSalt(const blink::StorageKey& storage_key,
142 base::OnceClosure done_closure) {
143 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
144 if (!base::FeatureList::IsEnabled(kMediaDeviceIdPartitioning)) {
145 std::move(done_closure).Run();
146 return;
147 }
148 db_.AsyncCall(&MediaDeviceSaltDatabase::DeleteEntry)
149 .WithArgs(storage_key)
150 .Then(base::BindOnce(&MediaDeviceSaltService::FinalizeDeleteSalts,
151 weak_factory_.GetWeakPtr(),
152 std::move(done_closure)));
153}
154
155void MediaDeviceSaltService::GetAllStorageKeys(
156 base::OnceCallback<void(std::vector<blink::StorageKey>)> callback) {
157 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
158 if (!base::FeatureList::IsEnabled(kMediaDeviceIdPartitioning)) {
159 std::move(callback).Run({});
160 return;
161 }
162 db_.AsyncCall(&MediaDeviceSaltDatabase::GetAllStorageKeys)
163 .Then(base::BindOnce(&MediaDeviceSaltService::FinalizeGetAllStorageKeys,
164 weak_factory_.GetWeakPtr(), std::move(callback)));
165}
166
167void MediaDeviceSaltService::FinalizeGetAllStorageKeys(
168 base::OnceCallback<void(std::vector<blink::StorageKey>)> callback,
169 std::vector<blink::StorageKey> storage_keys) {
170 std::move(callback).Run(std::move(storage_keys));
171}
172
Guido Urdanetafcee7ad2023-07-18 00:04:20173std::string MediaDeviceSaltService::GetGlobalSalt() {
174 return media_device_id_salt_->GetSalt();
175}
176
177void MediaDeviceSaltService::ResetGlobalSalt() {
Guido Urdaneta9f831c22023-06-22 13:44:34178 MediaDeviceIDSalt::Reset(pref_service_);
179}
180
181} // namespace media_device_salt