8000 feat: add API for receiving logs from service workers by trop[bot] · Pull Request #22313 · electron/electron · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: add API for receiving logs from service workers #22313

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions docs/api/service-workers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
## Class: ServiceWorkers

> Query and receive events from a sessions active service workers.
Process: [Main](../glossary.md#main-process)

Instances of the `ServiceWorkers` class are accessed by using `serviceWorkers` property of
a `Session`.

For example:

```javascript
const { session } = require('electron')

// Get all service workers.
console.log(session.defaultSession.serviceWorkers.getAllRunning())

// Handle logs and get service worker info
session.defaultSession.serviceWorkers.on('console-message', (event, messageDetails) => {
console.log(
'Got service worker message',
messageDetails,
'from',
session.defaultSession.serviceWorkers.getFromVersionID(messageDetails.versionId)
)
})
```

### Instance Events

The following events are available on instances of `ServiceWorkers`:

#### Event: 'console-message'

Returns:

* `event` Event
* `messageDetails` Object - Information about the console message
* `message` String - The actual console message
* `versionId` Number - The version ID of the service worker that sent the log message
* `source` String - The type of source for this message. Can be `javascript`, `xml`, `network`, `console-api`, `storage`, `app-cache`, `rendering`, `security`, `deprecation`, `worker`, `violation`, `intervention`, `recommendation` or `other`.
* `level` Number - The log level, from 0 to 3. In order it matches `verbose`, `info`, `warning` and `error`.
* `sourceUrl` String - The URL the message came from
* `lineNumber` Number - The line number of the source that triggered this console message

Emitted when a service worker logs something to the console.

### Instance Methods

The following methods are available on instances of `ServiceWorkers`:

#### `serviceWorkers.getAllRunning()`

Returns `Record<Number, ServiceWorkerInfo>` - A [ServiceWorkerInfo](structures/service-worker-info.md) object where the keys are the service worker version ID and the values are the information about that service worker.

#### `serviceWorkers.getFromVersionID(versionId)`

* `versionId` Number

Returns [`ServiceWorkerInfo`](structures/service-worker-info.md) - Information about this service worker

If the service worker does not exist or is not running this method will throw an exception.
4 changes: 4 additions & 0 deletions docs/api/session.md
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,10 @@ code to the `setSpellCheckerLanaguages` API that isn't in this array will result

A [`Cookies`](cookies.md) object for this session.

#### `ses.serviceWorkers` _Readonly_

A [`ServiceWorkers`](service-workers.md) object for this session.

#### `ses.webRequest` _Readonly_

A [`WebRequest`](web-request.md) object for this session.
Expand Down
5 changes: 5 additions & 0 deletions docs/api/structures/service-worker-info.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# ServiceWorkerInfo Object

* `scriptUrl` String - The full URL to the script that this service worker runs
* `scope` String - The base URL that this service worker is active for.
* `renderProcessId` Number - The virtual ID of the process that this service worker is running in. This is not an OS level PID. This aligns with the ID set used for `webContents.getProcessId()`.
2 changes: 2 additions & 0 deletions filenames.auto.gni
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ auto_filenames = {
"docs/api/remote.md",
"docs/api/sandbox-option.md",
"docs/api/screen.md",
"docs/api/service-workers.md",
"docs/api/session.md",
"docs/api/shell.md",
"docs/api/structures",
Expand Down Expand Up @@ -110,6 +111,7 @@ auto_filenames = {
"docs/api/structures/remove-password.md",
"docs/api/structures/scrubber-item.md",
"docs/api/structures/segmented-control-segment.md",
"docs/api/structures/service-worker-info.md",
"docs/api/structures/shared-worker-info.md",
"docs/api/structures/shortcut-details.md",
"docs/api/structures/size.md",
Expand Down
2 changes: 2 additions & 0 deletions filenames.gni
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ filenames = {
"shell/browser/api/electron_api_protocol.h",
"shell/browser/api/electron_api_screen.cc",
"shell/browser/api/electron_api_screen.h",
"shell/browser/api/electron_api_service_worker_context.cc",
"shell/browser/api/electron_api_service_worker_context.h",
"shell/browser/api/electron_api_session.cc",
"shell/browser/api/electron_api_session.h",
"shell/browser/api/electron_api_system_preferences.cc",
Expand Down
5 changes: 3 additions & 2 deletions lib/browser/api/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const { EventEmitter } = require('events')
const { app, deprecate } = require('electron')
const { fromPartition, Session, Cookies, NetLog, Protocol } = process.electronBinding('session')
const { fromPartition, Session, Cookies, NetLog, Protocol, ServiceWorkerContext } = process.electronBinding('session')

// Public API.
Object.defineProperties(exports, {
Expand All @@ -16,8 +16,9 @@ Object.defineProperties(exports, {
}
})

Object.setPrototypeOf(Session.prototype, EventEmitter.prototype)
Object.setPrototypeOf(Cookies.prototype, EventEmitter.prototype)
Object.setPrototypeOf(ServiceWorkerContext.prototype, EventEmitter.prototype)
Object.setPrototypeOf(Session.prototype, EventEmitter.prototype)

Session.prototype._init = function () {
app.emit('session-created', this)
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@types/semver": "^6.0.1",
"@types/send": "^0.14.5",
"@types/split": "^1.0.0",
"@types/uuid": "^3.4.6",
"@types/webpack": "^4.4.32",
"@types/webpack-env": "^1.13.9",
"@typescript-eslint/eslint-plugin": "^2.6.0",
Expand Down Expand Up @@ -141,4 +142,4 @@
"@types/multiparty": "^0.0.32",
"@types/temp": "^0.8.34"
}
}
}
154 changes: 154 additions & 0 deletions shell/browser/api/electron_api_service_worker_context.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// Copyright (c) 2019 Slack Technologies, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "shell/browser/api/electron_api_service_worker_context.h"

#include <string>
#include <utility>

#include "chrome/browser/browser_process.h"
#include "content/public/browser/console_message.h"
#include "content/public/browser/storage_partition.h"
#include "gin/data_object_builder.h"
#include "gin/handle.h"
#include "shell/browser/electron_browser_context.h"
#include "shell/common/gin_converters/value_converter.h"
#include "shell/common/gin_helper/dictionary.h"
#include "shell/common/gin_helper/object_template_builder.h"
#include "shell/common/node_includes.h"

namespace electron {

namespace api {

namespace {

std::string MessageSourceToString(
const blink::mojom::ConsoleMessageSource source) {
if (source == blink::mojom::ConsoleMessageSource::kXml)
return "xml";
if (source == blink::mojom::ConsoleMessageSource::kJavaScript)
return "javascript";
if (source == blink::mojom::ConsoleMessageSource::kNetwork)
return "network";
if (source == blink::mojom::ConsoleMessageSource::kConsoleApi)
return "console-api";
if (source == blink::mojom::ConsoleMessageSource::kStorage)
return "storage";
if (source == blink::mojom::ConsoleMessageSource::kAppCache)
return "app-cache";
if (source == blink::mojom::ConsoleMessageSource::kRendering)
return "rendering";
if (source == blink::mojom::ConsoleMessageSource::kSecurity)
return "security";
if (source == blink::mojom::ConsoleMessageSource::kDeprecation)
return "deprecation";
if (source == blink::mojom::ConsoleMessageSource::kWorker)
return "worker";
if (source == blink::mojom::ConsoleMessageSource::kViolation)
return "violation";
if (source == blink::mojom::ConsoleMessageSource::kIntervention)
return "intervention";
if (source == blink::mojom::ConsoleMessageSource::kRecommendation)
return "recommendation";
return "other";
}

v8::Local<v8::Value> ServiceWorkerRunningInfoToDict(
v8::Isolate* isolate,
const content::ServiceWorkerRunningInfo& info) {
return gin::DataObjectBuilder(isolate)
.Set("scriptUrl", info.script_url.spec())
.Set("scope", info.scope.spec())
.Set("renderProcessId", info.render_process_id)
.Build();
}

} // namespace

ServiceWorkerContext::ServiceWorkerContext(
v8::Isolate* isolate,
ElectronBrowserContext* browser_context)
: browser_context_(browser_context), weak_ptr_factory_(this) {
Init(isolate);
service_worker_context_ =
content::BrowserContext::GetDefaultStoragePartition(browser_context_)
->GetServiceWorkerContext();
service_worker_context_->AddObserver(this);
}

ServiceWorkerContext::~ServiceWorkerContext() {
service_worker_context_->RemoveObserver(this);
}

void ServiceWorkerContext::OnReportConsoleMessage(
int64_t version_id,
const content::ConsoleMessage& message) {
Emit("console-message",
gin::DataObjectBuilder(v8::Isolate::GetCurrent())
.Set("versionId", version_id)
.Set("source", MessageSourceToString(message.source))
.Set("level", static_cast<int32_t>(message.message_level))
.Set("message", message.message)
.Set("lineNumber", message.line_number)
.Set("sourceUrl", message.source_url.spec())
.Build());
}

void ServiceWorkerContext::OnDestruct(content::ServiceWorkerContext* context) {
if (context == service_worker_context_) {
delete this;
}
}

v8::Local<v8::Value> ServiceWorkerContext::GetAllRunningWorkerInfo(
v8::Isolate* isolate) {
gin::DataObjectBuilder builder(isolate);
const base::flat_map<int64_t, content::ServiceWorkerRunningInfo>& info_map =
service_worker_context_->GetRunningServiceWorkerInfos();
for (auto iter = info_map.begin(); iter != info_map.end(); ++iter) {
builder.Set(
std::to_string(iter->first),
ServiceWorkerRunningInfoToDict(isolate, std::move(iter->second)));
}
return builder.Build();
}

v8::Local<v8::Value> ServiceWorkerContext::GetWorkerInfoFromID(
gin_helper::ErrorThrower thrower,
int64_t version_id) {
const base::flat_map<int64_t, content::ServiceWorkerRunningInfo>& info_map =
service_worker_context_->GetRunningServiceWorkerInfos();
auto iter = info_map.find(version_id);
if (iter == info_map.end()) {
thrower.ThrowError("Could not find service worker with that version_id");
return v8::Local<v8::Value>();
}
return ServiceWorkerRunningInfoToDict(thrower.isolate(),
std::move(iter->second));
}

// static
gin::Handle<ServiceWorkerContext> ServiceWorkerContext::Create(
v8::Isolate* isolate,
ElectronBrowserContext* browser_context) {
return gin::CreateHandle(isolate,
new ServiceWorkerContext(isolate, browser_context));
}

// static
void ServiceWorkerContext::BuildPrototype(
v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(gin::StringToV8(isolate, "ServiceWorkerContext"));
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("getAllRunning",
&ServiceWorkerContext::GetAllRunningWorkerInfo)
.SetMethod("getFromVersionID",
&ServiceWorkerContext::GetWorkerInfoFromID);
}

} // namespace api

} // namespace electron
58 changes: 58 additions & 0 deletions shell/browser/api/electron_api_service_worker_context.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) 2019 Slack Technologies, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#ifndef SHELL_BROWSER_API_ELECTRON_API_SERVICE_WORKER_CONTEXT_H_
#define SHELL_BROWSER_API_ELECTRON_API_SERVICE_WORKER_CONTEXT_H_

#include "content/public/browser/service_worker_context.h"
#include "content/public/browser/service_worker_context_observer.h"
#include "gin/handle.h"
#include "shell/common/gin_helper/trackable_object.h"

namespace electron {

class ElectronBrowserContext;

namespace api {

class ServiceWorkerContext
: public gin_helper::TrackableObject<ServiceWorkerContext>,
public content::ServiceWorkerContextObserver {
public:
static gin::Handle<ServiceWorkerContext> Create(
v8::Isolate* isolate,
ElectronBrowserContext* browser_context);

static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);

v8::Local<v8::Value> GetAllRunningWorkerInfo(v8::Isolate* isolate);
v8::Local<v8::Value> GetWorkerInfoFromID(gin_helper::ErrorThrower thrower,
int64_t version_id);

// content::ServiceWorkerContextObserver
void OnReportConsoleMessage(int64_t version_id,
const content::ConsoleMessage& message) override;
void OnDestruct(content::ServiceWorkerContext* context) override;

protected:
explicit ServiceWorkerContext(v8::Isolate* isolate,
ElectronBrowserContext* browser_context);
~ServiceWorkerContext() override;

private:
ElectronBrowserContext* browser_context_;

content::ServiceWorkerContext* service_worker_context_;

base::WeakPtrFactory<ServiceWorkerContext> weak_ptr_factory_;

DISALLOW_COPY_AND_ASSIGN(ServiceWorkerContext);
};

} // namespace api

} // namespace electron

#endif // SHELL_BROWSER_API_ELECTRON_API_SERVICE_WORKER_CONTEXT_H_
Loading
0