Commit dcf9a3a8 authored by Johan Tibell's avatar Johan Tibell Committed by Commit Bot

Pref service: support for incognito prefs

preferences.mojom and preferences_configuration.mojom had to be merged as they
would cause a circular import otherwise.

BUG: 654988
Change-Id: I061365e7c6c7ae3c851e427a24d2a322e1210987
Reviewed-on: https://chromium-review.googlesource.com/514902Reviewed-by: default avatarMartin Barbella <mbarbella@chromium.org>
Reviewed-by: default avatarBernhard Bauer <bauerb@chromium.org>
Reviewed-by: default avatarSam McNally <sammc@chromium.org>
Commit-Queue: Johan Tibell <tibell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#476490}
parent 5837bd97
......@@ -29,6 +29,17 @@ void ActiveProfilePrefService::Connect(
std::move(callback));
}
void ActiveProfilePrefService::ConnectToUserPrefStore(
const std::vector<std::string>& prefs_to_observe,
ConnectToUserPrefStoreCallback callback) {
auto* connector = content::BrowserContext::GetConnectorFor(
ProfileManager::GetActiveUserProfile()->GetOriginalProfile());
connector->BindInterface(prefs::mojom::kServiceName, &connector_ptr_);
connector_ptr_.set_connection_error_handler(base::Bind(
&ActiveProfilePrefService::OnConnectError, base::Unretained(this)));
connector_ptr_->ConnectToUserPrefStore(prefs_to_observe, std::move(callback));
}
void ActiveProfilePrefService::Create(
const service_manager::BindSourceInfo& source_info,
prefs::mojom::PrefStoreConnectorRequest request) {
......
......@@ -32,6 +32,8 @@ class ActiveProfilePrefService : public prefs::mojom::PrefStoreConnector,
prefs::mojom::PrefRegistryPtr pref_registry,
const std::vector<PrefValueStore::PrefStoreType>& already_connected_types,
ConnectCallback callback) override;
void ConnectToUserPrefStore(const std::vector<std::string>& prefs_to_observe,
ConnectToUserPrefStoreCallback callback) override;
// service_manager::Service:
void OnStart() override;
......
......@@ -14,7 +14,7 @@
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "services/preferences/public/interfaces/preferences_configuration.mojom.h"
#include "services/preferences/public/interfaces/preferences.mojom.h"
#include "services/preferences/public/interfaces/tracked_preference_validation_delegate.mojom.h"
class PersistentPrefStore;
......
......@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
#include "components/prefs/in_memory_pref_store.h"
#include "components/prefs/json_pref_store.h"
#include "components/prefs/pref_filter.h"
#include "services/preferences/persistent_pref_store_impl.h"
......@@ -44,6 +45,10 @@ std::unique_ptr<PersistentPrefStoreImpl> CreatePersistentPrefStore(
std::move(configuration->get_tracked_configuration()), worker_pool),
std::move(on_initialized));
}
if (configuration->is_incognito_configuration()) {
return base::MakeUnique<PersistentPrefStoreImpl>(
base::MakeRefCounted<InMemoryPrefStore>(), std::move(on_initialized));
}
NOTREACHED();
return nullptr;
}
......
......@@ -36,9 +36,13 @@ PrefStoreManagerImpl::PrefStoreManagerImpl(
base::ContainsValue(expected_pref_stores_, PrefValueStore::DEFAULT_STORE))
<< "expected_pref_stores must always include PrefValueStore::USER_STORE "
"and PrefValueStore::DEFAULT_STORE.";
// The user store is not actually connected to in the implementation, but
// accessed directly.
// The user store is not actually registered or connected to in the
// implementation, but accessed directly.
expected_pref_stores_.erase(PrefValueStore::USER_STORE);
DVLOG(1) << "Expecting " << expected_pref_stores_.size()
<< " pref store(s) to register";
// This store is done in-process so it's already "registered":
DVLOG(1) << "Registering pref store: " << PrefValueStore::DEFAULT_STORE;
registry_.AddInterface<prefs::mojom::PrefStoreConnector>(
base::Bind(&PrefStoreManagerImpl::BindPrefStoreConnectorRequest,
base::Unretained(this)));
......@@ -50,7 +54,10 @@ PrefStoreManagerImpl::PrefStoreManagerImpl(
base::Unretained(this)));
}
PrefStoreManagerImpl::~PrefStoreManagerImpl() = default;
PrefStoreManagerImpl::~PrefStoreManagerImpl() {
// For logging consistency:
DVLOG(1) << "Deregistering pref store: " << PrefValueStore::DEFAULT_STORE;
}
void PrefStoreManagerImpl::Register(PrefValueStore::PrefStoreType type,
mojom::PrefStorePtr pref_store_ptr) {
......@@ -79,6 +86,9 @@ void PrefStoreManagerImpl::Connect(
mojom::PrefRegistryPtr pref_registry,
const std::vector<PrefValueStore::PrefStoreType>& already_connected_types,
ConnectCallback callback) {
DVLOG(1) << "Will connect to "
<< expected_pref_stores_.size() - already_connected_types.size()
<< " pref store(s)";
std::set<PrefValueStore::PrefStoreType> required_remote_types;
for (auto type : expected_pref_stores_) {
if (!base::ContainsValue(already_connected_types, type)) {
......@@ -98,6 +108,19 @@ void PrefStoreManagerImpl::Connect(
for (auto type : remaining_remote_types) {
pending_connections_[type].push_back(connection);
}
if (!Initialized()) {
pending_incognito_connections_.push_back(connection);
} else if (incognito_connector_) {
connection->ProvideIncognitoConnector(incognito_connector_);
}
}
void PrefStoreManagerImpl::ConnectToUserPrefStore(
const std::vector<std::string>& observed_prefs,
mojom::PrefStoreConnector::ConnectToUserPrefStoreCallback callback) {
std::move(callback).Run(persistent_pref_store_->CreateConnection(
PersistentPrefStoreImpl::ObservedPrefs(observed_prefs.begin(),
observed_prefs.end())));
}
void PrefStoreManagerImpl::BindPrefStoreConnectorRequest(
......@@ -129,6 +152,14 @@ void PrefStoreManagerImpl::Init(
mojom::PersistentPrefStoreConfigurationPtr configuration) {
DCHECK(!persistent_pref_store_);
if (configuration->is_incognito_configuration()) {
incognito_connector_ =
std::move(configuration->get_incognito_configuration()->connector);
for (auto connection : pending_incognito_connections_) {
connection->ProvideIncognitoConnector(incognito_connector_);
}
}
pending_incognito_connections_.clear();
persistent_pref_store_ = CreatePersistentPrefStore(
std::move(configuration), worker_pool_.get(),
base::Bind(&PrefStoreManagerImpl::OnPersistentPrefStoreReady,
......@@ -162,4 +193,8 @@ void PrefStoreManagerImpl::OnPersistentPrefStoreReady() {
pending_persistent_connections_.clear();
}
bool PrefStoreManagerImpl::Initialized() const {
return bool(persistent_pref_store_);
}
} // namespace prefs
......@@ -54,13 +54,18 @@ class PrefStoreManagerImpl : public mojom::PrefStoreRegistry,
void Register(PrefValueStore::PrefStoreType type,
mojom::PrefStorePtr pref_store_ptr) override;
// mojom::PrefStoreConnector: |already_connected_types| must not include
// PrefValueStore::DEFAULT_STORE and PrefValueStore::USER_STORE as these must
// always be accessed through the service.
// mojom::PrefStoreConnector:
// |already_connected_types| must not include PrefValueStore::DEFAULT_STORE
// and PrefValueStore::USER_STORE as these must always be accessed through the
// service.
void Connect(
mojom::PrefRegistryPtr pref_registry,
const std::vector<PrefValueStore::PrefStoreType>& already_connected_types,
ConnectCallback callback) override;
void ConnectToUserPrefStore(
const std::vector<std::string>& observed_prefs,
mojom::PrefStoreConnector::ConnectToUserPrefStoreCallback callback)
override;
void BindPrefStoreConnectorRequest(
const service_manager::BindSourceInfo& source_info,
......@@ -86,6 +91,9 @@ class PrefStoreManagerImpl : public mojom::PrefStoreRegistry,
void OnPersistentPrefStoreReady();
// Has |Init| been called?
bool Initialized() const;
// PrefStores that need to register before replying to any Connect calls. This
// does not include the PersistentPrefStore, which is handled separately.
std::set<PrefValueStore::PrefStoreType> expected_pref_stores_;
......@@ -99,6 +107,8 @@ class PrefStoreManagerImpl : public mojom::PrefStoreRegistry,
std::unique_ptr<PersistentPrefStoreImpl> persistent_pref_store_;
mojo::Binding<mojom::PrefServiceControl> init_binding_;
mojom::PrefStoreConnectorPtr incognito_connector_;
const scoped_refptr<DefaultPrefStore> defaults_;
const std::unique_ptr<PrefStoreImpl> defaults_wrapper_;
......@@ -110,6 +120,8 @@ class PrefStoreManagerImpl : public mojom::PrefStoreRegistry,
pending_connections_;
std::vector<scoped_refptr<ScopedPrefConnectionBuilder>>
pending_persistent_connections_;
std::vector<scoped_refptr<ScopedPrefConnectionBuilder>>
pending_incognito_connections_;
const scoped_refptr<base::SequencedWorkerPool> worker_pool_;
......
......@@ -73,7 +73,7 @@ PersistentPrefStoreClient::PersistentPrefStoreClient(
PersistentPrefStoreClient::PersistentPrefStoreClient(
mojom::PersistentPrefStoreConnectionPtr connection)
: weak_factory_(this) {
OnConnect(std::move(connection),
OnConnect(std::move(connection), mojom::PersistentPrefStoreConnection::New(),
std::unordered_map<PrefValueStore::PrefStoreType,
prefs::mojom::PrefStoreConnectionPtr>());
}
......@@ -139,16 +139,18 @@ PersistentPrefStore::PrefReadError PersistentPrefStoreClient::GetReadError()
PersistentPrefStore::PrefReadError PersistentPrefStoreClient::ReadPrefs() {
mojom::PersistentPrefStoreConnectionPtr connection;
mojom::PersistentPrefStoreConnectionPtr incognito_connection;
std::unordered_map<PrefValueStore::PrefStoreType,
prefs::mojom::PrefStoreConnectionPtr>
other_pref_stores;
mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_calls;
bool success = connector_->Connect(SerializePrefRegistry(*pref_registry_),
already_connected_types_, &connection,
&other_pref_stores);
&incognito_connection, &other_pref_stores);
DCHECK(success);
pref_registry_ = nullptr;
OnConnect(std::move(connection), std::move(other_pref_stores));
OnConnect(std::move(connection), std::move(incognito_connection),
std::move(other_pref_stores));
return read_error_;
}
......@@ -188,6 +190,7 @@ PersistentPrefStoreClient::~PersistentPrefStoreClient() {
void PersistentPrefStoreClient::OnConnect(
mojom::PersistentPrefStoreConnectionPtr connection,
mojom::PersistentPrefStoreConnectionPtr incognito_connection,
std::unordered_map<PrefValueStore::PrefStoreType,
prefs::mojom::PrefStoreConnectionPtr>
other_pref_stores) {
......
......@@ -70,6 +70,7 @@ class PersistentPrefStoreClient
private:
void OnConnect(mojom::PersistentPrefStoreConnectionPtr connection,
mojom::PersistentPrefStoreConnectionPtr incognito_connection,
std::unordered_map<PrefValueStore::PrefStoreType,
prefs::mojom::PrefStoreConnectionPtr>
other_pref_stores);
......
......@@ -5,6 +5,7 @@
#include "services/preferences/public/cpp/pref_service_factory.h"
#include "base/callback_helpers.h"
#include "components/prefs/overlay_user_pref_store.h"
#include "components/prefs/persistent_pref_store.h"
#include "components/prefs/pref_notifier_impl.h"
#include "components/prefs/pref_registry.h"
......@@ -64,6 +65,7 @@ void OnConnect(
local_layered_pref_stores,
ConnectCallback callback,
mojom::PersistentPrefStoreConnectionPtr persistent_pref_store_connection,
mojom::PersistentPrefStoreConnectionPtr incognito_connection,
std::unordered_map<PrefValueStore::PrefStoreType,
mojom::PrefStoreConnectionPtr> connections) {
scoped_refptr<PrefStore> managed_prefs = CreatePrefStoreClient(
......@@ -86,13 +88,22 @@ void OnConnect(
scoped_refptr<PersistentPrefStore> persistent_pref_store(
new PersistentPrefStoreClient(
std::move(persistent_pref_store_connection)));
// If in incognito mode, |persistent_pref_store| above will be a connection to
// an in-memory pref store and |incognito_connection| will refer to the
// underlying profile's user pref store.
scoped_refptr<PersistentPrefStore> user_pref_store =
incognito_connection
? new OverlayUserPrefStore(
persistent_pref_store.get(),
new PersistentPrefStoreClient(std::move(incognito_connection)))
: persistent_pref_store;
PrefNotifierImpl* pref_notifier = new PrefNotifierImpl();
auto* pref_value_store = new PrefValueStore(
managed_prefs.get(), supervised_user_prefs.get(), extension_prefs.get(),
command_line_prefs.get(), persistent_pref_store.get(),
recommended_prefs.get(), pref_registry->defaults().get(), pref_notifier);
command_line_prefs.get(), user_pref_store.get(), recommended_prefs.get(),
pref_registry->defaults().get(), pref_notifier);
callback.Run(base::MakeUnique<::PrefService>(
pref_notifier, pref_value_store, persistent_pref_store.get(),
pref_notifier, pref_value_store, user_pref_store.get(),
pref_registry.get(), base::Bind(&DoNothingHandleReadError), true));
connector_ptr->reset();
}
......
......@@ -5,7 +5,7 @@
#ifndef SERVICES_PREFERENCES_PUBLIC_CPP_TRACKED_CONFIGURATION_H_
#define SERVICES_PREFERENCES_PUBLIC_CPP_TRACKED_CONFIGURATION_H_
#include "services/preferences/public/interfaces/preferences_configuration.mojom.h"
#include "services/preferences/public/interfaces/preferences.mojom.h"
namespace prefs {
......
......@@ -12,7 +12,7 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "services/preferences/public/interfaces/preferences_configuration.mojom.h"
#include "services/preferences/public/interfaces/preferences.mojom.h"
#include "services/preferences/public/interfaces/tracked_preference_validation_delegate.mojom.h"
class MockValidationDelegate;
......
......@@ -7,7 +7,6 @@ import("//mojo/public/tools/bindings/mojom.gni")
mojom("interfaces") {
sources = [
"preferences.mojom",
"preferences_configuration.mojom",
"tracked_preference_validation_delegate.mojom",
]
public_deps = [
......
......@@ -4,8 +4,10 @@
module prefs.mojom;
import "mojo/common/file_path.mojom";
import "mojo/common/string16.mojom";
import "mojo/common/values.mojom";
import "services/preferences/public/interfaces/preferences_configuration.mojom";
import "services/preferences/public/interfaces/tracked_preference_validation_delegate.mojom";
const string kServiceName = "preferences";
const string kForwarderServiceName = "preferences_forwarder";
......@@ -92,11 +94,24 @@ interface PrefStoreConnector {
// be received. The client asserts that it is already connected to the
// |already_connected_types| pref stores through some other means, so the
// Connect call will not connect to those.
//
// The returned |connection| is the connection to the main writable user pref
// store. If a |underlay| is returned any writes or reads not serviced by
// |connection| should be serviced by |underlay| instead (e.g. by using an
// |OverlayUserPrefStore|).
//
// Calls to |Connect| before |Init| are allowed and will cause the calls to
// queue and connect once |Init| has been called.
[Sync]
Connect(PrefRegistry pref_registry,
array<PrefStoreType> already_connected_types) =>
(PersistentPrefStoreConnection connection,
PersistentPrefStoreConnection? underlay,
map<PrefStoreType, PrefStoreConnection> connections);
// Connect to the user pref store. Used for incognito.
ConnectToUserPrefStore(array<string> prefs_to_observe) =>
(PersistentPrefStoreConnection connection);
};
// An update to a subcomponent of a pref.
......@@ -155,3 +170,65 @@ interface PrefServiceControl {
// be used.
Init(PersistentPrefStoreConfiguration configuration);
};
// ---------------------------------------------------------------------
// Service Configuration
union PersistentPrefStoreConfiguration {
SimplePersistentPrefStoreConfiguration simple_configuration;
TrackedPersistentPrefStoreConfiguration tracked_configuration;
IncognitoPersistentPrefStoreConfiguration incognito_configuration;
};
struct SimplePersistentPrefStoreConfiguration {
mojo.common.mojom.FilePath pref_filename;
};
// These parameters are passed to prefs::CreateTrackedPersistentPrefStore() in
// services/preferences/persistent_pref_store_factory.cc.
struct TrackedPersistentPrefStoreConfiguration {
mojo.common.mojom.FilePath unprotected_pref_filename;
mojo.common.mojom.FilePath protected_pref_filename;
array<TrackedPreferenceMetadata> tracking_configuration;
uint64 reporting_ids_count;
string seed;
string legacy_device_id;
string registry_seed;
mojo.common.mojom.String16 registry_path;
TrackedPreferenceValidationDelegate? validation_delegate;
ResetOnLoadObserver? reset_on_load_observer;
};
struct TrackedPreferenceMetadata {
enum EnforcementLevel { NO_ENFORCEMENT, ENFORCE_ON_LOAD };
enum PrefTrackingStrategy {
// Atomic preferences are tracked as a whole.
ATOMIC,
// Split preferences are dictionaries for which each top-level entry is
// tracked independently. Note: preferences using this strategy must be kept
// in sync with TrackedSplitPreferences in histograms.xml.
SPLIT,
};
enum ValueType {
IMPERSONAL,
// The preference value may contain personal information.
PERSONAL,
};
uint64 reporting_id;
string name;
EnforcementLevel enforcement_level;
PrefTrackingStrategy strategy;
ValueType value_type;
};
interface ResetOnLoadObserver {
OnResetOnLoad();
};
struct IncognitoPersistentPrefStoreConfiguration {
// A connector for the underlying profile's prefs.
PrefStoreConnector connector;
};
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module prefs.mojom;
import "mojo/common/file_path.mojom";
import "mojo/common/string16.mojom";
import "services/preferences/public/interfaces/tracked_preference_validation_delegate.mojom";
union PersistentPrefStoreConfiguration {
SimplePersistentPrefStoreConfiguration simple_configuration;
TrackedPersistentPrefStoreConfiguration tracked_configuration;
};
struct SimplePersistentPrefStoreConfiguration {
mojo.common.mojom.FilePath pref_filename;
};
// These parameters are passed to prefs::CreateTrackedPersistentPrefStore() in
// services/preferences/persistent_pref_store_factory.cc.
struct TrackedPersistentPrefStoreConfiguration {
mojo.common.mojom.FilePath unprotected_pref_filename;
mojo.common.mojom.FilePath protected_pref_filename;
array<TrackedPreferenceMetadata> tracking_configuration;
uint64 reporting_ids_count;
string seed;
string legacy_device_id;
string registry_seed;
mojo.common.mojom.String16 registry_path;
TrackedPreferenceValidationDelegate? validation_delegate;
ResetOnLoadObserver? reset_on_load_observer;
};
struct TrackedPreferenceMetadata {
enum EnforcementLevel { NO_ENFORCEMENT, ENFORCE_ON_LOAD };
enum PrefTrackingStrategy {
// Atomic preferences are tracked as a whole.
ATOMIC,
// Split preferences are dictionaries for which each top-level entry is
// tracked independently. Note: preferences using this strategy must be kept
// in sync with TrackedSplitPreferences in histograms.xml.
SPLIT,
};
enum ValueType {
IMPERSONAL,
// The preference value may contain personal information.
PERSONAL,
};
uint64 reporting_id;
string name;
EnforcementLevel enforcement_level;
PrefTrackingStrategy strategy;
ValueType value_type;
};
interface ResetOnLoadObserver {
OnResetOnLoad();
};
......@@ -46,8 +46,16 @@ void ScopedPrefConnectionBuilder::ProvidePersistentPrefStore(
observed_prefs_.end()));
}
void ScopedPrefConnectionBuilder::ProvideIncognitoConnector(
const mojom::PrefStoreConnectorPtr& incognito_connector) {
incognito_connector->ConnectToUserPrefStore(
observed_prefs_,
base::Bind(&ScopedPrefConnectionBuilder::OnIncognitoConnect, this));
}
ScopedPrefConnectionBuilder::~ScopedPrefConnectionBuilder() {
std::move(callback_).Run(std::move(persistent_pref_store_connection_),
std::move(incognito_connection_),
std::move(connections_));
}
......@@ -58,4 +66,10 @@ void ScopedPrefConnectionBuilder::OnConnect(
DCHECK(inserted);
}
void ScopedPrefConnectionBuilder::OnIncognitoConnect(
mojom::PersistentPrefStoreConnectionPtr connection_ptr) {
DCHECK(!incognito_connection_);
incognito_connection_ = std::move(connection_ptr);
}
} // namespace prefs
......@@ -40,6 +40,9 @@ class ScopedPrefConnectionBuilder
void ProvidePersistentPrefStore(
PersistentPrefStoreImpl* persistent_pref_store);
void ProvideIncognitoConnector(
const mojom::PrefStoreConnectorPtr& incognito_connector);
private:
friend class base::RefCounted<ScopedPrefConnectionBuilder>;
~ScopedPrefConnectionBuilder();
......@@ -47,6 +50,9 @@ class ScopedPrefConnectionBuilder
void OnConnect(PrefValueStore::PrefStoreType type,
mojom::PrefStoreConnectionPtr connection_ptr);
void OnIncognitoConnect(
mojom::PersistentPrefStoreConnectionPtr connection_ptr);
mojom::PrefStoreConnector::ConnectCallback callback_;
std::vector<std::string> observed_prefs_;
......@@ -57,6 +63,7 @@ class ScopedPrefConnectionBuilder
connections_;
mojom::PersistentPrefStoreConnectionPtr persistent_pref_store_connection_;
mojom::PersistentPrefStoreConnectionPtr incognito_connection_;
DISALLOW_COPY_AND_ASSIGN(ScopedPrefConnectionBuilder);
};
......
......@@ -18,7 +18,7 @@
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/optional.h"
#include "services/preferences/public/interfaces/preferences_configuration.mojom.h"
#include "services/preferences/public/interfaces/preferences.mojom.h"
#include "services/preferences/tracked/hash_store_contents.h"
#include "services/preferences/tracked/interceptable_pref_filter.h"
#include "services/preferences/tracked/tracked_preference.h"
......
......@@ -6,7 +6,7 @@
#define SERVICES_PREFERENCES_TRACKED_TRACKED_PERSISTENT_PREF_STORE_FACTORY_H_
#include <utility>
#include "services/preferences/public/interfaces/preferences_configuration.mojom.h"
#include "services/preferences/public/interfaces/preferences.mojom.h"
namespace base {
class DictionaryValue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment