1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_OBJECT_HOST_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_OBJECT_HOST_H_
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/associated_receiver_set.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote_set.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "url/origin.h"
namespace content {
class ServiceWorkerContainerHost;
class ServiceWorkerContextCore;
namespace service_worker_object_host_unittest {
class ServiceWorkerObjectHostTest;
} // namespace service_worker_object_host_unittest
// Roughly corresponds to one blink::ServiceWorker object in the renderer
// process.
//
// The blink::ServiceWorker object in the renderer process maintains a
// reference to |this| by owning a Mojo remote to
// blink::mojom::ServiceWorkerObjectHost. When all Mojo connections bound with
// |receivers_| are disconnected, |this| will be deleted. See also comments on
// |receivers_|.
//
// Has references to the corresponding ServiceWorkerVersion in order to ensure
// that the version is alive while this handle is around.
class CONTENT_EXPORT ServiceWorkerObjectHost
: public blink::mojom::ServiceWorkerObjectHost,
public ServiceWorkerVersion::Observer {
public:
ServiceWorkerObjectHost(
base::WeakPtr<ServiceWorkerContextCore> context,
base::WeakPtr<ServiceWorkerContainerHost> container_host,
scoped_refptr<ServiceWorkerVersion> version);
ServiceWorkerObjectHost(const ServiceWorkerObjectHost&) = delete;
ServiceWorkerObjectHost& operator=(const ServiceWorkerObjectHost&) = delete;
~ServiceWorkerObjectHost() override;
// ServiceWorkerVersion::Observer overrides.
void OnVersionStateChanged(ServiceWorkerVersion* version) override;
// Returns an info for the ServiceWorker object. The info contains a Mojo
// ptr to |this| which ensures |this| stays alive while the info is alive.
// Furthermore, it contains a Mojo request for the ServiceWorkerObject
// interface in the renderer. |this| will make calls to the
// ServiceWorkerObject to update its state.
//
// WARNING: The returned info must be sent immediately over Mojo, because
// |this| will start making calls on an associated interface ptr to
// ServiceWorkerObject, which crashes unless the request inside the info has
// been sent. If the info cannot be sent immediately, use
// CreateIncompleteObjectInfo() instead.
blink::mojom::ServiceWorkerObjectInfoPtr CreateCompleteObjectInfoToSend();
base::WeakPtr<ServiceWorkerObjectHost> AsWeakPtr();
private:
friend class service_worker_object_host_unittest::ServiceWorkerObjectHostTest;
// Implements blink::mojom::ServiceWorkerObjectHost.
void PostMessageToServiceWorker(
::blink::TransferableMessage message) override;
void TerminateForTesting(TerminateForTestingCallback callback) override;
// TODO(leonhsl): Remove |callback| parameter because it's just for unit tests
// and production code does not use it. We need to figure out another way to
// observe the dispatch result in unit tests.
void DispatchExtendableMessageEvent(
::blink::TransferableMessage message,
base::OnceCallback<void(blink::ServiceWorkerStatusCode)> callback);
void OnConnectionError();
base::WeakPtr<ServiceWorkerContextCore> context_;
// |container_host_| is valid throughout lifetime of |this| because it owns
// |this|.
//
// However, there exists an exception, because of an ownership cycle
// between 1,2,3,4,5:
// 1. ServiceWorkerContainerHost owns as member (2)
// 2. ServiceWorkerObjectManager owns via unique_ptr (3)
// 3. ServiceWorkerObjectHost owns via scoped_ptr(4)
// 4. ServiceWorkerVersion owns via unique_ptr (5)
// 5. ServiceWorkerHost owns via unique_ptr (1)
//
// The cycle is broken in `ServiceWorkerObjectManager::RemoveHost`, by
// transferring ownership of |this| to the stack, while deleting
// |container_host_|.
//
// As a result, |container_host_| is always valid, except during the
// destructor.
const base::WeakPtr<ServiceWorkerContainerHost> container_host_;
// The origin of the |container_host_|. Note that this is const because once a
// JavaScript ServiceWorker object is created for an execution context, we
// don't expect that context to change origins and still hold on to the
// object.
const url::Origin container_origin_;
scoped_refptr<ServiceWorkerVersion> version_;
// Typically both |receivers_| and |remote_objects_| contain only one Mojo
// connection, corresponding to the blink::ServiceWorker in the renderer which
// corresponds to the ServiceWorker JavaScript object. However, multiple Mojo
// connections may exist while propagating multiple service worker object
// infos to the renderer process, but only the first one that arrived there
// will be used to create the new blink::ServiceWorker instance and be bound
// to it.
mojo::AssociatedReceiverSet<blink::mojom::ServiceWorkerObjectHost> receivers_;
mojo::AssociatedRemoteSet<blink::mojom::ServiceWorkerObject> remote_objects_;
base::WeakPtrFactory<ServiceWorkerObjectHost> weak_ptr_factory_{this};
};
} // namespace content
#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_OBJECT_HOST_H_
|