electron_api_service_worker_main.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // Copyright (c) 2025 Salesforce, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #ifndef ELECTRON_SHELL_BROWSER_API_ELECTRON_API_SERVICE_WORKER_MAIN_H_
  5. #define ELECTRON_SHELL_BROWSER_API_ELECTRON_API_SERVICE_WORKER_MAIN_H_
  6. #include <optional>
  7. #include <string>
  8. #include <vector>
  9. #include "base/memory/raw_ptr.h"
  10. #include "base/memory/weak_ptr.h"
  11. #include "base/process/process.h"
  12. #include "content/public/browser/global_routing_id.h"
  13. #include "content/public/browser/service_worker_context.h"
  14. #include "content/public/browser/service_worker_version_base_info.h"
  15. #include "gin/wrappable.h"
  16. #include "mojo/public/cpp/bindings/associated_receiver.h"
  17. #include "mojo/public/cpp/bindings/associated_remote.h"
  18. #include "mojo/public/cpp/bindings/pending_receiver.h"
  19. #include "mojo/public/cpp/bindings/remote.h"
  20. #include "shell/browser/event_emitter_mixin.h"
  21. #include "shell/common/api/api.mojom.h"
  22. #include "shell/common/gin_helper/constructible.h"
  23. #include "shell/common/gin_helper/pinnable.h"
  24. #include "third_party/blink/public/common/service_worker/embedded_worker_status.h"
  25. class GURL;
  26. namespace content {
  27. class StoragePartition;
  28. }
  29. namespace gin {
  30. class Arguments;
  31. } // namespace gin
  32. namespace gin_helper {
  33. class Dictionary;
  34. template <typename T>
  35. class Handle;
  36. template <typename T>
  37. class Promise;
  38. } // namespace gin_helper
  39. namespace electron::api {
  40. // Key to uniquely identify a ServiceWorkerMain by its Version ID within the
  41. // associated StoragePartition.
  42. struct ServiceWorkerKey {
  43. int64_t version_id;
  44. raw_ptr<const content::StoragePartition> storage_partition;
  45. ServiceWorkerKey(int64_t id, const content::StoragePartition* partition)
  46. : version_id(id), storage_partition(partition) {}
  47. bool operator<(const ServiceWorkerKey& other) const {
  48. return std::tie(version_id, storage_partition) <
  49. std::tie(other.version_id, other.storage_partition);
  50. }
  51. bool operator==(const ServiceWorkerKey& other) const {
  52. return version_id == other.version_id &&
  53. storage_partition == other.storage_partition;
  54. }
  55. struct Hasher {
  56. std::size_t operator()(const ServiceWorkerKey& key) const {
  57. return std::hash<const content::StoragePartition*>()(
  58. key.storage_partition) ^
  59. std::hash<int64_t>()(key.version_id);
  60. }
  61. };
  62. };
  63. // Creates a wrapper to align with the lifecycle of the non-public
  64. // content::ServiceWorkerVersion. Object instances are pinned for the lifetime
  65. // of the underlying SW such that registered IPC handlers continue to dispatch.
  66. //
  67. // Instances are uniquely identified by pairing their version ID and the
  68. // StoragePartition in which they're registered. In Electron, this is always
  69. // the default StoragePartition for the associated BrowserContext.
  70. class ServiceWorkerMain final
  71. : public gin::Wrappable<ServiceWorkerMain>,
  72. public gin_helper::EventEmitterMixin<ServiceWorkerMain>,
  73. public gin_helper::Pinnable<ServiceWorkerMain>,
  74. public gin_helper::Constructible<ServiceWorkerMain> {
  75. public:
  76. // Create a new ServiceWorkerMain and return the V8 wrapper of it.
  77. static gin::Handle<ServiceWorkerMain> New(v8::Isolate* isolate);
  78. static gin::Handle<ServiceWorkerMain> From(
  79. v8::Isolate* isolate,
  80. content::ServiceWorkerContext* sw_context,
  81. const content::StoragePartition* storage_partition,
  82. int64_t version_id);
  83. static ServiceWorkerMain* FromVersionID(
  84. int64_t version_id,
  85. const content::StoragePartition* storage_partition);
  86. // gin_helper::Constructible
  87. static void FillObjectTemplate(v8::Isolate*, v8::Local<v8::ObjectTemplate>);
  88. static const char* GetClassName() { return "ServiceWorkerMain"; }
  89. // gin::Wrappable
  90. static gin::WrapperInfo kWrapperInfo;
  91. const char* GetTypeName() override;
  92. // disable copy
  93. ServiceWorkerMain(const ServiceWorkerMain&) = delete;
  94. ServiceWorkerMain& operator=(const ServiceWorkerMain&) = delete;
  95. void OnRunningStatusChanged(blink::EmbeddedWorkerStatus running_status);
  96. void OnVersionRedundant();
  97. protected:
  98. explicit ServiceWorkerMain(content::ServiceWorkerContext* sw_context,
  99. int64_t version_id,
  100. const ServiceWorkerKey& key);
  101. ~ServiceWorkerMain() override;
  102. private:
  103. void Destroy();
  104. void MaybeDisconnectRemote();
  105. const blink::StorageKey GetStorageKey();
  106. // Increments external requests for the service worker to keep it alive.
  107. gin_helper::Dictionary StartExternalRequest(v8::Isolate* isolate,
  108. bool has_timeout);
  109. void FinishExternalRequest(v8::Isolate* isolate, std::string uuid);
  110. size_t CountExternalRequestsForTest();
  111. // Get or create a Mojo connection to the renderer process.
  112. mojom::ElectronRenderer* GetRendererApi();
  113. // Send a message to the renderer process.
  114. void Send(v8::Isolate* isolate,
  115. bool internal,
  116. const std::string& channel,
  117. v8::Local<v8::Value> args);
  118. void InvalidateVersionInfo();
  119. const content::ServiceWorkerVersionBaseInfo* version_info() const {
  120. return version_info_.get();
  121. }
  122. bool IsDestroyed() const;
  123. int64_t VersionID() const;
  124. GURL ScopeURL() const;
  125. // Version ID unique only to the StoragePartition.
  126. int64_t version_id_;
  127. // Unique identifier pairing the Version ID and StoragePartition.
  128. ServiceWorkerKey key_;
  129. // Whether the Service Worker version has been destroyed.
  130. bool version_destroyed_ = false;
  131. // Whether the Service Worker version's state is redundant.
  132. bool redundant_ = false;
  133. // Store copy of version info so it's accessible when not running.
  134. std::unique_ptr<content::ServiceWorkerVersionBaseInfo> version_info_;
  135. raw_ptr<content::ServiceWorkerContext> service_worker_context_;
  136. mojo::AssociatedRemote<mojom::ElectronRenderer> remote_;
  137. std::unique_ptr<gin_helper::Promise<void>> start_worker_promise_;
  138. base::WeakPtrFactory<ServiceWorkerMain> weak_factory_{this};
  139. };
  140. } // namespace electron::api
  141. #endif // ELECTRON_SHELL_BROWSER_API_ELECTRON_API_SERVICE_WORKER_MAIN_H_