blob: 729df89e82c5aea8770db483dfdfbb6bdf806e55 [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"
bene1bbc002016-07-05 16:04:3643#include "services/shell/public/interfaces/service.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,
bene1bbc002016-07-05 16:04:36153 shell::mojom::ServiceRequest request)
rockot963ad3e82016-04-13 16:33:23154 : root_connection_(std::move(connection)),
rockotcef38272016-07-15 22:47:47155 shell_connection_(MojoShellConnection::Create(
156 std::move(request),
157 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO))) {}
rockot963ad3e82016-04-13 16:33:23158 ~BrowserContextShellConnectionHolder() override {}
159
ben146248de2016-06-14 15:24:59160 MojoShellConnection* shell_connection() { return shell_connection_.get(); }
rockot963ad3e82016-04-13 16:33:23161
162 private:
rockotb00e6462016-04-14 02:24:03163 std::unique_ptr<shell::Connection> root_connection_;
ben146248de2016-06-14 15:24:59164 std::unique_ptr<MojoShellConnection> shell_connection_;
rockot963ad3e82016-04-13 16:33:23165
166 DISALLOW_COPY_AND_ASSIGN(BrowserContextShellConnectionHolder);
167};
168
[email protected]735e20c2012-03-20 01:16:59169} // namespace
170
[email protected]14acc642012-11-17 12:20:10171// static
172void BrowserContext::AsyncObliterateStoragePartition(
173 BrowserContext* browser_context,
[email protected]399583b2012-12-11 09:33:42174 const GURL& site,
175 const base::Closure& on_gc_required) {
176 GetStoragePartitionMap(browser_context)->AsyncObliterate(site,
177 on_gc_required);
178}
179
180// static
181void BrowserContext::GarbageCollectStoragePartitions(
dcheng59716272016-04-09 05:19:08182 BrowserContext* browser_context,
183 std::unique_ptr<base::hash_set<base::FilePath>> active_paths,
184 const base::Closure& done) {
dcheng36b6aec92015-12-26 06:16:36185 GetStoragePartitionMap(browser_context)
186 ->GarbageCollect(std::move(active_paths), done);
[email protected]14acc642012-11-17 12:20:10187}
188
[email protected]b441a8492012-06-06 14:55:57189DownloadManager* BrowserContext::GetDownloadManager(
190 BrowserContext* context) {
mostynbfbcdc27a2015-03-13 17:58:52191 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]b441a8492012-06-06 14:55:57192 if (!context->GetUserData(kDownloadManagerKeyName)) {
[email protected]eba4a4d2013-05-29 02:18:06193 DownloadManager* download_manager =
[email protected]d25fda12012-06-12 17:05:03194 new DownloadManagerImpl(
[email protected]16798692013-04-23 18:08:38195 GetContentClient()->browser()->GetNetLog(), context);
[email protected]d25fda12012-06-12 17:05:03196
ttr31481dc54b2015-08-06 20:11:26197 SetDownloadManager(context, download_manager);
[email protected]b441a8492012-06-06 14:55:57198 download_manager->SetDelegate(context->GetDownloadManagerDelegate());
[email protected]b441a8492012-06-06 14:55:57199 }
200
[email protected]eba4a4d2013-05-29 02:18:06201 return static_cast<DownloadManager*>(
202 context->GetUserData(kDownloadManagerKeyName));
[email protected]b441a8492012-06-06 14:55:57203}
204
[email protected]6ef0c3912013-01-25 22:46:34205// static
[email protected]cd501a72014-08-22 19:58:31206storage::ExternalMountPoints* BrowserContext::GetMountPoints(
[email protected]6ef0c3912013-01-25 22:46:34207 BrowserContext* context) {
208 // Ensure that these methods are called on the UI thread, except for
209 // unittests where a UI thread might not have been created.
210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
211 !BrowserThread::IsMessageLoopValid(BrowserThread::UI));
212
213#if defined(OS_CHROMEOS)
214 if (!context->GetUserData(kMountPointsKey)) {
[email protected]cd501a72014-08-22 19:58:31215 scoped_refptr<storage::ExternalMountPoints> mount_points =
216 storage::ExternalMountPoints::CreateRefCounted();
[email protected]6ef0c3912013-01-25 22:46:34217 context->SetUserData(
218 kMountPointsKey,
[email protected]cd501a72014-08-22 19:58:31219 new UserDataAdapter<storage::ExternalMountPoints>(mount_points.get()));
[email protected]6ef0c3912013-01-25 22:46:34220 }
221
[email protected]cd501a72014-08-22 19:58:31222 return UserDataAdapter<storage::ExternalMountPoints>::Get(context,
223 kMountPointsKey);
[email protected]6ef0c3912013-01-25 22:46:34224#else
225 return NULL;
226#endif
227}
228
[email protected]4c3a23582012-08-18 08:54:34229StoragePartition* BrowserContext::GetStoragePartition(
230 BrowserContext* browser_context,
231 SiteInstance* site_instance) {
[email protected]1bc28312012-11-08 08:31:53232 std::string partition_domain;
233 std::string partition_name;
234 bool in_memory = false;
[email protected]4c3a23582012-08-18 08:54:34235
236 // TODO(ajwong): After GetDefaultStoragePartition() is removed, get rid of
237 // this conditional and require that |site_instance| is non-NULL.
238 if (site_instance) {
[email protected]1bc28312012-11-08 08:31:53239 GetContentClient()->browser()->GetStoragePartitionConfigForSite(
[email protected]14acc642012-11-17 12:20:10240 browser_context, site_instance->GetSiteURL(), true,
[email protected]1bc28312012-11-08 08:31:53241 &partition_domain, &partition_name, &in_memory);
[email protected]4c3a23582012-08-18 08:54:34242 }
243
[email protected]1bc28312012-11-08 08:31:53244 return GetStoragePartitionFromConfig(
245 browser_context, partition_domain, partition_name, in_memory);
[email protected]4c3a23582012-08-18 08:54:34246}
247
[email protected]e94bbcb2012-09-07 05:33:57248StoragePartition* BrowserContext::GetStoragePartitionForSite(
249 BrowserContext* browser_context,
250 const GURL& site) {
[email protected]1bc28312012-11-08 08:31:53251 std::string partition_domain;
252 std::string partition_name;
253 bool in_memory;
[email protected]e94bbcb2012-09-07 05:33:57254
[email protected]1bc28312012-11-08 08:31:53255 GetContentClient()->browser()->GetStoragePartitionConfigForSite(
[email protected]14acc642012-11-17 12:20:10256 browser_context, site, true, &partition_domain, &partition_name,
257 &in_memory);
[email protected]1bc28312012-11-08 08:31:53258
259 return GetStoragePartitionFromConfig(
260 browser_context, partition_domain, partition_name, in_memory);
[email protected]e94bbcb2012-09-07 05:33:57261}
262
[email protected]4c3a23582012-08-18 08:54:34263void BrowserContext::ForEachStoragePartition(
264 BrowserContext* browser_context,
265 const StoragePartitionCallback& callback) {
266 StoragePartitionImplMap* partition_map =
267 static_cast<StoragePartitionImplMap*>(
a.cavalcantiffab73762015-08-15 02:55:48268 browser_context->GetUserData(kStoragePartitionMapKeyName));
[email protected]4c3a23582012-08-18 08:54:34269 if (!partition_map)
270 return;
271
272 partition_map->ForEach(callback);
273}
274
275StoragePartition* BrowserContext::GetDefaultStoragePartition(
276 BrowserContext* browser_context) {
277 return GetStoragePartition(browser_context, NULL);
[email protected]55eb70e762012-02-20 17:38:39278}
279
tbarzicdb712682015-03-06 06:05:41280// static
[email protected]393b6cb2014-05-15 00:55:12281void BrowserContext::CreateMemoryBackedBlob(BrowserContext* browser_context,
282 const char* data, size_t length,
283 const BlobCallback& callback) {
mostynbfbcdc27a2015-03-13 17:58:52284 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]393b6cb2014-05-15 00:55:12285
286 ChromeBlobStorageContext* blob_context =
287 ChromeBlobStorageContext::GetFor(browser_context);
288 BrowserThread::PostTaskAndReplyWithResult(
289 BrowserThread::IO, FROM_HERE,
290 base::Bind(&ChromeBlobStorageContext::CreateMemoryBackedBlob,
291 make_scoped_refptr(blob_context), data, length),
292 callback);
293}
294
[email protected]66e53d0282014-08-07 10:04:35295// static
tbarzicdb712682015-03-06 06:05:41296void BrowserContext::CreateFileBackedBlob(
297 BrowserContext* browser_context,
298 const base::FilePath& path,
299 int64_t offset,
300 int64_t size,
301 const base::Time& expected_modification_time,
302 const BlobCallback& callback) {
mostynbfbcdc27a2015-03-13 17:58:52303 DCHECK_CURRENTLY_ON(BrowserThread::UI);
tbarzicdb712682015-03-06 06:05:41304
305 ChromeBlobStorageContext* blob_context =
306 ChromeBlobStorageContext::GetFor(browser_context);
307 BrowserThread::PostTaskAndReplyWithResult(
308 BrowserThread::IO, FROM_HERE,
309 base::Bind(&ChromeBlobStorageContext::CreateFileBackedBlob,
310 make_scoped_refptr(blob_context), path, offset, size,
311 expected_modification_time),
312 callback);
313}
314
315// static
[email protected]66e53d0282014-08-07 10:04:35316void BrowserContext::DeliverPushMessage(
317 BrowserContext* browser_context,
318 const GURL& origin,
avib7348942015-12-25 20:57:10319 int64_t service_worker_registration_id,
harknessdd4d2b22016-01-27 19:26:43320 const PushEventPayload& payload,
johnmea80c2552014-10-17 14:51:40321 const base::Callback<void(PushDeliveryStatus)>& callback) {
mostynbfbcdc27a2015-03-13 17:58:52322 DCHECK_CURRENTLY_ON(BrowserThread::UI);
harknessdd4d2b22016-01-27 19:26:43323 PushMessagingRouter::DeliverMessage(browser_context, origin,
324 service_worker_registration_id, payload,
325 callback);
[email protected]66e53d0282014-08-07 10:04:35326}
327
falken41f4175162014-10-29 07:03:41328// static
329void BrowserContext::NotifyWillBeDestroyed(BrowserContext* browser_context) {
330 // Service Workers must shutdown before the browser context is destroyed,
331 // since they keep render process hosts alive and the codebase assumes that
332 // render process hosts die before their profile (browser context) dies.
333 ForEachStoragePartition(browser_context,
334 base::Bind(ShutdownServiceWorkerContext));
335}
336
[email protected]314c3e22012-02-21 03:57:42337void BrowserContext::EnsureResourceContextInitialized(BrowserContext* context) {
[email protected]7e26ac92012-02-27 20:15:05338 // This will be enough to tickle initialization of BrowserContext if
339 // necessary, which initializes ResourceContext. The reason we don't call
[email protected]4c3a23582012-08-18 08:54:34340 // ResourceContext::InitializeResourceContext() directly here is that
341 // ResourceContext initialization may call back into BrowserContext
342 // and when that call returns it'll end rewriting its UserData map. It will
343 // end up rewriting the same value but this still causes a race condition.
344 //
345 // See http://crbug.com/115678.
346 GetDefaultStoragePartition(context);
[email protected]55eb70e762012-02-20 17:38:39347}
348
[email protected]6e2d3d22012-02-24 18:10:36349void BrowserContext::SaveSessionState(BrowserContext* browser_context) {
[email protected]5c8e67c2012-08-29 00:48:52350 GetDefaultStoragePartition(browser_context)->GetDatabaseTracker()->
351 SetForceKeepSessionState();
[email protected]b1b502e2012-09-16 07:31:43352 StoragePartition* storage_partition =
353 BrowserContext::GetDefaultStoragePartition(browser_context);
[email protected]6e2d3d22012-02-24 18:10:36354
355 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
356 BrowserThread::PostTask(
357 BrowserThread::IO, FROM_HERE,
[email protected]6939075a2012-08-28 08:35:53358 base::Bind(
359 &SaveSessionStateOnIOThread,
jamb84299e2016-04-12 16:58:59360 make_scoped_refptr(BrowserContext::GetDefaultStoragePartition(
361 browser_context)->GetURLRequestContext()),
[email protected]98d6d4562014-06-25 20:57:55362 static_cast<AppCacheServiceImpl*>(
[email protected]63ef85512014-06-05 14:21:26363 storage_partition->GetAppCacheService())));
[email protected]6e2d3d22012-02-24 18:10:36364 }
365
[email protected]5f2aa722013-08-07 16:59:41366 DOMStorageContextWrapper* dom_storage_context_proxy =
367 static_cast<DOMStorageContextWrapper*>(
[email protected]b1b502e2012-09-16 07:31:43368 storage_partition->GetDOMStorageContext());
[email protected]5f2aa722013-08-07 16:59:41369 dom_storage_context_proxy->SetForceKeepSessionState();
[email protected]735e20c2012-03-20 01:16:59370
[email protected]89acda82013-06-25 20:52:50371 IndexedDBContextImpl* indexed_db_context_impl =
372 static_cast<IndexedDBContextImpl*>(
[email protected]b1b502e2012-09-16 07:31:43373 storage_partition->GetIndexedDBContext());
[email protected]89acda82013-06-25 20:52:50374 // No task runner in unit tests.
375 if (indexed_db_context_impl->TaskRunner()) {
376 indexed_db_context_impl->TaskRunner()->PostTask(
377 FROM_HERE,
378 base::Bind(&SaveSessionStateOnIndexedDBThread,
379 make_scoped_refptr(indexed_db_context_impl)));
[email protected]6e2d3d22012-02-24 18:10:36380 }
381}
382
ttr31481dc54b2015-08-06 20:11:26383void BrowserContext::SetDownloadManagerForTesting(
384 BrowserContext* browser_context,
385 DownloadManager* download_manager) {
386 SetDownloadManager(browser_context, download_manager);
387}
388
rockot963ad3e82016-04-13 16:33:23389// static
erge69130f52016-03-02 00:13:28390void BrowserContext::Initialize(
391 BrowserContext* browser_context,
392 const base::FilePath& path) {
ben6c85c4492016-06-16 20:40:51393
394 std::string new_id;
395 if (GetContentClient() && GetContentClient()->browser()) {
396 new_id = GetContentClient()->browser()->GetShellUserIdForBrowserContext(
397 browser_context);
398 } else {
399 // Some test scenarios initialize a BrowserContext without a content client.
bencccfe2a2016-03-05 16:54:14400 new_id = base::GenerateGUID();
ben6c85c4492016-06-16 20:40:51401 }
erge69130f52016-03-02 00:13:28402
ben6c85c4492016-06-16 20:40:51403 ShellUserIdHolder* holder = static_cast<ShellUserIdHolder*>(
404 browser_context->GetUserData(kMojoShellUserId));
405 if (holder)
406 user_service::ForgetShellUserIdUserDirAssociation(holder->user_id());
407 user_service::AssociateShellUserIdWithUserDir(new_id, path);
408 RemoveBrowserContextFromUserIdMap(browser_context);
409 g_user_id_to_context.Get()[new_id] = browser_context;
410 browser_context->SetUserData(kMojoShellUserId,
411 new ShellUserIdHolder(new_id));
erge69130f52016-03-02 00:13:28412
erge69130f52016-03-02 00:13:28413 browser_context->SetUserData(kMojoWasInitialized,
414 new base::SupportsUserData::Data);
rockot963ad3e82016-04-13 16:33:23415
ben6c85c4492016-06-16 20:40:51416 MojoShellConnection* shell = MojoShellConnection::GetForProcess();
ben99cf17e2016-07-01 20:40:07417 if (shell && base::MessageLoop::current()) {
rockot963ad3e82016-04-13 16:33:23418 // NOTE: Many unit tests create a TestBrowserContext without initializing
419 // Mojo or the global Mojo shell connection.
420
bene1bbc002016-07-05 16:04:36421 shell::mojom::ServicePtr service;
422 shell::mojom::ServiceRequest service_request = mojo::GetProxy(&service);
rockot963ad3e82016-04-13 16:33:23423
rockotb00e6462016-04-14 02:24:03424 shell::mojom::PIDReceiverPtr pid_receiver;
425 shell::Connector::ConnectParams params(
426 shell::Identity(kBrowserMojoApplicationName, new_id));
bene1bbc002016-07-05 16:04:36427 params.set_client_process_connection(std::move(service),
rockot963ad3e82016-04-13 16:33:23428 mojo::GetProxy(&pid_receiver));
429 pid_receiver->SetPID(base::GetCurrentProcId());
430
431 BrowserContextShellConnectionHolder* connection_holder =
432 new BrowserContextShellConnectionHolder(
433 shell->GetConnector()->Connect(&params),
bene1bbc002016-07-05 16:04:36434 std::move(service_request));
rockot963ad3e82016-04-13 16:33:23435 browser_context->SetUserData(kMojoShellConnection, connection_holder);
436
ben146248de2016-06-14 15:24:59437 MojoShellConnection* connection = connection_holder->shell_connection();
rockotcef38272016-07-15 22:47:47438 connection->Start();
rockot963ad3e82016-04-13 16:33:23439
ben146248de2016-06-14 15:24:59440 // New embedded service factories should be added to |connection| here.
rockot963ad3e82016-04-13 16:33:23441
442 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
443 switches::kMojoLocalStorage)) {
rockot017f0ef2016-05-16 17:15:52444 MojoApplicationInfo info;
thestig529ad8a2016-07-08 20:30:12445 info.application_factory =
446 base::Bind(&user_service::CreateUserService,
447 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE),
448 BrowserThread::GetTaskRunnerForThread(BrowserThread::DB));
ben146248de2016-06-14 15:24:59449 connection->AddEmbeddedService(user_service::kUserServiceName, info);
rockot963ad3e82016-04-13 16:33:23450 }
451 }
erge69130f52016-03-02 00:13:28452}
453
rockot963ad3e82016-04-13 16:33:23454// static
ben6c85c4492016-06-16 20:40:51455const std::string& BrowserContext::GetShellUserIdFor(
bencccfe2a2016-03-05 16:54:14456 BrowserContext* browser_context) {
erge69130f52016-03-02 00:13:28457 CHECK(browser_context->GetUserData(kMojoWasInitialized))
458 << "Attempting to get the mojo user id for a BrowserContext that was "
459 << "never Initialize()ed.";
460
ben6c85c4492016-06-16 20:40:51461 ShellUserIdHolder* holder = static_cast<ShellUserIdHolder*>(
462 browser_context->GetUserData(kMojoShellUserId));
463 return holder->user_id();
erge69130f52016-03-02 00:13:28464}
465
rockot963ad3e82016-04-13 16:33:23466// static
ben6c85c4492016-06-16 20:40:51467BrowserContext* BrowserContext::GetBrowserContextForShellUserId(
468 const std::string& user_id) {
469 auto it = g_user_id_to_context.Get().find(user_id);
470 return it != g_user_id_to_context.Get().end() ? it->second : nullptr;
471}
472
473// static
474shell::Connector* BrowserContext::GetShellConnectorFor(
rockot963ad3e82016-04-13 16:33:23475 BrowserContext* browser_context) {
476 BrowserContextShellConnectionHolder* connection_holder =
477 static_cast<BrowserContextShellConnectionHolder*>(
478 browser_context->GetUserData(kMojoShellConnection));
479 if (!connection_holder)
480 return nullptr;
481 return connection_holder->shell_connection()->GetConnector();
482}
483
[email protected]55eb70e762012-02-20 17:38:39484BrowserContext::~BrowserContext() {
erge69130f52016-03-02 00:13:28485 CHECK(GetUserData(kMojoWasInitialized))
486 << "Attempting to destroy a BrowserContext that never called "
487 << "Initialize()";
488
ben6c85c4492016-06-16 20:40:51489 RemoveBrowserContextFromUserIdMap(this);
490
[email protected]b441a8492012-06-06 14:55:57491 if (GetUserData(kDownloadManagerKeyName))
492 GetDownloadManager(this)->Shutdown();
[email protected]55eb70e762012-02-20 17:38:39493}
494
[email protected]55eb70e762012-02-20 17:38:39495} // namespace content