[M120 Migration][VD] Enable direct rendering for TVPlus
[platform/framework/web/chromium-efl.git] / components / media_device_salt / media_device_salt_service_unittest.cc
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/media_device_salt/media_device_salt_service.h"
6
7 #include "base/containers/contains.h"
8 #include "base/files/file_path.h"
9 #include "base/run_loop.h"
10 #include "base/system/system_monitor.h"
11 #include "base/test/bind.h"
12 #include "base/test/mock_devices_changed_observer.h"
13 #include "base/test/scoped_feature_list.h"
14 #include "base/test/test_future.h"
15 #include "base/time/time.h"
16 #include "components/keyed_service/content/browser_context_dependency_manager.h"
17 #include "components/media_device_salt/media_device_id_salt.h"
18 #include "components/sync_preferences/testing_pref_service_syncable.h"
19 #include "components/user_prefs/user_prefs.h"
20 #include "content/public/test/browser_task_environment.h"
21 #include "content/public/test/test_browser_context.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "third_party/blink/public/common/storage_key/storage_key.h"
25
26 namespace media_device_salt {
27
28 namespace {
29
30 using ::testing::IsEmpty;
31 using ::testing::UnorderedElementsAre;
32 using StorageKeyMatcher =
33     ::content::StoragePartition::StorageKeyMatcherFunction;
34
35 blink::StorageKey StorageKey1() {
36   return blink::StorageKey::CreateFromStringForTesting("https://example1.com");
37 }
38
39 blink::StorageKey StorageKey2() {
40   return blink::StorageKey::CreateFromStringForTesting("https://example2.com");
41 }
42
43 blink::StorageKey StorageKey3() {
44   return blink::StorageKey::CreateFromStringForTesting("https://example3.com");
45 }
46
47 }  // namespace
48
49 class MediaDeviceSaltServiceTest : public testing::TestWithParam<bool> {
50  public:
51   void SetUp() override {
52     if (UsePerStorageKeySalts()) {
53       feature_list_.InitWithFeatures(
54           {kMediaDeviceIdPartitioning, kMediaDeviceIdRandomSaltsPerStorageKey},
55           {});
56     } else {
57       feature_list_.InitWithFeatures({kMediaDeviceIdPartitioning},
58                                      {kMediaDeviceIdRandomSaltsPerStorageKey});
59     }
60     BrowserContextDependencyManager::GetInstance()->MarkBrowserContextLive(
61         &browser_context_);
62
63     user_prefs::UserPrefs::Set(&browser_context_, &pref_service_);
64     ASSERT_FALSE(pref_service_.FindPreference(
65         media_device_salt::prefs::kMediaDeviceIdSalt));
66
67     MediaDeviceIDSalt::RegisterProfilePrefs(pref_service_.registry());
68     ASSERT_TRUE(pref_service_.FindPreference(
69         media_device_salt::prefs::kMediaDeviceIdSalt));
70
71     service_ = std::make_unique<MediaDeviceSaltService>(&pref_service_,
72                                                         base::FilePath());
73   }
74
75   void TearDown() override {
76     BrowserContextDependencyManager::GetInstance()
77         ->DestroyBrowserContextServices(&browser_context_);
78   }
79
80  protected:
81   content::BrowserTaskEnvironment& task_environment() {
82     return task_environment_;
83   }
84   base::test::ScopedFeatureList& feature_list() { return feature_list_; }
85   const sync_preferences::TestingPrefServiceSyncable& pref_service() const {
86     return pref_service_;
87   }
88   MediaDeviceSaltService* service() const { return service_.get(); }
89
90   bool UsePerStorageKeySalts() const { return GetParam(); }
91
92   std::string GetSalt(const blink::StorageKey& storage_key) const {
93     base::test::TestFuture<const std::string&> future;
94     service_->GetSalt(storage_key, future.GetCallback());
95     return future.Get();
96   }
97
98   void DeleteSaltUsingMatcher(const blink::StorageKey& storage_key) const {
99     base::test::TestFuture<void> future;
100     auto matcher = base::BindLambdaForTesting(
101         [&storage_key](const blink::StorageKey& candidate_key) {
102           return candidate_key == storage_key;
103         });
104     service_->DeleteSalts(base::Time::Min(), base::Time::Max(), matcher,
105                           future.GetCallback());
106     CHECK(future.Wait());
107   }
108
109   void DeleteSalts(const std::vector<blink::StorageKey>& keys) {
110     base::test::TestFuture<void> future;
111     auto matcher = base::BindLambdaForTesting(
112         [&keys](const blink::StorageKey& candidate_key) {
113           return base::Contains(keys, candidate_key);
114         });
115     service_->DeleteSalts(base::Time::Min(), base::Time::Max(), matcher,
116                           future.GetCallback());
117     CHECK(future.Wait());
118   }
119
120   void DeleteSaltsInTimeRange(base::Time delete_begin, base::Time delete_end) {
121     base::test::TestFuture<void> future;
122     service_->DeleteSalts(delete_begin, delete_end, StorageKeyMatcher(),
123                           future.GetCallback());
124     CHECK(future.Wait());
125   }
126
127   void DeleteSingleSalt(const blink::StorageKey& storage_key) {
128     base::test::TestFuture<void> future;
129     service_->DeleteSalt(storage_key, future.GetCallback());
130     CHECK(future.Wait());
131   }
132
133   std::vector<blink::StorageKey> GetAllStorageKeys() {
134     base::test::TestFuture<std::vector<blink::StorageKey>> future;
135     service_->GetAllStorageKeys(future.GetCallback());
136     return future.Get();
137   }
138
139  private:
140   content::BrowserTaskEnvironment task_environment_;
141   base::test::ScopedFeatureList feature_list_;
142   content::TestBrowserContext browser_context_;
143   sync_preferences::TestingPrefServiceSyncable pref_service_;
144   std::unique_ptr<MediaDeviceSaltService> service_;
145 };
146
147 TEST_P(MediaDeviceSaltServiceTest, ResetGlobalSaltFiresDeviceChange) {
148   feature_list().Reset();
149   feature_list().InitAndDisableFeature(kMediaDeviceIdPartitioning);
150   base::SystemMonitor monitor;
151   ASSERT_EQ(base::SystemMonitor::Get(), &monitor);
152   testing::StrictMock<base::MockDevicesChangedObserver> observer;
153   monitor.AddDevicesChangedObserver(&observer);
154
155   EXPECT_CALL(observer, OnDevicesChanged(base::SystemMonitor::DEVTYPE_AUDIO));
156   EXPECT_CALL(observer,
157               OnDevicesChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE));
158   service()->DeleteSalts(base::Time::Min(), base::Time::Max(),
159                          StorageKeyMatcher(), base::DoNothing());
160   task_environment().RunUntilIdle();
161
162   monitor.RemoveDevicesChangedObserver(&observer);
163 }
164
165 TEST_P(MediaDeviceSaltServiceTest, DeleteSingleSaltUsingMatcher) {
166   // Deletion of individual salts is not supported when using the global salt.
167   std::string salt1 = GetSalt(StorageKey1());
168   std::string salt2 = GetSalt(StorageKey2());
169   EXPECT_FALSE(salt1.empty());
170   EXPECT_EQ(salt1 != salt2, UsePerStorageKeySalts());
171
172   DeleteSaltUsingMatcher(StorageKey1());
173   std::string salt1b = GetSalt(StorageKey1());
174   std::string salt2b = GetSalt(StorageKey2());
175   EXPECT_FALSE(salt1b.empty());
176   EXPECT_EQ(salt1 != salt1b, UsePerStorageKeySalts());
177   EXPECT_EQ(salt2b, salt2);
178
179   DeleteSaltUsingMatcher(StorageKey2());
180   std::string salt1c = GetSalt(StorageKey1());
181   std::string salt2c = GetSalt(StorageKey2());
182   EXPECT_EQ(salt1c, salt1b);
183   EXPECT_EQ(salt2c != salt2b, UsePerStorageKeySalts());
184   EXPECT_EQ(salt2c != salt1c, UsePerStorageKeySalts());
185 }
186
187 TEST_P(MediaDeviceSaltServiceTest, DeleteMultipleSaltsUsingMatcher) {
188   // Deletion of individual salts is not supported when using the global salt.
189   std::string salt1 = GetSalt(StorageKey1());
190   std::string salt2 = GetSalt(StorageKey2());
191   std::string salt3 = GetSalt(StorageKey3());
192
193   DeleteSalts({StorageKey1(), StorageKey2()});
194   std::string salt1b = GetSalt(StorageKey1());
195   std::string salt2b = GetSalt(StorageKey2());
196   std::string salt3b = GetSalt(StorageKey3());
197
198   EXPECT_EQ(salt1 != salt1b, UsePerStorageKeySalts());
199   EXPECT_EQ(salt2 != salt2b, UsePerStorageKeySalts());
200   EXPECT_EQ(salt3, salt3b);
201 }
202
203 TEST_P(MediaDeviceSaltServiceTest, DeleteSingleSalt) {
204   // Deletion of individual salts is not supported when using the global salt.
205   std::string salt1 = GetSalt(StorageKey1());
206   std::string salt2 = GetSalt(StorageKey2());
207   EXPECT_FALSE(salt1.empty());
208   EXPECT_EQ(salt1 != salt2, UsePerStorageKeySalts());
209
210   DeleteSingleSalt(StorageKey1());
211   std::string salt1b = GetSalt(StorageKey1());
212   std::string salt2b = GetSalt(StorageKey2());
213   EXPECT_FALSE(salt1b.empty());
214   EXPECT_EQ(salt1 != salt1b, UsePerStorageKeySalts());
215   EXPECT_EQ(salt2b, salt2);
216
217   DeleteSingleSalt(StorageKey2());
218   std::string salt1c = GetSalt(StorageKey1());
219   std::string salt2c = GetSalt(StorageKey2());
220   EXPECT_EQ(salt1c, salt1b);
221   EXPECT_EQ(salt2c != salt2b, UsePerStorageKeySalts());
222   EXPECT_EQ(salt2c != salt1c, UsePerStorageKeySalts());
223 }
224
225 TEST_P(MediaDeviceSaltServiceTest, DeleteSaltsInTimeRange) {
226   // Deletion of salts by time range is supported with both the global and
227   // per-storage-key salts.
228   base::Time time1 = base::Time::Now();
229   std::string salt1 = GetSalt(StorageKey1());
230   std::string salt2 = GetSalt(StorageKey2());
231   base::Time time3 = base::Time::Now();
232   std::string salt3 = GetSalt(StorageKey3());
233   base::Time time4 = base::Time::Now();
234
235   // No salts deleted
236   DeleteSaltsInTimeRange(time4, base::Time::Max());
237   std::string salt1b = GetSalt(StorageKey1());
238   std::string salt2b = GetSalt(StorageKey2());
239   std::string salt3b = GetSalt(StorageKey3());
240   EXPECT_EQ(salt1b, salt1);
241   EXPECT_EQ(salt2b, salt2);
242   EXPECT_EQ(salt3b, salt3);
243
244   // Only salt for StorageKey3 deleted
245   DeleteSaltsInTimeRange(time3, base::Time::Max());
246   std::string salt1c = GetSalt(StorageKey1());
247   std::string salt2c = GetSalt(StorageKey2());
248   std::string salt3c = GetSalt(StorageKey3());
249   EXPECT_EQ(salt1c, salt1b);
250   EXPECT_EQ(salt2c, salt2b);
251   EXPECT_NE(salt3c, salt3b);
252
253   // Salts for StorageKey1 and StorageKey2 deleted
254   DeleteSaltsInTimeRange(time1, time3);
255   std::string salt1d = GetSalt(StorageKey1());
256   std::string salt2d = GetSalt(StorageKey2());
257   std::string salt3d = GetSalt(StorageKey3());
258   EXPECT_NE(salt1d, salt1c);
259   EXPECT_NE(salt2d, salt2c);
260   EXPECT_EQ(salt3d, salt3c);
261
262   // All salts deleted
263   DeleteSaltsInTimeRange(base::Time::Min(), base::Time::Max());
264   std::string salt1e = GetSalt(StorageKey1());
265   std::string salt2e = GetSalt(StorageKey2());
266   std::string salt3e = GetSalt(StorageKey3());
267   EXPECT_NE(salt1e, salt1d);
268   EXPECT_NE(salt2e, salt2d);
269   EXPECT_NE(salt3e, salt3d);
270 }
271
272 TEST_P(MediaDeviceSaltServiceTest, GetAllStorageKeys) {
273   // Deletion of individual salts is not supported when using the global salt.
274   std::string salt1 = GetSalt(StorageKey1());
275   std::string salt2 = GetSalt(StorageKey2());
276   std::string salt3 = GetSalt(StorageKey3());
277   EXPECT_THAT(
278       GetAllStorageKeys(),
279       UnorderedElementsAre(StorageKey1(), StorageKey2(), StorageKey3()));
280
281   DeleteSingleSalt(StorageKey2());
282   EXPECT_THAT(GetAllStorageKeys(),
283               UnorderedElementsAre(StorageKey1(), StorageKey3()));
284
285   DeleteSaltsInTimeRange(base::Time::Min(), base::Time::Max());
286   EXPECT_THAT(GetAllStorageKeys(), IsEmpty());
287 }
288
289 TEST_P(MediaDeviceSaltServiceTest, OpaqueKey) {
290   // Storage keys with opaque origin use an ephemeral global salt.
291   std::string salt1 = GetSalt(blink::StorageKey());
292
293   // The fallback salt is reset when all salts are deleted.
294   DeleteSaltsInTimeRange(base::Time::Min(), base::Time::Max());
295   std::string salt2 = GetSalt(blink::StorageKey());
296   EXPECT_NE(salt1, salt2);
297
298   // The fallback salt is not deleted in a matching deletion.
299   DeleteSaltUsingMatcher(blink::StorageKey());
300   std::string salt3 = GetSalt(blink::StorageKey());
301   EXPECT_EQ(salt2, salt3);
302 }
303
304 TEST_P(MediaDeviceSaltServiceTest, ManyGetSalts) {
305   const size_t n = 100;
306   std::vector<std::string> salts;
307   base::RunLoop run_loop;
308   for (size_t i = 0; i < n; i++) {
309     service()->GetSalt(StorageKey1(),
310                        base::BindLambdaForTesting([&](const std::string& salt) {
311                          salts.push_back(salt);
312                          if (salts.size() == n) {
313                            run_loop.Quit();
314                          }
315                        }));
316   }
317   run_loop.Run();
318   ASSERT_EQ(salts.size(), n);
319   EXPECT_FALSE(salts[0].empty());
320   for (size_t i = 1; i < n; i++) {
321     EXPECT_EQ(salts[i], salts[0]);
322   }
323 }
324
325 TEST_P(MediaDeviceSaltServiceTest, DeviceChangeEvent) {
326   base::SystemMonitor monitor;
327   ASSERT_EQ(base::SystemMonitor::Get(), &monitor);
328   testing::StrictMock<base::MockDevicesChangedObserver> observer;
329   monitor.AddDevicesChangedObserver(&observer);
330   GetSalt(StorageKey1());
331   GetSalt(StorageKey2());
332
333   EXPECT_CALL(observer, OnDevicesChanged(base::SystemMonitor::DEVTYPE_AUDIO));
334   EXPECT_CALL(observer,
335               OnDevicesChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE));
336   DeleteSaltUsingMatcher(StorageKey1());
337   task_environment().RunUntilIdle();
338
339   EXPECT_CALL(observer, OnDevicesChanged(base::SystemMonitor::DEVTYPE_AUDIO));
340   EXPECT_CALL(observer,
341               OnDevicesChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE));
342   DeleteSaltsInTimeRange(base::Time::Min(), base::Time::Max());
343   task_environment().RunUntilIdle();
344
345   monitor.RemoveDevicesChangedObserver(&observer);
346 }
347
348 INSTANTIATE_TEST_SUITE_P(All, MediaDeviceSaltServiceTest, testing::Bool());
349 }  // namespace media_device_salt