blob: b0251f2d41d5a9d4e79ff943724983281db0bf53 [file] [log] [blame]
[email protected]55eb70e762012-02-20 17:38:391// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/public/browser/browser_context.h"
6
avib7348942015-12-25 20:57:107#include <stddef.h>
8#include <stdint.h>
erge69130f52016-03-02 00:13:289#include <algorithm>
10#include <limits>
rockot963ad3e82016-04-13 16:33:2311#include <memory>
dcheng36b6aec92015-12-26 06:16:3612#include <utility>
rockot963ad3e82016-04-13 16:33:2313#include <vector>
avib7348942015-12-25 20:57:1014
rockot963ad3e82016-04-13 16:33:2315#include "base/command_line.h"
bencccfe2a2016-03-05 16:54:1416#include "base/guid.h"
erge69130f52016-03-02 00:13:2817#include "base/lazy_instance.h"
rockot963ad3e82016-04-13 16:33:2318#include "base/macros.h"
erge69130f52016-03-02 00:13:2819#include "base/rand_util.h"
ben21a34c252016-06-29 22:24:3720#include "base/threading/thread_task_runner_handle.h"
avib7348942015-12-25 20:57:1021#include "build/build_config.h"
dmurph7ac019a2016-05-13 00:13:1722#include "content/browser/blob_storage/chrome_blob_storage_context.h"
[email protected]b441a8492012-06-06 14:55:5723#include "content/browser/download/download_manager_impl.h"
[email protected]c4d281662013-03-31 00:35:0824#include "content/browser/indexed_db/indexed_db_context_impl.h"
[email protected]678c0362012-12-05 08:02:4425#include "content/browser/loader/resource_dispatcher_host_impl.h"
rockot963ad3e82016-04-13 16:33:2326#include "content/browser/mojo/constants.h"
mvanouwerkerk17205ea2014-11-07 17:30:1527#include "content/browser/push_messaging/push_messaging_router.h"
[email protected]4c3a23582012-08-18 08:54:3428#include "content/browser/storage_partition_impl_map.h"
[email protected]d7c7c98a2012-07-12 21:27:4429#include "content/common/child_process_host_impl.h"
[email protected]393b6cb2014-05-15 00:55:1230#include "content/public/browser/blob_handle.h"
[email protected]55eb70e762012-02-20 17:38:3931#include "content/public/browser/browser_thread.h"
[email protected]b441a8492012-06-06 14:55:5732#include "content/public/browser/content_browser_client.h"
[email protected]536fd0b2013-03-14 17:41:5733#include "content/public/browser/site_instance.h"
rockot963ad3e82016-04-13 16:33:2334#include "content/public/common/content_switches.h"
35#include "content/public/common/mojo_shell_connection.h"
[email protected]4d7c4ef2012-03-16 01:47:1236#include "net/cookies/cookie_store.h"
[email protected]6b8a3c742014-07-25 00:25:3537#include "net/ssl/channel_id_service.h"
38#include "net/ssl/channel_id_store.h"
[email protected]6e2d3d22012-02-24 18:10:3639#include "net/url_request/url_request_context.h"
[email protected]6939075a2012-08-28 08:35:5340#include "net/url_request/url_request_context_getter.h"
rockot963ad3e82016-04-13 16:33:2341#include "services/shell/public/cpp/connection.h"
42#include "services/shell/public/cpp/connector.h"
43#include "services/shell/public/interfaces/shell_client.mojom.h"
bendbc8f972016-04-13 22:29:3044#include "services/user/public/cpp/constants.h"
45#include "services/user/user_id_map.h"
46#include "services/user/user_shell_client.h"
pilgrime92c5fcd2014-09-10 23:31:2347#include "storage/browser/database/database_tracker.h"
48#include "storage/browser/fileapi/external_mount_points.h"
[email protected]55eb70e762012-02-20 17:38:3949
[email protected]314c3e22012-02-21 03:57:4250using base::UserDataAdapter;
[email protected]55eb70e762012-02-20 17:38:3951
[email protected]55eb70e762012-02-20 17:38:3952namespace content {
53
[email protected]735e20c2012-03-20 01:16:5954namespace {
55
ben6c85c4492016-06-16 20:40:5156base::LazyInstance<std::map<std::string, BrowserContext*>>
57 g_user_id_to_context = LAZY_INSTANCE_INITIALIZER;
58
59class ShellUserIdHolder : public base::SupportsUserData::Data {
60 public:
61 explicit ShellUserIdHolder(const std::string& user_id) : user_id_(user_id) {}
62 ~ShellUserIdHolder() override {}
63
64 const std::string& user_id() const { return user_id_; }
65
66 private:
67 std::string user_id_;
68
69 DISALLOW_COPY_AND_ASSIGN(ShellUserIdHolder);
70};
erge69130f52016-03-02 00:13:2871
[email protected]e0ce8a1e2012-09-18 10:26:3672// Key names on BrowserContext.
[email protected]6ef0c3912013-01-25 22:46:3473const char kDownloadManagerKeyName[] = "download_manager";
rockot963ad3e82016-04-13 16:33:2374const char kMojoShellConnection[] = "mojo-shell-connection";
erge69130f52016-03-02 00:13:2875const char kMojoWasInitialized[] = "mojo-was-initialized";
ben6c85c4492016-06-16 20:40:5176const char kMojoShellUserId[] = "mojo-shell-user-id";
rockot963ad3e82016-04-13 16:33:2377const char kStoragePartitionMapKeyName[] = "content_storage_partition_map";
erge69130f52016-03-02 00:13:2878
[email protected]9afc14e22013-09-25 22:34:1479#if defined(OS_CHROMEOS)
80const char kMountPointsKey[] = "mount_points";
81#endif // defined(OS_CHROMEOS)
82
ben6c85c4492016-06-16 20:40:5183void RemoveBrowserContextFromUserIdMap(BrowserContext* browser_context) {
84 ShellUserIdHolder* holder = static_cast<ShellUserIdHolder*>(
85 browser_context->GetUserData(kMojoShellUserId));
86 if (holder) {
87 auto it = g_user_id_to_context.Get().find(holder->user_id());
88 if (it != g_user_id_to_context.Get().end())
89 g_user_id_to_context.Get().erase(it);
90 }
91}
92
[email protected]14acc642012-11-17 12:20:1093StoragePartitionImplMap* GetStoragePartitionMap(
94 BrowserContext* browser_context) {
[email protected]4c3a23582012-08-18 08:54:3495 StoragePartitionImplMap* partition_map =
96 static_cast<StoragePartitionImplMap*>(
a.cavalcantiffab73762015-08-15 02:55:4897 browser_context->GetUserData(kStoragePartitionMapKeyName));
[email protected]d7c7c98a2012-07-12 21:27:4498 if (!partition_map) {
[email protected]4c3a23582012-08-18 08:54:3499 partition_map = new StoragePartitionImplMap(browser_context);
a.cavalcantiffab73762015-08-15 02:55:48100 browser_context->SetUserData(kStoragePartitionMapKeyName, partition_map);
[email protected]d7c7c98a2012-07-12 21:27:44101 }
[email protected]14acc642012-11-17 12:20:10102 return partition_map;
103}
104
105StoragePartition* GetStoragePartitionFromConfig(
106 BrowserContext* browser_context,
107 const std::string& partition_domain,
108 const std::string& partition_name,
109 bool in_memory) {
110 StoragePartitionImplMap* partition_map =
111 GetStoragePartitionMap(browser_context);
[email protected]d7c7c98a2012-07-12 21:27:44112
[email protected]1bc28312012-11-08 08:31:53113 if (browser_context->IsOffTheRecord())
114 in_memory = true;
115
[email protected]1bc28312012-11-08 08:31:53116 return partition_map->Get(partition_domain, partition_name, in_memory);
[email protected]d1198fd2012-08-13 22:50:19117}
118
[email protected]6939075a2012-08-28 08:35:53119void SaveSessionStateOnIOThread(
120 const scoped_refptr<net::URLRequestContextGetter>& context_getter,
[email protected]98d6d4562014-06-25 20:57:55121 AppCacheServiceImpl* appcache_service) {
[email protected]6939075a2012-08-28 08:35:53122 net::URLRequestContext* context = context_getter->GetURLRequestContext();
mmenkeded79da2016-02-06 08:28:51123 context->cookie_store()->SetForceKeepSessionState();
[email protected]6b8a3c742014-07-25 00:25:35124 context->channel_id_service()->GetChannelIDStore()->
[email protected]6939075a2012-08-28 08:35:53125 SetForceKeepSessionState();
126 appcache_service->set_force_keep_session_state();
[email protected]6e2d3d22012-02-24 18:10:36127}
128
[email protected]89acda82013-06-25 20:52:50129void SaveSessionStateOnIndexedDBThread(
[email protected]6e2d3d22012-02-24 18:10:36130 scoped_refptr<IndexedDBContextImpl> indexed_db_context) {
[email protected]bf510ed2012-06-05 08:31:43131 indexed_db_context->SetForceKeepSessionState();
[email protected]6e2d3d22012-02-24 18:10:36132}
133
falken41f4175162014-10-29 07:03:41134void ShutdownServiceWorkerContext(StoragePartition* partition) {
135 ServiceWorkerContextWrapper* wrapper =
136 static_cast<ServiceWorkerContextWrapper*>(
137 partition->GetServiceWorkerContext());
138 wrapper->process_manager()->Shutdown();
139}
140
ttr31481dc54b2015-08-06 20:11:26141void SetDownloadManager(BrowserContext* context,
142 content::DownloadManager* download_manager) {
143 DCHECK_CURRENTLY_ON(BrowserThread::UI);
144 DCHECK(download_manager);
145 context->SetUserData(kDownloadManagerKeyName, download_manager);
146}
147
rockot963ad3e82016-04-13 16:33:23148class BrowserContextShellConnectionHolder
149 : public base::SupportsUserData::Data {
150 public:
151 BrowserContextShellConnectionHolder(
rockotb00e6462016-04-14 02:24:03152 std::unique_ptr<shell::Connection> connection,
153 shell::mojom::ShellClientRequest request)
rockot963ad3e82016-04-13 16:33:23154 : root_connection_(std::move(connection)),
ben6c85c4492016-06-16 20:40:51155 shell_connection_(MojoShellConnection::Create(std::move(request))) {}
rockot963ad3e82016-04-13 16:33:23156 ~BrowserContextShellConnectionHolder() override {}
157
ben146248de2016-06-14 15:24:59158 MojoShellConnection* shell_connection() { return shell_connection_.get(); }
rockot963ad3e82016-04-13 16:33:23159
160 private:
rockotb00e6462016-04-14 02:24:03161 std::unique_ptr<shell::Connection> root_connection_;
ben146248de2016-06-14 15:24:59162 std::unique_ptr<MojoShellConnection> shell_connection_;
rockot963ad3e82016-04-13 16:33:23163
164 DISALLOW_COPY_AND_ASSIGN(BrowserContextShellConnectionHolder);
165};
166
[email protected]735e20c2012-03-20 01:16:59167} // namespace
168
[email protected]14acc642012-11-17 12:20:10169// static
170void BrowserContext::AsyncObliterateStoragePartition(
171 BrowserContext* browser_context,
[email protected]399583b2012-12-11 09:33:42172 const GURL& site,
173 const base::Closure& on_gc_required) {
174 GetStoragePartitionMap(browser_context)->AsyncObliterate(site,
175 on_gc_required);
176}
177
178// static
179void BrowserContext::GarbageCollectStoragePartitions(
dcheng59716272016-04-09 05:19:08180 BrowserContext* browser_context,
181 std::unique_ptr<base::hash_set<base::FilePath>> active_paths,
182 const base::Closure& done) {
dcheng36b6aec92015-12-26 06:16:36183 GetStoragePartitionMap(browser_context)
184 ->GarbageCollect(std::move(active_paths), done);
[email protected]14acc642012-11-17 12:20:10185}
186
[email protected]b441a8492012-06-06 14:55:57187DownloadManager* BrowserContext::GetDownloadManager(
188 BrowserContext* context) {
mostynbfbcdc27a2015-03-13 17:58:52189 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]b441a8492012-06-06 14:55:57190 if (!context->GetUserData(kDownloadManagerKeyName)) {
[email protected]eba4a4d2013-05-29 02:18:06191 DownloadManager* download_manager =
[email protected]d25fda12012-06-12 17:05:03192 new DownloadManagerImpl(
[email protected]16798692013-04-23 18:08:38193 GetContentClient()->browser()->GetNetLog(), context);
[email protected]d25fda12012-06-12 17:05:03194
ttr31481dc54b2015-08-06 20:11:26195 SetDownloadManager(context, download_manager);
[email protected]b441a8492012-06-06 14:55:57196 download_manager->SetDelegate(context->GetDownloadManagerDelegate());
[email protected]b441a8492012-06-06 14:55:57197 }
198
[email protected]eba4a4d2013-05-29 02:18:06199 return static_cast<DownloadManager*>(
200 context->GetUserData(kDownloadManagerKeyName));
[email protected]b441a8492012-06-06 14:55:57201}
202
[email protected]6ef0c3912013-01-25 22:46:34203// static
[email protected]cd501a72014-08-22 19:58:31204storage::ExternalMountPoints* BrowserContext::GetMountPoints(
[email protected]6ef0c3912013-01-25 22:46:34205 BrowserContext* context) {
206 // Ensure that these methods are called on the UI thread, except for
207 // unittests where a UI thread might not have been created.
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
209 !BrowserThread::IsMessageLoopValid(BrowserThread::UI));
210
211#if defined(OS_CHROMEOS)
212 if (!context->GetUserData(kMountPointsKey)) {
[email protected]cd501a72014-08-22 19:58:31213 scoped_refptr<storage::ExternalMountPoints> mount_points =
214 storage::ExternalMountPoints::CreateRefCounted();
[email protected]6ef0c3912013-01-25 22:46:34215 context->SetUserData(
216 kMountPointsKey,
[email protected]cd501a72014-08-22 19:58:31217 new UserDataAdapter<storage::ExternalMountPoints>(mount_points.get()));
[email protected]6ef0c3912013-01-25 22:46:34218 }
219
[email protected]cd501a72014-08-22 19:58:31220 return UserDataAdapter<storage::ExternalMountPoints>::Get(context,
221 kMountPointsKey);
[email protected]6ef0c3912013-01-25 22:46:34222#else
223 return NULL;
224#endif
225}
226
[email protected]4c3a23582012-08-18 08:54:34227StoragePartition* BrowserContext::GetStoragePartition(
228 BrowserContext* browser_context,
229 SiteInstance* site_instance) {
[email protected]1bc28312012-11-08 08:31:53230 std::string partition_domain;
231 std::string partition_name;
232 bool in_memory = false;
[email protected]4c3a23582012-08-18 08:54:34233
234 // TODO(ajwong): After GetDefaultStoragePartition() is removed, get rid of
235 // this conditional and require that |site_instance| is non-NULL.
236 if (site_instance) {
[email protected]1bc28312012-11-08 08:31:53237 GetContentClient()->browser()->GetStoragePartitionConfigForSite(
[email protected]14acc642012-11-17 12:20:10238 browser_context, site_instance->GetSiteURL(), true,
[email protected]1bc28312012-11-08 08:31:53239 &partition_domain, &partition_name, &in_memory);
[email protected]4c3a23582012-08-18 08:54:34240 }
241
[email protected]1bc28312012-11-08 08:31:53242 return GetStoragePartitionFromConfig(
243 browser_context, partition_domain, partition_name, in_memory);
[email protected]4c3a23582012-08-18 08:54:34244}
245
[email protected]e94bbcb2012-09-07 05:33:57246StoragePartition* BrowserContext::GetStoragePartitionForSite(
247 BrowserContext* browser_context,
248 const GURL& site) {
[email protected]1bc28312012-11-08 08:31:53249 std::string partition_domain;
250 std::string partition_name;
251 bool in_memory;
[email protected]e94bbcb2012-09-07 05:33:57252
[email protected]1bc28312012-11-08 08:31:53253 GetContentClient()->browser()->GetStoragePartitionConfigForSite(
[email protected]14acc642012-11-17 12:20:10254 browser_context, site, true, &partition_domain, &partition_name,
255 &in_memory);
[email protected]1bc28312012-11-08 08:31:53256
257 return GetStoragePartitionFromConfig(
258 browser_context, partition_domain, partition_name, in_memory);
[email protected]e94bbcb2012-09-07 05:33:57259}
260
[email protected]4c3a23582012-08-18 08:54:34261void BrowserContext::ForEachStoragePartition(
262 BrowserContext* browser_context,
263 const StoragePartitionCallback& callback) {
264 StoragePartitionImplMap* partition_map =
265 static_cast<StoragePartitionImplMap*>(
a.cavalcantiffab73762015-08-15 02:55:48266 browser_context->GetUserData(kStoragePartitionMapKeyName));
[email protected]4c3a23582012-08-18 08:54:34267 if (!partition_map)
268 return;
269
270 partition_map->ForEach(callback);
271}
272
273StoragePartition* BrowserContext::GetDefaultStoragePartition(
274 BrowserContext* browser_context) {
275 return GetStoragePartition(browser_context, NULL);
[email protected]55eb70e762012-02-20 17:38:39276}
277
tbarzicdb712682015-03-06 06:05:41278// static
[email protected]393b6cb2014-05-15 00:55:12279void BrowserContext::CreateMemoryBackedBlob(BrowserContext* browser_context,
280 const char* data, size_t length,
281 const BlobCallback& callback) {
mostynbfbcdc27a2015-03-13 17:58:52282 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]393b6cb2014-05-15 00:55:12283
284 ChromeBlobStorageContext* blob_context =
285 ChromeBlobStorageContext::GetFor(browser_context);
286 BrowserThread::PostTaskAndReplyWithResult(
287 BrowserThread::IO, FROM_HERE,
288 base::Bind(&ChromeBlobStorageContext::CreateMemoryBackedBlob,
289 make_scoped_refptr(blob_context), data, length),
290 callback);
291}
292
[email protected]66e53d0282014-08-07 10:04:35293// static
tbarzicdb712682015-03-06 06:05:41294void BrowserContext::CreateFileBackedBlob(
295 BrowserContext* browser_context,
296 const base::FilePath& path,
297 int64_t offset,
298 int64_t size,
299 const base::Time& expected_modification_time,
300 const BlobCallback& callback) {
mostynbfbcdc27a2015-03-13 17:58:52301 DCHECK_CURRENTLY_ON(BrowserThread::UI);
tbarzicdb712682015-03-06 06:05:41302
303 ChromeBlobStorageContext* blob_context =
304 ChromeBlobStorageContext::GetFor(browser_context);
305 BrowserThread::PostTaskAndReplyWithResult(
306 BrowserThread::IO, FROM_HERE,
307 base::Bind(&ChromeBlobStorageContext::CreateFileBackedBlob,
308 make_scoped_refptr(blob_context), path, offset, size,
309 expected_modification_time),
310 callback);
311}
312
313// static
[email protected]66e53d0282014-08-07 10:04:35314void BrowserContext::DeliverPushMessage(
315 BrowserContext* browser_context,
316 const GURL& origin,
avib7348942015-12-25 20:57:10317 int64_t service_worker_registration_id,
harknessdd4d2b22016-01-27 19:26:43318 const PushEventPayload& payload,
johnmea80c2552014-10-17 14:51:40319 const base::Callback<void(PushDeliveryStatus)>& callback) {
mostynbfbcdc27a2015-03-13 17:58:52320 DCHECK_CURRENTLY_ON(BrowserThread::UI);
harknessdd4d2b22016-01-27 19:26:43321 PushMessagingRouter::DeliverMessage(browser_context, origin,
322 service_worker_registration_id, payload,
323 callback);
[email protected]66e53d0282014-08-07 10:04:35324}
325
falken41f4175162014-10-29 07:03:41326// static
327void BrowserContext::NotifyWillBeDestroyed(BrowserContext* browser_context) {
328 // Service Workers must shutdown before the browser context is destroyed,
329 // since they keep render process hosts alive and the codebase assumes that
330 // render process hosts die before their profile (browser context) dies.
331 ForEachStoragePartition(browser_context,
332 base::Bind(ShutdownServiceWorkerContext));
333}
334
[email protected]314c3e22012-02-21 03:57:42335void BrowserContext::EnsureResourceContextInitialized(BrowserContext* context) {
[email protected]7e26ac92012-02-27 20:15:05336 // This will be enough to tickle initialization of BrowserContext if
337 // necessary, which initializes ResourceContext. The reason we don't call
[email protected]4c3a23582012-08-18 08:54:34338 // ResourceContext::InitializeResourceContext() directly here is that
339 // ResourceContext initialization may call back into BrowserContext
340 // and when that call returns it'll end rewriting its UserData map. It will
341 // end up rewriting the same value but this still causes a race condition.
342 //
343 // See http://crbug.com/115678.
344 GetDefaultStoragePartition(context);
[email protected]55eb70e762012-02-20 17:38:39345}
346
[email protected]6e2d3d22012-02-24 18:10:36347void BrowserContext::SaveSessionState(BrowserContext* browser_context) {
[email protected]5c8e67c2012-08-29 00:48:52348 GetDefaultStoragePartition(browser_context)->GetDatabaseTracker()->
349 SetForceKeepSessionState();
[email protected]b1b502e2012-09-16 07:31:43350 StoragePartition* storage_partition =
351 BrowserContext::GetDefaultStoragePartition(browser_context);
[email protected]6e2d3d22012-02-24 18:10:36352
353 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
354 BrowserThread::PostTask(
355 BrowserThread::IO, FROM_HERE,
[email protected]6939075a2012-08-28 08:35:53356 base::Bind(
357 &SaveSessionStateOnIOThread,
jamb84299e2016-04-12 16:58:59358 make_scoped_refptr(BrowserContext::GetDefaultStoragePartition(
359 browser_context)->GetURLRequestContext()),
[email protected]98d6d4562014-06-25 20:57:55360 static_cast<AppCacheServiceImpl*>(
[email protected]63ef85512014-06-05 14:21:26361 storage_partition->GetAppCacheService())));
[email protected]6e2d3d22012-02-24 18:10:36362 }
363
[email protected]5f2aa722013-08-07 16:59:41364 DOMStorageContextWrapper* dom_storage_context_proxy =
365 static_cast<DOMStorageContextWrapper*>(
[email protected]b1b502e2012-09-16 07:31:43366 storage_partition->GetDOMStorageContext());
[email protected]5f2aa722013-08-07 16:59:41367 dom_storage_context_proxy->SetForceKeepSessionState();
[email protected]735e20c2012-03-20 01:16:59368
[email protected]89acda82013-06-25 20:52:50369 IndexedDBContextImpl* indexed_db_context_impl =
370 static_cast<IndexedDBContextImpl*>(
[email protected]b1b502e2012-09-16 07:31:43371 storage_partition->GetIndexedDBContext());
[email protected]89acda82013-06-25 20:52:50372 // No task runner in unit tests.
373 if (indexed_db_context_impl->TaskRunner()) {
374 indexed_db_context_impl->TaskRunner()->PostTask(
375 FROM_HERE,
376 base::Bind(&SaveSessionStateOnIndexedDBThread,
377 make_scoped_refptr(indexed_db_context_impl)));
[email protected]6e2d3d22012-02-24 18:10:36378 }
379}
380
ttr31481dc54b2015-08-06 20:11:26381void BrowserContext::SetDownloadManagerForTesting(
382 BrowserContext* browser_context,
383 DownloadManager* download_manager) {
384 SetDownloadManager(browser_context, download_manager);
385}
386
rockot963ad3e82016-04-13 16:33:23387// static
erge69130f52016-03-02 00:13:28388void BrowserContext::Initialize(
389 BrowserContext* browser_context,
390 const base::FilePath& path) {
ben6c85c4492016-06-16 20:40:51391
392 std::string new_id;
393 if (GetContentClient() && GetContentClient()->browser()) {
394 new_id = GetContentClient()->browser()->GetShellUserIdForBrowserContext(
395 browser_context);
396 } else {
397 // Some test scenarios initialize a BrowserContext without a content client.
bencccfe2a2016-03-05 16:54:14398 new_id = base::GenerateGUID();
ben6c85c4492016-06-16 20:40:51399 }
erge69130f52016-03-02 00:13:28400
ben6c85c4492016-06-16 20:40:51401 ShellUserIdHolder* holder = static_cast<ShellUserIdHolder*>(
402 browser_context->GetUserData(kMojoShellUserId));
403 if (holder)
404 user_service::ForgetShellUserIdUserDirAssociation(holder->user_id());
405 user_service::AssociateShellUserIdWithUserDir(new_id, path);
406 RemoveBrowserContextFromUserIdMap(browser_context);
407 g_user_id_to_context.Get()[new_id] = browser_context;
408 browser_context->SetUserData(kMojoShellUserId,
409 new ShellUserIdHolder(new_id));
erge69130f52016-03-02 00:13:28410
erge69130f52016-03-02 00:13:28411 browser_context->SetUserData(kMojoWasInitialized,
412 new base::SupportsUserData::Data);
rockot963ad3e82016-04-13 16:33:23413
ben6c85c4492016-06-16 20:40:51414 MojoShellConnection* shell = MojoShellConnection::GetForProcess();
ben21a34c252016-06-29 22:24:37415 if (shell && base::ThreadTaskRunnerHandle::Get()) {
rockot963ad3e82016-04-13 16:33:23416 // NOTE: Many unit tests create a TestBrowserContext without initializing
417 // Mojo or the global Mojo shell connection.
418
rockotb00e6462016-04-14 02:24:03419 shell::mojom::ShellClientPtr shell_client;
420 shell::mojom::ShellClientRequest shell_client_request =
rockot963ad3e82016-04-13 16:33:23421 mojo::GetProxy(&shell_client);
422
rockotb00e6462016-04-14 02:24:03423 shell::mojom::PIDReceiverPtr pid_receiver;
424 shell::Connector::ConnectParams params(
425 shell::Identity(kBrowserMojoApplicationName, new_id));
rockot963ad3e82016-04-13 16:33:23426 params.set_client_process_connection(std::move(shell_client),
427 mojo::GetProxy(&pid_receiver));
428 pid_receiver->SetPID(base::GetCurrentProcId());
429
430 BrowserContextShellConnectionHolder* connection_holder =
431 new BrowserContextShellConnectionHolder(
432 shell->GetConnector()->Connect(&params),
433 std::move(shell_client_request));
434 browser_context->SetUserData(kMojoShellConnection, connection_holder);
435
ben146248de2016-06-14 15:24:59436 MojoShellConnection* connection = connection_holder->shell_connection();
rockot963ad3e82016-04-13 16:33:23437
ben146248de2016-06-14 15:24:59438 // New embedded service factories should be added to |connection| here.
rockot963ad3e82016-04-13 16:33:23439
440 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
441 switches::kMojoLocalStorage)) {
rockot017f0ef2016-05-16 17:15:52442 MojoApplicationInfo info;
443 info.application_factory = base::Bind(
444 &user_service::CreateUserShellClient,
445 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
446 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB));
ben146248de2016-06-14 15:24:59447 connection->AddEmbeddedService(user_service::kUserServiceName, info);
rockot963ad3e82016-04-13 16:33:23448 }
449 }
erge69130f52016-03-02 00:13:28450}
451
rockot963ad3e82016-04-13 16:33:23452// static
ben6c85c4492016-06-16 20:40:51453const std::string& BrowserContext::GetShellUserIdFor(
bencccfe2a2016-03-05 16:54:14454 BrowserContext* browser_context) {
erge69130f52016-03-02 00:13:28455 CHECK(browser_context->GetUserData(kMojoWasInitialized))
456 << "Attempting to get the mojo user id for a BrowserContext that was "
457 << "never Initialize()ed.";
458
ben6c85c4492016-06-16 20:40:51459 ShellUserIdHolder* holder = static_cast<ShellUserIdHolder*>(
460 browser_context->GetUserData(kMojoShellUserId));
461 return holder->user_id();
erge69130f52016-03-02 00:13:28462}
463
rockot963ad3e82016-04-13 16:33:23464// static
ben6c85c4492016-06-16 20:40:51465BrowserContext* BrowserContext::GetBrowserContextForShellUserId(
466 const std::string& user_id) {
467 auto it = g_user_id_to_context.Get().find(user_id);
468 return it != g_user_id_to_context.Get().end() ? it->second : nullptr;
469}
470
471// static
472shell::Connector* BrowserContext::GetShellConnectorFor(
rockot963ad3e82016-04-13 16:33:23473 BrowserContext* browser_context) {
474 BrowserContextShellConnectionHolder* connection_holder =
475 static_cast<BrowserContextShellConnectionHolder*>(
476 browser_context->GetUserData(kMojoShellConnection));
477 if (!connection_holder)
478 return nullptr;
479 return connection_holder->shell_connection()->GetConnector();
480}
481
[email protected]55eb70e762012-02-20 17:38:39482BrowserContext::~BrowserContext() {
erge69130f52016-03-02 00:13:28483 CHECK(GetUserData(kMojoWasInitialized))
484 << "Attempting to destroy a BrowserContext that never called "
485 << "Initialize()";
486
ben6c85c4492016-06-16 20:40:51487 RemoveBrowserContextFromUserIdMap(this);
488
[email protected]b441a8492012-06-06 14:55:57489 if (GetUserData(kDownloadManagerKeyName))
490 GetDownloadManager(this)->Shutdown();
[email protected]55eb70e762012-02-20 17:38:39491}
492
[email protected]55eb70e762012-02-20 17:38:39493} // namespace content