| // Copyright 2018 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/browser/cookie_store/cookie_store_context.h" |
| |
| #include "base/bind.h" |
| #include "base/bind_post_task.h" |
| #include "base/sequence_checker.h" |
| #include "base/threading/sequenced_task_runner_handle.h" |
| #include "content/browser/service_worker/service_worker_context_wrapper.h" |
| #include "content/browser/storage_partition_impl.h" |
| #include "content/public/browser/browser_task_traits.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/render_process_host.h" |
| #include "content/public/browser/service_worker_context.h" |
| #include "content/public/browser/service_worker_version_base_info.h" |
| #include "content/public/browser/storage_partition.h" |
| |
| namespace content { |
| |
| CookieStoreContext::CookieStoreContext() |
| : base::RefCountedDeleteOnSequence<CookieStoreContext>( |
| BrowserThread::GetTaskRunnerForThread( |
| ServiceWorkerContext::GetCoreThreadId())) { |
| DETACH_FROM_SEQUENCE(core_sequence_checker_); |
| } |
| |
| CookieStoreContext::~CookieStoreContext() { |
| // The destructor must be called on the service worker core thread, because it |
| // runs `cookie_store_manager_`'s destructor, and the latter is only accessed |
| // on the service worker core thread. |
| DCHECK_CALLED_ON_VALID_SEQUENCE(core_sequence_checker_); |
| } |
| |
| void CookieStoreContext::Initialize( |
| scoped_refptr<ServiceWorkerContextWrapper> service_worker_context, |
| base::OnceCallback<void(bool)> success_callback) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| #if DCHECK_IS_ON() |
| DCHECK(!initialize_called_) << __func__ << " called twice"; |
| initialize_called_ = true; |
| #endif // DCHECK_IS_ON() |
| |
| RunOrPostTaskOnThread( |
| FROM_HERE, ServiceWorkerContext::GetCoreThreadId(), |
| base::BindOnce(&CookieStoreContext::InitializeOnCoreThread, this, |
| std::move(service_worker_context), |
| base::BindPostTask(base::SequencedTaskRunnerHandle::Get(), |
| std::move(success_callback)))); |
| } |
| |
| void CookieStoreContext::ListenToCookieChanges( |
| ::network::mojom::NetworkContext* network_context, |
| base::OnceCallback<void(bool)> success_callback) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| #if DCHECK_IS_ON() |
| DCHECK(initialize_called_) << __func__ << " called before Initialize()"; |
| #endif // DCHECK_IS_ON() |
| |
| mojo::PendingRemote<::network::mojom::CookieManager> cookie_manager_remote; |
| network_context->GetCookieManager( |
| cookie_manager_remote.InitWithNewPipeAndPassReceiver()); |
| |
| RunOrPostTaskOnThread( |
| FROM_HERE, ServiceWorkerContext::GetCoreThreadId(), |
| base::BindOnce(&CookieStoreContext::ListenToCookieChangesOnCoreThread, |
| this, std::move(cookie_manager_remote), |
| base::BindPostTask(base::SequencedTaskRunnerHandle::Get(), |
| std::move(success_callback)))); |
| } |
| |
| // static |
| void CookieStoreContext::CreateServiceForFrame( |
| RenderFrameHost* render_frame_host, |
| mojo::PendingReceiver<blink::mojom::CookieStore> receiver) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| DCHECK(render_frame_host); |
| RenderProcessHost* render_process_host = render_frame_host->GetProcess(); |
| DCHECK(render_process_host); |
| |
| StoragePartitionImpl* storage_partition = static_cast<StoragePartitionImpl*>( |
| render_process_host->GetStoragePartition()); |
| storage_partition->GetCookieStoreContext()->CreateServiceForTesting( |
| render_frame_host->GetLastCommittedOrigin(), std::move(receiver)); |
| } |
| |
| // static |
| void CookieStoreContext::CreateServiceForWorker( |
| const ServiceWorkerVersionBaseInfo& info, |
| mojo::PendingReceiver<blink::mojom::CookieStore> receiver) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| RenderProcessHost* render_process_host = |
| RenderProcessHost::FromID(info.process_id); |
| if (render_process_host == nullptr) |
| return; |
| |
| StoragePartitionImpl* storage_partition = static_cast<StoragePartitionImpl*>( |
| render_process_host->GetStoragePartition()); |
| storage_partition->GetCookieStoreContext()->CreateServiceForTesting( |
| info.storage_key.origin(), std::move(receiver)); |
| } |
| |
| void CookieStoreContext::CreateServiceForTesting( |
| const url::Origin& origin, |
| mojo::PendingReceiver<blink::mojom::CookieStore> receiver) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| #if DCHECK_IS_ON() |
| DCHECK(initialize_called_) << __func__ << " called before Initialize()"; |
| #endif // DCHECK_IS_ON() |
| RunOrPostTaskOnThread( |
| FROM_HERE, ServiceWorkerContext::GetCoreThreadId(), |
| base::BindOnce(&CookieStoreContext::CreateServiceOnCoreThread, this, |
| origin, std::move(receiver))); |
| } |
| |
| void CookieStoreContext::InitializeOnCoreThread( |
| scoped_refptr<ServiceWorkerContextWrapper> service_worker_context, |
| base::OnceCallback<void(bool)> success_callback) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(core_sequence_checker_); |
| DCHECK(!cookie_store_manager_) << __func__ << " called more than once"; |
| |
| cookie_store_manager_ = |
| std::make_unique<CookieStoreManager>(std::move(service_worker_context)); |
| cookie_store_manager_->LoadAllSubscriptions(std::move(success_callback)); |
| } |
| |
| void CookieStoreContext::ListenToCookieChangesOnCoreThread( |
| mojo::PendingRemote<::network::mojom::CookieManager> cookie_manager_remote, |
| base::OnceCallback<void(bool)> success_callback) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(core_sequence_checker_); |
| DCHECK(cookie_store_manager_); |
| |
| cookie_store_manager_->ListenToCookieChanges(std::move(cookie_manager_remote), |
| std::move(success_callback)); |
| } |
| |
| void CookieStoreContext::CreateServiceOnCoreThread( |
| const url::Origin& origin, |
| mojo::PendingReceiver<blink::mojom::CookieStore> receiver) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(core_sequence_checker_); |
| DCHECK(cookie_store_manager_); |
| |
| cookie_store_manager_->CreateService(std::move(receiver), origin); |
| } |
| |
| } // namespace content |