blob: f5ec433add25adc2d7006cebb2225733007f7ffb [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"
mvanouwerkerk17205ea2014-11-07 17:30:1526#include "content/browser/push_messaging/push_messaging_router.h"
[email protected]4c3a23582012-08-18 08:54:3427#include "content/browser/storage_partition_impl_map.h"
[email protected]d7c7c98a2012-07-12 21:27:4428#include "content/common/child_process_host_impl.h"
[email protected]393b6cb2014-05-15 00:55:1229#include "content/public/browser/blob_handle.h"
[email protected]55eb70e762012-02-20 17:38:3930#include "content/public/browser/browser_thread.h"
[email protected]b441a8492012-06-06 14:55:5731#include "content/public/browser/content_browser_client.h"
falken04a6912a2016-09-23 21:06:2932#include "content/public/browser/render_process_host.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"
benc70c0e32016-09-22 03:50:3736#include "content/public/common/service_names.h"
[email protected]4d7c4ef2012-03-16 01:47:1237#include "net/cookies/cookie_store.h"
[email protected]6b8a3c742014-07-25 00:25:3538#include "net/ssl/channel_id_service.h"
39#include "net/ssl/channel_id_store.h"
[email protected]6e2d3d22012-02-24 18:10:3640#include "net/url_request/url_request_context.h"
[email protected]6939075a2012-08-28 08:35:5341#include "net/url_request/url_request_context_getter.h"
ben768c8dc2016-08-12 00:26:5042#include "services/file/file_service.h"
43#include "services/file/public/cpp/constants.h"
44#include "services/file/user_id_map.h"
rockot963ad3e82016-04-13 16:33:2345#include "services/shell/public/cpp/connection.h"
46#include "services/shell/public/cpp/connector.h"
bene1bbc002016-07-05 16:04:3647#include "services/shell/public/interfaces/service.mojom.h"
pilgrime92c5fcd2014-09-10 23:31:2348#include "storage/browser/database/database_tracker.h"
49#include "storage/browser/fileapi/external_mount_points.h"
[email protected]55eb70e762012-02-20 17:38:3950
[email protected]314c3e22012-02-21 03:57:4251using base::UserDataAdapter;
[email protected]55eb70e762012-02-20 17:38:3952
[email protected]55eb70e762012-02-20 17:38:3953namespace content {
54
[email protected]735e20c2012-03-20 01:16:5955namespace {
56
ben6c85c4492016-06-16 20:40:5157base::LazyInstance<std::map<std::string, BrowserContext*>>
58 g_user_id_to_context = LAZY_INSTANCE_INITIALIZER;
59
60class ShellUserIdHolder : public base::SupportsUserData::Data {
61 public:
62 explicit ShellUserIdHolder(const std::string& user_id) : user_id_(user_id) {}
63 ~ShellUserIdHolder() override {}
64
65 const std::string& user_id() const { return user_id_; }
66
67 private:
68 std::string user_id_;
69
70 DISALLOW_COPY_AND_ASSIGN(ShellUserIdHolder);
71};
erge69130f52016-03-02 00:13:2872
[email protected]e0ce8a1e2012-09-18 10:26:3673// Key names on BrowserContext.
[email protected]6ef0c3912013-01-25 22:46:3474const char kDownloadManagerKeyName[] = "download_manager";
rockot963ad3e82016-04-13 16:33:2375const char kMojoShellConnection[] = "mojo-shell-connection";
erge69130f52016-03-02 00:13:2876const char kMojoWasInitialized[] = "mojo-was-initialized";
ben6c85c4492016-06-16 20:40:5177const char kMojoShellUserId[] = "mojo-shell-user-id";
rockot963ad3e82016-04-13 16:33:2378const char kStoragePartitionMapKeyName[] = "content_storage_partition_map";
erge69130f52016-03-02 00:13:2879
[email protected]9afc14e22013-09-25 22:34:1480#if defined(OS_CHROMEOS)
81const char kMountPointsKey[] = "mount_points";
82#endif // defined(OS_CHROMEOS)
83
ben6c85c4492016-06-16 20:40:5184void RemoveBrowserContextFromUserIdMap(BrowserContext* browser_context) {
85 ShellUserIdHolder* holder = static_cast<ShellUserIdHolder*>(
86 browser_context->GetUserData(kMojoShellUserId));
87 if (holder) {
88 auto it = g_user_id_to_context.Get().find(holder->user_id());
89 if (it != g_user_id_to_context.Get().end())
90 g_user_id_to_context.Get().erase(it);
91 }
92}
93
[email protected]14acc642012-11-17 12:20:1094StoragePartitionImplMap* GetStoragePartitionMap(
95 BrowserContext* browser_context) {
[email protected]4c3a23582012-08-18 08:54:3496 StoragePartitionImplMap* partition_map =
97 static_cast<StoragePartitionImplMap*>(
a.cavalcantiffab73762015-08-15 02:55:4898 browser_context->GetUserData(kStoragePartitionMapKeyName));
[email protected]d7c7c98a2012-07-12 21:27:4499 if (!partition_map) {
[email protected]4c3a23582012-08-18 08:54:34100 partition_map = new StoragePartitionImplMap(browser_context);
a.cavalcantiffab73762015-08-15 02:55:48101 browser_context->SetUserData(kStoragePartitionMapKeyName, partition_map);
[email protected]d7c7c98a2012-07-12 21:27:44102 }
[email protected]14acc642012-11-17 12:20:10103 return partition_map;
104}
105
106StoragePartition* GetStoragePartitionFromConfig(
107 BrowserContext* browser_context,
108 const std::string& partition_domain,
109 const std::string& partition_name,
110 bool in_memory) {
111 StoragePartitionImplMap* partition_map =
112 GetStoragePartitionMap(browser_context);
[email protected]d7c7c98a2012-07-12 21:27:44113
[email protected]1bc28312012-11-08 08:31:53114 if (browser_context->IsOffTheRecord())
115 in_memory = true;
116
[email protected]1bc28312012-11-08 08:31:53117 return partition_map->Get(partition_domain, partition_name, in_memory);
[email protected]d1198fd2012-08-13 22:50:19118}
119
[email protected]6939075a2012-08-28 08:35:53120void SaveSessionStateOnIOThread(
121 const scoped_refptr<net::URLRequestContextGetter>& context_getter,
[email protected]98d6d4562014-06-25 20:57:55122 AppCacheServiceImpl* appcache_service) {
[email protected]6939075a2012-08-28 08:35:53123 net::URLRequestContext* context = context_getter->GetURLRequestContext();
mmenkeded79da2016-02-06 08:28:51124 context->cookie_store()->SetForceKeepSessionState();
[email protected]6b8a3c742014-07-25 00:25:35125 context->channel_id_service()->GetChannelIDStore()->
[email protected]6939075a2012-08-28 08:35:53126 SetForceKeepSessionState();
127 appcache_service->set_force_keep_session_state();
[email protected]6e2d3d22012-02-24 18:10:36128}
129
[email protected]89acda82013-06-25 20:52:50130void SaveSessionStateOnIndexedDBThread(
[email protected]6e2d3d22012-02-24 18:10:36131 scoped_refptr<IndexedDBContextImpl> indexed_db_context) {
[email protected]bf510ed2012-06-05 08:31:43132 indexed_db_context->SetForceKeepSessionState();
[email protected]6e2d3d22012-02-24 18:10:36133}
134
falken41f4175162014-10-29 07:03:41135void ShutdownServiceWorkerContext(StoragePartition* partition) {
136 ServiceWorkerContextWrapper* wrapper =
137 static_cast<ServiceWorkerContextWrapper*>(
138 partition->GetServiceWorkerContext());
139 wrapper->process_manager()->Shutdown();
140}
141
ttr31481dc54b2015-08-06 20:11:26142void SetDownloadManager(BrowserContext* context,
143 content::DownloadManager* download_manager) {
144 DCHECK_CURRENTLY_ON(BrowserThread::UI);
145 DCHECK(download_manager);
146 context->SetUserData(kDownloadManagerKeyName, download_manager);
147}
148
rockot963ad3e82016-04-13 16:33:23149class BrowserContextShellConnectionHolder
150 : public base::SupportsUserData::Data {
151 public:
152 BrowserContextShellConnectionHolder(
rockotb00e6462016-04-14 02:24:03153 std::unique_ptr<shell::Connection> connection,
bene1bbc002016-07-05 16:04:36154 shell::mojom::ServiceRequest request)
rockot963ad3e82016-04-13 16:33:23155 : root_connection_(std::move(connection)),
rockotcef38272016-07-15 22:47:47156 shell_connection_(MojoShellConnection::Create(
157 std::move(request),
158 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO))) {}
rockot963ad3e82016-04-13 16:33:23159 ~BrowserContextShellConnectionHolder() override {}
160
ben146248de2016-06-14 15:24:59161 MojoShellConnection* shell_connection() { return shell_connection_.get(); }
rockot963ad3e82016-04-13 16:33:23162
163 private:
rockotb00e6462016-04-14 02:24:03164 std::unique_ptr<shell::Connection> root_connection_;
ben146248de2016-06-14 15:24:59165 std::unique_ptr<MojoShellConnection> shell_connection_;
rockot963ad3e82016-04-13 16:33:23166
167 DISALLOW_COPY_AND_ASSIGN(BrowserContextShellConnectionHolder);
168};
169
[email protected]735e20c2012-03-20 01:16:59170} // namespace
171
[email protected]14acc642012-11-17 12:20:10172// static
173void BrowserContext::AsyncObliterateStoragePartition(
174 BrowserContext* browser_context,
[email protected]399583b2012-12-11 09:33:42175 const GURL& site,
176 const base::Closure& on_gc_required) {
177 GetStoragePartitionMap(browser_context)->AsyncObliterate(site,
178 on_gc_required);
179}
180
181// static
182void BrowserContext::GarbageCollectStoragePartitions(
dcheng59716272016-04-09 05:19:08183 BrowserContext* browser_context,
184 std::unique_ptr<base::hash_set<base::FilePath>> active_paths,
185 const base::Closure& done) {
dcheng36b6aec92015-12-26 06:16:36186 GetStoragePartitionMap(browser_context)
187 ->GarbageCollect(std::move(active_paths), done);
[email protected]14acc642012-11-17 12:20:10188}
189
[email protected]b441a8492012-06-06 14:55:57190DownloadManager* BrowserContext::GetDownloadManager(
191 BrowserContext* context) {
mostynbfbcdc27a2015-03-13 17:58:52192 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]b441a8492012-06-06 14:55:57193 if (!context->GetUserData(kDownloadManagerKeyName)) {
[email protected]eba4a4d2013-05-29 02:18:06194 DownloadManager* download_manager =
[email protected]d25fda12012-06-12 17:05:03195 new DownloadManagerImpl(
[email protected]16798692013-04-23 18:08:38196 GetContentClient()->browser()->GetNetLog(), context);
[email protected]d25fda12012-06-12 17:05:03197
ttr31481dc54b2015-08-06 20:11:26198 SetDownloadManager(context, download_manager);
[email protected]b441a8492012-06-06 14:55:57199 download_manager->SetDelegate(context->GetDownloadManagerDelegate());
[email protected]b441a8492012-06-06 14:55:57200 }
201
[email protected]eba4a4d2013-05-29 02:18:06202 return static_cast<DownloadManager*>(
203 context->GetUserData(kDownloadManagerKeyName));
[email protected]b441a8492012-06-06 14:55:57204}
205
[email protected]6ef0c3912013-01-25 22:46:34206// static
[email protected]cd501a72014-08-22 19:58:31207storage::ExternalMountPoints* BrowserContext::GetMountPoints(
[email protected]6ef0c3912013-01-25 22:46:34208 BrowserContext* context) {
209 // Ensure that these methods are called on the UI thread, except for
210 // unittests where a UI thread might not have been created.
211 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
212 !BrowserThread::IsMessageLoopValid(BrowserThread::UI));
213
214#if defined(OS_CHROMEOS)
215 if (!context->GetUserData(kMountPointsKey)) {
[email protected]cd501a72014-08-22 19:58:31216 scoped_refptr<storage::ExternalMountPoints> mount_points =
217 storage::ExternalMountPoints::CreateRefCounted();
[email protected]6ef0c3912013-01-25 22:46:34218 context->SetUserData(
219 kMountPointsKey,
[email protected]cd501a72014-08-22 19:58:31220 new UserDataAdapter<storage::ExternalMountPoints>(mount_points.get()));
[email protected]6ef0c3912013-01-25 22:46:34221 }
222
[email protected]cd501a72014-08-22 19:58:31223 return UserDataAdapter<storage::ExternalMountPoints>::Get(context,
224 kMountPointsKey);
[email protected]6ef0c3912013-01-25 22:46:34225#else
226 return NULL;
227#endif
228}
229
[email protected]4c3a23582012-08-18 08:54:34230StoragePartition* BrowserContext::GetStoragePartition(
231 BrowserContext* browser_context,
232 SiteInstance* site_instance) {
[email protected]1bc28312012-11-08 08:31:53233 std::string partition_domain;
234 std::string partition_name;
235 bool in_memory = false;
[email protected]4c3a23582012-08-18 08:54:34236
237 // TODO(ajwong): After GetDefaultStoragePartition() is removed, get rid of
238 // this conditional and require that |site_instance| is non-NULL.
239 if (site_instance) {
[email protected]1bc28312012-11-08 08:31:53240 GetContentClient()->browser()->GetStoragePartitionConfigForSite(
[email protected]14acc642012-11-17 12:20:10241 browser_context, site_instance->GetSiteURL(), true,
[email protected]1bc28312012-11-08 08:31:53242 &partition_domain, &partition_name, &in_memory);
[email protected]4c3a23582012-08-18 08:54:34243 }
244
[email protected]1bc28312012-11-08 08:31:53245 return GetStoragePartitionFromConfig(
246 browser_context, partition_domain, partition_name, in_memory);
[email protected]4c3a23582012-08-18 08:54:34247}
248
[email protected]e94bbcb2012-09-07 05:33:57249StoragePartition* BrowserContext::GetStoragePartitionForSite(
250 BrowserContext* browser_context,
251 const GURL& site) {
[email protected]1bc28312012-11-08 08:31:53252 std::string partition_domain;
253 std::string partition_name;
254 bool in_memory;
[email protected]e94bbcb2012-09-07 05:33:57255
[email protected]1bc28312012-11-08 08:31:53256 GetContentClient()->browser()->GetStoragePartitionConfigForSite(
[email protected]14acc642012-11-17 12:20:10257 browser_context, site, true, &partition_domain, &partition_name,
258 &in_memory);
[email protected]1bc28312012-11-08 08:31:53259
260 return GetStoragePartitionFromConfig(
261 browser_context, partition_domain, partition_name, in_memory);
[email protected]e94bbcb2012-09-07 05:33:57262}
263
[email protected]4c3a23582012-08-18 08:54:34264void BrowserContext::ForEachStoragePartition(
265 BrowserContext* browser_context,
266 const StoragePartitionCallback& callback) {
267 StoragePartitionImplMap* partition_map =
268 static_cast<StoragePartitionImplMap*>(
a.cavalcantiffab73762015-08-15 02:55:48269 browser_context->GetUserData(kStoragePartitionMapKeyName));
[email protected]4c3a23582012-08-18 08:54:34270 if (!partition_map)
271 return;
272
273 partition_map->ForEach(callback);
274}
275
276StoragePartition* BrowserContext::GetDefaultStoragePartition(
277 BrowserContext* browser_context) {
278 return GetStoragePartition(browser_context, NULL);
[email protected]55eb70e762012-02-20 17:38:39279}
280
tbarzicdb712682015-03-06 06:05:41281// static
[email protected]393b6cb2014-05-15 00:55:12282void BrowserContext::CreateMemoryBackedBlob(BrowserContext* browser_context,
283 const char* data, size_t length,
284 const BlobCallback& callback) {
mostynbfbcdc27a2015-03-13 17:58:52285 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]393b6cb2014-05-15 00:55:12286
287 ChromeBlobStorageContext* blob_context =
288 ChromeBlobStorageContext::GetFor(browser_context);
289 BrowserThread::PostTaskAndReplyWithResult(
290 BrowserThread::IO, FROM_HERE,
291 base::Bind(&ChromeBlobStorageContext::CreateMemoryBackedBlob,
292 make_scoped_refptr(blob_context), data, length),
293 callback);
294}
295
[email protected]66e53d0282014-08-07 10:04:35296// static
tbarzicdb712682015-03-06 06:05:41297void BrowserContext::CreateFileBackedBlob(
298 BrowserContext* browser_context,
299 const base::FilePath& path,
300 int64_t offset,
301 int64_t size,
302 const base::Time& expected_modification_time,
303 const BlobCallback& callback) {
mostynbfbcdc27a2015-03-13 17:58:52304 DCHECK_CURRENTLY_ON(BrowserThread::UI);
tbarzicdb712682015-03-06 06:05:41305
306 ChromeBlobStorageContext* blob_context =
307 ChromeBlobStorageContext::GetFor(browser_context);
308 BrowserThread::PostTaskAndReplyWithResult(
309 BrowserThread::IO, FROM_HERE,
310 base::Bind(&ChromeBlobStorageContext::CreateFileBackedBlob,
311 make_scoped_refptr(blob_context), path, offset, size,
312 expected_modification_time),
313 callback);
314}
315
316// static
[email protected]66e53d0282014-08-07 10:04:35317void BrowserContext::DeliverPushMessage(
318 BrowserContext* browser_context,
319 const GURL& origin,
avib7348942015-12-25 20:57:10320 int64_t service_worker_registration_id,
harknessdd4d2b22016-01-27 19:26:43321 const PushEventPayload& payload,
johnmea80c2552014-10-17 14:51:40322 const base::Callback<void(PushDeliveryStatus)>& callback) {
mostynbfbcdc27a2015-03-13 17:58:52323 DCHECK_CURRENTLY_ON(BrowserThread::UI);
harknessdd4d2b22016-01-27 19:26:43324 PushMessagingRouter::DeliverMessage(browser_context, origin,
325 service_worker_registration_id, payload,
326 callback);
[email protected]66e53d0282014-08-07 10:04:35327}
328
falken41f4175162014-10-29 07:03:41329// static
330void BrowserContext::NotifyWillBeDestroyed(BrowserContext* browser_context) {
331 // Service Workers must shutdown before the browser context is destroyed,
332 // since they keep render process hosts alive and the codebase assumes that
333 // render process hosts die before their profile (browser context) dies.
334 ForEachStoragePartition(browser_context,
335 base::Bind(ShutdownServiceWorkerContext));
falken04a6912a2016-09-23 21:06:29336
337 // Shared workers also keep render process hosts alive, and are expected to
338 // return ref counts to 0 after documents close. However, shared worker
339 // bookkeeping is done on the IO thread and we want to ensure the hosts are
340 // destructed now, so forcibly release their ref counts here.
341 for (RenderProcessHost::iterator host_iterator =
342 RenderProcessHost::AllHostsIterator();
343 !host_iterator.IsAtEnd(); host_iterator.Advance()) {
344 RenderProcessHost* host = host_iterator.GetCurrentValue();
345 if (host->GetBrowserContext() == browser_context)
346 host->ForceReleaseWorkerRefCounts();
347 }
falken41f4175162014-10-29 07:03:41348}
349
[email protected]314c3e22012-02-21 03:57:42350void BrowserContext::EnsureResourceContextInitialized(BrowserContext* context) {
[email protected]7e26ac92012-02-27 20:15:05351 // This will be enough to tickle initialization of BrowserContext if
352 // necessary, which initializes ResourceContext. The reason we don't call
[email protected]4c3a23582012-08-18 08:54:34353 // ResourceContext::InitializeResourceContext() directly here is that
354 // ResourceContext initialization may call back into BrowserContext
355 // and when that call returns it'll end rewriting its UserData map. It will
356 // end up rewriting the same value but this still causes a race condition.
357 //
358 // See http://crbug.com/115678.
359 GetDefaultStoragePartition(context);
[email protected]55eb70e762012-02-20 17:38:39360}
361
[email protected]6e2d3d22012-02-24 18:10:36362void BrowserContext::SaveSessionState(BrowserContext* browser_context) {
[email protected]5c8e67c2012-08-29 00:48:52363 GetDefaultStoragePartition(browser_context)->GetDatabaseTracker()->
364 SetForceKeepSessionState();
[email protected]b1b502e2012-09-16 07:31:43365 StoragePartition* storage_partition =
366 BrowserContext::GetDefaultStoragePartition(browser_context);
[email protected]6e2d3d22012-02-24 18:10:36367
368 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
369 BrowserThread::PostTask(
370 BrowserThread::IO, FROM_HERE,
[email protected]6939075a2012-08-28 08:35:53371 base::Bind(
372 &SaveSessionStateOnIOThread,
jamb84299e2016-04-12 16:58:59373 make_scoped_refptr(BrowserContext::GetDefaultStoragePartition(
374 browser_context)->GetURLRequestContext()),
[email protected]98d6d4562014-06-25 20:57:55375 static_cast<AppCacheServiceImpl*>(
[email protected]63ef85512014-06-05 14:21:26376 storage_partition->GetAppCacheService())));
[email protected]6e2d3d22012-02-24 18:10:36377 }
378
[email protected]5f2aa722013-08-07 16:59:41379 DOMStorageContextWrapper* dom_storage_context_proxy =
380 static_cast<DOMStorageContextWrapper*>(
[email protected]b1b502e2012-09-16 07:31:43381 storage_partition->GetDOMStorageContext());
[email protected]5f2aa722013-08-07 16:59:41382 dom_storage_context_proxy->SetForceKeepSessionState();
[email protected]735e20c2012-03-20 01:16:59383
[email protected]89acda82013-06-25 20:52:50384 IndexedDBContextImpl* indexed_db_context_impl =
385 static_cast<IndexedDBContextImpl*>(
[email protected]b1b502e2012-09-16 07:31:43386 storage_partition->GetIndexedDBContext());
[email protected]89acda82013-06-25 20:52:50387 // No task runner in unit tests.
388 if (indexed_db_context_impl->TaskRunner()) {
389 indexed_db_context_impl->TaskRunner()->PostTask(
390 FROM_HERE,
391 base::Bind(&SaveSessionStateOnIndexedDBThread,
392 make_scoped_refptr(indexed_db_context_impl)));
[email protected]6e2d3d22012-02-24 18:10:36393 }
394}
395
ttr31481dc54b2015-08-06 20:11:26396void BrowserContext::SetDownloadManagerForTesting(
397 BrowserContext* browser_context,
398 DownloadManager* download_manager) {
399 SetDownloadManager(browser_context, download_manager);
400}
401
rockot963ad3e82016-04-13 16:33:23402// static
erge69130f52016-03-02 00:13:28403void BrowserContext::Initialize(
404 BrowserContext* browser_context,
405 const base::FilePath& path) {
ben6c85c4492016-06-16 20:40:51406
407 std::string new_id;
408 if (GetContentClient() && GetContentClient()->browser()) {
409 new_id = GetContentClient()->browser()->GetShellUserIdForBrowserContext(
410 browser_context);
411 } else {
412 // Some test scenarios initialize a BrowserContext without a content client.
bencccfe2a2016-03-05 16:54:14413 new_id = base::GenerateGUID();
ben6c85c4492016-06-16 20:40:51414 }
erge69130f52016-03-02 00:13:28415
ben6c85c4492016-06-16 20:40:51416 ShellUserIdHolder* holder = static_cast<ShellUserIdHolder*>(
417 browser_context->GetUserData(kMojoShellUserId));
418 if (holder)
ben768c8dc2016-08-12 00:26:50419 file::ForgetShellUserIdUserDirAssociation(holder->user_id());
420 file::AssociateShellUserIdWithUserDir(new_id, path);
ben6c85c4492016-06-16 20:40:51421 RemoveBrowserContextFromUserIdMap(browser_context);
422 g_user_id_to_context.Get()[new_id] = browser_context;
423 browser_context->SetUserData(kMojoShellUserId,
424 new ShellUserIdHolder(new_id));
erge69130f52016-03-02 00:13:28425
erge69130f52016-03-02 00:13:28426 browser_context->SetUserData(kMojoWasInitialized,
427 new base::SupportsUserData::Data);
rockot963ad3e82016-04-13 16:33:23428
ben6c85c4492016-06-16 20:40:51429 MojoShellConnection* shell = MojoShellConnection::GetForProcess();
ben99cf17e2016-07-01 20:40:07430 if (shell && base::MessageLoop::current()) {
rockot963ad3e82016-04-13 16:33:23431 // NOTE: Many unit tests create a TestBrowserContext without initializing
432 // Mojo or the global Mojo shell connection.
433
bene1bbc002016-07-05 16:04:36434 shell::mojom::ServicePtr service;
435 shell::mojom::ServiceRequest service_request = mojo::GetProxy(&service);
rockot963ad3e82016-04-13 16:33:23436
rockotb00e6462016-04-14 02:24:03437 shell::mojom::PIDReceiverPtr pid_receiver;
438 shell::Connector::ConnectParams params(
439 shell::Identity(kBrowserMojoApplicationName, new_id));
bene1bbc002016-07-05 16:04:36440 params.set_client_process_connection(std::move(service),
rockot963ad3e82016-04-13 16:33:23441 mojo::GetProxy(&pid_receiver));
442 pid_receiver->SetPID(base::GetCurrentProcId());
443
444 BrowserContextShellConnectionHolder* connection_holder =
445 new BrowserContextShellConnectionHolder(
446 shell->GetConnector()->Connect(&params),
bene1bbc002016-07-05 16:04:36447 std::move(service_request));
rockot963ad3e82016-04-13 16:33:23448 browser_context->SetUserData(kMojoShellConnection, connection_holder);
449
ben146248de2016-06-14 15:24:59450 MojoShellConnection* connection = connection_holder->shell_connection();
rockotcef38272016-07-15 22:47:47451 connection->Start();
rockot963ad3e82016-04-13 16:33:23452
ben146248de2016-06-14 15:24:59453 // New embedded service factories should be added to |connection| here.
rockot963ad3e82016-04-13 16:33:23454
455 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
456 switches::kMojoLocalStorage)) {
rockot017f0ef2016-05-16 17:15:52457 MojoApplicationInfo info;
thestig529ad8a2016-07-08 20:30:12458 info.application_factory =
ben768c8dc2016-08-12 00:26:50459 base::Bind(&file::CreateFileService,
thestig529ad8a2016-07-08 20:30:12460 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE),
461 BrowserThread::GetTaskRunnerForThread(BrowserThread::DB));
ben768c8dc2016-08-12 00:26:50462 connection->AddEmbeddedService(file::kFileServiceName, info);
rockot963ad3e82016-04-13 16:33:23463 }
464 }
erge69130f52016-03-02 00:13:28465}
466
rockot963ad3e82016-04-13 16:33:23467// static
ben6c85c4492016-06-16 20:40:51468const std::string& BrowserContext::GetShellUserIdFor(
bencccfe2a2016-03-05 16:54:14469 BrowserContext* browser_context) {
erge69130f52016-03-02 00:13:28470 CHECK(browser_context->GetUserData(kMojoWasInitialized))
471 << "Attempting to get the mojo user id for a BrowserContext that was "
472 << "never Initialize()ed.";
473
ben6c85c4492016-06-16 20:40:51474 ShellUserIdHolder* holder = static_cast<ShellUserIdHolder*>(
475 browser_context->GetUserData(kMojoShellUserId));
476 return holder->user_id();
erge69130f52016-03-02 00:13:28477}
478
rockot963ad3e82016-04-13 16:33:23479// static
ben6c85c4492016-06-16 20:40:51480BrowserContext* BrowserContext::GetBrowserContextForShellUserId(
481 const std::string& user_id) {
482 auto it = g_user_id_to_context.Get().find(user_id);
483 return it != g_user_id_to_context.Get().end() ? it->second : nullptr;
484}
485
486// static
487shell::Connector* BrowserContext::GetShellConnectorFor(
rockot963ad3e82016-04-13 16:33:23488 BrowserContext* browser_context) {
ben5be0b9132016-08-03 00:17:18489 MojoShellConnection* connection = GetMojoShellConnectionFor(browser_context);
490 return connection ? connection->GetConnector() : nullptr;
491}
492
493// static
494MojoShellConnection* BrowserContext::GetMojoShellConnectionFor(
495 BrowserContext* browser_context) {
rockot963ad3e82016-04-13 16:33:23496 BrowserContextShellConnectionHolder* connection_holder =
497 static_cast<BrowserContextShellConnectionHolder*>(
498 browser_context->GetUserData(kMojoShellConnection));
ben5be0b9132016-08-03 00:17:18499 return connection_holder ? connection_holder->shell_connection() : nullptr;
rockot963ad3e82016-04-13 16:33:23500}
501
[email protected]55eb70e762012-02-20 17:38:39502BrowserContext::~BrowserContext() {
erge69130f52016-03-02 00:13:28503 CHECK(GetUserData(kMojoWasInitialized))
504 << "Attempting to destroy a BrowserContext that never called "
505 << "Initialize()";
506
kinukof6ed359c2016-07-26 13:27:21507 DCHECK(!GetUserData(kStoragePartitionMapKeyName))
508 << "StoragePartitionMap is not shut down properly";
509
ben6c85c4492016-06-16 20:40:51510 RemoveBrowserContextFromUserIdMap(this);
511
[email protected]b441a8492012-06-06 14:55:57512 if (GetUserData(kDownloadManagerKeyName))
513 GetDownloadManager(this)->Shutdown();
[email protected]55eb70e762012-02-20 17:38:39514}
515
kinukof6ed359c2016-07-26 13:27:21516void BrowserContext::ShutdownStoragePartitions() {
517 if (GetUserData(kStoragePartitionMapKeyName))
518 RemoveUserData(kStoragePartitionMapKeyName);
519}
520
[email protected]55eb70e762012-02-20 17:38:39521} // namespace content