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
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_PERFORMANCE_MANAGER_SERVICE_WORKER_CONTEXT_ADAPTER_H_
#define COMPONENTS_PERFORMANCE_MANAGER_SERVICE_WORKER_CONTEXT_ADAPTER_H_
#include <memory>
#include <string>
#include "base/check_op.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/observer_list.h"
#include "base/scoped_observation.h"
#include "content/public/browser/service_worker_context.h"
#include "content/public/browser/service_worker_context_observer.h"
namespace content {
class RenderProcessHost;
}
namespace performance_manager {
// Interface that makes testing easier. The only practical implementaion is the
// class below.
class ServiceWorkerContextAdapter {
public:
virtual ~ServiceWorkerContextAdapter() = default;
// Adds/removes an observer.
virtual void AddObserver(content::ServiceWorkerContextObserver* observer) = 0;
virtual void RemoveObserver(
content::ServiceWorkerContextObserver* observer) = 0;
};
// This class adapts an existing ServiceWorkerContext to ensure that the
// OnVersionStoppedRunning() notifications are sent as soon as the render
// process of a running service worker exits.
//
// It observes the underlying context so that it can receive the original
// notifications and control when they are sent to the observers.
//
// Lives on the UI thread. Must outlive |underlying_context|.
//
// Note: This is a temporary class that can be removed when the representation
// of a worker in the content/ layer (ServiceWorkerVersion) is moved to
// the UI thread. At that point, it'll be able to observe its associated
// RenderProcessHost itself. See https://crbug.com/824858.
class ServiceWorkerContextAdapterImpl
: public ServiceWorkerContextAdapter,
public content::ServiceWorkerContextObserver {
public:
explicit ServiceWorkerContextAdapterImpl(
content::ServiceWorkerContext* underlying_context);
~ServiceWorkerContextAdapterImpl() override;
// ServiceWorkerContextAdapter:
// Note that this is a minimal implementation for the use case of the
// PerformanceManager. Only AddObserver/RemoveObserver are implemented.
void AddObserver(content::ServiceWorkerContextObserver* observer) override;
void RemoveObserver(content::ServiceWorkerContextObserver* observer) override;
// content::ServiceWorkerContextObserver:
void OnVersionStartedRunning(
int64_t version_id,
const content::ServiceWorkerRunningInfo& running_info) override;
void OnVersionStoppedRunning(int64_t version_id) override;
void OnControlleeAdded(
int64_t version_id,
const std::string& client_uuid,
const content::ServiceWorkerClientInfo& client_info) override;
void OnControlleeRemoved(int64_t version_id,
const std::string& client_uuid) override;
void OnControlleeNavigationCommitted(
int64_t version_id,
const std::string& uuid,
content::GlobalRenderFrameHostId render_frame_host_id) override;
private:
class RunningServiceWorker;
// Invoked by a RunningServiceWorker when it observes that the render process
// has exited.
void OnRenderProcessExited(int64_t version_id);
// Adds a registration to |worker_process_host| that will result in
// |OnRenderProcessExited| with |version_id| when it exits.
void AddRunningServiceWorker(int64_t version_id,
content::RenderProcessHost* worker_process_host);
// Removes a registration made by |AddRunningServiceWorker| if one exists,
// returns true if a registration existed, false otherwise.
bool MaybeRemoveRunningServiceWorker(int64_t version_id);
base::ScopedObservation<content::ServiceWorkerContext,
content::ServiceWorkerContextObserver>
scoped_underlying_context_observation_{this};
base::ObserverList<content::ServiceWorkerContextObserver, true, false>::
Unchecked observer_list_;
// For each running service worker, tracks when their render process exits.
base::flat_map<int64_t /*version_id*/, std::unique_ptr<RunningServiceWorker>>
running_service_workers_;
// Tracks the OnControlleeAdded and OnControlleeRemoved notification for each
// service worker, with the goal of cleaning up duplicate notifications for
// observers of this class.
// TODO(crbug.com/40653867): Fix the underlying code in
// content/browser/service_worker so
// that duplicate notifications are no longer sent.
base::flat_map<int64_t /*version_id*/,
base::flat_set<std::string /*client_uuid*/>>
service_worker_clients_;
#if DCHECK_IS_ON()
// Keeps track of service worker whose render process exited early.
base::flat_set<int64_t> stopped_service_workers_;
#endif // DCHECK_IS_ON()
};
} // namespace performance_manager
#endif // COMPONENTS_PERFORMANCE_MANAGER_SERVICE_WORKER_CONTEXT_ADAPTER_H_
|