[go: nahoru, domu]

blob: 15fc42f78a2b7aea959b1b15c04e0724145df6cb [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/media_device_salt/media_device_salt_service.h"
#include <utility>
#include "base/containers/cxx20_erase_vector.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/system/system_monitor.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/threading/sequence_bound.h"
#include "base/time/time.h"
#include "base/unguessable_token.h"
#include "components/media_device_salt/media_device_id_salt.h"
#include "components/media_device_salt/media_device_salt_database.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
namespace media_device_salt {
BASE_FEATURE(kMediaDeviceIdPartitioning,
"MediaDeviceIdPartitioning",
base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kMediaDeviceIdRandomSaltsPerStorageKey,
"MediaDeviceIdRandomSaltsPerStorageKey",
base::FEATURE_ENABLED_BY_DEFAULT);
namespace {
scoped_refptr<base::SequencedTaskRunner> CreateDatabaseTaskRunner() {
// We use a SequencedTaskRunner so that there is a global ordering to a
// storage key's directory operations.
return base::ThreadPool::CreateSequencedTaskRunner({
base::MayBlock(), // For File I/O
base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::BLOCK_SHUTDOWN, // To allow clean shutdown
});
}
} // namespace
MediaDeviceSaltService::MediaDeviceSaltService(PrefService* pref_service,
const base::FilePath& path)
: fallback_salt_(CreateRandomSalt()),
fallback_salt_creation_time_(base::Time::Now()),
media_device_id_salt_(
base::MakeRefCounted<MediaDeviceIDSalt>(pref_service)),
pref_service_(pref_service),
db_(base::FeatureList::IsEnabled(kMediaDeviceIdPartitioning)
? base::SequenceBound<MediaDeviceSaltDatabase>(
CreateDatabaseTaskRunner(),
path)
: base::SequenceBound<MediaDeviceSaltDatabase>()) {}
MediaDeviceSaltService::~MediaDeviceSaltService() = default;
void MediaDeviceSaltService::GetSalt(
const blink::StorageKey& storage_key,
base::OnceCallback<void(const std::string&)> callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!base::FeatureList::IsEnabled(kMediaDeviceIdPartitioning)) {
std::move(callback).Run(GetGlobalSalt());
return;
}
if (storage_key.origin().opaque()) {
std::move(callback).Run(fallback_salt_);
return;
}
std::optional<std::string> candidate_salt;
if (!base::FeatureList::IsEnabled(kMediaDeviceIdRandomSaltsPerStorageKey)) {
candidate_salt = GetGlobalSalt();
}
db_.AsyncCall(&MediaDeviceSaltDatabase::GetOrInsertSalt)
.WithArgs(storage_key, candidate_salt)
.Then(base::BindOnce(&MediaDeviceSaltService::FinalizeGetSalt,
weak_factory_.GetWeakPtr(), std::move(callback)));
}
void MediaDeviceSaltService::FinalizeGetSalt(
base::OnceCallback<void(const std::string&)> callback,
std::optional<std::string> salt) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
std::move(callback).Run(salt.has_value() ? *salt : fallback_salt_);
}
void MediaDeviceSaltService::DeleteSalts(
base::Time delete_begin,
base::Time delete_end,
content::StoragePartition::StorageKeyMatcherFunction matcher,
base::OnceClosure done_closure) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (matcher) {
if (!base::FeatureList::IsEnabled(kMediaDeviceIdPartitioning)) {
std::move(done_closure).Run();
return;
}
} else {
if (!base::FeatureList::IsEnabled(kMediaDeviceIdRandomSaltsPerStorageKey) ||
!base::FeatureList::IsEnabled(kMediaDeviceIdPartitioning)) {
ResetGlobalSalt();
}
if (!base::FeatureList::IsEnabled(kMediaDeviceIdPartitioning)) {
FinalizeDeleteSalts(std::move(done_closure));
return;
}
// Reset the fallback key if the deletion period includes its creation time.
if (delete_begin <= fallback_salt_creation_time_ &&
fallback_salt_creation_time_ <= delete_end) {
fallback_salt_ = CreateRandomSalt();
fallback_salt_creation_time_ = base::Time::Now();
}
}
db_.AsyncCall(&MediaDeviceSaltDatabase::DeleteEntries)
.WithArgs(delete_begin, delete_end, std::move(matcher))
.Then(base::BindOnce(&MediaDeviceSaltService::FinalizeDeleteSalts,
weak_factory_.GetWeakPtr(),
std::move(done_closure)));
}
void MediaDeviceSaltService::FinalizeDeleteSalts(
base::OnceClosure done_closure) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Propagate device change notifications, for anything currently using devices
// which will now have new IDs.
if (base::SystemMonitor* monitor = base::SystemMonitor::Get()) {
monitor->ProcessDevicesChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
monitor->ProcessDevicesChanged(base::SystemMonitor::DEVTYPE_AUDIO);
}
std::move(done_closure).Run();
}
void MediaDeviceSaltService::DeleteSalt(const blink::StorageKey& storage_key,
base::OnceClosure done_closure) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!base::FeatureList::IsEnabled(kMediaDeviceIdPartitioning)) {
std::move(done_closure).Run();
return;
}
db_.AsyncCall(&MediaDeviceSaltDatabase::DeleteEntry)
.WithArgs(storage_key)
.Then(base::BindOnce(&MediaDeviceSaltService::FinalizeDeleteSalts,
weak_factory_.GetWeakPtr(),
std::move(done_closure)));
}
void MediaDeviceSaltService::GetAllStorageKeys(
base::OnceCallback<void(std::vector<blink::StorageKey>)> callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!base::FeatureList::IsEnabled(kMediaDeviceIdPartitioning)) {
std::move(callback).Run({});
return;
}
db_.AsyncCall(&MediaDeviceSaltDatabase::GetAllStorageKeys)
.Then(base::BindOnce(&MediaDeviceSaltService::FinalizeGetAllStorageKeys,
weak_factory_.GetWeakPtr(), std::move(callback)));
}
void MediaDeviceSaltService::FinalizeGetAllStorageKeys(
base::OnceCallback<void(std::vector<blink::StorageKey>)> callback,
std::vector<blink::StorageKey> storage_keys) {
std::move(callback).Run(std::move(storage_keys));
}
std::string MediaDeviceSaltService::GetGlobalSalt() {
return media_device_id_salt_->GetSalt();
}
void MediaDeviceSaltService::ResetGlobalSalt() {
MediaDeviceIDSalt::Reset(pref_service_);
}
} // namespace media_device_salt