summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/filesystem/directory_impl.cc5
-rw-r--r--components/filesystem/directory_impl.h4
-rw-r--r--components/filesystem/file_impl.cc8
-rw-r--r--components/filesystem/file_impl.h6
-rw-r--r--components/filesystem/file_system_app.cc2
-rw-r--r--components/filesystem/file_system_app.h2
-rw-r--r--components/filesystem/file_system_impl.cc5
-rw-r--r--components/filesystem/file_system_impl.h4
-rw-r--r--components/filesystem/lock_table.h7
-rw-r--r--components/leveldb/OWNERS1
-rw-r--r--components/leveldb/leveldb_app.cc6
-rw-r--r--components/leveldb/leveldb_app.h2
-rw-r--r--components/leveldb/leveldb_database_impl.cc2
-rw-r--r--components/leveldb/leveldb_database_impl.h2
-rw-r--r--components/leveldb/leveldb_service_impl.cc6
-rw-r--r--components/leveldb/leveldb_service_impl.h3
-rw-r--r--components/profile_service/BUILD.gn3
-rw-r--r--components/profile_service/DEPS3
-rw-r--r--components/profile_service/profile_app.cc116
-rw-r--r--components/profile_service/profile_app.h60
-rw-r--r--components/profile_service/profile_service.gyp2
-rw-r--r--components/profile_service/profile_service_impl.cc47
-rw-r--r--components/profile_service/profile_service_impl.h20
-rw-r--r--components/profile_service/public/interfaces/profile.mojom8
-rw-r--r--components/profile_service/user_id_map.cc29
-rw-r--r--components/profile_service/user_id_map.h31
-rw-r--r--content/browser/BUILD.gn1
-rw-r--r--content/browser/DEPS3
-rw-r--r--content/browser/browser_context.cc4
-rw-r--r--content/browser/browser_main_loop.cc3
-rw-r--r--content/browser/dom_storage/dom_storage_context_wrapper.cc192
-rw-r--r--content/browser/dom_storage/dom_storage_context_wrapper.h17
-rw-r--r--content/browser/frame_host/frame_mojo_shell.cc9
-rw-r--r--content/browser/leveldb_wrapper_impl.cc27
-rw-r--r--content/browser/leveldb_wrapper_impl.h6
-rw-r--r--content/browser/mojo/mojo_app_connection_impl.cc9
-rw-r--r--content/browser/mojo/mojo_app_connection_impl.h5
-rw-r--r--content/browser/mojo/mojo_shell_context.cc39
-rw-r--r--content/browser/mojo/mojo_shell_context.h6
-rw-r--r--content/browser/mojo_shell_browsertest.cc15
-rw-r--r--content/browser/storage_partition_impl.cc11
-rw-r--r--content/browser/storage_partition_impl.h15
-rw-r--r--content/browser/storage_partition_impl_map.cc11
-rw-r--r--content/common/mojo/current_thread_loader.cc25
-rw-r--r--content/common/mojo/current_thread_loader.h46
-rw-r--r--content/content_browser.gypi1
-rw-r--r--content/content_common.gypi2
-rw-r--r--content/public/browser/mojo_app_connection.h6
-rw-r--r--mojo/mojo_services.gyp2
-rw-r--r--mojo/shell/public/cpp/message_loop_ref.h6
50 files changed, 630 insertions, 215 deletions
diff --git a/components/filesystem/directory_impl.cc b/components/filesystem/directory_impl.cc
index e8fab2a..c80731d 100644
--- a/components/filesystem/directory_impl.cc
+++ b/components/filesystem/directory_impl.cc
@@ -14,6 +14,7 @@
#include "base/memory/scoped_ptr.h"
#include "build/build_config.h"
#include "components/filesystem/file_impl.h"
+#include "components/filesystem/lock_table.h"
#include "components/filesystem/util.h"
#include "mojo/common/common_type_converters.h"
#include "mojo/platform_handle/platform_handle_functions.h"
@@ -25,11 +26,11 @@ namespace filesystem {
DirectoryImpl::DirectoryImpl(mojo::InterfaceRequest<Directory> request,
base::FilePath directory_path,
scoped_ptr<base::ScopedTempDir> temp_dir,
- LockTable* lock_table)
+ scoped_refptr<LockTable> lock_table)
: binding_(this, std::move(request)),
directory_path_(directory_path),
temp_dir_(std::move(temp_dir)),
- lock_table_(lock_table) {}
+ lock_table_(std::move(lock_table)) {}
DirectoryImpl::~DirectoryImpl() {
}
diff --git a/components/filesystem/directory_impl.h b/components/filesystem/directory_impl.h
index 347c514..03bba30 100644
--- a/components/filesystem/directory_impl.h
+++ b/components/filesystem/directory_impl.h
@@ -30,7 +30,7 @@ class DirectoryImpl : public Directory {
DirectoryImpl(mojo::InterfaceRequest<Directory> request,
base::FilePath directory_path,
scoped_ptr<base::ScopedTempDir> temp_dir,
- LockTable* lock_table);
+ scoped_refptr<LockTable> lock_table);
~DirectoryImpl() override;
void set_connection_error_handler(const mojo::Closure& error_handler) {
@@ -73,7 +73,7 @@ class DirectoryImpl : public Directory {
mojo::StrongBinding<Directory> binding_;
base::FilePath directory_path_;
scoped_ptr<base::ScopedTempDir> temp_dir_;
- LockTable* lock_table_;
+ scoped_refptr<LockTable> lock_table_;
DISALLOW_COPY_AND_ASSIGN(DirectoryImpl);
};
diff --git a/components/filesystem/file_impl.cc b/components/filesystem/file_impl.cc
index 21b38d7..13ebced 100644
--- a/components/filesystem/file_impl.cc
+++ b/components/filesystem/file_impl.cc
@@ -34,22 +34,22 @@ const size_t kMaxReadSize = 1 * 1024 * 1024; // 1 MB.
FileImpl::FileImpl(mojo::InterfaceRequest<File> request,
const base::FilePath& path,
uint32_t flags,
- LockTable* lock_table)
+ scoped_refptr<LockTable> lock_table)
: binding_(this, std::move(request)),
file_(path, flags),
path_(path),
- lock_table_(lock_table) {
+ lock_table_(std::move(lock_table)) {
DCHECK(file_.IsValid());
}
FileImpl::FileImpl(mojo::InterfaceRequest<File> request,
const base::FilePath& path,
base::File file,
- LockTable* lock_table)
+ scoped_refptr<LockTable> lock_table)
: binding_(this, std::move(request)),
file_(std::move(file)),
path_(path),
- lock_table_(lock_table) {
+ lock_table_(std::move(lock_table)) {
DCHECK(file_.IsValid());
}
diff --git a/components/filesystem/file_impl.h b/components/filesystem/file_impl.h
index 9314776..bdae38e 100644
--- a/components/filesystem/file_impl.h
+++ b/components/filesystem/file_impl.h
@@ -27,11 +27,11 @@ class FileImpl : public File {
FileImpl(mojo::InterfaceRequest<File> request,
const base::FilePath& path,
uint32_t flags,
- LockTable* lock_table);
+ scoped_refptr<LockTable> lock_table);
FileImpl(mojo::InterfaceRequest<File> request,
const base::FilePath& path,
base::File file,
- LockTable* lock_table);
+ scoped_refptr<LockTable> lock_table);
~FileImpl() override;
// Returns whether the underlying file handle is valid.
@@ -74,7 +74,7 @@ class FileImpl : public File {
mojo::StrongBinding<File> binding_;
base::File file_;
base::FilePath path_;
- LockTable* lock_table_;
+ scoped_refptr<LockTable> lock_table_;
DISALLOW_COPY_AND_ASSIGN(FileImpl);
};
diff --git a/components/filesystem/file_system_app.cc b/components/filesystem/file_system_app.cc
index 9ec3806..2163351 100644
--- a/components/filesystem/file_system_app.cc
+++ b/components/filesystem/file_system_app.cc
@@ -52,7 +52,7 @@ bool FileSystemApp::AcceptConnection(mojo::Connection* connection) {
void FileSystemApp::Create(mojo::Connection* connection,
mojo::InterfaceRequest<FileSystem> request) {
new FileSystemImpl(connection, std::move(request), GetUserDataDir(),
- lock_table_.get());
+ lock_table_);
}
void FileSystemApp::ShellConnectionLost() {
diff --git a/components/filesystem/file_system_app.h b/components/filesystem/file_system_app.h
index 1eb65c3..5e297ad 100644
--- a/components/filesystem/file_system_app.h
+++ b/components/filesystem/file_system_app.h
@@ -42,7 +42,7 @@ class FileSystemApp : public mojo::ShellClient,
mojo::TracingImpl tracing_;
- scoped_ptr<LockTable> lock_table_;
+ scoped_refptr<LockTable> lock_table_;
DISALLOW_COPY_AND_ASSIGN(FileSystemApp);
};
diff --git a/components/filesystem/file_system_impl.cc b/components/filesystem/file_system_impl.cc
index f8b9594..b1eacf16 100644
--- a/components/filesystem/file_system_impl.cc
+++ b/components/filesystem/file_system_impl.cc
@@ -15,6 +15,7 @@
#include "base/memory/scoped_ptr.h"
#include "build/build_config.h"
#include "components/filesystem/directory_impl.h"
+#include "components/filesystem/lock_table.h"
#include "mojo/shell/public/cpp/connection.h"
#include "url/gurl.h"
@@ -23,10 +24,10 @@ namespace filesystem {
FileSystemImpl::FileSystemImpl(mojo::Connection* connection,
mojo::InterfaceRequest<FileSystem> request,
base::FilePath persistent_dir,
- LockTable* lock_table)
+ scoped_refptr<LockTable> lock_table)
: remote_application_name_(connection->GetRemoteIdentity().name()),
binding_(this, std::move(request)),
- lock_table_(lock_table),
+ lock_table_(std::move(lock_table)),
persistent_dir_(persistent_dir) {}
FileSystemImpl::~FileSystemImpl() {
diff --git a/components/filesystem/file_system_impl.h b/components/filesystem/file_system_impl.h
index 7bbecd2..ff5d9bc 100644
--- a/components/filesystem/file_system_impl.h
+++ b/components/filesystem/file_system_impl.h
@@ -32,7 +32,7 @@ class FileSystemImpl : public FileSystem {
FileSystemImpl(mojo::Connection* connection,
mojo::InterfaceRequest<FileSystem> request,
base::FilePath persistent_dir,
- LockTable* lock_table);
+ scoped_refptr<LockTable> lock_table);
~FileSystemImpl() override;
// |Files| implementation:
@@ -46,7 +46,7 @@ class FileSystemImpl : public FileSystem {
private:
const std::string remote_application_name_;
mojo::StrongBinding<FileSystem> binding_;
- LockTable* lock_table_;
+ scoped_refptr<LockTable> lock_table_;
base::FilePath persistent_dir_;
diff --git a/components/filesystem/lock_table.h b/components/filesystem/lock_table.h
index 9be4ca6..73674ac2 100644
--- a/components/filesystem/lock_table.h
+++ b/components/filesystem/lock_table.h
@@ -8,6 +8,7 @@
#include <set>
#include "base/files/file.h"
+#include "base/memory/ref_counted.h"
namespace filesystem {
@@ -16,10 +17,9 @@ class FileImpl;
// A table of all locks held by this process. We have one global table owned by
// the app, but accessible by everything just in case two connections from the
// same origin try to lock the same file.
-class LockTable {
+class LockTable : public base::RefCounted<LockTable> {
public:
LockTable();
- ~LockTable();
// Locks a file.
base::File::Error LockFile(FileImpl* file);
@@ -33,6 +33,9 @@ class LockTable {
void RemoveFromLockTable(const base::FilePath& path);
private:
+ friend class base::RefCounted<LockTable>;
+ ~LockTable();
+
// Open, locked files. We keep track of this so we quickly error when we try
// to double lock a file.
std::set<base::FilePath> locked_files_;
diff --git a/components/leveldb/OWNERS b/components/leveldb/OWNERS
new file mode 100644
index 0000000..4733a4f
--- /dev/null
+++ b/components/leveldb/OWNERS
@@ -0,0 +1 @@
+erg@chromium.org
diff --git a/components/leveldb/leveldb_app.cc b/components/leveldb/leveldb_app.cc
index aad49e28..ac2855f 100644
--- a/components/leveldb/leveldb_app.cc
+++ b/components/leveldb/leveldb_app.cc
@@ -4,6 +4,7 @@
#include "components/leveldb/leveldb_app.h"
+#include "base/message_loop/message_loop.h"
#include "components/leveldb/leveldb_service_impl.h"
#include "mojo/shell/public/cpp/connection.h"
@@ -17,7 +18,6 @@ void LevelDBApp::Initialize(mojo::Connector* connector,
const mojo::Identity& identity,
uint32_t id) {
tracing_.Initialize(connector, identity.name());
- service_.reset(new LevelDBServiceImpl);
}
bool LevelDBApp::AcceptConnection(mojo::Connection* connection) {
@@ -31,7 +31,9 @@ void LevelDBApp::ShellConnectionLost() {
}
void LevelDBApp::Create(mojo::Connection* connection,
- mojo::InterfaceRequest<LevelDBService> request) {
+ leveldb::LevelDBServiceRequest request) {
+ if (!service_)
+ service_.reset(new LevelDBServiceImpl);
bindings_.AddBinding(service_.get(), std::move(request));
}
diff --git a/components/leveldb/leveldb_app.h b/components/leveldb/leveldb_app.h
index a2e806f..6db5194 100644
--- a/components/leveldb/leveldb_app.h
+++ b/components/leveldb/leveldb_app.h
@@ -29,7 +29,7 @@ class LevelDBApp : public mojo::ShellClient,
// |InterfaceFactory<LevelDBService>| implementation:
void Create(mojo::Connection* connection,
- mojo::InterfaceRequest<LevelDBService> request) override;
+ leveldb::LevelDBServiceRequest request) override;
mojo::TracingImpl tracing_;
scoped_ptr<LevelDBService> service_;
diff --git a/components/leveldb/leveldb_database_impl.cc b/components/leveldb/leveldb_database_impl.cc
index efefc5a..d5e8fa6 100644
--- a/components/leveldb/leveldb_database_impl.cc
+++ b/components/leveldb/leveldb_database_impl.cc
@@ -28,7 +28,7 @@ uint64_t GetSafeRandomId(const std::map<uint64_t, T>& m) {
} // namespace
LevelDBDatabaseImpl::LevelDBDatabaseImpl(
- mojo::InterfaceRequest<LevelDBDatabase> request,
+ leveldb::LevelDBDatabaseRequest request,
scoped_ptr<MojoEnv> environment,
scoped_ptr<leveldb::DB> db)
: binding_(this, std::move(request)),
diff --git a/components/leveldb/leveldb_database_impl.h b/components/leveldb/leveldb_database_impl.h
index 5b5721c..29ff697 100644
--- a/components/leveldb/leveldb_database_impl.h
+++ b/components/leveldb/leveldb_database_impl.h
@@ -18,7 +18,7 @@ class MojoEnv;
// The backing to a database object that we pass to our called.
class LevelDBDatabaseImpl : public LevelDBDatabase {
public:
- LevelDBDatabaseImpl(mojo::InterfaceRequest<LevelDBDatabase> request,
+ LevelDBDatabaseImpl(leveldb::LevelDBDatabaseRequest request,
scoped_ptr<MojoEnv> environment,
scoped_ptr<leveldb::DB> db);
~LevelDBDatabaseImpl() override;
diff --git a/components/leveldb/leveldb_service_impl.cc b/components/leveldb/leveldb_service_impl.cc
index 404019e..baff56b 100644
--- a/components/leveldb/leveldb_service_impl.cc
+++ b/components/leveldb/leveldb_service_impl.cc
@@ -15,15 +15,13 @@
namespace leveldb {
-LevelDBServiceImpl::LevelDBServiceImpl()
- : thread_(new LevelDBFileThread) {
-}
+LevelDBServiceImpl::LevelDBServiceImpl() : thread_(new LevelDBFileThread) {}
LevelDBServiceImpl::~LevelDBServiceImpl() {}
void LevelDBServiceImpl::Open(filesystem::DirectoryPtr directory,
const mojo::String& dbname,
- mojo::InterfaceRequest<LevelDBDatabase> database,
+ leveldb::LevelDBDatabaseRequest database,
const OpenCallback& callback) {
// This is the place where we open a database.
leveldb::Options options;
diff --git a/components/leveldb/leveldb_service_impl.h b/components/leveldb/leveldb_service_impl.h
index 54b2942..8d554f7 100644
--- a/components/leveldb/leveldb_service_impl.h
+++ b/components/leveldb/leveldb_service_impl.h
@@ -8,6 +8,7 @@
#include "base/memory/ref_counted.h"
#include "components/leveldb/leveldb_file_thread.h"
#include "components/leveldb/public/interfaces/leveldb.mojom.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
namespace leveldb {
@@ -20,7 +21,7 @@ class LevelDBServiceImpl : public LevelDBService {
// Overridden from LevelDBService:
void Open(filesystem::DirectoryPtr directory,
const mojo::String& dbname,
- mojo::InterfaceRequest<LevelDBDatabase> database,
+ leveldb::LevelDBDatabaseRequest database,
const OpenCallback& callback) override;
private:
diff --git a/components/profile_service/BUILD.gn b/components/profile_service/BUILD.gn
index cdde7a0..3ff648b 100644
--- a/components/profile_service/BUILD.gn
+++ b/components/profile_service/BUILD.gn
@@ -10,6 +10,8 @@ source_set("lib") {
"profile_app.h",
"profile_service_impl.cc",
"profile_service_impl.h",
+ "user_id_map.cc",
+ "user_id_map.h",
]
deps = [
@@ -21,6 +23,7 @@ source_set("lib") {
"//components/profile_service/public/interfaces",
"//mojo/common",
"//mojo/common:common_base",
+ "//mojo/message_pump",
"//mojo/platform_handle",
"//mojo/services/tracing/public/cpp",
"//mojo/shell/public/cpp",
diff --git a/components/profile_service/DEPS b/components/profile_service/DEPS
index 3760a3f..4e7a9d8 100644
--- a/components/profile_service/DEPS
+++ b/components/profile_service/DEPS
@@ -2,9 +2,10 @@ include_rules = [
"+components/filesystem",
"+components/leveldb",
"+mojo/common",
- "+mojo/shell",
+ "+mojo/message_pump",
"+mojo/platform_handle",
"+mojo/public",
"+mojo/services/tracing/public/cpp",
+ "+mojo/shell",
"+mojo/util",
]
diff --git a/components/profile_service/profile_app.cc b/components/profile_service/profile_app.cc
index 27491db..a580711 100644
--- a/components/profile_service/profile_app.cc
+++ b/components/profile_service/profile_app.cc
@@ -4,46 +4,96 @@
#include "components/profile_service/profile_app.h"
-#include "base/lazy_instance.h"
+#include "base/bind.h"
+#include "base/memory/weak_ptr.h"
+#include "components/filesystem/lock_table.h"
#include "components/leveldb/leveldb_service_impl.h"
#include "components/profile_service/profile_service_impl.h"
+#include "components/profile_service/user_id_map.h"
+#include "mojo/public/cpp/bindings/callback.h"
#include "mojo/shell/public/cpp/connection.h"
namespace profile {
-namespace {
-
-base::LazyInstance<std::map<std::string, base::FilePath>>
- g_user_id_to_data_dir = LAZY_INSTANCE_INITIALIZER;
-
-} // namespace
-
-scoped_ptr<mojo::ShellClient> CreateProfileApp() {
- return make_scoped_ptr(new ProfileApp);
+class ProfileApp::ProfileServiceObjects
+ : public base::SupportsWeakPtr<ProfileServiceObjects> {
+ public:
+ // Created on the main thread.
+ ProfileServiceObjects(base::FilePath profile_data_dir)
+ : profile_data_dir_(profile_data_dir) {}
+
+ // Destroyed on the |profile_service_runner_|.
+ ~ProfileServiceObjects() {}
+
+ // Called on the |profile_service_runner_|.
+ void OnProfileServiceRequest(mojo::Connection* connection,
+ ProfileServiceRequest request) {
+ if (!lock_table_)
+ lock_table_ = new filesystem::LockTable;
+ profile_service_bindings_.AddBinding(
+ new ProfileServiceImpl(profile_data_dir_, lock_table_),
+ std::move(request));
+ }
+
+ private:
+ mojo::BindingSet<ProfileService> profile_service_bindings_;
+ scoped_refptr<filesystem::LockTable> lock_table_;
+ base::FilePath profile_data_dir_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProfileServiceObjects);
+};
+
+class ProfileApp::LevelDBServiceObjects
+ : public base::SupportsWeakPtr<LevelDBServiceObjects> {
+ public:
+ // Created on the main thread.
+ LevelDBServiceObjects() {}
+
+ // Destroyed on the |leveldb_service_runner_|.
+ ~LevelDBServiceObjects() {}
+
+ // Called on the |leveldb_service_runner_|.
+ void OnLevelDBServiceRequest(mojo::Connection* connection,
+ leveldb::LevelDBServiceRequest request) {
+ if (!leveldb_service_)
+ leveldb_service_.reset(new leveldb::LevelDBServiceImpl);
+ leveldb_bindings_.AddBinding(leveldb_service_.get(), std::move(request));
+ }
+
+ private:
+ // Variables that are only accessible on the |leveldb_service_runner_| thread.
+ scoped_ptr<leveldb::LevelDBService> leveldb_service_;
+ mojo::BindingSet<leveldb::LevelDBService> leveldb_bindings_;
+
+ DISALLOW_COPY_AND_ASSIGN(LevelDBServiceObjects);
+};
+
+scoped_ptr<mojo::ShellClient> CreateProfileApp(
+ scoped_refptr<base::SingleThreadTaskRunner> profile_service_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> leveldb_service_runner) {
+ return make_scoped_ptr(new ProfileApp(
+ std::move(profile_service_runner),
+ std::move(leveldb_service_runner)));
}
-ProfileApp::ProfileApp()
- : lock_table_(new filesystem::LockTable) {
-}
-
-ProfileApp::~ProfileApp() {}
+ProfileApp::ProfileApp(
+ scoped_refptr<base::SingleThreadTaskRunner> profile_service_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> leveldb_service_runner)
+ : profile_service_runner_(std::move(profile_service_runner)),
+ leveldb_service_runner_(std::move(leveldb_service_runner)) {}
-// static
-void ProfileApp::AssociateMojoUserIDWithProfileDir(
- const std::string& user_id,
- const base::FilePath& profile_data_dir) {
- g_user_id_to_data_dir.Get()[user_id] = profile_data_dir;
+ProfileApp::~ProfileApp() {
+ profile_service_runner_->DeleteSoon(FROM_HERE, profile_objects_.release());
+ leveldb_service_runner_->DeleteSoon(FROM_HERE, leveldb_objects_.release());
}
void ProfileApp::Initialize(mojo::Connector* connector,
const mojo::Identity& identity,
uint32_t id) {
tracing_.Initialize(connector, identity.name());
- leveldb_service_.reset(new leveldb::LevelDBServiceImpl);
-
- auto it = g_user_id_to_data_dir.Get().find(identity.user_id());
- DCHECK(it != g_user_id_to_data_dir.Get().end());
- profile_data_dir_ = it->second;
+ profile_objects_.reset(new ProfileApp::ProfileServiceObjects(
+ GetProfileDirForUserID(identity.user_id())));
+ leveldb_objects_.reset(new ProfileApp::LevelDBServiceObjects);
}
bool ProfileApp::AcceptConnection(mojo::Connection* connection) {
@@ -54,16 +104,20 @@ bool ProfileApp::AcceptConnection(mojo::Connection* connection) {
void ProfileApp::Create(mojo::Connection* connection,
ProfileServiceRequest request) {
- // No, we need one of these per connection.
- new ProfileServiceImpl(connection,
- std::move(request),
- profile_data_dir_,
- lock_table_.get());
+ profile_service_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&ProfileApp::ProfileServiceObjects::OnProfileServiceRequest,
+ profile_objects_->AsWeakPtr(), connection,
+ base::Passed(&request)));
}
void ProfileApp::Create(mojo::Connection* connection,
leveldb::LevelDBServiceRequest request) {
- leveldb_bindings_.AddBinding(leveldb_service_.get(), std::move(request));
+ leveldb_service_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&ProfileApp::LevelDBServiceObjects::OnLevelDBServiceRequest,
+ leveldb_objects_->AsWeakPtr(), connection,
+ base::Passed(&request)));
}
} // namespace profile
diff --git a/components/profile_service/profile_app.h b/components/profile_service/profile_app.h
index 8da3f56..2e61087 100644
--- a/components/profile_service/profile_app.h
+++ b/components/profile_service/profile_app.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_PROFILE_SERVICE_PROFILE_APP_H_
#define COMPONENTS_PROFILE_SERVICE_PROFILE_APP_H_
+#include "base/memory/ref_counted.h"
#include "components/filesystem/lock_table.h"
#include "components/leveldb/public/interfaces/leveldb.mojom.h"
#include "components/profile_service/public/interfaces/profile.mojom.h"
@@ -13,46 +14,28 @@
#include "mojo/shell/public/cpp/interface_factory.h"
#include "mojo/shell/public/cpp/shell_client.h"
-namespace filesystem {
-class LockTable;
-}
-
namespace profile {
-scoped_ptr<mojo::ShellClient> CreateProfileApp();
+scoped_ptr<mojo::ShellClient> CreateProfileApp(
+ scoped_refptr<base::SingleThreadTaskRunner> profile_service_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> leveldb_service_runner);
// Application which hands off per-profile services.
//
-// This Application serves ProfileService, and serves LevelDBService since most
-// of the users of leveldb will want to write directly to the Directory
-// provided by the ProfileService; we want file handling to be done in the same
-// process to minimize IPC.
-//
-// In the future, this application will probably also offer any service that
-// most Profile using applications will need, such as preferences.
+// This Application serves ProfileService. In the future, this application will
+// probably also offer any service that most Profile using applications will
+// need, such as preferences; this class will have to be made into a
+// application which is an InterfaceProvider which internally spawns threads
+// for different sub-applications.
class ProfileApp : public mojo::ShellClient,
public mojo::InterfaceFactory<ProfileService>,
public mojo::InterfaceFactory<leveldb::LevelDBService> {
public:
- ProfileApp();
+ ProfileApp(
+ scoped_refptr<base::SingleThreadTaskRunner> profile_service_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> leveldb_service_runner);
~ProfileApp() override;
- // Currently, ProfileApp is run from within the chrome process. This means it
- // that the ApplicationLoader is registered during MojoShellContext startup,
- // even though the application itself is not started. As soon as a
- // BrowserContext is created, the BrowserContext will choose a |user_id| for
- // itself and call us to register the mapping from |user_id| to
- // |profile_data_dir|.
- //
- // This data is then accessed when we get our Initialize() call.
- //
- // TODO(erg): This is a temporary hack until we redo how we initialize mojo
- // applications inside of chrome in general; this system won't work once
- // ProfileApp gets put in its own sandboxed process.
- static void AssociateMojoUserIDWithProfileDir(
- const std::string& user_id,
- const base::FilePath& profile_data_dir);
-
private:
// |ShellClient| override:
void Initialize(mojo::Connector* connector,
@@ -68,17 +51,22 @@ class ProfileApp : public mojo::ShellClient,
void Create(mojo::Connection* connection,
leveldb::LevelDBServiceRequest request) override;
- mojo::TracingImpl tracing_;
+ void OnLevelDBServiceRequest(mojo::Connection* connection,
+ leveldb::LevelDBServiceRequest request);
+ void OnLevelDBServiceError();
- scoped_ptr<ProfileService> profile_service_;
- mojo::BindingSet<ProfileService> profile_bindings_;
+ scoped_refptr<base::SingleThreadTaskRunner> profile_service_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> leveldb_service_runner_;
- scoped_ptr<leveldb::LevelDBService> leveldb_service_;
- mojo::BindingSet<leveldb::LevelDBService> leveldb_bindings_;
+ mojo::TracingImpl tracing_;
- scoped_ptr<filesystem::LockTable> lock_table_;
+ // We create these two objects so we can delete them on the correct task
+ // runners.
+ class ProfileServiceObjects;
+ scoped_ptr<ProfileServiceObjects> profile_objects_;
- base::FilePath profile_data_dir_;
+ class LevelDBServiceObjects;
+ scoped_ptr<LevelDBServiceObjects> leveldb_objects_;
DISALLOW_COPY_AND_ASSIGN(ProfileApp);
};
diff --git a/components/profile_service/profile_service.gyp b/components/profile_service/profile_service.gyp
index 75561bde..e0676ae 100644
--- a/components/profile_service/profile_service.gyp
+++ b/components/profile_service/profile_service.gyp
@@ -22,6 +22,8 @@
'profile_app.h',
'profile_service_impl.cc',
'profile_service_impl.h',
+ 'user_id_map.cc',
+ 'user_id_map.h',
],
'dependencies': [
'profile_service_bindings',
diff --git a/components/profile_service/profile_service_impl.cc b/components/profile_service/profile_service_impl.cc
index b6239dd..dee44ad 100644
--- a/components/profile_service/profile_service_impl.cc
+++ b/components/profile_service/profile_service_impl.cc
@@ -4,36 +4,57 @@
#include "components/profile_service/profile_service_impl.h"
+#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/strings/utf_string_conversions.h"
#include "components/filesystem/directory_impl.h"
#include "components/filesystem/lock_table.h"
+#include "components/filesystem/public/interfaces/types.mojom.h"
#include "mojo/shell/public/cpp/connection.h"
+#include "mojo/shell/public/cpp/message_loop_ref.h"
namespace profile {
ProfileServiceImpl::ProfileServiceImpl(
- mojo::Connection* connection,
- mojo::InterfaceRequest<ProfileService> request,
- base::FilePath base_profile_dir,
- filesystem::LockTable* lock_table)
- : binding_(this, std::move(request)),
- lock_table_(lock_table),
- path_(base_profile_dir) {
- if (!base::PathExists(path_))
- base::CreateDirectory(path_);
+ const base::FilePath& base_profile_dir,
+ const scoped_refptr<filesystem::LockTable>& lock_table)
+ : lock_table_(lock_table), path_(base_profile_dir) {
+ base::CreateDirectory(path_);
}
-ProfileServiceImpl::~ProfileServiceImpl() {
-}
+ProfileServiceImpl::~ProfileServiceImpl() {}
-void ProfileServiceImpl::GetDirectory(
- mojo::InterfaceRequest<filesystem::Directory> request) {
+void ProfileServiceImpl::GetDirectory(filesystem::DirectoryRequest request,
+ const GetDirectoryCallback& callback) {
new filesystem::DirectoryImpl(std::move(request),
path_,
scoped_ptr<base::ScopedTempDir>(),
lock_table_);
+ callback.Run();
+}
+
+void ProfileServiceImpl::GetSubDirectory(
+ const mojo::String& sub_directory_path,
+ filesystem::DirectoryRequest request,
+ const GetSubDirectoryCallback& callback) {
+ // Ensure that we've made |subdirectory| recursively under our profile.
+ base::FilePath subdir = path_.Append(
+#if defined(OS_WIN)
+ base::UTF8ToWide(sub_directory_path.To<std::string>()));
+#else
+ sub_directory_path.To<std::string>());
+#endif
+ base::File::Error error;
+ if (!base::CreateDirectoryAndGetError(subdir, &error)) {
+ callback.Run(static_cast<filesystem::FileError>(error));
+ return;
+ }
+
+ new filesystem::DirectoryImpl(std::move(request), subdir,
+ scoped_ptr<base::ScopedTempDir>(), lock_table_);
+ callback.Run(filesystem::FileError::OK);
}
} // namespace profile
diff --git a/components/profile_service/profile_service_impl.h b/components/profile_service/profile_service_impl.h
index 72f7ce8..6022af0 100644
--- a/components/profile_service/profile_service_impl.h
+++ b/components/profile_service/profile_service_impl.h
@@ -16,24 +16,28 @@ namespace filesystem {
class LockTable;
}
+namespace mojo {
+class MessageLoopRef;
+}
+
namespace profile {
// A service which serves directories to callers.
class ProfileServiceImpl : public ProfileService {
public:
- ProfileServiceImpl(mojo::Connection* connection,
- mojo::InterfaceRequest<ProfileService> request,
- base::FilePath base_profile_dir,
- filesystem::LockTable* lock_table);
+ ProfileServiceImpl(const base::FilePath& base_profile_dir,
+ const scoped_refptr<filesystem::LockTable>& lock_table);
~ProfileServiceImpl() override;
// Overridden from ProfileService:
- void GetDirectory(
- mojo::InterfaceRequest<filesystem::Directory> request) override;
+ void GetDirectory(filesystem::DirectoryRequest request,
+ const GetDirectoryCallback& callback) override;
+ void GetSubDirectory(const mojo::String& sub_directory_path,
+ filesystem::DirectoryRequest request,
+ const GetSubDirectoryCallback& callback) override;
private:
- mojo::StrongBinding<ProfileService> binding_;
- filesystem::LockTable* lock_table_;
+ scoped_refptr<filesystem::LockTable> lock_table_;
base::FilePath path_;
DISALLOW_COPY_AND_ASSIGN(ProfileServiceImpl);
diff --git a/components/profile_service/public/interfaces/profile.mojom b/components/profile_service/public/interfaces/profile.mojom
index 898f457..3f974f2 100644
--- a/components/profile_service/public/interfaces/profile.mojom
+++ b/components/profile_service/public/interfaces/profile.mojom
@@ -5,6 +5,7 @@
module profile;
import "components/filesystem/public/interfaces/directory.mojom";
+import "components/filesystem/public/interfaces/types.mojom";
// An encapsulation around the per-profile storage.
//
@@ -13,5 +14,10 @@ import "components/filesystem/public/interfaces/directory.mojom";
// it has access to is the User's profile.
interface ProfileService {
// Returns the user profile directory.
- GetDirectory(filesystem.Directory& dir);
+ GetDirectory(filesystem.Directory& dir) => ();
+
+ // Returns a subdirectory under the profile dir. Returns a filesystem error
+ // when we fail to create the subdirectory.
+ GetSubDirectory(string dir_path, filesystem.Directory& dir)
+ => (filesystem.FileError err);
};
diff --git a/components/profile_service/user_id_map.cc b/components/profile_service/user_id_map.cc
new file mode 100644
index 0000000..a5e54e4
--- /dev/null
+++ b/components/profile_service/user_id_map.cc
@@ -0,0 +1,29 @@
+// Copyright 2016 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.
+
+#include "components/profile_service/user_id_map.h"
+
+#include <map>
+
+#include "base/lazy_instance.h"
+
+namespace profile {
+
+namespace {
+base::LazyInstance<std::map<std::string, base::FilePath>>
+ g_user_id_to_data_dir = LAZY_INSTANCE_INITIALIZER;
+} // namespace
+
+void AssociateMojoUserIDWithProfileDir(const std::string& user_id,
+ const base::FilePath& profile_data_dir) {
+ g_user_id_to_data_dir.Get()[user_id] = profile_data_dir;
+}
+
+base::FilePath GetProfileDirForUserID(const std::string& user_id) {
+ auto it = g_user_id_to_data_dir.Get().find(user_id);
+ DCHECK(it != g_user_id_to_data_dir.Get().end());
+ return it->second;
+}
+
+} // namespace profile
diff --git a/components/profile_service/user_id_map.h b/components/profile_service/user_id_map.h
new file mode 100644
index 0000000..4d5a56b
--- /dev/null
+++ b/components/profile_service/user_id_map.h
@@ -0,0 +1,31 @@
+// Copyright 2016 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.
+
+#ifndef COMPONENTS_PROFILE_SERVICE_USER_ID_MAP_H_
+#define COMPONENTS_PROFILE_SERVICE_USER_ID_MAP_H_
+
+#include <string>
+#include "base/files/file_path.h"
+
+namespace profile {
+
+// Currently, ProfileApp is run from within the chrome process. This means that
+// the ApplicationLoader is registered during MojoShellContext startup, even
+// though the application itself is not started. As soon as a BrowserContext is
+// created, the BrowserContext will choose a |user_id| for itself and call us
+// to register the mapping from |user_id| to |profile_data_dir|.
+//
+// This data is then accessed when we get our Initialize() call.
+//
+// TODO(erg): This is a temporary hack until we redo how we initialize mojo
+// applications inside of chrome in general; this system won't work once
+// ProfileApp gets put in its own sandboxed process.
+void AssociateMojoUserIDWithProfileDir(const std::string& user_id,
+ const base::FilePath& profile_data_dir);
+
+base::FilePath GetProfileDirForUserID(const std::string& user_id);
+
+} // namespace profile
+
+#endif // COMPONENTS_PROFILE_SERVICE_USER_ID_MAP_H_
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index aea09ca..3acc6fd 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -120,6 +120,7 @@ source_set("browser") {
deps += [
"//cc",
"//cc/surfaces",
+ "//components/filesystem:lib",
"//components/leveldb:lib",
"//components/profile_service:lib",
"//components/scheduler:common",
diff --git a/content/browser/DEPS b/content/browser/DEPS
index 650dbd4..cac7295 100644
--- a/content/browser/DEPS
+++ b/content/browser/DEPS
@@ -1,7 +1,8 @@
include_rules = [
# Allow inclusion of specific components that we depend on. We may only
# depend on components which we share with the mojo html_viewer.
- "+components/leveldb/public/interfaces",
+ "+components/filesystem",
+ "+components/leveldb",
"+components/mime_util",
"+components/mus/public/interfaces",
"+components/mus/public",
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc
index 56382ca..4b8396e 100644
--- a/content/browser/browser_context.cc
+++ b/content/browser/browser_context.cc
@@ -14,7 +14,7 @@
#include "base/lazy_instance.h"
#include "base/rand_util.h"
#include "build/build_config.h"
-#include "components/profile_service/profile_app.h"
+#include "components/profile_service/user_id_map.h"
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/fileapi/chrome_blob_storage_context.h"
#include "content/browser/indexed_db/indexed_db_context_impl.h"
@@ -340,7 +340,7 @@ void BrowserContext::Initialize(
g_used_user_ids.Get().insert(new_id);
g_context_to_user_id.Get().push_back(std::make_pair(browser_context, new_id));
- profile::ProfileApp::AssociateMojoUserIDWithProfileDir(new_id, path);
+ profile::AssociateMojoUserIDWithProfileDir(new_id, path);
browser_context->SetUserData(kMojoWasInitialized,
new base::SupportsUserData::Data);
}
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index ba04371..3c39e53 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -1168,7 +1168,8 @@ int BrowserMainLoop::BrowserThreadsStarted() {
mojo_ipc_support_.reset(new IPC::ScopedIPCSupport(
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO)
->task_runner()));
- mojo_shell_context_.reset(new MojoShellContext);
+ mojo_shell_context_.reset(new MojoShellContext(file_thread_->task_runner(),
+ db_thread_->task_runner()));
#if defined(OS_MACOSX)
mojo::edk::SetMachPortProvider(MachBroker::GetInstance());
#endif // defined(OS_MACOSX)
diff --git a/content/browser/dom_storage/dom_storage_context_wrapper.cc b/content/browser/dom_storage/dom_storage_context_wrapper.cc
index 1bbe8af..7ab88bb 100644
--- a/content/browser/dom_storage/dom_storage_context_wrapper.cc
+++ b/content/browser/dom_storage/dom_storage_context_wrapper.cc
@@ -11,8 +11,13 @@
#include "base/bind_helpers.h"
#include "base/files/file_path.h"
#include "base/location.h"
+#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
+#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h"
+#include "components/filesystem/public/interfaces/directory.mojom.h"
+#include "components/leveldb/public/interfaces/leveldb.mojom.h"
+#include "components/profile_service/public/interfaces/profile.mojom.h"
#include "content/browser/dom_storage/dom_storage_area.h"
#include "content/browser/dom_storage/dom_storage_context_impl.h"
#include "content/browser/dom_storage/dom_storage_task_runner.h"
@@ -20,7 +25,9 @@
#include "content/browser/leveldb_wrapper_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/local_storage_usage_info.h"
+#include "content/public/browser/mojo_app_connection.h"
#include "content/public/browser/session_storage_usage_info.h"
+#include "mojo/common/common_type_converters.h"
namespace content {
namespace {
@@ -66,9 +73,163 @@ void GetSessionStorageUsageHelper(
} // namespace
+// Used for mojo-based LocalStorage implementation (behind --mojo-local-storage
+// for now).
+class DOMStorageContextWrapper::MojoState {
+ public:
+ MojoState(const std::string& mojo_user_id, const base::FilePath& subdirectory)
+ : mojo_user_id_(mojo_user_id),
+ subdirectory_(subdirectory),
+ connection_state_(NO_CONNECTION),
+ weak_ptr_factory_(this) {}
+
+ void OpenLocalStorage(const url::Origin& origin,
+ LevelDBWrapperRequest request);
+
+ private:
+ void LevelDBWrapperImplHasNoBindings(const url::Origin& origin) {
+ DCHECK(level_db_wrappers_.find(origin) != level_db_wrappers_.end());
+ level_db_wrappers_.erase(origin);
+ }
+
+ // Part of our asynchronous directory opening called from OpenLocalStorage().
+ void OnDirectoryOpened(filesystem::FileError err);
+ void OnDatabaseOpened(leveldb::DatabaseError status);
+
+ // The (possibly delayed) implementation of OpenLocalStorage(). Can be called
+ // directly from that function, or through |on_database_open_callbacks_|.
+ void BindLocalStorage(const url::Origin& origin,
+ LevelDBWrapperRequest request);
+
+ // Maps between an origin and its prefixed LevelDB view.
+ std::map<url::Origin, scoped_ptr<LevelDBWrapperImpl>> level_db_wrappers_;
+
+ std::string mojo_user_id_;
+ base::FilePath subdirectory_;
+
+ enum ConnectionState {
+ NO_CONNECTION,
+ CONNECTION_IN_PROGRESS,
+ CONNECTION_FINISHED
+ } connection_state_;
+
+ scoped_ptr<MojoAppConnection> profile_app_connection_;
+ profile::ProfileServicePtr profile_service_;
+ filesystem::DirectoryPtr directory_;
+
+ leveldb::LevelDBServicePtr leveldb_service_;
+ leveldb::LevelDBDatabasePtr database_;
+
+ std::vector<base::Closure> on_database_opened_callbacks_;
+
+ base::WeakPtrFactory<MojoState> weak_ptr_factory_;
+};
+
+void DOMStorageContextWrapper::MojoState::OpenLocalStorage(
+ const url::Origin& origin,
+ LevelDBWrapperRequest request) {
+ // If we don't have a specific subdirectory where we want to put our data
+ // (ie, we're in incognito mode), just bind the storage with a null leveldb_
+ // database.
+ if (subdirectory_.empty()) {
+ BindLocalStorage(origin, std::move(request));
+ return;
+ }
+
+ // If we don't have a filesystem_connection_, we'll need to establish one.
+ if (connection_state_ == NO_CONNECTION) {
+ profile_app_connection_ = MojoAppConnection::Create(
+ mojo_user_id_, "mojo:profile", kBrowserMojoAppUrl);
+ profile_app_connection_->GetInterface(&profile_service_);
+
+ profile_service_->GetSubDirectory(
+ mojo::String::From(subdirectory_.AsUTF8Unsafe()),
+ GetProxy(&directory_),
+ base::Bind(&MojoState::OnDirectoryOpened,
+ weak_ptr_factory_.GetWeakPtr()));
+ connection_state_ = CONNECTION_IN_PROGRESS;
+ }
+
+ if (connection_state_ == CONNECTION_IN_PROGRESS) {
+ // Queue this OpenLocalStorage call for when we have a level db pointer.
+ on_database_opened_callbacks_.push_back(
+ base::Bind(&MojoState::BindLocalStorage, weak_ptr_factory_.GetWeakPtr(),
+ origin, base::Passed(&request)));
+ return;
+ }
+
+ BindLocalStorage(origin, std::move(request));
+}
+
+void DOMStorageContextWrapper::MojoState::OnDirectoryOpened(
+ filesystem::FileError err) {
+ if (err != filesystem::FileError::OK) {
+ // We failed to open the directory; continue with startup so that we create
+ // the |level_db_wrappers_|.
+ OnDatabaseOpened(leveldb::DatabaseError::IO_ERROR);
+ return;
+ }
+
+ // Now that we have a directory, connect to the LevelDB service and get our
+ // database.
+ profile_app_connection_->GetInterface(&leveldb_service_);
+
+ leveldb_service_->Open(
+ std::move(directory_), "leveldb", GetProxy(&database_),
+ base::Bind(&MojoState::OnDatabaseOpened, weak_ptr_factory_.GetWeakPtr()));
+}
+
+void DOMStorageContextWrapper::MojoState::OnDatabaseOpened(
+ leveldb::DatabaseError status) {
+ if (status != leveldb::DatabaseError::OK) {
+ // If we failed to open the database, reset the service object so we pass
+ // null pointers to our wrappers.
+ database_.reset();
+ leveldb_service_.reset();
+ }
+
+ // We no longer need the profile service; we've either transferred
+ // |directory_| to the leveldb service, or we got a file error and no more is
+ // possible.
+ directory_.reset();
+ profile_service_.reset();
+
+ // |leveldb_| should be known to either be valid or invalid by now. Run our
+ // delayed bindings.
+ connection_state_ = CONNECTION_FINISHED;
+ for (size_t i = 0; i < on_database_opened_callbacks_.size(); ++i)
+ on_database_opened_callbacks_[i].Run();
+ on_database_opened_callbacks_.clear();
+}
+
+void DOMStorageContextWrapper::MojoState::BindLocalStorage(
+ const url::Origin& origin,
+ LevelDBWrapperRequest request) {
+ if (level_db_wrappers_.find(origin) == level_db_wrappers_.end()) {
+ level_db_wrappers_[origin] = make_scoped_ptr(new LevelDBWrapperImpl(
+ database_.get(),
+ origin.Serialize(),
+ base::Bind(&MojoState::LevelDBWrapperImplHasNoBindings,
+ base::Unretained(this),
+ origin)));
+ }
+
+ level_db_wrappers_[origin]->Bind(std::move(request));
+}
+
DOMStorageContextWrapper::DOMStorageContextWrapper(
- const base::FilePath& data_path,
+ const std::string& mojo_user_id,
+ const base::FilePath& profile_path,
+ const base::FilePath& local_partition_path,
storage::SpecialStoragePolicy* special_storage_policy) {
+ base::FilePath storage_dir;
+ if (!profile_path.empty())
+ storage_dir = local_partition_path.AppendASCII(kLocalStorageDirectory);
+ mojo_state_.reset(new MojoState(mojo_user_id, storage_dir));
+
+ base::FilePath data_path;
+ if (!profile_path.empty())
+ data_path = profile_path.Append(local_partition_path);
base::SequencedWorkerPool* worker_pool = BrowserThread::GetBlockingPool();
context_ = new DOMStorageContextImpl(
data_path.empty() ? data_path
@@ -84,8 +245,7 @@ DOMStorageContextWrapper::DOMStorageContextWrapper(
.get()));
}
-DOMStorageContextWrapper::~DOMStorageContextWrapper() {
-}
+DOMStorageContextWrapper::~DOMStorageContextWrapper() {}
void DOMStorageContextWrapper::GetLocalStorageUsage(
const GetLocalStorageUsageCallback& callback) {
@@ -154,6 +314,7 @@ void DOMStorageContextWrapper::SetForceKeepSessionState() {
void DOMStorageContextWrapper::Shutdown() {
DCHECK(context_.get());
+ mojo_state_.reset();
context_->task_runner()->PostShutdownBlockingTask(
FROM_HERE,
DOMStorageTaskRunner::PRIMARY_SEQUENCE,
@@ -167,28 +328,9 @@ void DOMStorageContextWrapper::Flush() {
base::Bind(&DOMStorageContextImpl::Flush, context_));
}
-void DOMStorageContextWrapper::OpenLocalStorage(
- const url::Origin& origin,
- mojo::InterfaceRequest<LevelDBWrapper> request) {
- if (level_db_wrappers_.find(origin) == level_db_wrappers_.end()) {
- level_db_wrappers_[origin] = make_scoped_ptr(new LevelDBWrapperImpl(
- origin.Serialize(),
- base::Bind(&DOMStorageContextWrapper::LevelDBWrapperImplHasNoBindings,
- base::Unretained(this),
- origin)));
- }
- // TODO(jam): call LevelDB service (once per this object) to open the database
- // for LocalStorage and keep a pointer to it in this class. Then keep a map
- // from origins to LevelDBWrapper object. Each call here for the same origin
- // should use the same LevelDBWrapper object.
-
- level_db_wrappers_[origin]->Bind(std::move(request));
-}
-
-void DOMStorageContextWrapper::LevelDBWrapperImplHasNoBindings(
- const url::Origin& origin) {
- DCHECK(level_db_wrappers_.find(origin) != level_db_wrappers_.end());
- level_db_wrappers_.erase(origin);
+void DOMStorageContextWrapper::OpenLocalStorage(const url::Origin& origin,
+ LevelDBWrapperRequest request) {
+ mojo_state_->OpenLocalStorage(origin, std::move(request));
}
} // namespace content
diff --git a/content/browser/dom_storage/dom_storage_context_wrapper.h b/content/browser/dom_storage/dom_storage_context_wrapper.h
index 7ec0899..4de7f5f4 100644
--- a/content/browser/dom_storage/dom_storage_context_wrapper.h
+++ b/content/browser/dom_storage/dom_storage_context_wrapper.h
@@ -36,7 +36,9 @@ class CONTENT_EXPORT DOMStorageContextWrapper :
public:
// If |data_path| is empty, nothing will be saved to disk.
DOMStorageContextWrapper(
+ const std::string& mojo_user_id,
const base::FilePath& data_path,
+ const base::FilePath& local_partition_path,
storage::SpecialStoragePolicy* special_storage_policy);
// DOMStorageContext implementation.
@@ -63,9 +65,8 @@ class CONTENT_EXPORT DOMStorageContextWrapper :
void Flush();
// See StoragePartitionService interface.
- void OpenLocalStorage(
- const url::Origin& origin,
- mojo::InterfaceRequest<LevelDBWrapper> request);
+ void OpenLocalStorage(const url::Origin& origin,
+ LevelDBWrapperRequest request);
private:
friend class DOMStorageMessageFilter; // for access to context()
@@ -75,12 +76,10 @@ class CONTENT_EXPORT DOMStorageContextWrapper :
~DOMStorageContextWrapper() override;
DOMStorageContextImpl* context() const { return context_.get(); }
- void LevelDBWrapperImplHasNoBindings(const url::Origin& origin);
-
- // Used for mojo-based LocalStorage implementation (behind
- // --mojo-local-storage for now). Maps between an origin and its prefixed
- // LevelDB view.
- std::map<url::Origin, scoped_ptr<LevelDBWrapperImpl>> level_db_wrappers_;
+ // An inner class to keep all mojo-ish details together and not bleed them
+ // through the public interface.
+ class MojoState;
+ scoped_ptr<MojoState> mojo_state_;
scoped_refptr<DOMStorageContextImpl> context_;
diff --git a/content/browser/frame_host/frame_mojo_shell.cc b/content/browser/frame_host/frame_mojo_shell.cc
index 74a9f13..556bfc9 100644
--- a/content/browser/frame_host/frame_mojo_shell.cc
+++ b/content/browser/frame_host/frame_mojo_shell.cc
@@ -9,8 +9,10 @@
#include "build/build_config.h"
#include "content/browser/mojo/mojo_shell_context.h"
#include "content/common/mojo/service_registry_impl.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
#include "content/public/browser/site_instance.h"
#include "content/public/common/content_client.h"
#include "mojo/common/url_type_converters.h"
@@ -53,14 +55,13 @@ void FrameMojoShell::Connect(
mojo::shell::mojom::InterfaceProviderPtr /* exposed_services */,
mojo::shell::mojom::ClientProcessConnectionPtr client_process_connection,
const mojo::shell::mojom::Connector::ConnectCallback& callback) {
- // TODO(beng): user_id is dropped on the floor right now. Figure out what to
- // do with it.
mojo::shell::mojom::InterfaceProviderPtr frame_services;
service_provider_bindings_.AddBinding(GetServiceRegistry(),
GetProxy(&frame_services));
-
+ std::string mojo_user_id = BrowserContext::GetMojoUserIdFor(
+ frame_host_->GetProcess()->GetBrowserContext());
MojoShellContext::ConnectToApplication(
- target->name,
+ mojo_user_id, target->name,
frame_host_->GetSiteInstance()->GetSiteURL().spec(), std::move(services),
std::move(frame_services), callback);
}
diff --git a/content/browser/leveldb_wrapper_impl.cc b/content/browser/leveldb_wrapper_impl.cc
index dd8b283..623b728 100644
--- a/content/browser/leveldb_wrapper_impl.cc
+++ b/content/browser/leveldb_wrapper_impl.cc
@@ -9,46 +9,57 @@
namespace content {
LevelDBWrapperImpl::LevelDBWrapperImpl(
- const std::string& prefix, const base::Closure& no_bindings_callback)
- : prefix_(prefix), no_bindings_callback_(no_bindings_callback) {
+ leveldb::LevelDBDatabase* database,
+ const std::string& prefix,
+ const base::Closure& no_bindings_callback)
+ : prefix_(prefix),
+ no_bindings_callback_(no_bindings_callback),
+ database_(database) {
bindings_.set_connection_error_handler(base::Bind(
&LevelDBWrapperImpl::OnConnectionError, base::Unretained(this)));
}
-void LevelDBWrapperImpl::Bind(mojo::InterfaceRequest<LevelDBWrapper> request) {
+void LevelDBWrapperImpl::Bind(LevelDBWrapperRequest request) {
bindings_.AddBinding(this, std::move(request));
}
-LevelDBWrapperImpl::~LevelDBWrapperImpl() {
-}
+LevelDBWrapperImpl::~LevelDBWrapperImpl() {}
void LevelDBWrapperImpl::Put(mojo::Array<uint8_t> key,
mojo::Array<uint8_t> value,
const mojo::String& source,
const PutCallback& callback) {
- // TODO(jam): call observers before running callback.
+ NOTIMPLEMENTED();
+ callback.Run(leveldb::DatabaseError::NOT_SUPPORTED);
}
void LevelDBWrapperImpl::Delete(mojo::Array<uint8_t> key,
const mojo::String& source,
const DeleteCallback& callback) {
- // TODO(jam): call observers before running callback.
+ NOTIMPLEMENTED();
+ callback.Run(leveldb::DatabaseError::NOT_SUPPORTED);
}
void LevelDBWrapperImpl::DeleteAll(LevelDBObserverPtr observer,
const mojo::String& source,
const DeleteAllCallback& callback) {
// TODO(jam): store observer and call it when changes occur.
- // TODO(jam): call observers before running callback.
+ NOTIMPLEMENTED();
+ callback.Run(leveldb::DatabaseError::NOT_SUPPORTED);
}
void LevelDBWrapperImpl::Get(mojo::Array<uint8_t> key,
const GetCallback& callback) {
+ NOTIMPLEMENTED();
+ callback.Run(leveldb::DatabaseError::NOT_SUPPORTED, mojo::Array<uint8_t>());
}
void LevelDBWrapperImpl::GetAll(LevelDBObserverPtr observer,
const GetAllCallback& callback) {
// TODO(jam): store observer and call it when changes occur.
+ NOTIMPLEMENTED();
+ callback.Run(leveldb::DatabaseError::NOT_SUPPORTED,
+ mojo::Array<KeyValuePtr>());
}
void LevelDBWrapperImpl::OnConnectionError() {
diff --git a/content/browser/leveldb_wrapper_impl.h b/content/browser/leveldb_wrapper_impl.h
index 445fcaa..0aa5fcc 100644
--- a/content/browser/leveldb_wrapper_impl.h
+++ b/content/browser/leveldb_wrapper_impl.h
@@ -24,11 +24,12 @@ class LevelDBWrapperImpl : public LevelDBWrapper {
public:
// |no_bindings_callback| will be called when this object has no more
// bindings.
- LevelDBWrapperImpl(const std::string& prefix,
+ LevelDBWrapperImpl(leveldb::LevelDBDatabase* database,
+ const std::string& prefix,
const base::Closure& no_bindings_callback);
~LevelDBWrapperImpl() override;
- void Bind(mojo::InterfaceRequest<LevelDBWrapper> request);
+ void Bind(LevelDBWrapperRequest request);
private:
// LevelDBWrapperImpl:
@@ -51,6 +52,7 @@ class LevelDBWrapperImpl : public LevelDBWrapper {
std::string prefix_;
mojo::BindingSet<LevelDBWrapper> bindings_;
base::Closure no_bindings_callback_;
+ leveldb::LevelDBDatabase* database_;
DISALLOW_COPY_AND_ASSIGN(LevelDBWrapperImpl);
};
diff --git a/content/browser/mojo/mojo_app_connection_impl.cc b/content/browser/mojo/mojo_app_connection_impl.cc
index 5182971..b2941e2a 100644
--- a/content/browser/mojo/mojo_app_connection_impl.cc
+++ b/content/browser/mojo/mojo_app_connection_impl.cc
@@ -21,19 +21,20 @@ void OnGotInstanceID(mojo::shell::mojom::ConnectResult result,
// static
scoped_ptr<MojoAppConnection> MojoAppConnection::Create(
+ const std::string& user_id,
const std::string& name,
const std::string& requestor_name) {
return scoped_ptr<MojoAppConnection>(
- new MojoAppConnectionImpl(name, requestor_name));
+ new MojoAppConnectionImpl(user_id, name, requestor_name));
}
MojoAppConnectionImpl::MojoAppConnectionImpl(
+ const std::string& user_id,
const std::string& name,
const std::string& requestor_name) {
MojoShellContext::ConnectToApplication(
- name, requestor_name, mojo::GetProxy(&interfaces_),
- mojo::shell::mojom::InterfaceProviderPtr(),
- base::Bind(&OnGotInstanceID));
+ user_id, name, requestor_name, mojo::GetProxy(&interfaces_),
+ mojo::shell::mojom::InterfaceProviderPtr(), base::Bind(&OnGotInstanceID));
}
MojoAppConnectionImpl::~MojoAppConnectionImpl() {
diff --git a/content/browser/mojo/mojo_app_connection_impl.h b/content/browser/mojo/mojo_app_connection_impl.h
index 60caa12..5ed747b 100644
--- a/content/browser/mojo/mojo_app_connection_impl.h
+++ b/content/browser/mojo/mojo_app_connection_impl.h
@@ -14,7 +14,10 @@ namespace content {
// Implementation of the app connection mechanism provided to browser code.
class MojoAppConnectionImpl : public MojoAppConnection {
public:
- MojoAppConnectionImpl(const std::string& name,
+ // Takes a BrowserContext and derives a mojo userid from it for this
+ // connection.
+ MojoAppConnectionImpl(const std::string& user_id,
+ const std::string& name,
const std::string& requestor_name);
~MojoAppConnectionImpl() override;
diff --git a/content/browser/mojo/mojo_shell_context.cc b/content/browser/mojo/mojo_shell_context.cc
index 80857cd..2243806 100644
--- a/content/browser/mojo/mojo_shell_context.cc
+++ b/content/browser/mojo/mojo_shell_context.cc
@@ -6,6 +6,8 @@
#include <utility>
+#include "base/bind.h"
+#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/path_service.h"
@@ -14,6 +16,7 @@
#include "components/profile_service/profile_app.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/common/gpu/gpu_process_launch_causes.h"
+#include "content/common/mojo/current_thread_loader.h"
#include "content/common/mojo/mojo_shell_connection_impl.h"
#include "content/common/mojo/static_loader.h"
#include "content/common/process_control.mojom.h"
@@ -22,6 +25,7 @@
#include "content/public/browser/utility_process_host.h"
#include "content/public/browser/utility_process_host_client.h"
#include "content/public/common/content_client.h"
+#include "content/public/common/content_switches.h"
#include "content/public/common/service_registry.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/string.h"
@@ -160,6 +164,7 @@ class MojoShellContext::Proxy {
~Proxy() {}
void ConnectToApplication(
+ const std::string& user_id,
const std::string& name,
const std::string& requestor_name,
mojo::shell::mojom::InterfaceProviderRequest request,
@@ -168,7 +173,7 @@ class MojoShellContext::Proxy {
if (task_runner_ == base::ThreadTaskRunnerHandle::Get()) {
if (shell_context_) {
shell_context_->ConnectToApplicationOnOwnThread(
- name, requestor_name, std::move(request),
+ user_id, name, requestor_name, std::move(request),
std::move(exposed_services), callback);
}
} else {
@@ -177,9 +182,9 @@ class MojoShellContext::Proxy {
task_runner_->PostTask(
FROM_HERE,
base::Bind(&MojoShellContext::ConnectToApplicationOnOwnThread,
- base::Unretained(shell_context_), name, requestor_name,
- base::Passed(&request), base::Passed(&exposed_services),
- callback));
+ base::Unretained(shell_context_), user_id, name,
+ requestor_name, base::Passed(&request),
+ base::Passed(&exposed_services), callback));
}
}
@@ -199,7 +204,9 @@ void MojoShellContext::SetApplicationsForTest(
g_applications_for_test = apps;
}
-MojoShellContext::MojoShellContext() {
+MojoShellContext::MojoShellContext(
+ scoped_refptr<base::SingleThreadTaskRunner> file_thread,
+ scoped_refptr<base::SingleThreadTaskRunner> db_thread) {
proxy_.Get().reset(new Proxy(this));
scoped_refptr<base::SingleThreadTaskRunner> file_task_runner =
@@ -253,10 +260,14 @@ MojoShellContext::MojoShellContext() {
shell_->SetLoaderForName(make_scoped_ptr(new GpuProcessLoader), "mojo:media");
#endif
- base::Callback<scoped_ptr<mojo::ShellClient>()> profile_callback =
- base::Bind(&profile::CreateProfileApp);
- shell_->SetLoaderForName(
- make_scoped_ptr(new StaticLoader(profile_callback)), "mojo:profile");
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kMojoLocalStorage)) {
+ base::Callback<scoped_ptr<mojo::ShellClient>()> profile_callback =
+ base::Bind(&profile::CreateProfileApp, file_thread, db_thread);
+ shell_->SetLoaderForName(
+ make_scoped_ptr(new CurrentThreadLoader(profile_callback)),
+ "mojo:profile");
+ }
if (!IsRunningInMojoShell()) {
const bool is_external = false;
@@ -272,26 +283,28 @@ MojoShellContext::~MojoShellContext() {
// static
void MojoShellContext::ConnectToApplication(
+ const std::string& user_id,
const std::string& name,
const std::string& requestor_name,
mojo::shell::mojom::InterfaceProviderRequest request,
mojo::shell::mojom::InterfaceProviderPtr exposed_services,
const mojo::shell::mojom::Connector::ConnectCallback& callback) {
- proxy_.Get()->ConnectToApplication(name, requestor_name, std::move(request),
+ proxy_.Get()->ConnectToApplication(user_id, name, requestor_name,
+ std::move(request),
std::move(exposed_services), callback);
}
void MojoShellContext::ConnectToApplicationOnOwnThread(
+ const std::string& user_id,
const std::string& name,
const std::string& requestor_name,
mojo::shell::mojom::InterfaceProviderRequest request,
mojo::shell::mojom::InterfaceProviderPtr exposed_services,
const mojo::shell::mojom::Connector::ConnectCallback& callback) {
scoped_ptr<mojo::shell::ConnectParams> params(new mojo::shell::ConnectParams);
- // TODO(beng): kRootUserID is obviously wrong.
- mojo::Identity source_id(requestor_name, mojo::shell::mojom::kRootUserID);
+ mojo::Identity source_id(requestor_name, user_id);
params->set_source(source_id);
- params->set_target(mojo::Identity(name, mojo::shell::mojom::kRootUserID));
+ params->set_target(mojo::Identity(name, user_id));
params->set_remote_interfaces(std::move(request));
params->set_local_interfaces(std::move(exposed_services));
params->set_connect_callback(callback);
diff --git a/content/browser/mojo/mojo_shell_context.h b/content/browser/mojo/mojo_shell_context.h
index 3560364..fd8da40 100644
--- a/content/browser/mojo/mojo_shell_context.h
+++ b/content/browser/mojo/mojo_shell_context.h
@@ -12,6 +12,7 @@
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "base/single_thread_task_runner.h"
#include "content/common/content_export.h"
#include "mojo/shell/public/interfaces/connector.mojom.h"
#include "mojo/shell/shell.h"
@@ -33,7 +34,8 @@ class CONTENT_EXPORT MojoShellContext {
using StaticApplicationMap =
std::map<std::string, base::Callback<scoped_ptr<mojo::ShellClient>()>>;
- MojoShellContext();
+ MojoShellContext(scoped_refptr<base::SingleThreadTaskRunner> file_thread,
+ scoped_refptr<base::SingleThreadTaskRunner> db_thread);
~MojoShellContext();
// Connects an application at |name| and gets a handle to its exposed
@@ -41,6 +43,7 @@ class CONTENT_EXPORT MojoShellContext {
// some Mojo application. May be called from any thread. |requestor_name| is
// given to the target application as the requestor's name upon connection.
static void ConnectToApplication(
+ const std::string& user_id,
const std::string& name,
const std::string& requestor_name,
mojo::shell::mojom::InterfaceProviderRequest request,
@@ -54,6 +57,7 @@ class CONTENT_EXPORT MojoShellContext {
friend class Proxy;
void ConnectToApplicationOnOwnThread(
+ const std::string& user_id,
const std::string& name,
const std::string& requestor_name,
mojo::shell::mojom::InterfaceProviderRequest request,
diff --git a/content/browser/mojo_shell_browsertest.cc b/content/browser/mojo_shell_browsertest.cc
index 5e9eac1e..dfe8a06c 100644
--- a/content/browser/mojo_shell_browsertest.cc
+++ b/content/browser/mojo_shell_browsertest.cc
@@ -7,10 +7,13 @@
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "content/browser/mojo/mojo_shell_context.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/mojo_app_connection.h"
+#include "content/public/browser/web_contents.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/test_mojo_app.h"
#include "content/public/test/test_mojo_service.mojom.h"
+#include "content/shell/browser/shell.h"
#include "url/gurl.h"
namespace content {
@@ -24,6 +27,12 @@ class MojoShellTest : public ContentBrowserTest {
MojoShellContext::SetApplicationsForTest(&test_apps_);
}
+ protected:
+ std::string GetUserId() {
+ return BrowserContext::GetMojoUserIdFor(
+ shell()->web_contents()->GetBrowserContext());
+ }
+
private:
static scoped_ptr<mojo::ShellClient> CreateTestApp() {
return scoped_ptr<mojo::ShellClient>(new TestMojoApp);
@@ -35,8 +44,8 @@ class MojoShellTest : public ContentBrowserTest {
};
IN_PROC_BROWSER_TEST_F(MojoShellTest, TestBrowserConnection) {
- auto test_app = MojoAppConnection::Create(kInProcessTestMojoAppName,
- kBrowserMojoAppUrl);
+ auto test_app = MojoAppConnection::Create(
+ GetUserId(), kInProcessTestMojoAppName, kBrowserMojoAppUrl);
TestMojoServicePtr test_service;
test_app->GetInterface(&test_service);
@@ -49,7 +58,7 @@ IN_PROC_BROWSER_TEST_F(MojoShellTest, TestUtilityConnection) {
// With no loader registered at this URL, the shell should spawn a utility
// process and connect us to it. content_shell's utility process always hosts
// a TestMojoApp at |kTestMojoAppUrl|.
- auto test_app = MojoAppConnection::Create(kTestMojoAppUrl,
+ auto test_app = MojoAppConnection::Create(GetUserId(), kTestMojoAppUrl,
kBrowserMojoAppUrl);
TestMojoServicePtr test_service;
test_app->GetInterface(&test_service);
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index 7a9b90e..4b4a554 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -408,12 +408,15 @@ StoragePartitionImpl::~StoragePartitionImpl() {
StoragePartitionImpl* StoragePartitionImpl::Create(
BrowserContext* context,
bool in_memory,
- const base::FilePath& partition_path) {
+ const base::FilePath& relative_partition_path) {
// Ensure that these methods are called on the UI thread, except for
// unittests where a UI thread might not have been created.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
!BrowserThread::IsMessageLoopValid(BrowserThread::UI));
+ base::FilePath partition_path =
+ context->GetPath().Append(relative_partition_path);
+
// All of the clients have to be created and registered with the
// QuotaManager prior to the QuotaManger being used. We do them
// all together here prior to handing out a reference to anything
@@ -440,9 +443,11 @@ StoragePartitionImpl* StoragePartitionImpl::Create(
BrowserThread::GetMessageLoopProxyForThread(
BrowserThread::FILE).get());
- base::FilePath path = in_memory ? base::FilePath() : partition_path;
+ base::FilePath path = in_memory ? base::FilePath() : context->GetPath();
scoped_refptr<DOMStorageContextWrapper> dom_storage_context =
- new DOMStorageContextWrapper(path, context->GetSpecialStoragePolicy());
+ new DOMStorageContextWrapper(BrowserContext::GetMojoUserIdFor(context),
+ path, relative_partition_path,
+ context->GetSpecialStoragePolicy());
// BrowserMainLoop may not be initialized in unit tests. Tests will
// need to inject their own task runner into the IndexedDBContext.
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index d4bb809..1dc259a 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -131,15 +131,16 @@ class StoragePartitionImpl : public StoragePartition,
FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest,
RemoveLocalStorageForLastWeek);
- // The |partition_path| is the absolute path to the root of this
- // StoragePartition's on-disk storage.
+ // |relative_partition_path| is the relative path under |profile_path| to the
+ // StoragePartition's on-disk-storage.
//
- // If |in_memory| is true, the |partition_path| is (ab)used as a way of
- // distinguishing different in-memory partitions, but nothing is persisted
+ // If |in_memory| is true, the |relative_partition_path| is (ab)used as a way
+ // of distinguishing different in-memory partitions, but nothing is persisted
// on to disk.
- static StoragePartitionImpl* Create(BrowserContext* context,
- bool in_memory,
- const base::FilePath& profile_path);
+ static StoragePartitionImpl* Create(
+ BrowserContext* context,
+ bool in_memory,
+ const base::FilePath& relative_partition_path);
CONTENT_EXPORT StoragePartitionImpl(
BrowserContext* browser_context,
diff --git a/content/browser/storage_partition_impl_map.cc b/content/browser/storage_partition_impl_map.cc
index 7a0dd9c..4e98e17 100644
--- a/content/browser/storage_partition_impl_map.cc
+++ b/content/browser/storage_partition_impl_map.cc
@@ -396,12 +396,11 @@ StoragePartitionImpl* StoragePartitionImplMap::Get(
if (it != partitions_.end())
return it->second;
- base::FilePath partition_path =
- browser_context_->GetPath().Append(
- GetStoragePartitionPath(partition_domain, partition_name));
- StoragePartitionImpl* partition =
- StoragePartitionImpl::Create(browser_context_, in_memory,
- partition_path);
+ base::FilePath relative_partition_path =
+ GetStoragePartitionPath(partition_domain, partition_name);
+
+ StoragePartitionImpl* partition = StoragePartitionImpl::Create(
+ browser_context_, in_memory, relative_partition_path);
partitions_[partition_config] = partition;
partition->GetQuotaManager()->SetTemporaryStorageEvictionPolicy(
diff --git a/content/common/mojo/current_thread_loader.cc b/content/common/mojo/current_thread_loader.cc
new file mode 100644
index 0000000..eb64b15
--- /dev/null
+++ b/content/common/mojo/current_thread_loader.cc
@@ -0,0 +1,25 @@
+// Copyright 2016 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.
+
+#include "content/common/mojo/current_thread_loader.h"
+
+namespace content {
+
+CurrentThreadLoader::CurrentThreadLoader(const ApplicationFactory& factory)
+ : factory_(factory) {}
+
+CurrentThreadLoader::~CurrentThreadLoader() {}
+
+void CurrentThreadLoader::Load(const std::string& name,
+ mojo::shell::mojom::ShellClientRequest request) {
+ if (!shell_client_) {
+ shell_client_ = factory_.Run();
+ factory_ = ApplicationFactory();
+ }
+
+ connections_.push_back(make_scoped_ptr(
+ new mojo::ShellConnection(shell_client_.get(), std::move(request))));
+}
+
+} // namespace content
diff --git a/content/common/mojo/current_thread_loader.h b/content/common/mojo/current_thread_loader.h
new file mode 100644
index 0000000..e5e6e35
--- /dev/null
+++ b/content/common/mojo/current_thread_loader.h
@@ -0,0 +1,46 @@
+// Copyright 2016 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.
+
+#ifndef CONTENT_COMMON_MOJO_CURRENT_THREAD_LOADER_H_
+#define CONTENT_COMMON_MOJO_CURRENT_THREAD_LOADER_H_
+
+#include <vector>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "mojo/shell/loader.h"
+#include "mojo/shell/public/cpp/shell_client.h"
+#include "mojo/shell/public/cpp/shell_connection.h"
+
+namespace content {
+
+// A Loader which loads a single type of app from a mojo::ShellClientFactory on
+// the current thread.
+class CurrentThreadLoader : public mojo::shell::Loader {
+ public:
+ using ApplicationFactory = base::Callback<scoped_ptr<mojo::ShellClient>()>;
+
+ explicit CurrentThreadLoader(const ApplicationFactory& factory);
+ ~CurrentThreadLoader() override;
+
+ // mojo::shell::Loader:
+ void Load(const std::string& name,
+ mojo::shell::mojom::ShellClientRequest request) override;
+
+ private:
+ // The factory used to create new instances of the application delegate. This
+ // is called exactly once since all connections share a single client.
+ ApplicationFactory factory_;
+
+ // Our shared shell client, passed to each connection.
+ scoped_ptr<mojo::ShellClient> shell_client_;
+
+ std::vector<scoped_ptr<mojo::ShellConnection>> connections_;
+
+ DISALLOW_COPY_AND_ASSIGN(CurrentThreadLoader);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_MOJO_CURRENT_THREAD_LOADER_H_
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 67265b3..945fe25 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -7,6 +7,7 @@
'../base/base.gyp:base_static',
'../cc/cc.gyp:cc',
'../cc/cc.gyp:cc_surfaces',
+ '../components/leveldb/leveldb.gyp:leveldb_lib',
'../components/mime_util/mime_util.gyp:mime_util',
'../components/profile_service/profile_service.gyp:profile_service_lib',
'../components/scheduler/scheduler.gyp:scheduler_common',
diff --git a/content/content_common.gypi b/content/content_common.gypi
index 75fbe5f..48e67a6 100644
--- a/content/content_common.gypi
+++ b/content/content_common.gypi
@@ -519,6 +519,8 @@
'common/mime_registry_messages.h',
'common/mojo/channel_init.cc',
'common/mojo/channel_init.h',
+ 'common/mojo/current_thread_loader.cc',
+ 'common/mojo/current_thread_loader.h',
'common/mojo/mojo_messages.h',
'common/mojo/mojo_shell_connection_impl.cc',
'common/mojo/mojo_shell_connection_impl.h',
diff --git a/content/public/browser/mojo_app_connection.h b/content/public/browser/mojo_app_connection.h
index 3878825..6ac8055 100644
--- a/content/public/browser/mojo_app_connection.h
+++ b/content/public/browser/mojo_app_connection.h
@@ -28,9 +28,11 @@ class CONTENT_EXPORT MojoAppConnection {
virtual ~MojoAppConnection() {}
// Creates a new connection to the application at |name| using
- // |requestor_name| to identify the requestor upon connection. This may be
- // called from any thread.
+ // |requestor_name| to identify the requestor and |context|'s mojo userid to
+ // specify a profile specific application instantiation. This may be called
+ // from any thread.
static scoped_ptr<MojoAppConnection> Create(
+ const std::string& user_id,
const std::string& name,
const std::string& requestor_name);
diff --git a/mojo/mojo_services.gyp b/mojo/mojo_services.gyp
index d071c60..a42243187 100644
--- a/mojo/mojo_services.gyp
+++ b/mojo/mojo_services.gyp
@@ -76,7 +76,7 @@
},
{
# GN version: //mojo/services/tracing/public/interfaces
- 'target_name': 'tracing_service_bindings_lib',
+ 'target_name': 'tracing_service_bindings_lib',
'type': 'static_library',
'dependencies': [
'tracing_service_bindings_mojom',
diff --git a/mojo/shell/public/cpp/message_loop_ref.h b/mojo/shell/public/cpp/message_loop_ref.h
index fffb738..f678746 100644
--- a/mojo/shell/public/cpp/message_loop_ref.h
+++ b/mojo/shell/public/cpp/message_loop_ref.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MOJO_SHELL_PUBLIC_CPP_APPLICATION_RUNNER_REFERENCE_H_
-#define MOJO_SHELL_PUBLIC_CPP_APPLICATION_RUNNER_REFERENCE_H_
+#ifndef MOJO_SHELL_PUBLIC_CPP_MESSAGE_LOOP_REF_H_
+#define MOJO_SHELL_PUBLIC_CPP_MESSAGE_LOOP_REF_H_
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
@@ -54,4 +54,4 @@ class MessageLoopRefFactory {
} // namespace mojo
-#endif // MOJO_SHELL_PUBLIC_CPP_APPLICATION_RUNNER_REFERENCE_H_
+#endif // MOJO_SHELL_PUBLIC_CPP_MESSAGE_LOOP_REF_H_