Moar content MojoShellConnection/BrowserContext cleanup & bugfixes
. provide a means to go from shell user-id -> BC
. provide a means to change a BC's user-id
. make MojoChildConnection use the correct BC's Connector so the renderer gets created with the appropriate user-id.
. simplify the MojoShellConnection creation path.
. eliminate MojoAppConnection (unused)
. makes Navigation service derive BC from user-id, cleaning up content-specific initialization and isolating content code to ViewImpl.
[email protected]
Review-Url: https://codereview.chromium.org/2066583005
Cr-Commit-Position: refs/heads/master@{#400252}
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc
index 8fb13fa4..98c5ef6 100644
--- a/content/browser/browser_context.cc
+++ b/content/browser/browser_context.cc
@@ -52,21 +52,43 @@
namespace {
-base::LazyInstance<std::set<std::string>> g_used_user_ids =
- LAZY_INSTANCE_INITIALIZER;
-base::LazyInstance<std::vector<std::pair<BrowserContext*, std::string>>>
-g_context_to_user_id = LAZY_INSTANCE_INITIALIZER;
+base::LazyInstance<std::map<std::string, BrowserContext*>>
+ g_user_id_to_context = LAZY_INSTANCE_INITIALIZER;
+
+class ShellUserIdHolder : public base::SupportsUserData::Data {
+ public:
+ explicit ShellUserIdHolder(const std::string& user_id) : user_id_(user_id) {}
+ ~ShellUserIdHolder() override {}
+
+ const std::string& user_id() const { return user_id_; }
+
+ private:
+ std::string user_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(ShellUserIdHolder);
+};
// Key names on BrowserContext.
const char kDownloadManagerKeyName[] = "download_manager";
const char kMojoShellConnection[] = "mojo-shell-connection";
const char kMojoWasInitialized[] = "mojo-was-initialized";
+const char kMojoShellUserId[] = "mojo-shell-user-id";
const char kStoragePartitionMapKeyName[] = "content_storage_partition_map";
#if defined(OS_CHROMEOS)
const char kMountPointsKey[] = "mount_points";
#endif // defined(OS_CHROMEOS)
+void RemoveBrowserContextFromUserIdMap(BrowserContext* browser_context) {
+ ShellUserIdHolder* holder = static_cast<ShellUserIdHolder*>(
+ browser_context->GetUserData(kMojoShellUserId));
+ if (holder) {
+ auto it = g_user_id_to_context.Get().find(holder->user_id());
+ if (it != g_user_id_to_context.Get().end())
+ g_user_id_to_context.Get().erase(it);
+ }
+}
+
StoragePartitionImplMap* GetStoragePartitionMap(
BrowserContext* browser_context) {
StoragePartitionImplMap* partition_map =
@@ -129,8 +151,7 @@
std::unique_ptr<shell::Connection> connection,
shell::mojom::ShellClientRequest request)
: root_connection_(std::move(connection)),
- shell_connection_(MojoShellConnection::CreateInstance(
- std::move(request))) {}
+ shell_connection_(MojoShellConnection::Create(std::move(request))) {}
~BrowserContextShellConnectionHolder() override {}
MojoShellConnection* shell_connection() { return shell_connection_.get(); }
@@ -366,19 +387,30 @@
void BrowserContext::Initialize(
BrowserContext* browser_context,
const base::FilePath& path) {
- // Generate a GUID for |browser_context| to use as the Mojo user id.
- std::string new_id = base::GenerateGUID();
- while (g_used_user_ids.Get().find(new_id) != g_used_user_ids.Get().end())
+
+ std::string new_id;
+ if (GetContentClient() && GetContentClient()->browser()) {
+ new_id = GetContentClient()->browser()->GetShellUserIdForBrowserContext(
+ browser_context);
+ } else {
+ // Some test scenarios initialize a BrowserContext without a content client.
new_id = base::GenerateGUID();
+ }
- g_used_user_ids.Get().insert(new_id);
- g_context_to_user_id.Get().push_back(std::make_pair(browser_context, new_id));
+ ShellUserIdHolder* holder = static_cast<ShellUserIdHolder*>(
+ browser_context->GetUserData(kMojoShellUserId));
+ if (holder)
+ user_service::ForgetShellUserIdUserDirAssociation(holder->user_id());
+ user_service::AssociateShellUserIdWithUserDir(new_id, path);
+ RemoveBrowserContextFromUserIdMap(browser_context);
+ g_user_id_to_context.Get()[new_id] = browser_context;
+ browser_context->SetUserData(kMojoShellUserId,
+ new ShellUserIdHolder(new_id));
- user_service::AssociateMojoUserIDWithUserDir(new_id, path);
browser_context->SetUserData(kMojoWasInitialized,
new base::SupportsUserData::Data);
- MojoShellConnection* shell = MojoShellConnection::Get();
+ MojoShellConnection* shell = MojoShellConnection::GetForProcess();
if (shell) {
// NOTE: Many unit tests create a TestBrowserContext without initializing
// Mojo or the global Mojo shell connection.
@@ -417,23 +449,26 @@
}
// static
-const std::string& BrowserContext::GetMojoUserIdFor(
+const std::string& BrowserContext::GetShellUserIdFor(
BrowserContext* browser_context) {
CHECK(browser_context->GetUserData(kMojoWasInitialized))
<< "Attempting to get the mojo user id for a BrowserContext that was "
<< "never Initialize()ed.";
- auto it = std::find_if(
- g_context_to_user_id.Get().begin(),
- g_context_to_user_id.Get().end(),
- [&browser_context](const std::pair<BrowserContext*, std::string>& p) {
- return p.first == browser_context; });
- CHECK(it != g_context_to_user_id.Get().end());
- return it->second;
+ ShellUserIdHolder* holder = static_cast<ShellUserIdHolder*>(
+ browser_context->GetUserData(kMojoShellUserId));
+ return holder->user_id();
}
// static
-shell::Connector* BrowserContext::GetMojoConnectorFor(
+BrowserContext* BrowserContext::GetBrowserContextForShellUserId(
+ const std::string& user_id) {
+ auto it = g_user_id_to_context.Get().find(user_id);
+ return it != g_user_id_to_context.Get().end() ? it->second : nullptr;
+}
+
+// static
+shell::Connector* BrowserContext::GetShellConnectorFor(
BrowserContext* browser_context) {
BrowserContextShellConnectionHolder* connection_holder =
static_cast<BrowserContextShellConnectionHolder*>(
@@ -448,6 +483,8 @@
<< "Attempting to destroy a BrowserContext that never called "
<< "Initialize()";
+ RemoveBrowserContextFromUserIdMap(this);
+
if (GetUserData(kDownloadManagerKeyName))
GetDownloadManager(this)->Shutdown();
}