From 3919d4d429f23c00eec24c05ba72ea10a1d1e36a Mon Sep 17 00:00:00 2001 From: Maxim Date: Wed, 10 Sep 2025 22:00:58 +0300 Subject: [PATCH 01/13] Wire initial typescript (#338) * Wire initial typescript * Fix types * Something works * Finishing touches * Linter fixes * Build problems --- eslint.config.js | 18 +- google/protobuf/any.ts | 326 + lib/cli/please.js | 2 +- lib/db/handlers/group/index.js | 68 +- lib/db/index.ts | 20 +- lib/units/api/controllers/autotests.js | 3 +- lib/units/api/controllers/devices.js | 1 + lib/units/api/controllers/user.js | 20 +- lib/units/api/helpers/test.js | 11 + lib/units/api/helpers/useDevice.js | 5 +- lib/units/base-device/plugins/group.js | 7 +- lib/units/base-device/support/connector.js | 7 +- lib/units/base-device/support/push.ts | 2 +- lib/units/base-device/support/router.js | 2 +- lib/units/device/plugins/account.js | 11 +- lib/units/device/plugins/airplane.js | 3 +- lib/units/device/plugins/bluetooth.js | 7 +- lib/units/device/plugins/browser.js | 5 +- lib/units/device/plugins/clipboard.js | 5 +- lib/units/device/plugins/connect.js | 3 +- lib/units/device/plugins/filesystem.js | 5 +- lib/units/device/plugins/forward/index.js | 7 +- lib/units/device/plugins/group.js | 7 +- lib/units/device/plugins/install.js | 5 +- lib/units/device/plugins/logcat.js | 7 +- lib/units/device/plugins/reboot.js | 3 +- lib/units/device/plugins/ringer.js | 5 +- lib/units/device/plugins/screen/capture.js | 3 +- lib/units/device/plugins/screen/stream.js | 3 +- lib/units/device/plugins/sd.js | 3 +- lib/units/device/plugins/service.ts | 4 +- lib/units/device/plugins/shell.js | 5 +- lib/units/device/plugins/solo.js | 22 +- lib/units/device/plugins/store.js | 3 +- lib/units/device/plugins/touch/index.js | 15 +- lib/units/device/plugins/vnc/index.js | 3 +- lib/units/device/plugins/wifi.js | 5 +- lib/units/device/resources/service.js | 3 +- lib/units/groups-engine/watchers/devices.js | 3 +- lib/units/ios-device/plugins/clipboard.js | 3 +- lib/units/ios-device/plugins/devicelog.js | 7 +- lib/units/ios-device/plugins/filesystem.js | 5 +- lib/units/ios-device/plugins/install.js | 5 +- lib/units/ios-device/plugins/reboot.js | 3 +- lib/units/ios-device/plugins/wda/index.js | 29 +- lib/units/log/mongodb.js | 3 +- lib/units/processor/index.js | 95 +- lib/units/provider/ADBObserver.ts | 14 +- lib/units/provider/index.ts | 10 +- lib/units/reaper/index.js | 7 +- lib/units/tizen-device/index.js | 3 +- lib/units/tizen-device/plugins/filesystem.js | 5 +- lib/units/tizen-device/plugins/identity.js | 3 +- lib/units/tizen-device/plugins/install.js | 5 +- lib/units/tizen-device/plugins/launcher.js | 9 +- lib/units/vnc-device/plugins/group.js | 7 +- lib/units/vnc-device/plugins/screen/stream.js | 21 +- lib/units/websocket/index.js | 67 +- lib/util/apiutil.js | 4 +- lib/util/devutil.js | 2 +- lib/util/grouputil.js | 7 +- lib/util/lifecycle.js | 68 - lib/util/lifecycle.ts | 66 + lib/util/logger.ts | 15 +- lib/util/srv.ts | 3 +- lib/util/zmqutil.js | 8 +- lib/wire/google/protobuf/any.ts | 326 + lib/wire/index.js | 14 - lib/wire/index.ts | 35 + lib/wire/messagestream.ts | 2 +- lib/wire/router.ts | 154 +- lib/wire/transmanager.js | 3 +- lib/wire/util.js | 63 - lib/wire/util.ts | 108 + lib/wire/wire.proto | 143 +- lib/wire/wire.ts | 11545 ++++++++++++++++ package-lock.json | 524 +- package.json | 11 +- ui/src/store/device-connection.ts | 4 +- 79 files changed, 12985 insertions(+), 1058 deletions(-) create mode 100644 google/protobuf/any.ts create mode 100644 lib/units/api/helpers/test.js delete mode 100644 lib/util/lifecycle.js create mode 100644 lib/util/lifecycle.ts create mode 100644 lib/wire/google/protobuf/any.ts delete mode 100644 lib/wire/index.js create mode 100644 lib/wire/index.ts delete mode 100644 lib/wire/util.js create mode 100644 lib/wire/util.ts create mode 100644 lib/wire/wire.ts diff --git a/eslint.config.js b/eslint.config.js index 99f97b2655..02c704c90e 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -51,7 +51,8 @@ export default tseslint.config( }, }, { - ignores: ['dist'], + files: ['lib/**/*.js'], + // ignores: ['dist'], languageOptions: { ecmaVersion: 2025, sourceType: 'module', @@ -213,10 +214,17 @@ export default tseslint.config( 'no-restricted-modules': 0, 'no-sync': 0, 'no-async-promise-executor': 0, + + "no-restricted-imports": ["error", { + "patterns": [{ + "regex": ".*\\.ts", + "message": "Do not import typescript files. Import them with *.js" + }] + }] }, }, { - languageOptions: { + languageOptions: { parser: tseslint.parser, parserOptions: { projectService: true, @@ -224,4 +232,10 @@ export default tseslint.config( }, }, }, + tseslint.configs.eslintRecommended, + { + rules: { + "prefer-const": "off" + } + } ) diff --git a/google/protobuf/any.ts b/google/protobuf/any.ts new file mode 100644 index 0000000000..465a591802 --- /dev/null +++ b/google/protobuf/any.ts @@ -0,0 +1,326 @@ +// @generated by protobuf-ts 2.11.1 +// @generated from protobuf file "google/protobuf/any.proto" (package "google.protobuf", syntax proto3) +// tslint:disable +// +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +import type { BinaryWriteOptions } from "@protobuf-ts/runtime"; +import type { IBinaryWriter } from "@protobuf-ts/runtime"; +import { WireType } from "@protobuf-ts/runtime"; +import type { IBinaryReader } from "@protobuf-ts/runtime"; +import { UnknownFieldHandler } from "@protobuf-ts/runtime"; +import type { PartialMessage } from "@protobuf-ts/runtime"; +import { reflectionMergePartial } from "@protobuf-ts/runtime"; +import { isJsonObject } from "@protobuf-ts/runtime"; +import { typeofJsonValue } from "@protobuf-ts/runtime"; +import type { JsonValue } from "@protobuf-ts/runtime"; +import { jsonWriteOptions } from "@protobuf-ts/runtime"; +import type { JsonReadOptions } from "@protobuf-ts/runtime"; +import type { JsonWriteOptions } from "@protobuf-ts/runtime"; +import type { BinaryReadOptions } from "@protobuf-ts/runtime"; +import type { IMessageType } from "@protobuf-ts/runtime"; +import { MessageType } from "@protobuf-ts/runtime"; +/** + * `Any` contains an arbitrary serialized protocol buffer message along with a + * URL that describes the type of the serialized message. + * + * Protobuf library provides support to pack/unpack Any values in the form + * of utility functions or additional generated methods of the Any type. + * + * Example 1: Pack and unpack a message in C++. + * + * Foo foo = ...; + * Any any; + * any.PackFrom(foo); + * ... + * if (any.UnpackTo(&foo)) { + * ... + * } + * + * Example 2: Pack and unpack a message in Java. + * + * Foo foo = ...; + * Any any = Any.pack(foo); + * ... + * if (any.is(Foo.class)) { + * foo = any.unpack(Foo.class); + * } + * // or ... + * if (any.isSameTypeAs(Foo.getDefaultInstance())) { + * foo = any.unpack(Foo.getDefaultInstance()); + * } + * + * Example 3: Pack and unpack a message in Python. + * + * foo = Foo(...) + * any = Any() + * any.Pack(foo) + * ... + * if any.Is(Foo.DESCRIPTOR): + * any.Unpack(foo) + * ... + * + * Example 4: Pack and unpack a message in Go + * + * foo := &pb.Foo{...} + * any, err := anypb.New(foo) + * if err != nil { + * ... + * } + * ... + * foo := &pb.Foo{} + * if err := any.UnmarshalTo(foo); err != nil { + * ... + * } + * + * The pack methods provided by protobuf library will by default use + * 'type.googleapis.com/full.type.name' as the type URL and the unpack + * methods only use the fully qualified type name after the last '/' + * in the type URL, for example "foo.bar.com/x/y.z" will yield type + * name "y.z". + * + * JSON + * ==== + * The JSON representation of an `Any` value uses the regular + * representation of the deserialized, embedded message, with an + * additional field `@type` which contains the type URL. Example: + * + * package google.profile; + * message Person { + * string first_name = 1; + * string last_name = 2; + * } + * + * { + * "@type": "type.googleapis.com/google.profile.Person", + * "firstName": , + * "lastName": + * } + * + * If the embedded message type is well-known and has a custom JSON + * representation, that representation will be embedded adding a field + * `value` which holds the custom JSON in addition to the `@type` + * field. Example (for message [google.protobuf.Duration][]): + * + * { + * "@type": "type.googleapis.com/google.protobuf.Duration", + * "value": "1.212s" + * } + * + * + * @generated from protobuf message google.protobuf.Any + */ +export interface Any { + /** + * A URL/resource name that uniquely identifies the type of the serialized + * protocol buffer message. This string must contain at least + * one "/" character. The last segment of the URL's path must represent + * the fully qualified name of the type (as in + * `path/google.protobuf.Duration`). The name should be in a canonical form + * (e.g., leading "." is not accepted). + * + * In practice, teams usually precompile into the binary all types that they + * expect it to use in the context of Any. However, for URLs which use the + * scheme `http`, `https`, or no scheme, one can optionally set up a type + * server that maps type URLs to message definitions as follows: + * + * * If no scheme is provided, `https` is assumed. + * * An HTTP GET on the URL must yield a [google.protobuf.Type][] + * value in binary format, or produce an error. + * * Applications are allowed to cache lookup results based on the + * URL, or have them precompiled into a binary to avoid any + * lookup. Therefore, binary compatibility needs to be preserved + * on changes to types. (Use versioned type names to manage + * breaking changes.) + * + * Note: this functionality is not currently available in the official + * protobuf release, and it is not used for type URLs beginning with + * type.googleapis.com. As of May 2023, there are no widely used type server + * implementations and no plans to implement one. + * + * Schemes other than `http`, `https` (or the empty scheme) might be + * used with implementation specific semantics. + * + * + * @generated from protobuf field: string type_url = 1 + */ + typeUrl: string; + /** + * Must be a valid serialized protocol buffer of the above specified type. + * + * @generated from protobuf field: bytes value = 2 + */ + value: Uint8Array; +} +// @generated message type with reflection information, may provide speed optimized methods +class Any$Type extends MessageType { + constructor() { + super("google.protobuf.Any", [ + { no: 1, name: "type_url", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "value", kind: "scalar", T: 12 /*ScalarType.BYTES*/ } + ]); + } + /** + * Pack the message into a new `Any`. + * + * Uses 'type.googleapis.com/full.type.name' as the type URL. + */ + pack(message: T, type: IMessageType): Any { + return { + typeUrl: this.typeNameToUrl(type.typeName), value: type.toBinary(message), + }; + } + /** + * Unpack the message from the `Any`. + */ + unpack(any: Any, type: IMessageType, options?: Partial): T { + if (!this.contains(any, type)) + throw new Error("Cannot unpack google.protobuf.Any with typeUrl '" + any.typeUrl + "' as " + type.typeName + "."); + return type.fromBinary(any.value, options); + } + /** + * Does the given `Any` contain a packed message of the given type? + */ + contains(any: Any, type: IMessageType | string): boolean { + if (!any.typeUrl.length) + return false; + let wants = typeof type == "string" ? type : type.typeName; + let has = this.typeUrlToName(any.typeUrl); + return wants === has; + } + /** + * Convert the message to canonical JSON value. + * + * You have to provide the `typeRegistry` option so that the + * packed message can be converted to JSON. + * + * The `typeRegistry` option is also required to read + * `google.protobuf.Any` from JSON format. + */ + internalJsonWrite(any: Any, options: JsonWriteOptions): JsonValue { + if (any.typeUrl === "") + return {}; + let typeName = this.typeUrlToName(any.typeUrl); + let opt = jsonWriteOptions(options); + let type = opt.typeRegistry?.find(t => t.typeName === typeName); + if (!type) + throw new globalThis.Error("Unable to convert google.protobuf.Any with typeUrl '" + any.typeUrl + "' to JSON. The specified type " + typeName + " is not available in the type registry."); + let value = type.fromBinary(any.value, { readUnknownField: false }); + let json = type.internalJsonWrite(value, opt); + if (typeName.startsWith("google.protobuf.") || !isJsonObject(json)) + json = { value: json }; + json["@type"] = any.typeUrl; + return json; + } + internalJsonRead(json: JsonValue, options: JsonReadOptions, target?: Any): Any { + if (!isJsonObject(json)) + throw new globalThis.Error("Unable to parse google.protobuf.Any from JSON " + typeofJsonValue(json) + "."); + if (typeof json["@type"] != "string" || json["@type"] == "") + return this.create(); + let typeName = this.typeUrlToName(json["@type"]); + let type = options?.typeRegistry?.find(t => t.typeName == typeName); + if (!type) + throw new globalThis.Error("Unable to parse google.protobuf.Any from JSON. The specified type " + typeName + " is not available in the type registry."); + let value; + if (typeName.startsWith("google.protobuf.") && json.hasOwnProperty("value")) + value = type.fromJson(json["value"], options); + else { + let copy = Object.assign({}, json); + delete copy["@type"]; + value = type.fromJson(copy, options); + } + if (target === undefined) + target = this.create(); + target.typeUrl = json["@type"]; + target.value = type.toBinary(value); + return target; + } + typeNameToUrl(name: string): string { + if (!name.length) + throw new Error("invalid type name: " + name); + return "type.googleapis.com/" + name; + } + typeUrlToName(url: string): string { + if (!url.length) + throw new Error("invalid type url: " + url); + let slash = url.lastIndexOf("/"); + let name = slash > 0 ? url.substring(slash + 1) : url; + if (!name.length) + throw new Error("invalid type url: " + url); + return name; + } + create(value?: PartialMessage): Any { + const message = globalThis.Object.create((this.messagePrototype!)); + message.typeUrl = ""; + message.value = new Uint8Array(0); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: Any): Any { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string type_url */ 1: + message.typeUrl = reader.string(); + break; + case /* bytes value */ 2: + message.value = reader.bytes(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: Any, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string type_url = 1; */ + if (message.typeUrl !== "") + writer.tag(1, WireType.LengthDelimited).string(message.typeUrl); + /* bytes value = 2; */ + if (message.value.length) + writer.tag(2, WireType.LengthDelimited).bytes(message.value); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message google.protobuf.Any + */ +export const Any = new Any$Type(); diff --git a/lib/cli/please.js b/lib/cli/please.js index 68fcf377f6..1c513326fd 100644 --- a/lib/cli/please.js +++ b/lib/cli/please.js @@ -1 +1 @@ -import './index.ts' +import './index.js' diff --git a/lib/db/handlers/group/index.js b/lib/db/handlers/group/index.js index 7e540ad9be..74e7a8b92a 100644 --- a/lib/db/handlers/group/index.js +++ b/lib/db/handlers/group/index.js @@ -5,6 +5,7 @@ import wire from '../../../wire/index.js' import dbapi from '../../api.js' import GroupsScheduler from './scheduler.js' import {WireRouter} from '../../../wire/router.js' +import {GroupChangeMessage, GroupField, LeaveGroupMessage, UngroupMessage} from '../../../wire/wire.js' class GroupChangeHandler { @@ -31,12 +32,13 @@ class GroupChangeHandler { this.scheduler?.scheduleAllGroupsTasks() this.push.send([ channel, - wireutil.envelope(new wire.UngroupMessage(wireutil.toDeviceRequirements({ - serial: { - value: serial, - match: 'exact' - } - }))) + wireutil.pack(UngroupMessage, { + requirements: wireutil.toDeviceRequirements({ + serial: { + value: serial, + match: 'exact' + } + })}) ]) } @@ -50,32 +52,32 @@ class GroupChangeHandler { this.pushdev.send([ wireutil.global, - wireutil.envelope(new wire.GroupChangeMessage( - new wire.GroupField( - group.id - , group.name - , group.class - , group.privilege - , group.owner - , dates - , group.duration - , group.repetitions - , group.devices - , group.users - , group.state - , group.isActive - , group.moderators - ) - , action - , subscribers - , isChangedDates - , isChangedClass - , isAddedUser - , users - , isAddedDevice - , devices - , timeutil.now('nano') - )) + wireutil.pack(GroupChangeMessage, { + group: GroupField.create({ + id: group.id, + name: group.name, + class: group.class, + privilege: group.privilege, + owner: group.owner, + dates: dates, + duration: group.duration, + repetitions: group.repetitions, + devices: group.devices, + users: group.users, + state: group.state, + isActive: group.isActive, + moderators: group.moderators, + }), + action: action, + subscribers: subscribers, + isChangedDates: isChangedDates, + isChangedClass: isChangedClass, + isAddedUser: isAddedUser, + users: users, + isAddedDevice: isAddedDevice, + devices: devices, + timeStamp: timeutil.now('nano') + }) ]) } @@ -152,7 +154,7 @@ class GroupChangeHandler { } const listener = new WireRouter() - .on(wire.LeaveGroupMessage, (channel, message) => { + .on(LeaveGroupMessage, (channel, message) => { if (message.serial === serial && message.owner.email === email) { clearTimeout(responseTimer) diff --git a/lib/db/index.ts b/lib/db/index.ts index 26b6eec7d5..a4964c96d0 100644 --- a/lib/db/index.ts +++ b/lib/db/index.ts @@ -148,7 +148,7 @@ export default class DbClient { ) } catch (err) { - _log.fatal('Unable to connect to sub endpoint', err) + _log.fatal('Unable to connect to sub endpoint: %s', err) lifecycle.fatal() } }) @@ -173,7 +173,7 @@ export default class DbClient { ) } catch (err) { - _log.fatal('Unable to connect to subdev endpoint', err) + _log.fatal('Unable to connect to subdev endpoint: %s', err) lifecycle.fatal() } }) @@ -195,7 +195,7 @@ export default class DbClient { ) } catch (err) { - _log.fatal('Unable to connect to push endpoint', err) + _log.fatal('Unable to connect to push endpoint: %s', err) lifecycle.fatal() } }) @@ -218,7 +218,7 @@ export default class DbClient { } catch (err) { _log.fatal( - 'Unable to connect to pushdev endpoint', + 'Unable to connect to pushdev endpoint: %s', err ) lifecycle.fatal() @@ -254,13 +254,11 @@ export default class DbClient { // an issue with the processor unit, as it started processing messages before // it was actually truly able to save anything to the database. This lead to // lost messages in certain situations. - static ensureConnectivity = (fn: Function) => - function() { - let args = [].slice.call(arguments) - return DbClient.connect().then(function() { - return fn.apply(null, args) - }) - } + static ensureConnectivity = async (fn: T) => { + await DbClient.connect() + log.info("Db is up") + return fn + } // Sets up the database static setup = () => DbClient.connect().then((conn) => _setup(conn)) diff --git a/lib/units/api/controllers/autotests.js b/lib/units/api/controllers/autotests.js index 4a0423e839..93be14cafd 100644 --- a/lib/units/api/controllers/autotests.js +++ b/lib/units/api/controllers/autotests.js @@ -9,6 +9,7 @@ import logger from '../../../util/logger.js' import * as Sentry from '@sentry/node' import _ from 'lodash' import useDevice, {UseDeviceError} from '../helpers/useDevice.js' +import {InstallResultMessage} from '../../../wire/wire.js' const log = logger.createLogger('api:controllers:autotests') @@ -150,7 +151,7 @@ function installOnDevice(req, res) { return apiutil.respond(res, 504, 'Device is not responding') }, apiutil.INSTALL_APK_WAIT) let messageListener = new WireRouter() - .on(wire.InstallResultMessage, function(channel, message) { + .on(InstallResultMessage, function(channel, message) { if (message.serial === serial) { clearTimeout(timer) req.options.sub.unsubscribe(responseChannel) diff --git a/lib/units/api/controllers/devices.js b/lib/units/api/controllers/devices.js index c5be7246b9..7d9f916420 100644 --- a/lib/units/api/controllers/devices.js +++ b/lib/units/api/controllers/devices.js @@ -15,6 +15,7 @@ import * as jwtutil from '../../../util/jwtutil.js' import useDevice, {UseDeviceError} from '../helpers/useDevice.js' import * as Sentry from '@sentry/node' import {accessTokenAuth} from '../helpers/securityHandlers.js' +import {DeviceOriginGroupMessage} from '../../../wire/wire.js' var log = logger.createLogger('api:controllers:devices') /* ------------------------------------ PRIVATE FUNCTIONS ------------------------------- */ diff --git a/lib/units/api/controllers/user.js b/lib/units/api/controllers/user.js index 2bb043d0c0..6d1c7dd080 100644 --- a/lib/units/api/controllers/user.js +++ b/lib/units/api/controllers/user.js @@ -14,6 +14,7 @@ import * as jwtutil from '../../../util/jwtutil.js' import * as lockutil from '../../../util/lockutil.js' import * as Sentry from '@sentry/node' import generateToken from '../helpers/generateToken.js' +import {ConnectStartedMessage, ConnectStoppedMessage, JoinGroupMessage, LeaveGroupMessage, UngroupMessage} from '../../../wire/wire.js' import {runTransaction} from '../../../wire/transmanager.js' let log = logger.createLogger('api:controllers:user') @@ -132,7 +133,7 @@ function addUserDevice(req, res) { return apiutil.respond(res, 504, 'Device is not responding') }, apiutil.GRPC_WAIT_TIMEOUT) let messageListener = new WireRouter() - .on(wire.JoinGroupMessage, function(channel, message) { + .on(JoinGroupMessage, function(channel, message) { log.info(device.serial + ' added to user group ' + req.user) if (message.serial === serial && message.owner.email === req.user.email) { clearTimeout(responseTimer) @@ -208,12 +209,13 @@ function deleteUserDeviceBySerial(req, res) { } } - await runTransaction(device.channel, new wire.UngroupMessage(wireutil.toDeviceRequirements({ - serial: { - value: serial, - match: 'exact' - } - }))) + await runTransaction(device.channel, UngroupMessage.create({ + requirements: wireutil.toDeviceRequirements({ + serial: { + value: serial, + match: 'exact' + } + })})) }) .catch(function(err) { let errSerial @@ -259,7 +261,7 @@ function remoteConnectUserDeviceBySerial(req, res) { return apiutil.respond(res, 504, 'Device is not responding') }, apiutil.GRPC_WAIT_TIMEOUT) let messageListener = new WireRouter() - .on(wire.ConnectStartedMessage, function(channel, message) { + .on(ConnectStartedMessage, function(channel, message) { if (message.serial === serial) { clearTimeout(timer) req.options.sub.unsubscribe(responseChannel) @@ -332,7 +334,7 @@ function remoteDisconnectUserDeviceBySerial(req, res) { } }, apiutil.GRPC_WAIT_TIMEOUT) var messageListener = new WireRouter() - .on(wire.ConnectStoppedMessage, function(channel, message) { + .on(ConnectStoppedMessage, function(channel, message) { if (message.serial === serial) { clearTimeout(timer) req.options.sub.unsubscribe(responseChannel) diff --git a/lib/units/api/helpers/test.js b/lib/units/api/helpers/test.js new file mode 100644 index 0000000000..6a88e940c4 --- /dev/null +++ b/lib/units/api/helpers/test.js @@ -0,0 +1,11 @@ +import * as jwtutil from '../../../util/jwtutil.js' + +const a = jwtutil.encode({ + payload: { + email: user.email, + name: user.name + }, + secret: secret +}) + +console.log(a) diff --git a/lib/units/api/helpers/useDevice.js b/lib/units/api/helpers/useDevice.js index 7e769d7f3a..41e10af9b5 100644 --- a/lib/units/api/helpers/useDevice.js +++ b/lib/units/api/helpers/useDevice.js @@ -9,6 +9,7 @@ import wire from '../../../wire/index.js' import {v4 as uuidv4} from 'uuid' import {Log} from '../../../util/logger.js' import {runTransaction} from '../../../wire/transmanager.js' +import {ConnectStartedMessage, JoinGroupMessage} from '../../../wire/wire.js' export const UseDeviceError = Object.freeze({ NOT_FOUND: 0, @@ -61,7 +62,7 @@ const useDevice = ({user, device, channelRouter, push, sub, usage = null, log}) }, apiutil.GRPC_WAIT_TIMEOUT) const useDeviceMessageListener = new WireRouter() - .on(wire.JoinGroupMessage, function(channel, message) { + .on(JoinGroupMessage, function(channel, message) { log?.info(device.serial + ' added to user group ' + user) if (message.serial === device.serial && message.owner.email === user.email) { @@ -79,7 +80,7 @@ const useDevice = ({user, device, channelRouter, push, sub, usage = null, log}) }, apiutil.GRPC_WAIT_TIMEOUT) const messageListener = new WireRouter() - .on(wire.ConnectStartedMessage, function(channel, message) { + .on(ConnectStartedMessage, function(channel, message) { if (message.serial === device.serial) { clearTimeout(connectTimeout) sub.unsubscribe(responseChannel) diff --git a/lib/units/base-device/plugins/group.js b/lib/units/base-device/plugins/group.js index fbf8cf3f84..d01d8a6012 100755 --- a/lib/units/base-device/plugins/group.js +++ b/lib/units/base-device/plugins/group.js @@ -14,6 +14,7 @@ import router from '../support/router.js' import push from '../support/push.js' import sub from '../support/sub.js' import channels from '../support/channels.js' +import {AutoGroupMessage, GroupMessage, UngroupMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(solo) .dependency(router) @@ -91,7 +92,7 @@ export default syrup.serial() }) } router - .on(wire.GroupMessage, (channel, message) => { + .on(GroupMessage, (channel, message) => { let reply = wireutil.reply(options.serial) // grouputil.match(ident, message.requirements) plugin.join(message.owner, message.timeout, message.usage) @@ -114,7 +115,7 @@ export default syrup.serial() ]) }) }) - .on(wire.AutoGroupMessage, (channel, message) => { + .on(AutoGroupMessage, (channel, message) => { return plugin.join(message.owner, message.timeout, message.identifier) .then(() => { plugin.emit('autojoin', message.identifier, true) @@ -123,7 +124,7 @@ export default syrup.serial() plugin.emit('autojoin', message.identifier, false) }) }) - .on(wire.UngroupMessage, (channel, message) => { + .on(UngroupMessage, (channel, message) => { let reply = wireutil.reply(options.serial) Promise.method(() => { return plugin.leave('ungroup_request') diff --git a/lib/units/base-device/support/connector.js b/lib/units/base-device/support/connector.js index c3b5d0e2d3..4e48ca0bd6 100755 --- a/lib/units/base-device/support/connector.js +++ b/lib/units/base-device/support/connector.js @@ -6,6 +6,7 @@ import dbapi from '../../../db/api.js' import wireutil from '../../../wire/util.js' import db from '../../../db/index.js' import push from './push.js' +import {ConnectGetForwardUrlMessage, ConnectStartMessage, ConnectStopMessage} from '../../../wire/wire.js' /** * @typedef {{ @@ -52,13 +53,13 @@ export default syrup.serial() this.urlWithoutAdbPort = urlWithoutAdbPort router - .on(wire.ConnectStartMessage, + .on(ConnectStartMessage, (channel) => this.start(channel) ) - .on(wire.ConnectGetForwardUrlMessage, + .on(ConnectGetForwardUrlMessage, (channel) => this.getUrl(channel) ) - .on(wire.ConnectStopMessage, + .on(ConnectStopMessage, (channel) => this.stop(channel) ) } diff --git a/lib/units/base-device/support/push.ts b/lib/units/base-device/support/push.ts index 0fe7c58d4d..65c066af5a 100755 --- a/lib/units/base-device/support/push.ts +++ b/lib/units/base-device/support/push.ts @@ -32,7 +32,7 @@ export default syrup.serial().define( return push } catch (err) { - log.fatal('Unable to connect to sub endpoint', err) + log.fatal('Unable to connect to sub endpoint: %s', err) return lifecycle.fatal() // kill process } } diff --git a/lib/units/base-device/support/router.js b/lib/units/base-device/support/router.js index 26bf2a7cc6..ee9bb7a68a 100755 --- a/lib/units/base-device/support/router.js +++ b/lib/units/base-device/support/router.js @@ -9,7 +9,7 @@ export default syrup.serial() const router = new WireRouter() sub.on('message', router.handler()) // Special case, we're hooking into a message that's not actually routed. - router.on({$code: 'message'}, channel => { + router.on('message', channel => { channels.keepalive(channel) }) return router diff --git a/lib/units/device/plugins/account.js b/lib/units/device/plugins/account.js index 4323a982d3..52d9951393 100644 --- a/lib/units/device/plugins/account.js +++ b/lib/units/device/plugins/account.js @@ -8,6 +8,7 @@ import touch from './touch/index.js' import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' import adb from '../support/adb.js' +import {AccountAddMenuMessage, AccountAddMessage, AccountCheckMessage, AccountGetMessage, AccountRemoveMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(service) .dependency(identity) @@ -27,7 +28,7 @@ export default syrup.serial() throw new Error('The account is not added') }) } - router.on(wire.AccountCheckMessage, function(channel, message) { + router.on(AccountCheckMessage, function(channel, message) { var reply = wireutil.reply(options.serial) log.info('Checking if account "%s" is added', message.account) checkAccount(message.type, message.account) @@ -45,7 +46,7 @@ export default syrup.serial() ]) }) }) - router.on(wire.AccountGetMessage, function(channel, message) { + router.on(AccountGetMessage, function(channel, message) { var reply = wireutil.reply(options.serial) log.info('Getting account(s)') service.getAccounts(message) @@ -64,7 +65,7 @@ export default syrup.serial() ]) }) }) - router.on(wire.AccountRemoveMessage, function(channel, message) { + router.on(AccountRemoveMessage, function(channel, message) { var reply = wireutil.reply(options.serial) log.info('Removing "%s" account(s)', message.type) service.removeAccount(message) @@ -83,7 +84,7 @@ export default syrup.serial() ]) }) }) - router.on(wire.AccountAddMenuMessage, function(channel) { + router.on(AccountAddMenuMessage, function(channel) { var reply = wireutil.reply(options.serial) log.info('Showing add account menu for Google Account') service.addAccountMenu() @@ -102,7 +103,7 @@ export default syrup.serial() ]) }) }) - router.on(wire.AccountAddMessage, function(channel, message) { + router.on(AccountAddMessage, function(channel, message) { var reply = wireutil.reply(options.serial) var type = 'com.google' var account = message.user + '@gmail.com' diff --git a/lib/units/device/plugins/airplane.js b/lib/units/device/plugins/airplane.js index eef54033a6..9649f57ec4 100644 --- a/lib/units/device/plugins/airplane.js +++ b/lib/units/device/plugins/airplane.js @@ -5,13 +5,14 @@ import wireutil from '../../../wire/util.js' import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' import devutil from '../../../util/devutil.js' +import {AirplaneSetMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(devutil) .dependency(router) .dependency(push) .define(function(options, devutil, router, push) { var log = logger.createLogger('device:plugins:airplane') - router.on(wire.AirplaneSetMessage, async function(channel, message) { + router.on(AirplaneSetMessage, async function(channel, message) { const reply = wireutil.reply(options.serial) const enabled = message.enabled log.info('Setting airplane mode to', enabled) diff --git a/lib/units/device/plugins/bluetooth.js b/lib/units/device/plugins/bluetooth.js index dab8241ecd..b47ac65048 100644 --- a/lib/units/device/plugins/bluetooth.js +++ b/lib/units/device/plugins/bluetooth.js @@ -5,13 +5,14 @@ import wireutil from '../../../wire/util.js' import service from './service.js' import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' +import {BluetoothCleanBondedMessage, BluetoothGetStatusMessage, BluetoothSetEnabledMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(service) .dependency(router) .dependency(push) .define(function(options, service, router, push) { var log = logger.createLogger('device:plugins:bluetooth') - router.on(wire.BluetoothSetEnabledMessage, function(channel, message) { + router.on(BluetoothSetEnabledMessage, function(channel, message) { var reply = wireutil.reply(options.serial) log.info('Setting Bluetooth "%s"', message.enabled) service.setBluetoothEnabled(message.enabled) @@ -30,7 +31,7 @@ export default syrup.serial() ]) }) }) - router.on(wire.BluetoothGetStatusMessage, function(channel) { + router.on(BluetoothGetStatusMessage, function(channel) { var reply = wireutil.reply(options.serial) log.info('Getting Bluetooth status') service.getBluetoothStatus() @@ -49,7 +50,7 @@ export default syrup.serial() ]) }) }) - router.on(wire.BluetoothCleanBondedMessage, function(channel) { + router.on(BluetoothCleanBondedMessage, function(channel) { var reply = wireutil.reply(options.serial) log.info('Clean bonded Bluetooth devices') service.cleanupBondedBluetoothDevices() diff --git a/lib/units/device/plugins/browser.js b/lib/units/device/plugins/browser.js index 86d65031e0..e1425ee2fe 100644 --- a/lib/units/device/plugins/browser.js +++ b/lib/units/device/plugins/browser.js @@ -7,6 +7,7 @@ import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' import adb from '../support/adb.js' import service from './service.js' +import {BrowserClearMessage, BrowserOpenMessage} from '../../../wire/wire.js' const mapping = (function() { var list = Object.create(null) Object.keys(browsers).forEach(function(id) { @@ -76,7 +77,7 @@ export default syrup.serial() return (url.indexOf('://') === -1 ? 'http://' : '') + url } service.on('browserPackageChange', updateBrowsers) - router.on(wire.BrowserOpenMessage, function(channel, message) { + router.on(BrowserOpenMessage, function(channel, message) { message.url = ensureHttpProtocol(message.url) if (message.browser) { log.info('Opening "%s" in "%s"', message.url, message.browser) @@ -109,7 +110,7 @@ export default syrup.serial() ]) }) }) - router.on(wire.BrowserClearMessage, function(channel, message) { + router.on(BrowserClearMessage, function(channel, message) { log.info('Clearing "%s"', message.browser) var reply = wireutil.reply(options.serial) adb.getDevice(options.serial).clear(pkg(message.browser)) diff --git a/lib/units/device/plugins/clipboard.js b/lib/units/device/plugins/clipboard.js index b5c0a20582..30d0278673 100644 --- a/lib/units/device/plugins/clipboard.js +++ b/lib/units/device/plugins/clipboard.js @@ -5,13 +5,14 @@ import wireutil from '../../../wire/util.js' import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' import service from './service.js' +import {CopyMessage, PasteMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(router) .dependency(push) .dependency(service) .define(function(options, router, push, service) { var log = logger.createLogger('device:plugins:clipboard') - router.on(wire.PasteMessage, function(channel, message) { + router.on(PasteMessage, function(channel, message) { log.info('Pasting "%s" to clipboard', message.text) var reply = wireutil.reply(options.serial) service.paste(message.text) @@ -29,7 +30,7 @@ export default syrup.serial() ]) }) }) - router.on(wire.CopyMessage, function(channel) { + router.on(CopyMessage, function(channel) { log.info('Copying clipboard contents') var reply = wireutil.reply(options.serial) service.copy() diff --git a/lib/units/device/plugins/connect.js b/lib/units/device/plugins/connect.js index 80b41d6bd1..51be539ca8 100644 --- a/lib/units/device/plugins/connect.js +++ b/lib/units/device/plugins/connect.js @@ -15,6 +15,7 @@ import urlformat from '../../base-device/support/urlformat.js' import identity from './util/identity.js' import data from './util/data.js' import {GRPC_WAIT_TIMEOUT} from '../../../util/apiutil.js' +import {AdbKeysUpdatedMessage} from '../../../wire/wire.js' // The promise passed as an argument will not be cancelled after the time has elapsed, // only the second promise will be rejected. @@ -83,7 +84,7 @@ export default syrup.serial() const auth = key => promiseTimeout(new Promise((resolve, reject) => { plugin.auth(key, resolve, reject) - router.on(wire.AdbKeysUpdatedMessage, () => notify(key)) + router.on(AdbKeysUpdatedMessage, () => notify(key)) notify(key) }), GRPC_WAIT_TIMEOUT) // reject after 2 minutes if autojoin event doesn't fire diff --git a/lib/units/device/plugins/filesystem.js b/lib/units/device/plugins/filesystem.js index 500e593a7f..a24964bb5b 100644 --- a/lib/units/device/plugins/filesystem.js +++ b/lib/units/device/plugins/filesystem.js @@ -7,6 +7,7 @@ import adb from '../support/adb.js' import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' import storage from '../../base-device/support/storage.js' +import {FileSystemGetMessage, FileSystemListMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(adb) .dependency(router) @@ -34,7 +35,7 @@ export default syrup.serial() }) }) } - router.on(wire.FileSystemGetMessage, function(channel, message) { + router.on(FileSystemGetMessage, function(channel, message) { var reply = wireutil.reply(options.serial) plugin.retrieve(message.file, message.jwt) .then(function(file) { @@ -51,7 +52,7 @@ export default syrup.serial() ]) }) }) - router.on(wire.FileSystemListMessage, function(channel, message) { + router.on(FileSystemListMessage, function(channel, message) { var reply = wireutil.reply(options.serial) adb.getDevice(options.serial).readdir(message.dir) .then(function(files) { diff --git a/lib/units/device/plugins/forward/index.js b/lib/units/device/plugins/forward/index.js index bd929415c7..181ca1a560 100644 --- a/lib/units/device/plugins/forward/index.js +++ b/lib/units/device/plugins/forward/index.js @@ -13,6 +13,7 @@ import router from '../../../base-device/support/router.js' import push from '../../../base-device/support/push.js' import minirev from '../../resources/minirev.js' import group from '../group.js' +import {ForwardCreateMessage, ForwardRemoveMessage, ForwardTestMessage} from '../../../../wire/wire.js' export default syrup.serial() .dependency(adb) .dependency(router) @@ -108,7 +109,7 @@ export default syrup.serial() .then(awaitServer) .then(function() { router - .on(wire.ForwardTestMessage, function(channel, message) { + .on(ForwardTestMessage, function(channel, message) { var reply = wireutil.reply(options.serial) plugin.connect(message) .then(function(conn) { @@ -125,7 +126,7 @@ export default syrup.serial() ]) }) }) - .on(wire.ForwardCreateMessage, function(channel, message) { + .on(ForwardCreateMessage, function(channel, message) { var reply = wireutil.reply(options.serial) plugin.createForward(message.id, message) .then(function() { @@ -142,7 +143,7 @@ export default syrup.serial() ]) }) }) - .on(wire.ForwardRemoveMessage, function(channel, message) { + .on(ForwardRemoveMessage, function(channel, message) { var reply = wireutil.reply(options.serial) plugin.removeForward(message.id) .then(function() { diff --git a/lib/units/device/plugins/group.js b/lib/units/device/plugins/group.js index 90da7e25fd..6a31e8a0aa 100644 --- a/lib/units/device/plugins/group.js +++ b/lib/units/device/plugins/group.js @@ -16,6 +16,7 @@ import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' import sub from '../../base-device/support/sub.js' import channels from '../../base-device/support/channels.js' +import {AutoGroupMessage, GroupMessage, UngroupMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(solo) .dependency(identity) @@ -143,7 +144,7 @@ export default syrup.serial() service.releaseWakeLock() }) router - .on(wire.GroupMessage, function(channel, message) { + .on(GroupMessage, function(channel, message) { let reply = wireutil.reply(options.serial) grouputil.match(ident, message.requirements) .then(function() { @@ -168,7 +169,7 @@ export default syrup.serial() ]) }) }) - .on(wire.AutoGroupMessage, function(channel, message) { + .on(AutoGroupMessage, function(channel, message) { return plugin.join(message.owner, message.timeout, message.identifier) .then(function() { plugin.emit('autojoin', message.identifier, true) @@ -177,7 +178,7 @@ export default syrup.serial() plugin.emit('autojoin', message.identifier, false) }) }) - .on(wire.UngroupMessage, function(channel, message) { + .on(UngroupMessage, function(channel, message) { let reply = wireutil.reply(options.serial) grouputil.match(ident, message.requirements) .then(function() { diff --git a/lib/units/device/plugins/install.js b/lib/units/device/plugins/install.js index e2384ef20f..9eae1703d2 100644 --- a/lib/units/device/plugins/install.js +++ b/lib/units/device/plugins/install.js @@ -11,6 +11,7 @@ import adb from '../support/adb.js' import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' import storage from '../../base-device/support/storage.js' +import {InstallMessage, UninstallMessage} from '../../../wire/wire.js' // @ts-ignore const readAll = async(stream) => Utils.readAll(stream) @@ -24,7 +25,7 @@ export default syrup.serial() const log = logger.createLogger('device:plugins:install') const reply = wireutil.reply(options.serial) - router.on(wire.InstallMessage, async(channel, message) => { + router.on(InstallMessage, async(channel, message) => { const manifest = JSON.parse(message.manifest) const pkg = manifest.package const installFlags = message.installFlags @@ -197,7 +198,7 @@ export default syrup.serial() } }) - router.on(wire.UninstallMessage, async(channel, message) => { + router.on(UninstallMessage, async(channel, message) => { log.info('Uninstalling "%s"', message.packageName) try { await adb.getDevice(options.serial).uninstall(message.packageName) diff --git a/lib/units/device/plugins/logcat.js b/lib/units/device/plugins/logcat.js index b90f6b3b12..b88c9f2ab4 100644 --- a/lib/units/device/plugins/logcat.js +++ b/lib/units/device/plugins/logcat.js @@ -8,6 +8,7 @@ import adb from '../support/adb.js' import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' import group from './group.js' +import {LogcatApplyFiltersMessage, LogcatStartMessage, LogcatStopMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(adb) .dependency(router) @@ -69,7 +70,7 @@ export default syrup.serial() lifecycle.observe(plugin.stop) group.on('leave', plugin.stop) router - .on(wire.LogcatStartMessage, function(channel, message) { + .on(LogcatStartMessage, function(channel, message) { var reply = wireutil.reply(options.serial) plugin.start(message.filters) .then(function() { @@ -86,7 +87,7 @@ export default syrup.serial() ]) }) }) - .on(wire.LogcatApplyFiltersMessage, function(channel, message) { + .on(LogcatApplyFiltersMessage, function(channel, message) { var reply = wireutil.reply(options.serial) plugin.reset(message.filters) .then(function() { @@ -103,7 +104,7 @@ export default syrup.serial() ]) }) }) - .on(wire.LogcatStopMessage, function(channel) { + .on(LogcatStopMessage, function(channel) { var reply = wireutil.reply(options.serial) plugin.stop() .then(function() { diff --git a/lib/units/device/plugins/reboot.js b/lib/units/device/plugins/reboot.js index 4e95cf4cfc..f872fe8a46 100644 --- a/lib/units/device/plugins/reboot.js +++ b/lib/units/device/plugins/reboot.js @@ -5,13 +5,14 @@ import wireutil from '../../../wire/util.js' import adb from '../support/adb.js' import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' +import {RebootMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(adb) .dependency(router) .dependency(push) .define(function(options, adb, router, push) { const log = logger.createLogger('device:plugins:reboot') - router.on(wire.RebootMessage, function(channel) { + router.on(RebootMessage, function(channel) { let reply = wireutil.reply(options.serial) log.important('Rebooting') adb.getDevice(options.serial).reboot() diff --git a/lib/units/device/plugins/ringer.js b/lib/units/device/plugins/ringer.js index 61d4445fa5..bafbfe9a19 100644 --- a/lib/units/device/plugins/ringer.js +++ b/lib/units/device/plugins/ringer.js @@ -5,13 +5,14 @@ import wireutil from '../../../wire/util.js' import service from './service.js' import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' +import {RingerGetMessage, RingerSetMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(service) .dependency(router) .dependency(push) .define(function(options, service, router, push) { var log = logger.createLogger('device:plugins:ringer') - router.on(wire.RingerSetMessage, function(channel, message) { + router.on(RingerSetMessage, function(channel, message) { var reply = wireutil.reply(options.serial) log.info('Setting ringer mode to mode "%s"', message.mode) service.setRingerMode(message.mode) @@ -30,7 +31,7 @@ export default syrup.serial() ]) }) }) - router.on(wire.RingerGetMessage, function(channel) { + router.on(RingerGetMessage, function(channel) { var reply = wireutil.reply(options.serial) log.info('Getting ringer mode') service.getRingerMode() diff --git a/lib/units/device/plugins/screen/capture.js b/lib/units/device/plugins/screen/capture.js index ed074b5e82..5d689d2be5 100644 --- a/lib/units/device/plugins/screen/capture.js +++ b/lib/units/device/plugins/screen/capture.js @@ -10,6 +10,7 @@ import push from '../../../base-device/support/push.js' import storage from '../../../base-device/support/storage.js' import minicap from '../../resources/minicap.js' import display from '../util/display.js' +import {ScreenCaptureMessage} from '../../../../wire/wire.js' export default syrup.serial() .dependency(adb) .dependency(router) @@ -48,7 +49,7 @@ export default syrup.serial() .then(Adb.util.readAll) }) } - router.on(wire.ScreenCaptureMessage, function(channel) { + router.on(ScreenCaptureMessage, function(channel) { var reply = wireutil.reply(options.serial) plugin.capture() .then(function(file) { diff --git a/lib/units/device/plugins/screen/stream.js b/lib/units/device/plugins/screen/stream.js index 77e2b52183..5305c28868 100644 --- a/lib/units/device/plugins/screen/stream.js +++ b/lib/units/device/plugins/screen/stream.js @@ -25,6 +25,7 @@ import options from './options.js' import group from '../group.js' import * as jwtutil from '../../../../util/jwtutil.js' import {NoGroupError} from '../../../../util/grouputil.js' +import {ChangeQualityMessage} from '../../../../wire/wire.js' export default syrup.serial() .dependency(adb) .dependency(router) @@ -439,7 +440,7 @@ export default syrup.serial() display.on('rotationChange', function(newRotation) { frameProducer.updateRotation(newRotation) }) - router.on(wire.ChangeQualityMessage, function(channel, message) { + router.on(ChangeQualityMessage, function(channel, message) { frameProducer.changeQuality(message.quality) }) frameProducer.on('start', function() { diff --git a/lib/units/device/plugins/sd.js b/lib/units/device/plugins/sd.js index 382315fd32..da4aca405c 100644 --- a/lib/units/device/plugins/sd.js +++ b/lib/units/device/plugins/sd.js @@ -5,13 +5,14 @@ import wireutil from '../../../wire/util.js' import service from './service.js' import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' +import {SdStatusMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(service) .dependency(router) .dependency(push) .define(function(options, service, router, push) { var log = logger.createLogger('device:plugins:sd') - router.on(wire.SdStatusMessage, function(channel, message) { + router.on(SdStatusMessage, function(channel, message) { var reply = wireutil.reply(options.serial) log.info('Getting SD card status') service.getSdStatus(message) diff --git a/lib/units/device/plugins/service.ts b/lib/units/device/plugins/service.ts index 94c077c319..7971808d8c 100644 --- a/lib/units/device/plugins/service.ts +++ b/lib/units/device/plugins/service.ts @@ -560,7 +560,7 @@ export default syrup.serial() log.important('Agent connection ended, attempting to relaunch') try { await openAgent() - log.important('Agent relaunched in %dms', Date.now() - startTime) + log.important('Agent relaunched in %sms', Date.now() - startTime) resolve() } catch (err: any) { @@ -599,7 +599,7 @@ export default syrup.serial() log.important('Service connection ended, attempting to relaunch') await openAgent() // restart agent await openService() - log.important('Service relaunched in %dms', Date.now() - startTime) + log.important('Service relaunched in %sms', Date.now() - startTime) } catch (err: any) { log.fatal('[prepareForServiceDeath] Service connection could not be relaunched: %s', err?.message) diff --git a/lib/units/device/plugins/shell.js b/lib/units/device/plugins/shell.js index 8bbe76ceff..4ce1ef79c4 100644 --- a/lib/units/device/plugins/shell.js +++ b/lib/units/device/plugins/shell.js @@ -7,6 +7,7 @@ import adb from '../support/adb.js' import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' import sub from '../../base-device/support/sub.js' +import {ShellCommandMessage, ShellKeepAliveMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(adb) .dependency(router) @@ -14,7 +15,7 @@ export default syrup.serial() .dependency(sub) .define(function(options, adb, router, push, sub) { var log = logger.createLogger('device:plugins:shell') - router.on(wire.ShellCommandMessage, async function(channel, message) { + router.on(ShellCommandMessage, async function(channel, message) { var reply = wireutil.reply(options.serial) log.info('Running shell command "%s"', message.command) const stream = await adb.getDevice(options.serial).shell(message.command) @@ -52,7 +53,7 @@ export default syrup.serial() stream.on('end', endListener) stream.on('error', errorListener) sub.subscribe(channel) - router.on(wire.ShellKeepAliveMessage, keepAliveListener) + router.on(ShellKeepAliveMessage, keepAliveListener) timer = setTimeout(forceStop, message.timeout) return resolver.promise.finally(function() { stream.removeListener('readable', readableListener) diff --git a/lib/units/device/plugins/solo.js b/lib/units/device/plugins/solo.js index dbc97524a1..e151d124e2 100644 --- a/lib/units/device/plugins/solo.js +++ b/lib/units/device/plugins/solo.js @@ -7,6 +7,7 @@ import sub from '../../base-device/support/sub.js' import push from '../../base-device/support/push.js' import router from '../../base-device/support/router.js' import identity from './util/identity.js' +import {DeviceDisplayMessage, DeviceIdentityMessage, DevicePhoneMessage, ProbeMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(sub) .dependency(push) @@ -24,10 +25,27 @@ export default syrup.serial() var channel = makeChannelId() log.info('Subscribing to permanent channel "%s"', channel) sub.subscribe(channel) - router.on(wire.ProbeMessage, function() { + router.on(ProbeMessage, function() { push.send([ wireutil.global, - wireutil.envelope(new wire.DeviceIdentityMessage(options.serial, identity.platform, identity.manufacturer, identity.operator, identity.model, identity.version, identity.abi, identity.sdk, new wire.DeviceDisplayMessage(identity.display), new wire.DevicePhoneMessage(identity.phone), identity.product, identity.cpuPlatform, identity.openGLESVersion, identity.marketName, identity.macAddress, identity.ram)) + wireutil.pack(DeviceIdentityMessage, { + serial: options.serial, + platform: identity.platform, + manufacturer: identity.manufacturer, + operator: identity.operator, + model: identity.model, + version: identity.version, + abi: identity.abi, + sdk: identity.sdk, + display: DeviceDisplayMessage.create(identity.display), + phone: DevicePhoneMessage.create(identity.phone), + product: identity.product, + cpuPlatform: identity.cpuPlatform, + openGLESVersion: identity.openGLESVersion, + marketName: identity.marketName, + macAddress: identity.macAddress, + ram: identity.ram + }) ]) }) return { diff --git a/lib/units/device/plugins/store.js b/lib/units/device/plugins/store.js index 8981525856..00d1a657eb 100644 --- a/lib/units/device/plugins/store.js +++ b/lib/units/device/plugins/store.js @@ -5,13 +5,14 @@ import wireutil from '../../../wire/util.js' import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' import adb from '../support/adb.js' +import {StoreOpenMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(router) .dependency(push) .dependency(adb) .define(function(options, router, push, adb) { var log = logger.createLogger('device:plugins:store') - router.on(wire.StoreOpenMessage, function(channel) { + router.on(StoreOpenMessage, function(channel) { log.info('Opening Play Store') var reply = wireutil.reply(options.serial) adb.getDevice(options.serial).startActivity({ diff --git a/lib/units/device/plugins/touch/index.js b/lib/units/device/plugins/touch/index.js index 028b44a8cc..e3256c771b 100644 --- a/lib/units/device/plugins/touch/index.js +++ b/lib/units/device/plugins/touch/index.js @@ -15,6 +15,7 @@ import adb from '../../support/adb.js' import router from '../../../base-device/support/router.js' import minitouch from '../../resources/minitouch.js' import flags from '../util/flags.js' +import {GestureStartMessage, GestureStopMessage, TouchCommitMessage, TouchDownMessage, TouchMoveMessage, TouchResetMessage, TouchUpMessage} from '../../../../wire/wire.js' export default syrup.serial() .dependency(adb) .dependency(router) @@ -434,35 +435,35 @@ export default syrup.serial() lifecycle.fatal() }) router - .on(wire.GestureStartMessage, function(channel, message) { + .on(GestureStartMessage, function(channel, message) { queue.start(message.seq) }) - .on(wire.GestureStopMessage, function(channel, message) { + .on(GestureStopMessage, function(channel, message) { queue.push(message.seq, function() { queue.stop() }) }) - .on(wire.TouchDownMessage, function(channel, message) { + .on(TouchDownMessage, function(channel, message) { queue.push(message.seq, function() { touchConsumer.touchDown(message) }) }) - .on(wire.TouchMoveMessage, function(channel, message) { + .on(TouchMoveMessage, function(channel, message) { queue.push(message.seq, function() { touchConsumer.touchMove(message) }) }) - .on(wire.TouchUpMessage, function(channel, message) { + .on(TouchUpMessage, function(channel, message) { queue.push(message.seq, function() { touchConsumer.touchUp(message) }) }) - .on(wire.TouchCommitMessage, function(channel, message) { + .on(TouchCommitMessage, function(channel, message) { queue.push(message.seq, function() { touchConsumer.touchCommit() }) }) - .on(wire.TouchResetMessage, function(channel, message) { + .on(TouchResetMessage, function(channel, message) { queue.push(message.seq, function() { touchConsumer.touchReset() }) diff --git a/lib/units/device/plugins/vnc/index.js b/lib/units/device/plugins/vnc/index.js index 7fd31c34ff..f980a369df 100644 --- a/lib/units/device/plugins/vnc/index.js +++ b/lib/units/device/plugins/vnc/index.js @@ -19,6 +19,7 @@ import stream from '../screen/stream.js' import touch from '../touch/index.js' import group from '../group.js' import solo from '../solo.js' +import {VncAuthResponsesUpdatedMessage} from '../../../../wire/wire.js' export default syrup.serial() .dependency(router) .dependency(push) @@ -63,7 +64,7 @@ export default syrup.serial() } group.on('join', joinListener) group.on('autojoin', autojoinListener) - router.on(wire.VncAuthResponsesUpdatedMessage, notify) + router.on(VncAuthResponsesUpdatedMessage, notify) notify() return resolver.promise .timeout(5000) diff --git a/lib/units/device/plugins/wifi.js b/lib/units/device/plugins/wifi.js index 742796b927..8aace2359f 100644 --- a/lib/units/device/plugins/wifi.js +++ b/lib/units/device/plugins/wifi.js @@ -5,13 +5,14 @@ import wireutil from '../../../wire/util.js' import service from './service.js' import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' +import {WifiGetStatusMessage, WifiSetEnabledMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(service) .dependency(router) .dependency(push) .define(function(options, service, router, push) { var log = logger.createLogger('device:plugins:wifi') - router.on(wire.WifiSetEnabledMessage, function(channel, message) { + router.on(WifiSetEnabledMessage, function(channel, message) { var reply = wireutil.reply(options.serial) log.info('Setting Wifi "%s"', message.enabled) service.setWifiEnabled(message.enabled) @@ -30,7 +31,7 @@ export default syrup.serial() ]) }) }) - router.on(wire.WifiGetStatusMessage, function(channel) { + router.on(WifiGetStatusMessage, function(channel) { var reply = wireutil.reply(options.serial) log.info('Getting Wifi status') service.getWifiStatus() diff --git a/lib/units/device/resources/service.js b/lib/units/device/resources/service.js index cb62d36c7d..8a10ed4841 100644 --- a/lib/units/device/resources/service.js +++ b/lib/units/device/resources/service.js @@ -22,7 +22,8 @@ export default syrup.serial() startIntent: { action: 'jp.co.cyberagent.stf.ACTION_START', component: 'jp.co.cyberagent.stf/.Service' - } + }, + path: '' } // am startservice -a jp.co.cyberagent.stf.ACTION_START jp.co.cyberagent.stf/.Service function getPath() { diff --git a/lib/units/groups-engine/watchers/devices.js b/lib/units/groups-engine/watchers/devices.js index 0dd21bef2e..d76ce6a9b3 100644 --- a/lib/units/groups-engine/watchers/devices.js +++ b/lib/units/groups-engine/watchers/devices.js @@ -8,6 +8,7 @@ import wireutil from '../../../wire/util.js' import wire from '../../../wire/index.js' import dbapi from '../../../db/api.js' import db from '../../../db/index.js' +import {LeaveGroupMessage} from '../../../wire/wire.js' export default (function(push, pushdev, channelRouter) { const log = logger.createLogger('watcher-devices') function sendReleaseDeviceControl(serial, channel) { @@ -48,7 +49,7 @@ export default (function(push, pushdev, channelRouter) { sendDeviceGroupChangeWrapper() }, 5000) messageListener = new WireRouter() - .on(wire.LeaveGroupMessage, function(channel, message) { + .on(LeaveGroupMessage, function(channel, message) { if (message.serial === device.serial && message.owner.email === device.owner.email) { clearTimeout(responseTimer) diff --git a/lib/units/ios-device/plugins/clipboard.js b/lib/units/ios-device/plugins/clipboard.js index b48c3e0c0e..140f4b3f69 100755 --- a/lib/units/ios-device/plugins/clipboard.js +++ b/lib/units/ios-device/plugins/clipboard.js @@ -5,13 +5,14 @@ import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' import wdaClient from './wda/client.js' import Logger from '../../../util/logger.js' +import {CopyMessage} from '../../../wire/wire.js' const log = Logger.createLogger('ios-device:clipboard') export default syrup.serial() .dependency(router) .dependency(push) .dependency(wdaClient) .define(function(options, router, push, wdaClient) { - router.on(wire.CopyMessage, function(channel) { + router.on(CopyMessage, function(channel) { const reply = wireutil.reply(options.serial) wdaClient.getClipBoard() .then(clipboard => { diff --git a/lib/units/ios-device/plugins/devicelog.js b/lib/units/ios-device/plugins/devicelog.js index 2f0cf184df..534c2ec923 100755 --- a/lib/units/ios-device/plugins/devicelog.js +++ b/lib/units/ios-device/plugins/devicelog.js @@ -12,6 +12,7 @@ import sub from '../../base-device/support/sub.js' import group from '../../base-device/plugins/group.js' import nsyslogParser from 'nsyslog-parser' import db from '../../../db/index.js' +import {LogcatStartMessage, LogcatStopMessage, GroupMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(push) @@ -102,7 +103,7 @@ export default syrup.serial() group.on('leave', deviceLogger.killLoggingProcess) router - .on(wire.LogcatStartMessage, async function(channel, message) { + .on(LogcatStartMessage, async function(channel, message) { const reply = wireutil.reply(options.serial) try { await dbapi.loadDeviceBySerial(options.serial) @@ -114,12 +115,12 @@ export default syrup.serial() deviceLogger.killLoggingProcess() } }) - .on(wire.LogcatStopMessage, function(channel, data) { + .on(LogcatStopMessage, function(channel, data) { const reply = wireutil.reply(options.serial) deviceLogger.killLoggingProcess() push.send([channel, reply.okay('success')]) }) - .on(wire.GroupMessage, function(channel, data) { + .on(GroupMessage, function(channel, data) { deviceLogger.channel = channel }) diff --git a/lib/units/ios-device/plugins/filesystem.js b/lib/units/ios-device/plugins/filesystem.js index 13d5abbbf3..b9fc1b20e2 100644 --- a/lib/units/ios-device/plugins/filesystem.js +++ b/lib/units/ios-device/plugins/filesystem.js @@ -9,6 +9,7 @@ import {execFile} from 'child_process' import path from 'path' import fs from 'fs' import {v4 as uuidv4} from 'uuid' +import {FileSystemGetMessage, FileSystemListMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(router) .dependency(push) @@ -28,7 +29,7 @@ export default syrup.serial() } } - router.on(wire.FileSystemGetMessage, function(channel, message) { + router.on(FileSystemGetMessage, function(channel, message) { let reply = wireutil.reply(options.serial) let file = message.file let currentPath = file.split('/') @@ -72,7 +73,7 @@ export default syrup.serial() } ) }) - router.on(wire.FileSystemListMessage, function(channel, message) { + router.on(FileSystemListMessage, function(channel, message) { let reply = wireutil.reply(options.serial) let dirs = [] let rootDir = message.dir diff --git a/lib/units/ios-device/plugins/install.js b/lib/units/ios-device/plugins/install.js index 425950e190..0d95efd686 100755 --- a/lib/units/ios-device/plugins/install.js +++ b/lib/units/ios-device/plugins/install.js @@ -10,6 +10,7 @@ import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' import storage from '../../base-device/support/storage.js' import deviceutil from '../../../util/deviceutil.js' +import {InstallMessage} from '../../../wire/wire.js' function execShellCommand(cmd) { return new Promise((resolve, reject) => { @@ -49,7 +50,7 @@ export default syrup.serial() const log = logger.createLogger('ios-device:plugins:install') const reply = wireutil.reply(options.serial) - router.on(wire.InstallMessage, async function(channel, message) { + router.on(InstallMessage, async function(channel, message) { log.info('Installing application from "%s"', message.href) const jwt = message.jwt @@ -99,7 +100,7 @@ export default syrup.serial() cleanup() }) }) - router.on(wire.UninstallIosMessage, function(channel, message) { + router.on(UninstallIosMessage, function(channel, message) { uninstallApp(options.serial, message.packageName) }) }) diff --git a/lib/units/ios-device/plugins/reboot.js b/lib/units/ios-device/plugins/reboot.js index 231944e61d..5c4cd53839 100755 --- a/lib/units/ios-device/plugins/reboot.js +++ b/lib/units/ios-device/plugins/reboot.js @@ -7,12 +7,13 @@ import wireutil from '../../../wire/util.js' import {execFileSync} from 'child_process' import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' +import {RebootMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(router) .dependency(push) .define((options, router, push) => { const log = logger.createLogger('device:plugins:reboot') - router.on(wire.RebootMessage, (channel) => { + router.on(RebootMessage, (channel) => { log.important('Rebooting') const reply = wireutil.reply(options.serial) let udid = options.serial diff --git a/lib/units/ios-device/plugins/wda/index.js b/lib/units/ios-device/plugins/wda/index.js index a94d9e1871..acda59c6e4 100755 --- a/lib/units/ios-device/plugins/wda/index.js +++ b/lib/units/ios-device/plugins/wda/index.js @@ -12,6 +12,7 @@ import push from '../../../base-device/support/push.js' import sub from '../../../base-device/support/sub.js' import wdaClient from './client.js' import {Esp32Touch} from '../touch/esp32touch.js' +import {BrowserOpenMessage, DashboardOpenMessage, KeyDownMessage, KeyPressMessage, PhysicalIdentifyMessage, RotateMessage, ScreenCaptureMessage, StoreOpenMessage, TapDeviceTreeElement, TouchDownMessage, TouchMoveIosMessage, TouchMoveMessage, TouchUpMessage, TypeMessage} from '../../../../wire/wire.js' export default syrup.serial() .dependency(push) .dependency(sub) @@ -46,7 +47,7 @@ export default syrup.serial() }) } sub.on('message', new WireRouter() - .on(wire.KeyPressMessage, (channel, message) => { + .on(KeyPressMessage, (channel, message) => { if (wdaClient.orientation === 'LANDSCAPE' && message.key === 'home') { wdaClient.rotation({orientation: 'PORTRAIT'}) .then(() => { @@ -70,16 +71,16 @@ export default syrup.serial() } } }) - .on(wire.StoreOpenMessage, (channel, message) => { + .on(StoreOpenMessage, (channel, message) => { wdaClient.pressButton('store') }) - .on(wire.DashboardOpenMessage, (channel, message) => { + .on(DashboardOpenMessage, (channel, message) => { wdaClient.pressButton('settings') }) - .on(wire.PhysicalIdentifyMessage, (channel, message) => { + .on(PhysicalIdentifyMessage, (channel, message) => { wdaClient.pressButton('finder') }) - .on(wire.TouchDownMessage, (channel, message) => { + .on(TouchDownMessage, (channel, message) => { if(cursorDevice?.state === 'paired') { cursorDevice.press() } @@ -87,17 +88,17 @@ export default syrup.serial() wdaClient.tap(message) } }) - .on(wire.TouchMoveIosMessage, (channel, message) => { + .on(TouchMoveIosMessage, (channel, message) => { if(cursorDevice?.state !== 'paired') { wdaClient.swipe(message) } }) - .on(wire.TouchMoveMessage, (channel, message) => { + .on(TouchMoveMessage, (channel, message) => { if(cursorDevice?.state === 'paired') { cursorDevice.move(message.x, message.y) } }) - .on(wire.TouchUpMessage, (channel, message) => { + .on(TouchUpMessage, (channel, message) => { if(cursorDevice?.state === 'paired') { cursorDevice.release() } @@ -105,14 +106,14 @@ export default syrup.serial() wdaClient.touchUp() } }) - .on(wire.TapDeviceTreeElement, (channel, message) => { + .on(TapDeviceTreeElement, (channel, message) => { wdaClient.tapDeviceTreeElement(message) }) - .on(wire.TypeMessage, (channel, message) => { + .on(TypeMessage, (channel, message) => { log.verbose('wire.TypeMessage: ', message) wdaClient.typeKey({value: [iosutil.asciiparser(message.text)]}) }) - .on(wire.KeyDownMessage, (channel, message) => { + .on(KeyDownMessage, (channel, message) => { log.verbose('wire.KeyDownMessage: ', message) if (message.key === 'home') { wdaClient.homeBtn() @@ -121,10 +122,10 @@ export default syrup.serial() wdaClient.typeKey({value: [iosutil.asciiparser(message.key)]}) } }) - .on(wire.BrowserOpenMessage, (channel, message) => { + .on(BrowserOpenMessage, (channel, message) => { wdaClient.openUrl(message) }) - .on(wire.RotateMessage, (channel, message) => { + .on(RotateMessage, (channel, message) => { if (wdaClient.isRotating) { return } @@ -140,7 +141,7 @@ export default syrup.serial() log.error('Failed to rotate device to : ', rotation, err) }) }) - .on(wire.ScreenCaptureMessage, (channel, message) => { + .on(ScreenCaptureMessage, (channel, message) => { wdaClient.screenshot() .then(response => { let reply = wireutil.reply(options.serial) diff --git a/lib/units/log/mongodb.js b/lib/units/log/mongodb.js index 8691670cda..33a5c78b09 100644 --- a/lib/units/log/mongodb.js +++ b/lib/units/log/mongodb.js @@ -7,6 +7,7 @@ import lifecycle from '../../util/lifecycle.js' import srv from '../../util/srv.js' import dbapi from '../../db/api.js' import * as zmqutil from '../../util/zmqutil.js' +import {DeviceLogMessage} from '../../wire/wire.js' export default (function(options) { var log = logger.createLogger('log-db') // Input @@ -25,7 +26,7 @@ export default (function(options) { sub.subscribe(channel) }) sub.on('message', new WireRouter() - .on(wire.DeviceLogMessage, function(channel, message) { + .on(DeviceLogMessage, function(channel, message) { if (message.priority >= options.priority) { dbapi.saveDeviceLog(message.serial, message) } diff --git a/lib/units/processor/index.js b/lib/units/processor/index.js index 8a9398f7ad..0b714c6be1 100644 --- a/lib/units/processor/index.js +++ b/lib/units/processor/index.js @@ -8,8 +8,9 @@ import dbapi from '../../db/models/all/index.js' import lifecycle from '../../util/lifecycle.js' import srv from '../../util/srv.js' import * as zmqutil from '../../util/zmqutil.js' +import {UpdateAccessTokenMessage, DeleteUserMessage, DeviceChangeMessage, UserChangeMessage, GroupChangeMessage, DeviceGroupChangeMessage, GroupUserChangeMessage, DeviceHeartbeatMessage, DeviceLogMessage, TransactionProgressMessage, TransactionDoneMessage, TransactionTreeMessage, InstallResultMessage, DeviceLogcatEntryMessage, TemporarilyUnavailableMessage, UpdateRemoteConnectUrl, InstalledApplications, DeviceIntroductionMessage, InitializeIosDeviceState, DevicePresentMessage, DeviceAbsentMessage, DeviceStatusMessage, DeviceReadyMessage, JoinGroupByAdbFingerprintMessage, JoinGroupByVncAuthResponseMessage, ConnectStartedMessage, ConnectStoppedMessage, JoinGroupMessage, LeaveGroupMessage, DeviceIdentityMessage, AirplaneModeEvent, BatteryEvent, DeviceBrowserMessage, ConnectivityEvent, PhoneStateEvent, RotationEvent, CapabilitiesMessage, ReverseForwardsEvent, SetDeviceDisplay, UpdateIosDevice, SdkIosVersion, SizeIosDevice, DeviceTypeMessage, DeleteDevice, SetAbsentDisconnectedDevices, GetServicesAvailabilityMessage} from '../../wire/wire.js' -export default db.ensureConnectivity(async function(options) { +export default await db.ensureConnectivity(async function(options) { const log = logger.createLogger('processor') if (options.name) { logger.setGlobalIdentifier(options.name) @@ -66,24 +67,24 @@ export default db.ensureConnectivity(async function(options) { const defaultWireHandler = (channel, _, data) => appDealer.send([channel, data]) const router = new WireRouter() - .on(wire.UpdateAccessTokenMessage, defaultWireHandler) - .on(wire.DeleteUserMessage, defaultWireHandler) - .on(wire.DeviceChangeMessage, defaultWireHandler) - .on(wire.UserChangeMessage, defaultWireHandler) - .on(wire.GroupChangeMessage, defaultWireHandler) - .on(wire.DeviceGroupChangeMessage, defaultWireHandler) - .on(wire.GroupUserChangeMessage, defaultWireHandler) - .on(wire.DeviceHeartbeatMessage, defaultWireHandler) - .on(wire.DeviceLogMessage, defaultWireHandler) - .on(wire.TransactionProgressMessage, defaultWireHandler) - .on(wire.TransactionDoneMessage, defaultWireHandler) - .on(wire.TransactionTreeMessage, defaultWireHandler) - .on(wire.InstallResultMessage, defaultWireHandler) - .on(wire.DeviceLogcatEntryMessage, defaultWireHandler) - .on(wire.TemporarilyUnavailableMessage, defaultWireHandler) - .on(wire.UpdateRemoteConnectUrl, defaultWireHandler) - .on(wire.InstalledApplications, defaultWireHandler) - .on(wire.DeviceIntroductionMessage, async(channel, message, data) => { + .on(UpdateAccessTokenMessage, defaultWireHandler) + .on(DeleteUserMessage, defaultWireHandler) + .on(DeviceChangeMessage, defaultWireHandler) + .on(UserChangeMessage, defaultWireHandler) + .on(GroupChangeMessage, defaultWireHandler) + .on(DeviceGroupChangeMessage, defaultWireHandler) + .on(GroupUserChangeMessage, defaultWireHandler) + .on(DeviceHeartbeatMessage, defaultWireHandler) + .on(DeviceLogMessage, defaultWireHandler) + .on(TransactionProgressMessage, defaultWireHandler) + .on(TransactionDoneMessage, defaultWireHandler) + .on(TransactionTreeMessage, defaultWireHandler) + .on(InstallResultMessage, defaultWireHandler) + .on(DeviceLogcatEntryMessage, defaultWireHandler) + .on(TemporarilyUnavailableMessage, defaultWireHandler) + .on(UpdateRemoteConnectUrl, defaultWireHandler) + .on(InstalledApplications, defaultWireHandler) + .on(DeviceIntroductionMessage, async(channel, message, data) => { await dbapi.saveDeviceInitialState(message.serial, message) devDealer.send([ message.provider.channel, @@ -91,29 +92,29 @@ export default db.ensureConnectivity(async function(options) { ]) appDealer.send([channel, data]) }) - .on(wire.InitializeIosDeviceState, (channel, message, data) => { + .on(InitializeIosDeviceState, (channel, message, data) => { dbapi.initializeIosDeviceState(options.publicIp, message) }) - .on(wire.DevicePresentMessage, async(channel, message, data) => { + .on(DevicePresentMessage, async(channel, message, data) => { await dbapi.setDevicePresent(message.serial) appDealer.send([channel, data]) }) - .on(wire.DeviceAbsentMessage, async(channel, message, data) => { + .on(DeviceAbsentMessage, async(channel, message, data) => { if (!message.applications) { await dbapi.setDeviceAbsent(message.serial) appDealer.send([channel, data]) } }) - .on(wire.DeviceStatusMessage, (channel, message, data) => { + .on(DeviceStatusMessage, (channel, message, data) => { dbapi.saveDeviceStatus(message.serial, message.status) appDealer.send([channel, data]) }) - .on(wire.DeviceReadyMessage, async(channel, message, data) => { + .on(DeviceReadyMessage, async(channel, message, data) => { await dbapi.setDeviceReady(message.serial, message.channel) devDealer.send([message.channel, wireutil.envelope(new wire.ProbeMessage())]) appDealer.send([channel, data]) }) - .on(wire.JoinGroupByAdbFingerprintMessage, async(channel, message, data) => { + .on(JoinGroupByAdbFingerprintMessage, async(channel, message, data) => { try { const user = await dbapi.lookupUserByAdbFingerprint(message.fingerprint) if (user) { @@ -132,7 +133,7 @@ export default db.ensureConnectivity(async function(options) { log.error('Unable to lookup user by ADB fingerprint "%s"', message.fingerprint, err.stack) } }) - .on(wire.JoinGroupByVncAuthResponseMessage, async(channel, message, data) => { + .on(JoinGroupByVncAuthResponseMessage, async(channel, message, data) => { try { const user = await dbapi.lookupUserByVncAuthResponse(message.response, message.serial) if (user) { @@ -152,15 +153,15 @@ export default db.ensureConnectivity(async function(options) { log.error('Unable to lookup user by VNC auth response "%s"', message.response, err.stack) } }) - .on(wire.ConnectStartedMessage, async(channel, message, data) => { + .on(ConnectStartedMessage, async(channel, message, data) => { await dbapi.setDeviceConnectUrl(message.serial, message.url) appDealer.send([channel, data]) }) - .on(wire.ConnectStoppedMessage, async(channel, message, data) => { + .on(ConnectStoppedMessage, async(channel, message, data) => { await dbapi.unsetDeviceConnectUrl(message.serial) appDealer.send([channel, data]) }) - .on(wire.JoinGroupMessage, async(channel, message, data) => { + .on(JoinGroupMessage, async(channel, message, data) => { await Promise.all([ dbapi.setDeviceOwner(message.serial, message.owner), @@ -175,7 +176,7 @@ export default db.ensureConnectivity(async function(options) { ]) appDealer.send([channel, data]) }) - .on(wire.LeaveGroupMessage, async(channel, message, data) => { + .on(LeaveGroupMessage, async(channel, message, data) => { await Promise.all([ dbapi.unsetDeviceOwner(message.serial), dbapi.unsetDeviceUsage(message.serial), @@ -187,43 +188,43 @@ export default db.ensureConnectivity(async function(options) { ]) appDealer.send([channel, data]) }) - .on(wire.DeviceIdentityMessage, (channel, message, data) => { + .on(DeviceIdentityMessage, (channel, message, data) => { dbapi.saveDeviceIdentity(message.serial, message) appDealer.send([channel, data]) }) - .on(wire.AirplaneModeEvent, (channel, message, data) => { + .on(AirplaneModeEvent, (channel, message, data) => { dbapi.setDeviceAirplaneMode(message.serial, message.enabled) appDealer.send([channel, data]) }) - .on(wire.BatteryEvent, (channel, message, data) => { + .on(BatteryEvent, (channel, message, data) => { dbapi.setDeviceBattery(message.serial, message) appDealer.send([channel, data]) }) - .on(wire.DeviceBrowserMessage, (channel, message, data) => { + .on(DeviceBrowserMessage, (channel, message, data) => { dbapi.setDeviceBrowser(message.serial, message) appDealer.send([channel, data]) }) - .on(wire.ConnectivityEvent, (channel, message, data) => { + .on(ConnectivityEvent, (channel, message, data) => { dbapi.setDeviceConnectivity(message.serial, message) appDealer.send([channel, data]) }) - .on(wire.PhoneStateEvent, (channel, message, data) => { + .on(PhoneStateEvent, (channel, message, data) => { dbapi.setDevicePhoneState(message.serial, message) appDealer.send([channel, data]) }) - .on(wire.RotationEvent, (channel, message, data) => { + .on(RotationEvent, (channel, message, data) => { dbapi.setDeviceRotation(message) appDealer.send([channel, data]) }) - .on(wire.CapabilitiesMessage, (channel, message, data) => { + .on(CapabilitiesMessage, (channel, message, data) => { dbapi.setDeviceCapabilities(message) appDealer.send([channel, data]) }) - .on(wire.ReverseForwardsEvent, (channel, message, data) => { + .on(ReverseForwardsEvent, (channel, message, data) => { dbapi.setDeviceReverseForwards(message.serial, message.forwards) appDealer.send([channel, data]) }) - .on(wire.SetDeviceDisplay, (channel, message, data) => { + .on(SetDeviceDisplay, (channel, message, data) => { dbapi .setDeviceSocketDisplay(message) .then(function(response) { @@ -233,7 +234,7 @@ export default db.ensureConnectivity(async function(options) { log.error('setDeviceSocketDisplay', err) }) }) - .on(wire.UpdateIosDevice, (channel, message, data) => { + .on(UpdateIosDevice, (channel, message, data) => { dbapi .updateIosDevice(message) .then(result => { @@ -243,7 +244,7 @@ export default db.ensureConnectivity(async function(options) { log.info('UpdateIosDevice error: %s', err?.message) }) }) - .on(wire.SdkIosVersion, (channel, message, data) => { + .on(SdkIosVersion, (channel, message, data) => { dbapi .setDeviceIosVersion(message) .then(result => { @@ -253,7 +254,7 @@ export default db.ensureConnectivity(async function(options) { log.info('SdkIosVersion error: %s', err?.message) }) }) - .on(wire.SizeIosDevice, (channel, message, data) => { + .on(SizeIosDevice, (channel, message, data) => { dbapi.sizeIosDevice(message.id, message.height, message.width, message.scale).then(result => { log.info('SizeIosDevice: %s', result) }).catch(err => { @@ -261,16 +262,16 @@ export default db.ensureConnectivity(async function(options) { }) appDealer.send([channel, data]) }) - .on(wire.DeviceTypeMessage, (channel, message, data) => { + .on(DeviceTypeMessage, (channel, message, data) => { dbapi.setDeviceType(message.serial, message.type) }) - .on(wire.DeleteDevice, (channel, message, data) => { + .on(DeleteDevice, (channel, message, data) => { dbapi.deleteDevice(message.serial) }) - .on(wire.SetAbsentDisconnectedDevices, (channel, message, data) => { + .on(SetAbsentDisconnectedDevices, (channel, message, data) => { dbapi.setAbsentDisconnectedDevices() }) - .on(wire.GetServicesAvailabilityMessage, (channel, message, data) => { + .on(GetServicesAvailabilityMessage, (channel, message, data) => { dbapi.setDeviceServicesAvailability(message.serial, message) appDealer.send([channel, data]) }) diff --git a/lib/units/provider/ADBObserver.ts b/lib/units/provider/ADBObserver.ts index fcc37487da..33fcfade03 100644 --- a/lib/units/provider/ADBObserver.ts +++ b/lib/units/provider/ADBObserver.ts @@ -1,9 +1,11 @@ import EventEmitter from 'events' import net, {Socket} from 'net' +export type ADBDeviceType = 'unknown' | 'bootloader' | 'device' | 'recovery' | 'sideload' | 'offline' | 'unauthorized' | 'unknown' // https://android.googlesource.com/platform/system/core/+/android-4.4_r1/adb/adb.c#394 + interface ADBDevice { serial: string - type: 'device' | 'unknown' | 'offline' | 'unauthorized' | 'recovery' + type: ADBDeviceType reconnect: () => Promise } @@ -240,7 +242,7 @@ class ADBObserver extends EventEmitter { reject(new Error('Connection closed')) } this.pendingRequests.clear() - + // Auto-reconnect if we should continue polling if (this.shouldContinuePolling && !this.isDestroyed) { this.ensureConnection().catch(err => { @@ -258,7 +260,7 @@ class ADBObserver extends EventEmitter { /** * Process ADB protocol responses and return remaining buffer */ - private processADBResponses(buffer: Buffer): Buffer { + private processADBResponses(buffer: Buffer): Buffer { let offset = 0 while (offset < buffer.length) { @@ -277,7 +279,7 @@ class ADBObserver extends EventEmitter { } const responseData = buffer.subarray(offset + 8, offset + 8 + dataLength).toString('utf-8') - + if (status === 'OKAY') { // Find and resolve the corresponding request const requestId = 'host:devices' // For now, we only handle device listing @@ -308,7 +310,7 @@ class ADBObserver extends EventEmitter { */ private async sendADBCommand(command: string): Promise { const connection = await this.ensureConnection() - + return new Promise((resolve, reject) => { // Store the request for response matching this.pendingRequests.set(command, {resolve, reject}) @@ -337,7 +339,7 @@ class ADBObserver extends EventEmitter { this.connection.destroy() this.connection = null } - + // Reject any pending requests for (const [, {reject}] of this.pendingRequests) { reject(new Error('Connection closed')) diff --git a/lib/units/provider/index.ts b/lib/units/provider/index.ts index 3200c92653..9156a0884f 100644 --- a/lib/units/provider/index.ts +++ b/lib/units/provider/index.ts @@ -10,6 +10,7 @@ import db from '../../db/index.js' import dbapi from '../../db/api.js' import {ChildProcess} from 'node:child_process' import ADBObserver, {ADBDevice} from './ADBObserver.js' +import { DeviceRegisteredMessage } from '../../wire/wire.ts' interface DeviceWorker { state: 'waiting' | 'running' @@ -66,7 +67,7 @@ export default (async function(options: Options) { })) } catch (err) { - log.fatal('Unable to connect to push endpoint', err) + log.fatal('Unable to connect to push endpoint: %s', err) lifecycle.fatal() } @@ -87,7 +88,7 @@ export default (async function(options: Options) { }) sub.on('message', new WireRouter() - .on(wire.DeviceRegisteredMessage, (channel, message) => { + .on(DeviceRegisteredMessage, (channel, message) => { if (workers[message.serial]?.resolveRegister) { workers[message.serial].resolveRegister!() delete workers[message.serial]?.resolveRegister @@ -97,7 +98,7 @@ export default (async function(options: Options) { ) } catch (err) { - log.fatal('Unable to connect to sub endpoint', err) + log.fatal('Unable to connect to sub endpoint: %s', err) lifecycle.fatal() } @@ -160,8 +161,7 @@ export default (async function(options: Options) { proc.removeAllListeners('message') if (signal) { - log.warn('Device worker "%s" was killed with signal %s, assuming ' + - 'deliberate action and not restarting', device.serial, signal) + log.warn('Device worker "%s" was killed with signal %s, assuming deliberate action and not restarting', device.serial, signal) if (workers[device.serial].state === 'running') { workers[device.serial].terminate() diff --git a/lib/units/reaper/index.js b/lib/units/reaper/index.js index 20529d9711..af4a59f442 100644 --- a/lib/units/reaper/index.js +++ b/lib/units/reaper/index.js @@ -9,6 +9,7 @@ import srv from '../../util/srv.js' import TtlSet from '../../util/ttlset.js' import * as zmqutil from '../../util/zmqutil.js' import db from '../../db/index.js' +import {DeviceIntroductionMessage, DeviceHeartbeatMessage, DeviceAbsentMessage} from '../../wire/wire.js' const log = logger.createLogger('reaper') export default (async function(options) { @@ -76,15 +77,15 @@ export default (async function(options) { } function listenToChanges() { sub.on('message', new WireRouter() - .on(wire.DeviceIntroductionMessage, function(channel, message) { + .on(DeviceIntroductionMessage, function(channel, message) { message.status = 3 ttlset.drop(message.serial, TtlSet.SILENT) ttlset.bump(message.serial, Date.now()) }) - .on(wire.DeviceHeartbeatMessage, function(channel, message) { + .on(DeviceHeartbeatMessage, function(channel, message) { ttlset.bump(message.serial, Date.now()) }) - .on(wire.DeviceAbsentMessage, function(channel, message) { + .on(DeviceAbsentMessage, function(channel, message) { ttlset.drop(message.serial, TtlSet.SILENT) }) .handler()) diff --git a/lib/units/tizen-device/index.js b/lib/units/tizen-device/index.js index 0f0c5b6666..b2368f042d 100644 --- a/lib/units/tizen-device/index.js +++ b/lib/units/tizen-device/index.js @@ -16,6 +16,7 @@ import router from '../base-device/support/router.js' import identity from './plugins/identity.js' import launcher from './plugins/launcher.js' import filesystem from './plugins/filesystem.js' +import {DeviceRegisteredMessage} from '../../wire/wire.js' const log = logger.createLogger('tizen-device') const isTcpPortOpen = (host, port, timeout = 2_000) => new Promise((resolve) => { @@ -59,7 +60,7 @@ export default (async(options) => syrup.serial() let listener const waitRegister = Promise.race([ new Promise(resolve => - router.on(wire.DeviceRegisteredMessage, listener = (...args) => resolve(args)) + router.on(DeviceRegisteredMessage, listener = (...args) => resolve(args)) ), new Promise(r => setTimeout(r, 15000)) ]) diff --git a/lib/units/tizen-device/plugins/filesystem.js b/lib/units/tizen-device/plugins/filesystem.js index 3e4c3e1dce..63564c20ef 100644 --- a/lib/units/tizen-device/plugins/filesystem.js +++ b/lib/units/tizen-device/plugins/filesystem.js @@ -9,6 +9,7 @@ import logger from '../../../util/logger.js' import storage from '../../base-device/support/storage.js' import {basename} from 'path' import {unlink} from 'fs' +import {FileSystemGetMessage, FileSystemListMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(push) @@ -41,7 +42,7 @@ export default syrup.serial() return storedFile } - router.on(wire.FileSystemGetMessage, async(channel, message) => { + router.on(FileSystemGetMessage, async(channel, message) => { try { const file = await uploadFromDevice(message.file, message.jwt) push.send([ @@ -77,7 +78,7 @@ export default syrup.serial() })) } - router.on(wire.FileSystemListMessage, async(channel, message) => { + router.on(FileSystemListMessage, async(channel, message) => { try { push.send([ channel, diff --git a/lib/units/tizen-device/plugins/identity.js b/lib/units/tizen-device/plugins/identity.js index 8a694da8fb..9696f3e19f 100644 --- a/lib/units/tizen-device/plugins/identity.js +++ b/lib/units/tizen-device/plugins/identity.js @@ -5,6 +5,7 @@ import wire from '../../../wire/index.js' import wireutil from '../../../wire/util.js' import push from '../../base-device/support/push.js' import {exec} from 'child_process' +import {ProbeMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(push) @@ -29,7 +30,7 @@ export default syrup.serial() }) }) - router.on(wire.ProbeMessage, () => { + router.on(ProbeMessage, () => { push.send([ wireutil.global, wireutil.envelope(new wire.DeviceIdentityMessage( diff --git a/lib/units/tizen-device/plugins/install.js b/lib/units/tizen-device/plugins/install.js index e0f8ef1978..ceb3a5de1c 100644 --- a/lib/units/tizen-device/plugins/install.js +++ b/lib/units/tizen-device/plugins/install.js @@ -7,6 +7,7 @@ import storage from '../../base-device/support/storage.js' import sdb from './sdb' import launcher from './launcher' import deviceutil from '../../../util/deviceutil.js' +import {InstallMessage, UninstallIosMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(router) @@ -18,7 +19,7 @@ export default syrup.serial() const log = logger.createLogger('tizen-device:plugins:install') const reply = wireutil.reply(options.serial) - router.on(wire.InstallMessage, async function(channel, message) { + router.on(InstallMessage, async function(channel, message) { log.info('Installing application from "%s"', message.href, message.launch ? '[ LAUNCH ]' : '') const sendProgress = (data, progress) => @@ -45,7 +46,7 @@ export default syrup.serial() sendProgress('installing_app', 100) }) - router.on(wire.UninstallIosMessage, function(channel, message) { + router.on(UninstallIosMessage, function(channel, message) { uninstallApp(options.serial, message.packageName) }) }) diff --git a/lib/units/tizen-device/plugins/launcher.js b/lib/units/tizen-device/plugins/launcher.js index ee4420c540..ae9839a883 100644 --- a/lib/units/tizen-device/plugins/launcher.js +++ b/lib/units/tizen-device/plugins/launcher.js @@ -6,6 +6,7 @@ import sdb from './sdb/index.js' import wire from '../../../wire/index.js' import wireutil from '../../../wire/util.js' import webinspector from './webinspector.js' +import {GetInstalledApplications, KillDeviceApp, LaunchDeviceApp, TerminateDeviceApp} from '../../../wire/wire.js' export default syrup.serial() .dependency(push) @@ -57,16 +58,16 @@ export default syrup.serial() group.on('join', () => plugin.killApp(true)) router - .on(wire.GetInstalledApplications, async(channel) => + .on(GetInstalledApplications, async(channel) => success(channel, Object.fromEntries(await sdb.getApps())) ) - .on(wire.LaunchDeviceApp, plugin.launchApp) + .on(LaunchDeviceApp, plugin.launchApp) - .on(wire.TerminateDeviceApp, async(channel) => + .on(TerminateDeviceApp, async(channel) => success(channel, await plugin.killApp()) ) - .on(wire.KillDeviceApp, async(channel) => + .on(KillDeviceApp, async(channel) => success(channel, await plugin.killApp(true)) ) } diff --git a/lib/units/vnc-device/plugins/group.js b/lib/units/vnc-device/plugins/group.js index 50fa723816..11dc7d4d52 100755 --- a/lib/units/vnc-device/plugins/group.js +++ b/lib/units/vnc-device/plugins/group.js @@ -14,6 +14,7 @@ import router from '../../base-device/support/router.js' import push from '../../base-device/support/push.js' import sub from '../../base-device/support/sub.js' import channels from '../../base-device/support/channels.js' +import {GroupMessage, AutoGroupMessage, UngroupMessage} from '../../../wire/wire.js' export default syrup.serial() .dependency(solo) @@ -116,7 +117,7 @@ export default syrup.serial() } router - .on(wire.GroupMessage, (channel, message) => { + .on(GroupMessage, (channel, message) => { let reply = wireutil.reply(options.serial) Promise.method(() => { return plugin.join(message.owner, message.timeout, message.usage) @@ -140,7 +141,7 @@ export default syrup.serial() ]) }) }) - .on(wire.AutoGroupMessage, (channel, message) => { + .on(AutoGroupMessage, (channel, message) => { return plugin.join(message.owner, message.timeout, message.identifier) .then(() => { plugin.emit('autojoin', message.identifier, true) @@ -149,7 +150,7 @@ export default syrup.serial() plugin.emit('autojoin', message.identifier, false) }) }) - .on(wire.UngroupMessage, (channel, message) => { + .on(UngroupMessage, (channel, message) => { let reply = wireutil.reply(options.serial) Promise.method(() => { return plugin.leave('ungroup_request') diff --git a/lib/units/vnc-device/plugins/screen/stream.js b/lib/units/vnc-device/plugins/screen/stream.js index 6bc74f1c44..9dc4d22608 100755 --- a/lib/units/vnc-device/plugins/screen/stream.js +++ b/lib/units/vnc-device/plugins/screen/stream.js @@ -15,6 +15,7 @@ import router from '../../../base-device/support/router.js' import group from '../group.js' import {decode} from '../../../../util/jwtutil.js' import {NoGroupError} from '../../../../util/grouputil.js' +import {GestureStartMessage, GestureStopMessage, TouchDownMessage, TouchMoveMessage, TouchUpMessage, TouchCommitMessage, TouchResetMessage, TypeMessage, KeyDownMessage, KeyUpMessage} from '../../../../wire/wire.js' export default syrup.serial() .dependency(solo) @@ -127,34 +128,34 @@ export default syrup.serial() }) router - .on(wire.GestureStartMessage, function(channel, message) { + .on(GestureStartMessage, function(channel, message) { }) - .on(wire.GestureStopMessage, function(channel, message) { + .on(GestureStopMessage, function(channel, message) { }) - .on(wire.TouchDownMessage, function(channel, message) { + .on(TouchDownMessage, function(channel, message) { lastClicked.x = message.x * height lastClicked.y = message.y * width r.pointerEvent(message.x * height, message.y * width, 1) }) - .on(wire.TouchMoveMessage, function(channel, message) { + .on(TouchMoveMessage, function(channel, message) { }) - .on(wire.TouchUpMessage, function(channel, message) { + .on(TouchUpMessage, function(channel, message) { }) - .on(wire.TouchCommitMessage, function(channel, message) { + .on(TouchCommitMessage, function(channel, message) { }) - .on(wire.TouchResetMessage, function(channel, message) { + .on(TouchResetMessage, function(channel, message) { }) - .on(wire.TypeMessage, function(channel, message) { + .on(TypeMessage, function(channel, message) { let keyCode = message.text.charCodeAt(0) r.keyEvent(keyCode, 1) r.keyEvent(keyCode, 0) r.requestUpdate(false, 0, 0, r.width, r.height) }) - .on(wire.KeyDownMessage, function(channel, message) { + .on(KeyDownMessage, function(channel, message) { r.keyEvent(keyNameToX11KeyCode(message.key), 1) r.requestUpdate(false, 0, 0, r.width, r.height) }) - .on(wire.KeyUpMessage, function(channel, message) { + .on(KeyUpMessage, function(channel, message) { r.keyEvent(keyNameToX11KeyCode(message.key), 0) r.requestUpdate(false, 0, 0, r.width, r.height) }) diff --git a/lib/units/websocket/index.js b/lib/units/websocket/index.js index bb0153eedf..70243e570a 100644 --- a/lib/units/websocket/index.js +++ b/lib/units/websocket/index.js @@ -25,6 +25,7 @@ import {Server} from 'socket.io' import db from '../../db/index.js' import EventEmitter from 'events' import generateToken from '../api/helpers/generateToken.js' +import {UpdateAccessTokenMessage, DeleteUserMessage, DeviceChangeMessage, UserChangeMessage, GroupChangeMessage, DeviceGroupChangeMessage, GroupUserChangeMessage, DeviceLogMessage, DeviceIntroductionMessage, DeviceReadyMessage, DevicePresentMessage, DeviceAbsentMessage, InstalledApplications, JoinGroupMessage, JoinGroupByAdbFingerprintMessage, LeaveGroupMessage, DeviceStatusMessage, DeviceIdentityMessage, TransactionProgressMessage, TransactionDoneMessage, TransactionTreeMessage, DeviceLogcatEntryMessage, AirplaneModeEvent, BatteryEvent, GetServicesAvailabilityMessage, DeviceBrowserMessage, ConnectivityEvent, PhoneStateEvent, RotationEvent, CapabilitiesMessage, ReverseForwardsEvent, TemporarilyUnavailableMessage, UpdateRemoteConnectUrl} from '../../wire/wire.js' const request = Promise.promisifyAll(postmanRequest) export default (async function(options) { const log = logger.createLogger('websocket') @@ -103,13 +104,13 @@ export default (async function(options) { } let disconnectSocket var messageListener = new WireRouter() - .on(wire.UpdateAccessTokenMessage, function() { + .on(UpdateAccessTokenMessage, function() { socket.emit('user.keys.accessToken.updated') }) - .on(wire.DeleteUserMessage, function() { + .on(DeleteUserMessage, function() { disconnectSocket(true) }) - .on(wire.DeviceChangeMessage, function(channel, message) { + .on(DeviceChangeMessage, function(channel, message) { if (user.groups.subscribed.indexOf(message.device.group.id) > -1) { socket.emit('device.change', { important: true, @@ -124,12 +125,12 @@ export default (async function(options) { socket.emit('user.settings.devices.' + message.action, message) } }) - .on(wire.UserChangeMessage, function(channel, message) { + .on(UserChangeMessage, function(channel, message) { Promise.map(message.targets, function(target) { socket.emit('user.' + target + '.users.' + message.action, message) }) }) - .on(wire.GroupChangeMessage, function(channel, message) { + .on(GroupChangeMessage, function(channel, message) { if (user.privilege === 'admin' || user.email === message.group.owner.email || !apiutil.isOriginGroup(message.group.class) && @@ -140,7 +141,7 @@ export default (async function(options) { socket.emit('user.view.groups.' + message.action, message) } }) - .on(wire.DeviceGroupChangeMessage, function(channel, message) { + .on(DeviceGroupChangeMessage, function(channel, message) { if (user.groups.subscribed.indexOf(message.id) > -1) { if (user.groups.subscribed.indexOf(message.group.id) > -1) { socket.emit('device.updateGroupDevice', { @@ -159,7 +160,7 @@ export default (async function(options) { socket.emit('device.addGroupDevices', {important: true, devices: [message.serial]}) } }) - .on(wire.GroupUserChangeMessage, function(channel, message) { + .on(GroupUserChangeMessage, function(channel, message) { if (message.users.indexOf(user.email) > -1) { if (message.isAdded) { user.groups.subscribed = _.union(user.groups.subscribed, [message.id]) @@ -182,10 +183,10 @@ export default (async function(options) { } } }) - .on(wire.DeviceLogMessage, function(channel, message) { + .on(DeviceLogMessage, function(channel, message) { io.emit('logcat.log', message) }) - .on(wire.DeviceIntroductionMessage, function(channel, message) { + .on(DeviceIntroductionMessage, function(channel, message) { if (message && message.group && user.groups.subscribed.indexOf(message.group.id) > -1) { io.emit('device.add', { important: true, @@ -202,7 +203,7 @@ export default (async function(options) { }) } }) - .on(wire.DeviceReadyMessage, function(channel, message) { + .on(DeviceReadyMessage, function(channel, message) { io.emit('device.change', { important: true, data: { @@ -214,7 +215,7 @@ export default (async function(options) { } }) }) - .on(wire.DevicePresentMessage, function(channel, message) { + .on(DevicePresentMessage, function(channel, message) { io.emit('device.change', { important: true, data: { @@ -223,7 +224,7 @@ export default (async function(options) { } }) }) - .on(wire.DeviceAbsentMessage, function(channel, message) { + .on(DeviceAbsentMessage, function(channel, message) { io.emit('device.remove', { important: true, data: { @@ -233,7 +234,7 @@ export default (async function(options) { } }) }) - .on(wire.InstalledApplications, function(channel, message, data) { + .on(InstalledApplications, function(channel, message, data) { socket.emit('device.applications', { important: true, data: { @@ -243,7 +244,7 @@ export default (async function(options) { }) }) // @TODO refactore JoimGroupMessage route - .on(wire.JoinGroupMessage, function(channel, message) { + .on(JoinGroupMessage, function(channel, message) { dbapi.getInstalledApplications({serial: message.serial}) .then(applications => { if (!user?.ownedChannels) { @@ -283,13 +284,13 @@ export default (async function(options) { }) }) }) - .on(wire.JoinGroupByAdbFingerprintMessage, function(channel, message) { + .on(JoinGroupByAdbFingerprintMessage, function(channel, message) { socket.emit('user.keys.adb.confirm', { title: message.comment, fingerprint: message.fingerprint }) }) - .on(wire.LeaveGroupMessage, function(channel, message) { + .on(LeaveGroupMessage, function(channel, message) { io.emit('device.change', { important: true, data: datautil.applyOwner({ @@ -299,33 +300,33 @@ export default (async function(options) { }, user) }) }) - .on(wire.DeviceStatusMessage, function(channel, message) { + .on(DeviceStatusMessage, function(channel, message) { message.likelyLeaveReason = 'status_change' io.emit('device.change', { important: true, data: message }) }) - .on(wire.DeviceIdentityMessage, function(channel, message) { + .on(DeviceIdentityMessage, function(channel, message) { datautil.applyData(message) io.emit('device.change', { important: true, data: message }) }) - .on(wire.TransactionProgressMessage, function(channel, message) { + .on(TransactionProgressMessage, function(channel, message) { socket.emit('tx.progress', channel.toString(), message) }) - .on(wire.TransactionDoneMessage, function(channel, message) { + .on(TransactionDoneMessage, function(channel, message) { socket.emit('tx.done', channel.toString(), message) }) - .on(wire.TransactionTreeMessage, function(channel, message) { + .on(TransactionTreeMessage, function(channel, message) { socket.emit('tx.tree', channel.toString(), message) }) - .on(wire.DeviceLogcatEntryMessage, function(channel, message) { + .on(DeviceLogcatEntryMessage, function(channel, message) { socket.emit('logcat.entry', message) }) - .on(wire.AirplaneModeEvent, function(channel, message) { + .on(AirplaneModeEvent, function(channel, message) { io.emit('device.change', { important: true, data: { @@ -334,7 +335,7 @@ export default (async function(options) { } }) }) - .on(wire.BatteryEvent, function(channel, message) { + .on(BatteryEvent, function(channel, message) { var {serial} = message delete message.serial io.emit('device.change', { @@ -345,7 +346,7 @@ export default (async function(options) { } }) }) - .on(wire.GetServicesAvailabilityMessage, function(channel, message) { + .on(GetServicesAvailabilityMessage, function(channel, message) { let serial = message.serial delete message.serial io.emit('device.change', { @@ -356,7 +357,7 @@ export default (async function(options) { } }) }) - .on(wire.DeviceBrowserMessage, function(channel, message) { + .on(DeviceBrowserMessage, function(channel, message) { var {serial} = message delete message.serial io.emit('device.change', { @@ -367,7 +368,7 @@ export default (async function(options) { }) }) }) - .on(wire.ConnectivityEvent, function(channel, message) { + .on(ConnectivityEvent, function(channel, message) { var {serial} = message delete message.serial io.emit('device.change', { @@ -378,7 +379,7 @@ export default (async function(options) { } }) }) - .on(wire.PhoneStateEvent, function(channel, message) { + .on(PhoneStateEvent, function(channel, message) { var {serial} = message delete message.serial io.emit('device.change', { @@ -389,7 +390,7 @@ export default (async function(options) { } }) }) - .on(wire.RotationEvent, function(channel, message) { + .on(RotationEvent, function(channel, message) { socket.emit('device.change', { important: false, data: { @@ -400,7 +401,7 @@ export default (async function(options) { } }) }) - .on(wire.CapabilitiesMessage, function(channel, message) { + .on(CapabilitiesMessage, function(channel, message) { socket.emit('device.change', { important: false, data: { @@ -412,7 +413,7 @@ export default (async function(options) { } }) }) - .on(wire.ReverseForwardsEvent, function(channel, message) { + .on(ReverseForwardsEvent, function(channel, message) { socket.emit('device.change', { important: false, data: { @@ -421,14 +422,14 @@ export default (async function(options) { } }) }) - .on(wire.TemporarilyUnavailableMessage, function(channel, message) { + .on(TemporarilyUnavailableMessage, function(channel, message) { socket.emit('temporarily-unavailable', { data: { removeConnectUrl: message.removeConnectUrl } }) }) - .on(wire.UpdateRemoteConnectUrl, function(channel, message) { + .on(UpdateRemoteConnectUrl, function(channel, message) { socket.emit('device.change', { important: true, data: { diff --git a/lib/util/apiutil.js b/lib/util/apiutil.js index d10c77cf87..7e33ab56bb 100644 --- a/lib/util/apiutil.js +++ b/lib/util/apiutil.js @@ -3,9 +3,9 @@ import _ from 'lodash' import logger from './logger.js' import datautil from './datautil.js' import wireutil from '../wire/util.js' -import wire from '../wire/index.js' import * as Sentry from '@sentry/node' import {v4 as uuidv4} from 'uuid' +import {ConnectGetForwardUrlMessage} from '../wire/wire.js' const log = logger.createLogger('api:controllers:apiutil') export const PENDING = 'pending' export const READY = 'ready' @@ -140,7 +140,7 @@ export const filterDevice = function(req, device) { let responseChannel = 'txn_' + uuidv4() req.options.push.send([ device.channel, - wireutil.transaction(responseChannel, new wire.ConnectGetForwardUrlMessage()) + wireutil.transaction(responseChannel, ConnectGetForwardUrlMessage.create()) ]) } if (fields) { diff --git a/lib/util/devutil.js b/lib/util/devutil.js index 0de51c695f..132663ee93 100644 --- a/lib/util/devutil.js +++ b/lib/util/devutil.js @@ -13,7 +13,7 @@ export default syrup.serial() devutil.executeShellCommand = function(command) { return adb.getDevice(options.serial).execOut(command).then(result => { - log.debug('executing shell command ' + command, result) + log.debug(`executing shell command ${command}, %s`, result) }) } devutil.ensureUnusedLocalSocket = function(sock) { diff --git a/lib/util/grouputil.js b/lib/util/grouputil.js index f8123242f4..caade52508 100644 --- a/lib/util/grouputil.js +++ b/lib/util/grouputil.js @@ -3,6 +3,7 @@ import Promise from 'bluebird' import semver from 'semver' import minimatch from 'minimatch' import wire from '../wire/index.js' +import {RequirementType} from '../wire/wire.js' function RequirementMismatchError(name) { Error.call(this) this.name = 'RequirementMismatchError' @@ -33,17 +34,17 @@ export const match = Promise.method(function(capabilities, requirements) { throw new RequirementMismatchError(req.name) } switch (req.type) { - case wire.RequirementType.SEMVER: + case RequirementType.SEMVER: if (!semver.satisfies(capability, req.value)) { throw new RequirementMismatchError(req.name) } break - case wire.RequirementType.GLOB: + case RequirementType.GLOB: if (!minimatch(capability, req.value)) { throw new RequirementMismatchError(req.name) } break - case wire.RequirementType.EXACT: + case RequirementType.EXACT: if (capability !== req.value) { throw new RequirementMismatchError(req.name) } diff --git a/lib/util/lifecycle.js b/lib/util/lifecycle.js deleted file mode 100644 index ef26d77fbb..0000000000 --- a/lib/util/lifecycle.js +++ /dev/null @@ -1,68 +0,0 @@ -import Promise from 'bluebird' -import logger from './logger.js' - -const log = logger.createLogger('util:lifecycle') - -export default new class Lifecycle { - observers = [] - ending = false - - constructor() { - process.on('SIGINT', this.graceful.bind(this)) - process.on('SIGTERM', this.graceful.bind(this)) - } - - share(name, emitter, options) { - const opts = Object.assign({ - end: true, error: true - }, options) - - if (opts.end) { - emitter.on('end', () => { - if (!this.ending) { - log.fatal(`${name} ended; we shall share its fate`) - this.fatal() - } - }) - } - - if (opts.error) { - emitter.on('error', (err) => { - if (!this.ending) { - log.fatal(`${name} had an error ${err.stack}`) - this.fatal() - } - }) - } - - if (emitter.end) { - this.observe(() => { - emitter.end() - }) - } - return emitter - } - - graceful(err) { - log.info(`Winding down for graceful exit ${err || ''}`) - if (this.ending) { - log.error('Repeated gracefull shutdown request. Exiting immediately.') - process.exit(1) - } - - this.ending = true - return Promise.all(this.observers.map(fn => fn())) - .then(() => process.exit(0)) - } - - /** @returns {any} */ - fatal(/** @type {any} */ err) { - log.fatal(`Shutting down due to fatal error ${err || ''}`) - this.ending = true - process.exit(1) - } - - observe(promise) { - this.observers.push(promise) - } -}() diff --git a/lib/util/lifecycle.ts b/lib/util/lifecycle.ts new file mode 100644 index 0000000000..0948079e8d --- /dev/null +++ b/lib/util/lifecycle.ts @@ -0,0 +1,66 @@ +import EventEmitter from "node:events"; +import logger from "./logger.ts"; + +const log = logger.createLogger("util:lifecycle"); + +type LifecycleObserver = () => Promise | unknown; + +export default new (class Lifecycle { + cleanups: LifecycleObserver[] = []; + ending = false; + + constructor() { + process.on("SIGINT", this.graceful.bind(this)); + process.on("SIGTERM", this.graceful.bind(this)); + } + + share(name: string, emitter: EventEmitter) { + emitter.on("end", () => { + if (!this.ending) { + log.fatal(`${name} ended; we shall share its fate`) + this.fatal(); + } + }); + + emitter.on("error", (err) => { + if (!this.ending) { + log.fatal(`${name} had an error ${err.stack}`) + this.fatal(); + } + }); + + if ('end' in emitter) { + this.observe(() => { + if(typeof emitter.end === 'function') { + emitter.end(); + } + }); + } + return emitter; + } + + graceful(err: Error) { + log.info(`Winding down for graceful exit ${err || ''}`) + if (this.ending) { + log.error( + "Repeated gracefull shutdown request. Exiting immediately." + ); + process.exit(1); + } + + this.ending = true; + return Promise.all(this.cleanups.map((fn) => fn())).then(() => + process.exit(0) + ); + } + + fatal(err?: Error | string): never { + log.fatal(`Shutting down due to fatal error ${err || ''}`) + this.ending = true; + process.exit(1); + } + + observe(cleanupFn: LifecycleObserver) { + this.cleanups.push(cleanupFn); + } +})(); diff --git a/lib/util/logger.ts b/lib/util/logger.ts index dd5faefc39..1c70342bd8 100644 --- a/lib/util/logger.ts +++ b/lib/util/logger.ts @@ -14,7 +14,17 @@ export enum LogLevel { const innerLogger = new EventEmitter() -type LogArguments = [string, ...any[]] +type BuildLog< + N extends number, + S extends any[] = [] // counter +> = + S['length'] extends N + ? [string, []] // base: just string + no args + : [`${BuildLog[0]}%s${string}`, [...BuildLog[1], any]]; + +type NLog = [BuildLog[0], ...BuildLog[1]] + +type LogArguments = NLog<0> | NLog<1> | NLog<2> | NLog<3> | NLog<4> export interface LogEntry { unit: string; @@ -117,7 +127,8 @@ export class Log extends EventEmitter { } private _format(entry: LogEntry): string { - entry.message = printf(...entry.args) + const args = entry.args as [string, ...any[]] + entry.message = printf(...args) const [fg, bg] = Log.unitColors[entry.unit] ?? [chalk.yellow, chalk.bgYellow] return ( `${chalk.grey(entry.timestamp.toJSON())} ${fg(bg(entry.unit))} ${this._name(entry.priority)}/${chalk.bold(entry.tag)} ${entry.pid} [${entry.identifier}] ${entry.message}\n` diff --git a/lib/util/srv.ts b/lib/util/srv.ts index 66179b1f9d..ba2114852d 100644 --- a/lib/util/srv.ts +++ b/lib/util/srv.ts @@ -3,7 +3,6 @@ import util from 'util' import dns from 'dns/promises' import {SrvRecord} from 'dns' import _ from 'lodash' -var srv = Object.create(null) function groupByPriority(records: SrvRecord[]) { return records .sort((a, b) => a.priority - b.priority) @@ -27,7 +26,7 @@ function shuffleWeighted(records: SrvRecord[]) { function pick(records: SrvRecord[], sum: number): SrvRecord[] { const rand = Math.random() * sum let counter = 0 - for (var i = 0, l = records.length; i < l; ++i) { + for (let i = 0, l = records.length; i < l; ++i) { counter += records[i].weight if (rand < counter) { const picked = records.splice(i, 1) diff --git a/lib/util/zmqutil.js b/lib/util/zmqutil.js index 2d1013b248..6098ff06d7 100644 --- a/lib/util/zmqutil.js +++ b/lib/util/zmqutil.js @@ -81,7 +81,7 @@ export class SocketWrapper extends EventEmitter { try { await this.socket.send( (Array.isArray(args) ? args : [args]) - .map(arg => Buffer.isBuffer(arg) ? arg : Buffer.from(String(arg))) + .map(arg => Buffer.isBuffer(arg) || ArrayBuffer.isView(arg) ? arg : Buffer.from(String(arg))) ) } catch (/** @type {any} */ err) { @@ -101,6 +101,10 @@ export class SocketWrapper extends EventEmitter { return this } + /** + * + * @returns {Promise} + */ async startReceiveLoop() { const isValidType = this.type === 'sub' || @@ -130,7 +134,7 @@ export class SocketWrapper extends EventEmitter { } } catch (/** @type {any} */ err) { - log.error('Error in message receive loop: %s', err?.message || err?.toString() || err) + log.error('Error in message receive loop: %s, %s', err?.message || err?.toString() || err, err.stack) return this.startReceiveLoop() } } diff --git a/lib/wire/google/protobuf/any.ts b/lib/wire/google/protobuf/any.ts new file mode 100644 index 0000000000..c13b7a74f2 --- /dev/null +++ b/lib/wire/google/protobuf/any.ts @@ -0,0 +1,326 @@ +// @generated by protobuf-ts 2.11.1 with parameter generate_dependencies +// @generated from protobuf file "google/protobuf/any.proto" (package "google.protobuf", syntax proto3) +// tslint:disable +// +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +import type { BinaryWriteOptions } from "@protobuf-ts/runtime"; +import type { IBinaryWriter } from "@protobuf-ts/runtime"; +import { WireType } from "@protobuf-ts/runtime"; +import type { IBinaryReader } from "@protobuf-ts/runtime"; +import { UnknownFieldHandler } from "@protobuf-ts/runtime"; +import type { PartialMessage } from "@protobuf-ts/runtime"; +import { reflectionMergePartial } from "@protobuf-ts/runtime"; +import { isJsonObject } from "@protobuf-ts/runtime"; +import { typeofJsonValue } from "@protobuf-ts/runtime"; +import type { JsonValue } from "@protobuf-ts/runtime"; +import { jsonWriteOptions } from "@protobuf-ts/runtime"; +import type { JsonReadOptions } from "@protobuf-ts/runtime"; +import type { JsonWriteOptions } from "@protobuf-ts/runtime"; +import type { BinaryReadOptions } from "@protobuf-ts/runtime"; +import type { IMessageType } from "@protobuf-ts/runtime"; +import { MessageType } from "@protobuf-ts/runtime"; +/** + * `Any` contains an arbitrary serialized protocol buffer message along with a + * URL that describes the type of the serialized message. + * + * Protobuf library provides support to pack/unpack Any values in the form + * of utility functions or additional generated methods of the Any type. + * + * Example 1: Pack and unpack a message in C++. + * + * Foo foo = ...; + * Any any; + * any.PackFrom(foo); + * ... + * if (any.UnpackTo(&foo)) { + * ... + * } + * + * Example 2: Pack and unpack a message in Java. + * + * Foo foo = ...; + * Any any = Any.pack(foo); + * ... + * if (any.is(Foo.class)) { + * foo = any.unpack(Foo.class); + * } + * // or ... + * if (any.isSameTypeAs(Foo.getDefaultInstance())) { + * foo = any.unpack(Foo.getDefaultInstance()); + * } + * + * Example 3: Pack and unpack a message in Python. + * + * foo = Foo(...) + * any = Any() + * any.Pack(foo) + * ... + * if any.Is(Foo.DESCRIPTOR): + * any.Unpack(foo) + * ... + * + * Example 4: Pack and unpack a message in Go + * + * foo := &pb.Foo{...} + * any, err := anypb.New(foo) + * if err != nil { + * ... + * } + * ... + * foo := &pb.Foo{} + * if err := any.UnmarshalTo(foo); err != nil { + * ... + * } + * + * The pack methods provided by protobuf library will by default use + * 'type.googleapis.com/full.type.name' as the type URL and the unpack + * methods only use the fully qualified type name after the last '/' + * in the type URL, for example "foo.bar.com/x/y.z" will yield type + * name "y.z". + * + * JSON + * ==== + * The JSON representation of an `Any` value uses the regular + * representation of the deserialized, embedded message, with an + * additional field `@type` which contains the type URL. Example: + * + * package google.profile; + * message Person { + * string first_name = 1; + * string last_name = 2; + * } + * + * { + * "@type": "type.googleapis.com/google.profile.Person", + * "firstName": , + * "lastName": + * } + * + * If the embedded message type is well-known and has a custom JSON + * representation, that representation will be embedded adding a field + * `value` which holds the custom JSON in addition to the `@type` + * field. Example (for message [google.protobuf.Duration][]): + * + * { + * "@type": "type.googleapis.com/google.protobuf.Duration", + * "value": "1.212s" + * } + * + * + * @generated from protobuf message google.protobuf.Any + */ +export interface Any { + /** + * A URL/resource name that uniquely identifies the type of the serialized + * protocol buffer message. This string must contain at least + * one "/" character. The last segment of the URL's path must represent + * the fully qualified name of the type (as in + * `path/google.protobuf.Duration`). The name should be in a canonical form + * (e.g., leading "." is not accepted). + * + * In practice, teams usually precompile into the binary all types that they + * expect it to use in the context of Any. However, for URLs which use the + * scheme `http`, `https`, or no scheme, one can optionally set up a type + * server that maps type URLs to message definitions as follows: + * + * * If no scheme is provided, `https` is assumed. + * * An HTTP GET on the URL must yield a [google.protobuf.Type][] + * value in binary format, or produce an error. + * * Applications are allowed to cache lookup results based on the + * URL, or have them precompiled into a binary to avoid any + * lookup. Therefore, binary compatibility needs to be preserved + * on changes to types. (Use versioned type names to manage + * breaking changes.) + * + * Note: this functionality is not currently available in the official + * protobuf release, and it is not used for type URLs beginning with + * type.googleapis.com. As of May 2023, there are no widely used type server + * implementations and no plans to implement one. + * + * Schemes other than `http`, `https` (or the empty scheme) might be + * used with implementation specific semantics. + * + * + * @generated from protobuf field: string type_url = 1 + */ + typeUrl: string; + /** + * Must be a valid serialized protocol buffer of the above specified type. + * + * @generated from protobuf field: bytes value = 2 + */ + value: Uint8Array; +} +// @generated message type with reflection information, may provide speed optimized methods +class Any$Type extends MessageType { + constructor() { + super("google.protobuf.Any", [ + { no: 1, name: "type_url", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "value", kind: "scalar", T: 12 /*ScalarType.BYTES*/ } + ]); + } + /** + * Pack the message into a new `Any`. + * + * Uses 'type.googleapis.com/full.type.name' as the type URL. + */ + pack(message: T, type: IMessageType): Any { + return { + typeUrl: this.typeNameToUrl(type.typeName), value: type.toBinary(message), + }; + } + /** + * Unpack the message from the `Any`. + */ + unpack(any: Any, type: IMessageType, options?: Partial): T { + if (!this.contains(any, type)) + throw new Error("Cannot unpack google.protobuf.Any with typeUrl '" + any.typeUrl + "' as " + type.typeName + "."); + return type.fromBinary(any.value, options); + } + /** + * Does the given `Any` contain a packed message of the given type? + */ + contains(any: Any, type: IMessageType | string): boolean { + if (!any.typeUrl.length) + return false; + let wants = typeof type == "string" ? type : type.typeName; + let has = this.typeUrlToName(any.typeUrl); + return wants === has; + } + /** + * Convert the message to canonical JSON value. + * + * You have to provide the `typeRegistry` option so that the + * packed message can be converted to JSON. + * + * The `typeRegistry` option is also required to read + * `google.protobuf.Any` from JSON format. + */ + internalJsonWrite(any: Any, options: JsonWriteOptions): JsonValue { + if (any.typeUrl === "") + return {}; + let typeName = this.typeUrlToName(any.typeUrl); + let opt = jsonWriteOptions(options); + let type = opt.typeRegistry?.find(t => t.typeName === typeName); + if (!type) + throw new globalThis.Error("Unable to convert google.protobuf.Any with typeUrl '" + any.typeUrl + "' to JSON. The specified type " + typeName + " is not available in the type registry."); + let value = type.fromBinary(any.value, { readUnknownField: false }); + let json = type.internalJsonWrite(value, opt); + if (typeName.startsWith("google.protobuf.") || !isJsonObject(json)) + json = { value: json }; + json["@type"] = any.typeUrl; + return json; + } + internalJsonRead(json: JsonValue, options: JsonReadOptions, target?: Any): Any { + if (!isJsonObject(json)) + throw new globalThis.Error("Unable to parse google.protobuf.Any from JSON " + typeofJsonValue(json) + "."); + if (typeof json["@type"] != "string" || json["@type"] == "") + return this.create(); + let typeName = this.typeUrlToName(json["@type"]); + let type = options?.typeRegistry?.find(t => t.typeName == typeName); + if (!type) + throw new globalThis.Error("Unable to parse google.protobuf.Any from JSON. The specified type " + typeName + " is not available in the type registry."); + let value; + if (typeName.startsWith("google.protobuf.") && json.hasOwnProperty("value")) + value = type.fromJson(json["value"], options); + else { + let copy = Object.assign({}, json); + delete copy["@type"]; + value = type.fromJson(copy, options); + } + if (target === undefined) + target = this.create(); + target.typeUrl = json["@type"]; + target.value = type.toBinary(value); + return target; + } + typeNameToUrl(name: string): string { + if (!name.length) + throw new Error("invalid type name: " + name); + return "type.googleapis.com/" + name; + } + typeUrlToName(url: string): string { + if (!url.length) + throw new Error("invalid type url: " + url); + let slash = url.lastIndexOf("/"); + let name = slash > 0 ? url.substring(slash + 1) : url; + if (!name.length) + throw new Error("invalid type url: " + url); + return name; + } + create(value?: PartialMessage): Any { + const message = globalThis.Object.create((this.messagePrototype!)); + message.typeUrl = ""; + message.value = new Uint8Array(0); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: Any): Any { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string type_url */ 1: + message.typeUrl = reader.string(); + break; + case /* bytes value */ 2: + message.value = reader.bytes(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: Any, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string type_url = 1; */ + if (message.typeUrl !== "") + writer.tag(1, WireType.LengthDelimited).string(message.typeUrl); + /* bytes value = 2; */ + if (message.value.length) + writer.tag(2, WireType.LengthDelimited).bytes(message.value); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message google.protobuf.Any + */ +export const Any = new Any$Type(); diff --git a/lib/wire/index.js b/lib/wire/index.js deleted file mode 100644 index fdfa458b9d..0000000000 --- a/lib/wire/index.js +++ /dev/null @@ -1,14 +0,0 @@ -import path from 'path' -import ProtoBuf from 'protobufjs' -var wire = ProtoBuf.loadProtoFile(path.join(import.meta.dirname, 'wire.proto')).build() -wire.ReverseMessageType = Object.keys(wire.MessageType) - .reduce(function(acc, type) { - var code = wire.MessageType[type] - if (!wire[type]) { - throw new Error('wire.MessageType has unknown value "' + type + '"') - } - wire[type].$code = wire[type].prototype.$code = code - acc[code] = type - return acc - }, Object.create(null)) -export default wire diff --git a/lib/wire/index.ts b/lib/wire/index.ts new file mode 100644 index 0000000000..a852eb53cc --- /dev/null +++ b/lib/wire/index.ts @@ -0,0 +1,35 @@ +import { MessageType } from "@protobuf-ts/runtime"; +import { createLogger } from "../util/logger.ts"; +const allClasses = await import('./wire.ts') + + +const log = createLogger('wire:legacy') + +interface UnknownMessage { + new(...args: unknown[]): T + type: MessageType +} + +const alerted = new Set() + +/** + * @deprecated Do not use the proxy for the constructor. Import the model directly from wire.ts + */ +export default new Proxy({} as Record>, { + get(target, prop, receiver) { + const messageType = (allClasses as any)[prop] as MessageType + if (!messageType) { + throw new Error(`Unknown message type tried constructing: ${prop.toString()}`) + } + if (!alerted.has(messageType.typeName)) { + alerted.add(messageType.typeName) + log.warn('Legacy contstructor lookup for %s', messageType.typeName) + } + const construct = function constructor(this: any, ...args: unknown[]) { + const message = messageType.create(Object.fromEntries(messageType.fields.map((name, index) => ([name.localName, args[index]])))) + Object.assign(this, message) + } + construct.type = messageType + return construct + } +}) diff --git a/lib/wire/messagestream.ts b/lib/wire/messagestream.ts index e0ea0e06ae..003ae9ce59 100644 --- a/lib/wire/messagestream.ts +++ b/lib/wire/messagestream.ts @@ -10,7 +10,7 @@ class DelimitedStream extends stream.Transform { this._buffer = Buffer.concat([this._buffer, chunk]) while (this._buffer.length) { if (this._readingLength) { - var byte = this._buffer[0] + const byte = this._buffer[0] this._length += (byte & 0x7f) << (7 * this._lengthIndex) if (byte & (1 << 7)) { this._lengthIndex += 1 diff --git a/lib/wire/router.ts b/lib/wire/router.ts index f0ab4eb122..eca2d22f87 100644 --- a/lib/wire/router.ts +++ b/lib/wire/router.ts @@ -1,61 +1,53 @@ -import EventEmitter from 'eventemitter3' -import wire from './index.js' -import logger from '../util/logger.js' +import EventEmitter from "eventemitter3"; +import logger from "../util/logger.js"; +import { MessageType } from "@protobuf-ts/runtime"; +import { Envelope } from "./wire.ts"; +import { Any } from "./google/protobuf/any.ts"; -const log = logger.createLogger('wire:router') -export interface WireMessage { - $code: string; -} +const log = logger.createLogger("wire:router"); -type EventType = string | symbol | WireMessage; +type MessageHandler = (channel: string, message: T) => unknown -export class WireRouter extends EventEmitter { - constructor() { - super() - } +export class WireRouter { + emitter = new EventEmitter() + registeredTypes = new Map> - on( - event: string | symbol, - fn: (...args: any[]) => void, - context?: any - ): this; - on(message: WireMessage, fn: (...args: any[]) => void): this; - on( - eventOrMessage: EventType, - fn: (...args: any[]) => void, - context?: any + on(eventName: string | symbol, fn: MessageHandler, context?: object): this; + on(messageType: MessageType, fn: MessageHandler): this; + on( + messageType: MessageType | string | symbol, + fn: MessageHandler, + context?: object ): this { if ( - typeof eventOrMessage !== 'string' && - typeof eventOrMessage !== 'symbol' && - '$code' in eventOrMessage + typeof messageType !== "string" && + typeof messageType !== "symbol" ) { // WireMessage - super.on(eventOrMessage.$code, fn) - } - else { - super.on(eventOrMessage as string | symbol, fn, context) + this.emitter.on(messageType.typeName, fn); + this.registeredTypes.set(Any.typeNameToUrl(messageType.typeName), messageType) + } else { + this.emitter.on(messageType, fn, context); } return this } - removeListener( - event: string | symbol, - fn: (...args: any[]) => void, - context?: any - ): this; - removeListener(message: WireMessage, fn: (...args: any[]) => void): this; - removeListener( - eventOrMessage: EventType, - fn: (...args: any[]) => void, - context?: any + removeAllListeners(messageType: MessageType) { + this.emitter.removeAllListeners(messageType.typeName) + } + + removeListener(eventName: string | symbol, fn: MessageHandler, context?: object): this; + removeListener(messageType: MessageType, fn: MessageHandler): this; + removeListener( + messageType: MessageType | string | symbol, + fn: MessageHandler, + context?: object ): this { - if (typeof eventOrMessage === 'object' && '$code' in eventOrMessage) { - super.removeListener(eventOrMessage.$code, fn) - } - else { - super.removeListener( - eventOrMessage as string | symbol, + if (typeof messageType === "object") { + this.emitter.removeListener(messageType.typeName, fn); + } else { + this.emitter.removeListener( + messageType, fn, context ) @@ -63,44 +55,48 @@ export class WireRouter extends EventEmitter { return this } - handler(): (channel: any, data: Uint8Array) => void { - return (channel: any, data: Uint8Array) => { - const wrapper = wire.Envelope.decode(data) - const type = wire.ReverseMessageType[wrapper.type] - let decodedMessage: any - - try { - decodedMessage = wire[type].decode(wrapper.message) + handler() { + return (channel: string, data: Buffer) => { + const decoded = Envelope.fromBinary(data); + if (!decoded.message) { + log.warn(`Message without message %s`, decoded) + return + } + let target = decoded.message.typeUrl; + if(!target) { + log.warn(`Message without typeUrl %s`, decoded) + return } - catch (e) { - log.error( - 'Received message with type "%s", but cant parse data ' + - wrapper.message - ) - throw e + const messageType = this.registeredTypes.get(target); + if (!messageType) { + // log.warn(`Unknown message type:`, decoded) + // Nobody is expecting such message type.. Ignoring.. + return } + const decodedMessage = Any.unpack(decoded.message, messageType) + // const wrapper = wire.Envelope.decode(data); + // const type = wire.ReverseMessageType[wrapper.type]; + // let decodedMessage: any; - log.info( - 'Received message with type "%s", and data %s', - type || wrapper.type, - JSON.stringify(decodedMessage) - ) + // try { + // decodedMessage = wire[type].decode(wrapper.message) + // } + // catch (e) { + // log.error( + // 'Received message with type "%s", but cant parse data ' + + // wrapper.message + // ); + // throw e; + // } - if (type) { - this.emit( - wrapper.type, - wrapper.channel || channel, - decodedMessage, - data - ) - this.emit('message', channel) - } - else { - log.warn( - 'Unknown message type "%d", perhaps we need an update?', - wrapper.type - ) - } + // log.info( + // 'Received message with type "%s", and data %s', + // messageType.typeName, + // messageType.toJsonString(decodedMessage) + // ) + + this.emitter.emit(messageType.typeName, decoded.channel || channel, decodedMessage, data) + this.emitter.emit('message', channel) } } } diff --git a/lib/wire/transmanager.js b/lib/wire/transmanager.js index 014bfb99e1..926b5ccfbb 100644 --- a/lib/wire/transmanager.js +++ b/lib/wire/transmanager.js @@ -4,6 +4,7 @@ import wire from './index.js' import {WireRouter} from './router.js' import * as Sentry from '@sentry/node' import wireutil from './util.js' +import {TransactionDoneMessage} from './wire.js' export const runTransaction = (channel, message, {sub, push, channelRouter, timeout = apiutil.GRPC_WAIT_TIMEOUT}) => { return Sentry.startSpan({ @@ -20,7 +21,7 @@ export const runTransaction = (channel, message, {sub, push, channelRouter, time sub.subscribe(responseChannel) return new Promise((resolve, reject) => { const messageListener = new WireRouter() - .on(wire.TransactionDoneMessage, function(channel, message) { + .on(TransactionDoneMessage, function(channel, message) { clearTimeout(trTimeout) sub.unsubscribe(responseChannel) channelRouter.removeListener(responseChannel, messageListener) diff --git a/lib/wire/util.js b/lib/wire/util.js deleted file mode 100644 index 8994705efa..0000000000 --- a/lib/wire/util.js +++ /dev/null @@ -1,63 +0,0 @@ -import {v4 as uuidv4} from 'uuid' -import wire from './index.js' -const wireutil = { - global: '*ALL', - makePrivateChannel: function() { - // @ts-ignore - return uuidv4(null, Buffer.alloc(16)).toString('base64') - }, - toDeviceStatus: function(type) { - return wire.DeviceStatus[{ - device: 'ONLINE', - emulator: 'ONLINE', - unauthorized: 'UNAUTHORIZED', - offline: 'OFFLINE', - connecting: 'CONNECTING', - authorizing: 'AUTHORIZING' - }[type]] - }, - toDeviceRequirements: function(/** @type {{ [x: string]: {value: string, match: "semver" | "glob" | "exact"}; }} */ requirements) { - return Object.keys(requirements).map(function(name) { - var item = requirements[name] - return new wire.DeviceRequirement(name, item.value, wire.RequirementType[item.match.toUpperCase()]) - }) - }, - toInstalledApps: function(installedApps) { - if (installedApps.length > 0) { - return installedApps.map(instApp => { - return new wire.Applications(instApp.bundleId, instApp.bundleName) - }) - } - else { - return [] - } - }, - envelope: function(message) { - return new wire.Envelope(message.$code, message.encode()).encodeNB() - }, - transaction: function(channel, message) { - return new wire.Envelope(message.$code, message.encode(), channel) - .encodeNB() - }, - reply: function(source) { - var seq = 0 - return { - okay: function(data, body) { - return wireutil.envelope(new wire.TransactionDoneMessage(source, seq++, true, data === null ? null : (data || 'success'), body ? JSON.stringify(body) : null)) - }, - fail: function(data, body) { - return wireutil.envelope(new wire.TransactionDoneMessage(source, seq++, false, data || 'fail', body ? JSON.stringify(body) : null)) - }, - tree: function(data, body) { - return wireutil.envelope(new wire.TransactionTreeMessage(source, seq++, true, data === null ? null : (data || 'success'), body ? JSON.stringify(body) : null)) - }, - progress: function(data, progress) { - return wireutil.envelope(new wire.TransactionProgressMessage(source, seq++, data, ~~progress)) - }, - device: function(data, body) { - return wireutil.envelope(new wire.TransationGetMessage(source, body ? JSON.stringify(body) : null)) - } - } - } -} -export default wireutil diff --git a/lib/wire/util.ts b/lib/wire/util.ts new file mode 100644 index 0000000000..748c4b04d7 --- /dev/null +++ b/lib/wire/util.ts @@ -0,0 +1,108 @@ + +import crypto from 'node:crypto' +import {DeviceRequirement, DeviceStatus, Envelope, RequirementType, TransactionDoneMessage, TransactionProgressMessage} from './wire.ts' +import { Any } from './google/protobuf/any.ts'; +import { createLogger } from '../util/logger.ts'; +import {MessageType} from "@protobuf-ts/runtime"; +import { ADBDeviceType } from '../units/provider/ADBObserver.js'; + +const DEVICE_STATUS_MAP = { + device: 'ONLINE', + // emulator: 'ONLINE', + unauthorized: 'UNAUTHORIZED', + offline: 'OFFLINE', + // connecting: 'CONNECTING', + // authorizing: 'AUTHORIZING', + unknown: 'OFFLINE', + recovery: 'OFFLINE', + bootloader: 'OFFLINE', + sideload: 'OFFLINE' +} as const satisfies Record // TODO: replace value type with proper type once it's ready + +const log = createLogger('wireutil') + +const wireutil = { + global: '*ALL', + makePrivateChannel() { + return crypto.randomBytes(16).toString('base64') + }, + toDeviceStatus(type: keyof typeof DEVICE_STATUS_MAP) { + return DeviceStatus[DEVICE_STATUS_MAP[type]] + }, + toDeviceRequirements(requirements: Record) { + return Object.keys(requirements).map(function(name) { + let item = requirements[name] + return DeviceRequirement.create({ + name, + value: item.value, + type: RequirementType[item.match.toUpperCase() as 'SEMVER' | 'GLOB' | 'EXACT'] + }) + }) + }, + /** + * @deprecated Do not use raw envelope with a message. Use `pack` for type safety + */ + envelope(message: object) { + return this.oldSend(message) + }, + // envelope(Message.create({...})) // <- forbidden - no way to extract the type + // envelope(new wire.Message(...)) + + pack(messageType: MessageType, message: T, channel: string | undefined = undefined) { + return Envelope.toBinary({ message: Any.pack(message, messageType), channel} ) + }, + + tr(channel: string, messageType: MessageType, message: T) { + return Envelope.toBinary({ message: Any.pack(message, messageType), channel} ) + }, + + /** + * @deprecated Use `tr` for type safety + */ + transaction(channel: string, message: object) { + return this.oldSend(message, channel) + }, + + oldSend(message: object, channel: string | undefined = undefined) { + // @ts-expect-error + const messageType = message.__proto__.constructor.type as MessageType + return this.pack(messageType, message, channel) + }, + + reply(source: string) { + let seq = 0 + return { + okay(data?: string, body?: string | object) { + return wireutil.pack(TransactionDoneMessage, { + source, + seq: seq++, + success: true, + data: data ?? 'success', + body: body ? JSON.stringify(body) : undefined + }) + }, + fail(data?: string, body?:string | object) { + return wireutil.pack(TransactionDoneMessage, { + source, + seq: seq++, + success: false, + data: data ?? 'fail', + body: body ? JSON.stringify(body) : undefined + }) + }, + progress(data: string, progress: number) { + if (!Number.isInteger(progress)) { + log.warn('Somebody is sending non integer as progress: %s', data) + progress = Math.round(progress) + } + return wireutil.pack(TransactionProgressMessage, { + source, + seq: seq++, + data: data, + progress: progress + }) + } + } + } +} +export default wireutil diff --git a/lib/wire/wire.proto b/lib/wire/wire.proto index a0aac52000..2e87a0f41a 100644 --- a/lib/wire/wire.proto +++ b/lib/wire/wire.proto @@ -4,136 +4,13 @@ // Message wrapper -enum MessageType { - CopyMessage = 33; - DeviceIntroductionMessage = 74; - DeviceAbsentMessage = 111; - DeviceIdentityMessage = 2; - DeviceLogcatEntryMessage = 3; - DeviceLogMessage = 4; - DeviceReadyMessage = 5; - DevicePresentMessage = 6; - DevicePropertiesMessage = 7; - DeviceRegisteredMessage = 8; - DeviceStatusMessage = 9; - DeviceTypeMessage = 20; - GroupMessage = 10; - InstallMessage = 30; - PhysicalIdentifyMessage = 29; - JoinGroupMessage = 11; - JoinGroupByAdbFingerprintMessage = 69; - JoinGroupByVncAuthResponseMessage = 90; - VncAuthResponsesUpdatedMessage = 91; - AutoGroupMessage = 70; - AdbKeysUpdatedMessage = 71; - KeyDownMessage = 12; - KeyPressMessage = 13; - KeyUpMessage = 14; - LaunchActivityMessage = 31; - LeaveGroupMessage = 15; - LogcatApplyFiltersMessage = 16; - PasteMessage = 32; - ProbeMessage = 17; - ShellCommandMessage = 18; - ShellKeepAliveMessage = 19; - TouchDownMessage = 21; - TouchMoveMessage = 22; - TouchUpMessage = 23; - TouchCommitMessage = 65; - TouchResetMessage = 66; - GestureStartMessage = 67; - GestureStopMessage = 68; - TransactionDoneMessage = 24; - TransactionProgressMessage = 25; - TypeMessage = 26; - UngroupMessage = 27; - UninstallMessage = 34; - RotateMessage = 35; - ForwardTestMessage = 36; - ForwardCreateMessage = 37; - ForwardRemoveMessage = 38; - LogcatStartMessage = 39; - LogcatStopMessage = 40; - BrowserOpenMessage = 41; - BrowserClearMessage = 42; - AirplaneModeEvent = 43; - BatteryEvent = 44; - DeviceBrowserMessage = 45; - ConnectivityEvent = 46; - PhoneStateEvent = 47; - RotationEvent = 48; - StoreOpenMessage = 49; - ScreenCaptureMessage = 50; - DeviceHeartbeatMessage = 73; - RebootMessage = 52; - ConnectStartMessage = 53; - ConnectStopMessage = 54; - RingerSetMessage = 56; - RingerGetMessage = 64; - WifiSetEnabledMessage = 57; - WifiGetStatusMessage = 58; - AccountAddMenuMessage = 59; - AccountAddMessage = 60; - AccountCheckMessage = 63; - AccountGetMessage = 62; - AccountRemoveMessage = 55; - SdStatusMessage = 61; - ReverseForwardsEvent = 72; - FileSystemListMessage = 81; - FileSystemGetMessage = 82; - InstalledApplications = 83; - GetInstalledApplications = 84; - Applications = 85; - ConnectStartedMessage = 92; - ConnectStoppedMessage = 93; - SetDeviceDisplay = 94; - IosDevicePorts = 95; - StartStreaming = 96; - TouchMoveIosMessage = 99; - DeviceIosIntroductionMessage = 100; - ProviderIosMessage = 101; - DeleteDevice = 104; - SetAbsentDisconnectedDevices = 105; - UninstallIosMessage = 106; - SetDeviceApp = 107; - GetIosDeviceApps = 109; - TransationGetMessage = 110; - UpdateIosDevice = 112; - SdkIosVersion = 114; - SizeIosDevice = 115; - DashboardOpenMessage = 116; - GetIosTreeElements = 117; - TransactionTreeMessage = 118; - TapDeviceTreeElement = 119; - TemporarilyUnavailableMessage = 120; - InitializeIosDeviceState = 121; - UpdateRemoteConnectUrl = 122; - GroupUserChangeMessage = 1200; - DeviceGroupChangeMessage = 1201; - DeviceOriginGroupMessage = 1202; - DeleteUserMessage = 1203; - UpdateAccessTokenMessage = 1204; - GroupChangeMessage = 1205; - UserChangeMessage = 1206; - DeviceChangeMessage = 1207; - IosServiceMessage = 1208; - ChangeQualityMessage = 1209; - InstallResultMessage = 1210; - UnlockDeviceMessage = 1211; - CapabilitiesMessage = 1212; - AirplaneSetMessage = 1213; - ConnectGetForwardUrlMessage = 9000; - GetServicesAvailabilityMessage = 9001; - BluetoothSetEnabledMessage = 9002; - BluetoothGetStatusMessage = 9003; - BluetoothCleanBondedMessage = 9004; - LaunchDeviceApp = 9005; - TerminateDeviceApp = 9006; - KillDeviceApp = 9007; - GetAppAsset = 9008; - GetAppAssetsList = 9009; - GetAppHTML = 9010; - GetAppInspectServerUrl = 9011; +import "google/protobuf/any.proto"; + + +message Envelope { + // required MessageType type = 1; + required google.protobuf.Any message = 2; + optional string channel = 3; } message UpdateAccessTokenMessage { @@ -323,12 +200,6 @@ message FileSystemGetMessage { optional string jwt = 2; } -message Envelope { - required MessageType type = 1; - required bytes message = 2; - optional string channel = 3; -} - message TransactionProgressMessage { required string source = 1; required uint32 seq = 2; diff --git a/lib/wire/wire.ts b/lib/wire/wire.ts new file mode 100644 index 0000000000..a005fb4e3c --- /dev/null +++ b/lib/wire/wire.ts @@ -0,0 +1,11545 @@ +// @generated by protobuf-ts 2.11.1 with parameter generate_dependencies +// @generated from protobuf file "wire.proto" (syntax proto2) +// tslint:disable +import type { BinaryWriteOptions } from "@protobuf-ts/runtime"; +import type { IBinaryWriter } from "@protobuf-ts/runtime"; +import { WireType } from "@protobuf-ts/runtime"; +import type { BinaryReadOptions } from "@protobuf-ts/runtime"; +import type { IBinaryReader } from "@protobuf-ts/runtime"; +import { UnknownFieldHandler } from "@protobuf-ts/runtime"; +import type { PartialMessage } from "@protobuf-ts/runtime"; +import { reflectionMergePartial } from "@protobuf-ts/runtime"; +import { MessageType } from "@protobuf-ts/runtime"; +import { Any } from "./google/protobuf/any.js"; // NOTE: KEEP THIS. ADD .js MANUALLY. +/** + * @generated from protobuf message Envelope + */ +export interface Envelope { + /** + * required MessageType type = 1; + * + * @generated from protobuf field: required google.protobuf.Any message = 2 + */ + message?: Any; + /** + * @generated from protobuf field: optional string channel = 3 + */ + channel?: string; +} +/** + * @generated from protobuf message UpdateAccessTokenMessage + */ +export interface UpdateAccessTokenMessage { +} +/** + * @generated from protobuf message UnlockDeviceMessage + */ +export interface UnlockDeviceMessage { +} +/** + * @generated from protobuf message DeleteUserMessage + */ +export interface DeleteUserMessage { + /** + * @generated from protobuf field: required string email = 1 + */ + email: string; +} +/** + * @generated from protobuf message DeviceOriginGroupMessage + */ +export interface DeviceOriginGroupMessage { + /** + * @generated from protobuf field: required string signature = 1 + */ + signature: string; +} +/** + * @generated from protobuf message UserQuotasDetailField + */ +export interface UserQuotasDetailField { + /** + * @generated from protobuf field: required double duration = 1 + */ + duration: number; + /** + * @generated from protobuf field: required uint32 number = 2 + */ + number: number; +} +/** + * @generated from protobuf message UserQuotasField + */ +export interface UserQuotasField { + /** + * @generated from protobuf field: required UserQuotasDetailField allocated = 1 + */ + allocated?: UserQuotasDetailField; + /** + * @generated from protobuf field: required UserQuotasDetailField consumed = 2 + */ + consumed?: UserQuotasDetailField; + /** + * @generated from protobuf field: required uint32 defaultGroupsDuration = 3 + */ + defaultGroupsDuration: number; + /** + * @generated from protobuf field: required uint32 defaultGroupsNumber = 4 + */ + defaultGroupsNumber: number; + /** + * @generated from protobuf field: required uint32 defaultGroupsRepetitions = 5 + */ + defaultGroupsRepetitions: number; + /** + * @generated from protobuf field: required uint32 repetitions = 6 + */ + repetitions: number; +} +/** + * @generated from protobuf message UserGroupsField + */ +export interface UserGroupsField { + /** + * @generated from protobuf field: required UserQuotasField quotas = 1 + */ + quotas?: UserQuotasField; + /** + * @generated from protobuf field: repeated string subscribed = 2 + */ + subscribed: string[]; +} +/** + * @generated from protobuf message AlertMessageField + */ +export interface AlertMessageField { + /** + * @generated from protobuf field: required string activation = 1 + */ + activation: string; + /** + * @generated from protobuf field: required string data = 2 + */ + data: string; + /** + * @generated from protobuf field: required string level = 3 + */ + level: string; +} +/** + * @generated from protobuf message UserSettingsField + */ +export interface UserSettingsField { + /** + * @generated from protobuf field: optional AlertMessageField alertMessage = 1 + */ + alertMessage?: AlertMessageField; +} +/** + * @generated from protobuf message UserField + */ +export interface UserField { + /** + * @generated from protobuf field: required string email = 1 + */ + email: string; + /** + * @generated from protobuf field: required string name = 2 + */ + name: string; + /** + * @generated from protobuf field: required string privilege = 3 + */ + privilege: string; + /** + * @generated from protobuf field: required UserGroupsField groups = 4 + */ + groups?: UserGroupsField; + /** + * @generated from protobuf field: optional UserSettingsField settings = 5 + */ + settings?: UserSettingsField; +} +/** + * @generated from protobuf message UserChangeMessage + */ +export interface UserChangeMessage { + /** + * @generated from protobuf field: required UserField user = 1 + */ + user?: UserField; + /** + * @generated from protobuf field: required bool isAddedGroup = 2 + */ + isAddedGroup: boolean; + /** + * @generated from protobuf field: repeated string groups = 3 + */ + groups: string[]; + /** + * @generated from protobuf field: required string action = 4 + */ + action: string; + /** + * @generated from protobuf field: repeated string targets = 5 + */ + targets: string[]; + /** + * @generated from protobuf field: required double timeStamp = 6 + */ + timeStamp: number; +} +/** + * @generated from protobuf message DeviceNetworkField + */ +export interface DeviceNetworkField { + /** + * @generated from protobuf field: optional string type = 1 + */ + type?: string; + /** + * @generated from protobuf field: optional string subtype = 2 + */ + subtype?: string; +} +/** + * @generated from protobuf message DeviceDisplayField + */ +export interface DeviceDisplayField { + /** + * @generated from protobuf field: optional uint32 height = 1 + */ + height?: number; + /** + * @generated from protobuf field: optional uint32 width = 2 + */ + width?: number; +} +/** + * @generated from protobuf message DevicePhoneField + */ +export interface DevicePhoneField { + /** + * @generated from protobuf field: optional string imei = 1 + */ + imei?: string; +} +/** + * @generated from protobuf message DeviceProviderField + */ +export interface DeviceProviderField { + /** + * @generated from protobuf field: optional string name = 1 + */ + name?: string; +} +/** + * @generated from protobuf message DeviceGroupField + */ +export interface DeviceGroupField { + /** + * @generated from protobuf field: optional string id = 1 + */ + id?: string; + /** + * @generated from protobuf field: optional string name = 2 + */ + name?: string; + /** + * @generated from protobuf field: optional string origin = 3 + */ + origin?: string; + /** + * @generated from protobuf field: optional string originName = 4 + */ + originName?: string; + /** + * @generated from protobuf field: optional GroupOwnerField owner = 5 + */ + owner?: GroupOwnerField; +} +/** + * @generated from protobuf message DeviceField + */ +export interface DeviceField { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: optional string model = 2 + */ + model?: string; + /** + * @generated from protobuf field: optional string version = 3 + */ + version?: string; + /** + * @generated from protobuf field: optional string operator = 4 + */ + operator?: string; + /** + * @generated from protobuf field: optional DeviceNetworkField network = 5 + */ + network?: DeviceNetworkField; + /** + * @generated from protobuf field: optional DeviceDisplayField display = 6 + */ + display?: DeviceDisplayField; + /** + * @generated from protobuf field: optional string manufacturer = 7 + */ + manufacturer?: string; + /** + * @generated from protobuf field: optional string sdk = 8 + */ + sdk?: string; + /** + * @generated from protobuf field: optional string abi = 9 + */ + abi?: string; + /** + * @generated from protobuf field: optional string cpuPlatform = 10 + */ + cpuPlatform?: string; + /** + * @generated from protobuf field: optional string openGLESVersion = 11 + */ + openGLESVersion?: string; + /** + * @generated from protobuf field: optional DevicePhoneField phone = 12 + */ + phone?: DevicePhoneField; + /** + * @generated from protobuf field: optional DeviceProviderField provider = 13 + */ + provider?: DeviceProviderField; + /** + * @generated from protobuf field: optional DeviceGroupField group = 14 + */ + group?: DeviceGroupField; + /** + * @generated from protobuf field: optional string marketName = 15 + */ + marketName?: string; +} +/** + * @generated from protobuf message DeviceChangeMessage + */ +export interface DeviceChangeMessage { + /** + * @generated from protobuf field: required DeviceField device = 1 + */ + device?: DeviceField; + /** + * @generated from protobuf field: required string action = 2 + */ + action: string; + /** + * @generated from protobuf field: required string oldOriginGroupId = 3 + */ + oldOriginGroupId: string; + /** + * @generated from protobuf field: required double timeStamp = 4 + */ + timeStamp: number; +} +/** + * @generated from protobuf message GroupDateField + */ +export interface GroupDateField { + /** + * @generated from protobuf field: required string start = 1 + */ + start: string; + /** + * @generated from protobuf field: required string stop = 2 + */ + stop: string; +} +/** + * @generated from protobuf message GroupOwnerField + */ +export interface GroupOwnerField { + /** + * @generated from protobuf field: required string email = 1 + */ + email: string; + /** + * @generated from protobuf field: required string name = 2 + */ + name: string; +} +/** + * @generated from protobuf message GroupField + */ +export interface GroupField { + /** + * @generated from protobuf field: required string id = 1 + */ + id: string; + /** + * @generated from protobuf field: required string name = 2 + */ + name: string; + /** + * @generated from protobuf field: required string class = 3 + */ + class: string; + /** + * @generated from protobuf field: required string privilege = 4 + */ + privilege: string; + /** + * @generated from protobuf field: required GroupOwnerField owner = 5 + */ + owner?: GroupOwnerField; + /** + * @generated from protobuf field: repeated GroupDateField dates = 6 + */ + dates: GroupDateField[]; + /** + * @generated from protobuf field: required uint32 duration = 7 + */ + duration: number; + /** + * @generated from protobuf field: required uint32 repetitions = 8 + */ + repetitions: number; + /** + * @generated from protobuf field: repeated string devices = 9 + */ + devices: string[]; + /** + * @generated from protobuf field: repeated string users = 10 + */ + users: string[]; + /** + * @generated from protobuf field: required string state = 11 + */ + state: string; + /** + * @generated from protobuf field: required bool isActive = 12 + */ + isActive: boolean; + /** + * @generated from protobuf field: repeated string moderators = 13 + */ + moderators: string[]; +} +/** + * @generated from protobuf message GroupChangeMessage + */ +export interface GroupChangeMessage { + /** + * @generated from protobuf field: required GroupField group = 1 + */ + group?: GroupField; + /** + * @generated from protobuf field: required string action = 2 + */ + action: string; + /** + * @generated from protobuf field: repeated string subscribers = 3 + */ + subscribers: string[]; + /** + * @generated from protobuf field: required bool isChangedDates = 4 + */ + isChangedDates: boolean; + /** + * @generated from protobuf field: required bool isChangedClass = 5 + */ + isChangedClass: boolean; + /** + * @generated from protobuf field: required bool isAddedUser = 6 + */ + isAddedUser: boolean; + /** + * @generated from protobuf field: repeated string users = 7 + */ + users: string[]; + /** + * @generated from protobuf field: required bool isAddedDevice = 8 + */ + isAddedDevice: boolean; + /** + * @generated from protobuf field: repeated string devices = 9 + */ + devices: string[]; + /** + * @generated from protobuf field: required double timeStamp = 10 + */ + timeStamp: number; +} +/** + * @generated from protobuf message DeviceGroupChangeMessage + */ +export interface DeviceGroupChangeMessage { + /** + * @generated from protobuf field: required string id = 1 + */ + id: string; + /** + * @generated from protobuf field: required DeviceGroupMessage group = 2 + */ + group?: DeviceGroupMessage; + /** + * @generated from protobuf field: required string serial = 3 + */ + serial: string; +} +/** + * @generated from protobuf message GroupUserChangeMessage + */ +export interface GroupUserChangeMessage { + /** + * @generated from protobuf field: repeated string users = 1 + */ + users: string[]; + /** + * @generated from protobuf field: required bool isAdded = 2 + */ + isAdded: boolean; + /** + * @generated from protobuf field: required string id = 3 + */ + id: string; + /** + * @generated from protobuf field: required bool isDeletedLater = 4 + */ + isDeletedLater: boolean; + /** + * @generated from protobuf field: repeated string devices = 5 + */ + devices: string[]; +} +/** + * @generated from protobuf message ConnectStartedMessage + */ +export interface ConnectStartedMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required string url = 2 + */ + url: string; +} +/** + * @generated from protobuf message InstallResultMessage + */ +export interface InstallResultMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required string result = 2 + */ + result: string; +} +/** + * @generated from protobuf message ConnectStoppedMessage + */ +export interface ConnectStoppedMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; +} +/** + * @generated from protobuf message FileSystemListMessage + */ +export interface FileSystemListMessage { + /** + * @generated from protobuf field: required string dir = 1 + */ + dir: string; +} +/** + * @generated from protobuf message FileSystemGetMessage + */ +export interface FileSystemGetMessage { + /** + * @generated from protobuf field: required string file = 1 + */ + file: string; + /** + * @generated from protobuf field: optional string jwt = 2 + */ + jwt?: string; +} +/** + * @generated from protobuf message TransactionProgressMessage + */ +export interface TransactionProgressMessage { + /** + * @generated from protobuf field: required string source = 1 + */ + source: string; + /** + * @generated from protobuf field: required uint32 seq = 2 + */ + seq: number; + /** + * @generated from protobuf field: optional string data = 3 + */ + data?: string; + /** + * @generated from protobuf field: optional uint32 progress = 4 [default = 0] + */ + progress?: number; +} +/** + * @generated from protobuf message TransactionDoneMessage + */ +export interface TransactionDoneMessage { + /** + * @generated from protobuf field: required string source = 1 + */ + source: string; + /** + * @generated from protobuf field: required uint32 seq = 2 + */ + seq: number; + /** + * @generated from protobuf field: required bool success = 3 + */ + success: boolean; + /** + * @generated from protobuf field: optional string data = 4 + */ + data?: string; + /** + * @generated from protobuf field: optional string body = 5 + */ + body?: string; +} +/** + * @generated from protobuf message TransactionTreeMessage + */ +export interface TransactionTreeMessage { + /** + * @generated from protobuf field: required string source = 1 + */ + source: string; + /** + * @generated from protobuf field: required uint32 seq = 2 + */ + seq: number; + /** + * @generated from protobuf field: required bool success = 3 + */ + success: boolean; + /** + * @generated from protobuf field: optional string data = 4 + */ + data?: string; + /** + * @generated from protobuf field: optional string body = 5 + */ + body?: string; +} +// Logging + +/** + * @generated from protobuf message DeviceLogMessage + */ +export interface DeviceLogMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required double timestamp = 2 + */ + timestamp: number; + /** + * @generated from protobuf field: required uint32 priority = 3 + */ + priority: number; + /** + * @generated from protobuf field: required string tag = 4 + */ + tag: string; + /** + * @generated from protobuf field: required uint32 pid = 5 + */ + pid: number; + /** + * @generated from protobuf field: required string message = 6 + */ + message: string; + /** + * @generated from protobuf field: required string identifier = 7 + */ + identifier: string; +} +// Introductions + +/** + * @generated from protobuf message DeviceGroupOwnerMessage + */ +export interface DeviceGroupOwnerMessage { + /** + * @generated from protobuf field: required string email = 1 + */ + email: string; + /** + * @generated from protobuf field: required string name = 2 + */ + name: string; +} +/** + * @generated from protobuf message DeviceGroupLifetimeMessage + */ +export interface DeviceGroupLifetimeMessage { + /** + * @generated from protobuf field: required double start = 1 + */ + start: number; + /** + * @generated from protobuf field: required double stop = 2 + */ + stop: number; +} +/** + * @generated from protobuf message DeviceGroupMessage + */ +export interface DeviceGroupMessage { + /** + * @generated from protobuf field: required string id = 1 + */ + id: string; + /** + * @generated from protobuf field: required string name = 2 + */ + name: string; + /** + * @generated from protobuf field: required DeviceGroupOwnerMessage owner = 3 + */ + owner?: DeviceGroupOwnerMessage; + /** + * @generated from protobuf field: required DeviceGroupLifetimeMessage lifeTime = 4 + */ + lifeTime?: DeviceGroupLifetimeMessage; + /** + * @generated from protobuf field: required string class = 5 + */ + class: string; + /** + * @generated from protobuf field: required uint32 repetitions = 6 + */ + repetitions: number; + /** + * @generated from protobuf field: required string originName = 7 + */ + originName: string; +} +/** + * @generated from protobuf message ProviderMessage + */ +export interface ProviderMessage { + /** + * @generated from protobuf field: required string channel = 1 + */ + channel: string; + /** + * @generated from protobuf field: required string name = 2 + */ + name: string; +} +/** + * @generated from protobuf message ProviderIosMessage + */ +export interface ProviderIosMessage { + /** + * @generated from protobuf field: required string channel = 1 + */ + channel: string; + /** + * @generated from protobuf field: required string name = 2 + */ + name: string; + /** + * @generated from protobuf field: required string screenWsUrlPattern = 3 + */ + screenWsUrlPattern: string; +} +/** + * @generated from protobuf message DeviceHeartbeatMessage + */ +export interface DeviceHeartbeatMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; +} +/** + * @generated from protobuf message DeviceIntroductionMessage + */ +export interface DeviceIntroductionMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required DeviceStatus status = 2 + */ + status: DeviceStatus; + /** + * @generated from protobuf field: required ProviderMessage provider = 3 + */ + provider?: ProviderMessage; // optional DeviceGroupMessage group = 4; +} +/** + * @generated from protobuf message DeviceIosIntroductionMessage + */ +export interface DeviceIosIntroductionMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required DeviceStatus status = 2 + */ + status: DeviceStatus; + /** + * @generated from protobuf field: required ProviderMessage provider = 3 + */ + provider?: ProviderMessage; +} +/** + * @generated from protobuf message InitializeIosDeviceState + */ +export interface InitializeIosDeviceState { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required DeviceStatus status = 2 + */ + status: DeviceStatus; + /** + * @generated from protobuf field: required ProviderIosMessage provider = 3 + */ + provider?: ProviderIosMessage; + /** + * @generated from protobuf field: required IosDevicePorts ports = 4 + */ + ports?: IosDevicePorts; + /** + * @generated from protobuf field: required UpdateIosDevice options = 5 + */ + options?: UpdateIosDevice; +} +/** + * @generated from protobuf message DeviceRegisteredMessage + */ +export interface DeviceRegisteredMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; +} +/** + * @generated from protobuf message DevicePresentMessage + */ +export interface DevicePresentMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; +} +/** + * @generated from protobuf message DeviceAbsentMessage + */ +export interface DeviceAbsentMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; +} +/** + * @generated from protobuf message DeviceReadyMessage + */ +export interface DeviceReadyMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required string channel = 2 + */ + channel: string; +} +/** + * @generated from protobuf message ProbeMessage + */ +export interface ProbeMessage { +} +/** + * @generated from protobuf message DeviceStatusMessage + */ +export interface DeviceStatusMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required DeviceStatus status = 2 + */ + status: DeviceStatus; +} +/** + * @generated from protobuf message DeviceTypeMessage + */ +export interface DeviceTypeMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required string type = 2 + */ + type: string; +} +/** + * @generated from protobuf message DeviceDisplayMessage + */ +export interface DeviceDisplayMessage { + /** + * @generated from protobuf field: required int32 id = 1 + */ + id: number; + /** + * @generated from protobuf field: required int32 width = 2 + */ + width: number; + /** + * @generated from protobuf field: required int32 height = 3 + */ + height: number; + /** + * @generated from protobuf field: required int32 rotation = 4 + */ + rotation: number; + /** + * @generated from protobuf field: required float xdpi = 5 + */ + xdpi: number; + /** + * @generated from protobuf field: required float ydpi = 6 + */ + ydpi: number; + /** + * @generated from protobuf field: required float fps = 7 + */ + fps: number; + /** + * @generated from protobuf field: required float density = 8 + */ + density: number; + /** + * @generated from protobuf field: required bool secure = 9 + */ + secure: boolean; + /** + * @generated from protobuf field: required string url = 10 + */ + url: string; + /** + * @generated from protobuf field: optional float size = 11 + */ + size?: number; +} +/** + * @generated from protobuf message DeviceBrowserAppMessage + */ +export interface DeviceBrowserAppMessage { + /** + * @generated from protobuf field: required string id = 1 + */ + id: string; + /** + * @generated from protobuf field: required string type = 2 + */ + type: string; + /** + * @generated from protobuf field: required string name = 3 + */ + name: string; + /** + * @generated from protobuf field: required bool selected = 4 + */ + selected: boolean; + /** + * @generated from protobuf field: required bool system = 5 + */ + system: boolean; +} +/** + * @generated from protobuf message DeviceBrowserMessage + */ +export interface DeviceBrowserMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required bool selected = 2 + */ + selected: boolean; + /** + * @generated from protobuf field: repeated DeviceBrowserAppMessage apps = 3 + */ + apps: DeviceBrowserAppMessage[]; +} +/** + * @generated from protobuf message GetServicesAvailabilityMessage + */ +export interface GetServicesAvailabilityMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required bool hasGMS = 2 + */ + hasGMS: boolean; + /** + * @generated from protobuf field: required bool hasHMS = 3 + */ + hasHMS: boolean; +} +/** + * @generated from protobuf message DevicePhoneMessage + */ +export interface DevicePhoneMessage { + /** + * @generated from protobuf field: optional string imei = 1 + */ + imei?: string; + /** + * @generated from protobuf field: optional string imsi = 5 + */ + imsi?: string; + /** + * @generated from protobuf field: optional string phoneNumber = 2 + */ + phoneNumber?: string; + /** + * @generated from protobuf field: optional string iccid = 3 + */ + iccid?: string; + /** + * @generated from protobuf field: optional string network = 4 + */ + network?: string; +} +/** + * @generated from protobuf message DeviceIdentityMessage + */ +export interface DeviceIdentityMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required string platform = 2 + */ + platform: string; + /** + * @generated from protobuf field: required string manufacturer = 3 + */ + manufacturer: string; + /** + * @generated from protobuf field: optional string operator = 4 + */ + operator?: string; + /** + * @generated from protobuf field: required string model = 5 + */ + model: string; + /** + * @generated from protobuf field: required string version = 6 + */ + version: string; + /** + * @generated from protobuf field: required string abi = 7 + */ + abi: string; + /** + * @generated from protobuf field: required string sdk = 8 + */ + sdk: string; + /** + * @generated from protobuf field: required DeviceDisplayMessage display = 9 + */ + display?: DeviceDisplayMessage; + /** + * @generated from protobuf field: required DevicePhoneMessage phone = 11 + */ + phone?: DevicePhoneMessage; + /** + * @generated from protobuf field: optional string product = 12 + */ + product?: string; + /** + * @generated from protobuf field: optional string cpuPlatform = 13 + */ + cpuPlatform?: string; + /** + * @generated from protobuf field: optional string openGLESVersion = 14 + */ + openGLESVersion?: string; + /** + * @generated from protobuf field: optional string marketName = 15 + */ + marketName?: string; + /** + * @generated from protobuf field: optional string macAddress = 16 + */ + macAddress?: string; + /** + * @generated from protobuf field: optional string ram = 17 + */ + ram?: string; +} +/** + * @generated from protobuf message DeviceProperty + */ +export interface DeviceProperty { + /** + * @generated from protobuf field: required string name = 1 + */ + name: string; + /** + * @generated from protobuf field: required string value = 2 + */ + value: string; +} +/** + * @generated from protobuf message DevicePropertiesMessage + */ +export interface DevicePropertiesMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: repeated DeviceProperty properties = 2 + */ + properties: DeviceProperty[]; +} +/** + * @generated from protobuf message DeviceRequirement + */ +export interface DeviceRequirement { + /** + * @generated from protobuf field: required string name = 1 + */ + name: string; + /** + * @generated from protobuf field: required string value = 2 + */ + value: string; + /** + * @generated from protobuf field: required RequirementType type = 3 + */ + type: RequirementType; +} +/** + * @generated from protobuf message OwnerMessage + */ +export interface OwnerMessage { + /** + * @generated from protobuf field: required string email = 1 + */ + email: string; + /** + * @generated from protobuf field: required string name = 2 + */ + name: string; + /** + * @generated from protobuf field: required string group = 3 + */ + group: string; +} +/** + * @generated from protobuf message GroupMessage + */ +export interface GroupMessage { + /** + * @generated from protobuf field: required OwnerMessage owner = 1 + */ + owner?: OwnerMessage; + /** + * @generated from protobuf field: optional uint32 timeout = 2 + */ + timeout?: number; + /** + * @generated from protobuf field: repeated DeviceRequirement requirements = 3 + */ + requirements: DeviceRequirement[]; + /** + * @generated from protobuf field: optional string usage = 4 + */ + usage?: string; +} +/** + * @generated from protobuf message AutoGroupMessage + */ +export interface AutoGroupMessage { + /** + * @generated from protobuf field: required OwnerMessage owner = 1 + */ + owner?: OwnerMessage; + /** + * @generated from protobuf field: required string identifier = 2 + */ + identifier: string; +} +/** + * @generated from protobuf message UngroupMessage + */ +export interface UngroupMessage { + /** + * @generated from protobuf field: repeated DeviceRequirement requirements = 2 + */ + requirements: DeviceRequirement[]; +} +/** + * @generated from protobuf message JoinGroupMessage + */ +export interface JoinGroupMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required OwnerMessage owner = 2 + */ + owner?: OwnerMessage; + /** + * @generated from protobuf field: optional string usage = 3 + */ + usage?: string; +} +/** + * @generated from protobuf message JoinGroupByAdbFingerprintMessage + */ +export interface JoinGroupByAdbFingerprintMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required string fingerprint = 2 + */ + fingerprint: string; + /** + * @generated from protobuf field: optional string comment = 3 + */ + comment?: string; + /** + * @generated from protobuf field: optional string currentGroup = 4 + */ + currentGroup?: string; +} +/** + * @generated from protobuf message JoinGroupByVncAuthResponseMessage + */ +export interface JoinGroupByVncAuthResponseMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required string response = 2 + */ + response: string; + /** + * @generated from protobuf field: optional string currentGroup = 4 + */ + currentGroup?: string; +} +/** + * @generated from protobuf message AdbKeysUpdatedMessage + */ +export interface AdbKeysUpdatedMessage { +} +/** + * @generated from protobuf message VncAuthResponsesUpdatedMessage + */ +export interface VncAuthResponsesUpdatedMessage { +} +/** + * @generated from protobuf message LeaveGroupMessage + */ +export interface LeaveGroupMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required OwnerMessage owner = 2 + */ + owner?: OwnerMessage; + /** + * @generated from protobuf field: required string reason = 3 + */ + reason: string; +} +// Input + +/** + * @generated from protobuf message PhysicalIdentifyMessage + */ +export interface PhysicalIdentifyMessage { +} +/** + * @generated from protobuf message TouchDownMessage + */ +export interface TouchDownMessage { + /** + * @generated from protobuf field: required uint32 seq = 1 + */ + seq: number; + /** + * @generated from protobuf field: required uint32 contact = 2 + */ + contact: number; + /** + * @generated from protobuf field: required float x = 3 + */ + x: number; + /** + * @generated from protobuf field: required float y = 4 + */ + y: number; + /** + * @generated from protobuf field: optional float pressure = 5 + */ + pressure?: number; +} +/** + * @generated from protobuf message TouchMoveMessage + */ +export interface TouchMoveMessage { + /** + * @generated from protobuf field: required uint32 seq = 1 + */ + seq: number; + /** + * @generated from protobuf field: required uint32 contact = 2 + */ + contact: number; + /** + * @generated from protobuf field: required float x = 3 + */ + x: number; + /** + * @generated from protobuf field: required float y = 4 + */ + y: number; + /** + * @generated from protobuf field: optional float pressure = 5 + */ + pressure?: number; +} +/** + * @generated from protobuf message TouchMoveIosMessage + */ +export interface TouchMoveIosMessage { + /** + * @generated from protobuf field: required float toX = 1 + */ + toX: number; + /** + * @generated from protobuf field: required float toY = 2 + */ + toY: number; + /** + * @generated from protobuf field: required float fromX = 3 + */ + fromX: number; + /** + * @generated from protobuf field: required float fromY = 4 + */ + fromY: number; + /** + * @generated from protobuf field: optional float duration = 5 + */ + duration?: number; +} +/** + * @generated from protobuf message TouchUpMessage + */ +export interface TouchUpMessage { + /** + * @generated from protobuf field: required uint32 seq = 1 + */ + seq: number; + /** + * @generated from protobuf field: required uint32 contact = 2 + */ + contact: number; +} +/** + * @generated from protobuf message TouchCommitMessage + */ +export interface TouchCommitMessage { + /** + * @generated from protobuf field: required uint32 seq = 1 + */ + seq: number; +} +/** + * @generated from protobuf message TouchResetMessage + */ +export interface TouchResetMessage { + /** + * @generated from protobuf field: required uint32 seq = 1 + */ + seq: number; +} +/** + * @generated from protobuf message GestureStartMessage + */ +export interface GestureStartMessage { + /** + * @generated from protobuf field: required uint32 seq = 1 + */ + seq: number; +} +/** + * @generated from protobuf message GestureStopMessage + */ +export interface GestureStopMessage { + /** + * @generated from protobuf field: required uint32 seq = 1 + */ + seq: number; +} +/** + * @generated from protobuf message TypeMessage + */ +export interface TypeMessage { + /** + * @generated from protobuf field: required string text = 1 + */ + text: string; +} +/** + * @generated from protobuf message PasteMessage + */ +export interface PasteMessage { + /** + * @generated from protobuf field: required string text = 1 + */ + text: string; +} +/** + * @generated from protobuf message CopyMessage + */ +export interface CopyMessage { +} +/** + * @generated from protobuf message KeyDownMessage + */ +export interface KeyDownMessage { + /** + * @generated from protobuf field: required string key = 1 + */ + key: string; +} +/** + * @generated from protobuf message KeyUpMessage + */ +export interface KeyUpMessage { + /** + * @generated from protobuf field: required string key = 1 + */ + key: string; +} +/** + * @generated from protobuf message KeyPressMessage + */ +export interface KeyPressMessage { + /** + * @generated from protobuf field: required string key = 1 + */ + key: string; +} +/** + * @generated from protobuf message RebootMessage + */ +export interface RebootMessage { +} +// Output + +/** + * @generated from protobuf message DeviceLogcatEntryMessage + */ +export interface DeviceLogcatEntryMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required double date = 2 + */ + date: number; + /** + * @generated from protobuf field: required uint32 pid = 3 + */ + pid: number; + /** + * @generated from protobuf field: required uint32 tid = 4 + */ + tid: number; + /** + * @generated from protobuf field: required uint32 priority = 5 + */ + priority: number; + /** + * @generated from protobuf field: required string tag = 6 + */ + tag: string; + /** + * @generated from protobuf field: required string message = 7 + */ + message: string; +} +/** + * @generated from protobuf message LogcatFilter + */ +export interface LogcatFilter { + /** + * @generated from protobuf field: required string tag = 1 + */ + tag: string; + /** + * @generated from protobuf field: required uint32 priority = 2 + */ + priority: number; +} +/** + * @generated from protobuf message LogcatStartMessage + */ +export interface LogcatStartMessage { + /** + * @generated from protobuf field: repeated LogcatFilter filters = 1 + */ + filters: LogcatFilter[]; +} +/** + * @generated from protobuf message LogcatStopMessage + */ +export interface LogcatStopMessage { +} +/** + * @generated from protobuf message LogcatApplyFiltersMessage + */ +export interface LogcatApplyFiltersMessage { + /** + * @generated from protobuf field: repeated LogcatFilter filters = 1 + */ + filters: LogcatFilter[]; +} +// Commands + +/** + * @generated from protobuf message ShellCommandMessage + */ +export interface ShellCommandMessage { + /** + * @generated from protobuf field: required string command = 1 + */ + command: string; + /** + * @generated from protobuf field: required uint32 timeout = 2 + */ + timeout: number; +} +/** + * @generated from protobuf message ShellKeepAliveMessage + */ +export interface ShellKeepAliveMessage { + /** + * @generated from protobuf field: required uint32 timeout = 1 + */ + timeout: number; +} +/** + * @generated from protobuf message InstallMessage + */ +export interface InstallMessage { + /** + * @generated from protobuf field: required string href = 1 + */ + href: string; + /** + * @generated from protobuf field: required bool launch = 2 + */ + launch: boolean; + /** + * @generated from protobuf field: required bool isApi = 3 + */ + isApi: boolean; + /** + * @generated from protobuf field: optional string manifest = 4 + */ + manifest?: string; + /** + * @generated from protobuf field: repeated string installFlags = 5 + */ + installFlags: string[]; + /** + * @generated from protobuf field: optional string jwt = 6 + */ + jwt?: string; // used for storage authorization + /** + * @generated from protobuf field: optional string pkg = 7 + */ + pkg?: string; // used for .tpk installation via sdb +} +/** + * @generated from protobuf message UninstallMessage + */ +export interface UninstallMessage { + /** + * @generated from protobuf field: required string packageName = 1 + */ + packageName: string; +} +/** + * @generated from protobuf message UninstallIosMessage + */ +export interface UninstallIosMessage { + /** + * @generated from protobuf field: required string packageName = 1 + */ + packageName: string; +} +/** + * @generated from protobuf message LaunchActivityMessage + */ +export interface LaunchActivityMessage { + /** + * @generated from protobuf field: required string action = 1 + */ + action: string; + /** + * @generated from protobuf field: required string component = 2 + */ + component: string; + /** + * @generated from protobuf field: repeated string category = 3 + */ + category: string[]; + /** + * @generated from protobuf field: optional uint32 flags = 4 + */ + flags?: number; +} +/** + * @generated from protobuf message RotateMessage + */ +export interface RotateMessage { + /** + * @generated from protobuf field: required int32 rotation = 1 + */ + rotation: number; +} +/** + * @generated from protobuf message ChangeQualityMessage + */ +export interface ChangeQualityMessage { + /** + * @generated from protobuf field: required int32 quality = 1 + */ + quality: number; +} +/** + * @generated from protobuf message ForwardTestMessage + */ +export interface ForwardTestMessage { + /** + * @generated from protobuf field: required string targetHost = 1 + */ + targetHost: string; + /** + * @generated from protobuf field: required uint32 targetPort = 2 + */ + targetPort: number; +} +/** + * @generated from protobuf message ForwardCreateMessage + */ +export interface ForwardCreateMessage { + /** + * @generated from protobuf field: required string id = 1 + */ + id: string; + /** + * @generated from protobuf field: required uint32 devicePort = 2 + */ + devicePort: number; + /** + * @generated from protobuf field: required string targetHost = 3 + */ + targetHost: string; + /** + * @generated from protobuf field: required uint32 targetPort = 4 + */ + targetPort: number; +} +/** + * @generated from protobuf message ForwardRemoveMessage + */ +export interface ForwardRemoveMessage { + /** + * @generated from protobuf field: required string id = 1 + */ + id: string; +} +/** + * @generated from protobuf message ReverseForward + */ +export interface ReverseForward { + /** + * @generated from protobuf field: required string id = 1 + */ + id: string; + /** + * @generated from protobuf field: required uint32 devicePort = 2 + */ + devicePort: number; + /** + * @generated from protobuf field: required string targetHost = 3 + */ + targetHost: string; + /** + * @generated from protobuf field: required uint32 targetPort = 4 + */ + targetPort: number; +} +/** + * @generated from protobuf message ReverseForwardsEvent + */ +export interface ReverseForwardsEvent { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: repeated ReverseForward forwards = 2 + */ + forwards: ReverseForward[]; +} +/** + * @generated from protobuf message BrowserOpenMessage + */ +export interface BrowserOpenMessage { + /** + * @generated from protobuf field: required string url = 1 + */ + url: string; + /** + * @generated from protobuf field: optional string browser = 2 + */ + browser?: string; +} +/** + * @generated from protobuf message BrowserClearMessage + */ +export interface BrowserClearMessage { + /** + * @generated from protobuf field: optional string browser = 1 + */ + browser?: string; +} +/** + * @generated from protobuf message StoreOpenMessage + */ +export interface StoreOpenMessage { +} +/** + * @generated from protobuf message ScreenCaptureMessage + */ +export interface ScreenCaptureMessage { +} +/** + * @generated from protobuf message ConnectStartMessage + */ +export interface ConnectStartMessage { +} +/** + * @generated from protobuf message ConnectGetForwardUrlMessage + */ +export interface ConnectGetForwardUrlMessage { +} +/** + * @generated from protobuf message ConnectStopMessage + */ +export interface ConnectStopMessage { +} +/** + * @generated from protobuf message AccountAddMenuMessage + */ +export interface AccountAddMenuMessage { +} +/** + * @generated from protobuf message AccountAddMessage + */ +export interface AccountAddMessage { + /** + * @generated from protobuf field: required string user = 1 + */ + user: string; + /** + * @generated from protobuf field: required string password = 2 + */ + password: string; +} +/** + * @generated from protobuf message AccountCheckMessage + */ +export interface AccountCheckMessage { + /** + * @generated from protobuf field: required string type = 1 + */ + type: string; + /** + * @generated from protobuf field: required string account = 2 + */ + account: string; +} +/** + * @generated from protobuf message AccountGetMessage + */ +export interface AccountGetMessage { + /** + * @generated from protobuf field: optional string type = 1 + */ + type?: string; +} +/** + * @generated from protobuf message AccountRemoveMessage + */ +export interface AccountRemoveMessage { + /** + * @generated from protobuf field: required string type = 1 + */ + type: string; + /** + * @generated from protobuf field: optional string account = 2 + */ + account?: string; +} +/** + * @generated from protobuf message SdStatusMessage + */ +export interface SdStatusMessage { +} +/** + * @generated from protobuf message AirplaneSetMessage + */ +export interface AirplaneSetMessage { + /** + * @generated from protobuf field: required bool enabled = 1 + */ + enabled: boolean; +} +/** + * @generated from protobuf message RingerSetMessage + */ +export interface RingerSetMessage { + /** + * @generated from protobuf field: required RingerMode mode = 1 + */ + mode: RingerMode; +} +/** + * @generated from protobuf message RingerGetMessage + */ +export interface RingerGetMessage { +} +/** + * @generated from protobuf message WifiSetEnabledMessage + */ +export interface WifiSetEnabledMessage { + /** + * @generated from protobuf field: required bool enabled = 1 + */ + enabled: boolean; +} +/** + * @generated from protobuf message WifiGetStatusMessage + */ +export interface WifiGetStatusMessage { +} +/** + * @generated from protobuf message BluetoothSetEnabledMessage + */ +export interface BluetoothSetEnabledMessage { + /** + * @generated from protobuf field: required bool enabled = 1 + */ + enabled: boolean; +} +/** + * @generated from protobuf message BluetoothGetStatusMessage + */ +export interface BluetoothGetStatusMessage { +} +/** + * @generated from protobuf message BluetoothCleanBondedMessage + */ +export interface BluetoothCleanBondedMessage { +} +/** + * @generated from protobuf message CapabilitiesMessage + */ +export interface CapabilitiesMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required bool hasTouch = 2 + */ + hasTouch: boolean; + /** + * @generated from protobuf field: required bool hasCursor = 3 + */ + hasCursor: boolean; // TODO: + // required bool hasKeyboard = 1; + // hasLogs + // hasMedia + // hasClipboard and stuff like that, but later.. +} +// Events, these must be kept in sync with STFService/wire.proto + +/** + * @generated from protobuf message AirplaneModeEvent + */ +export interface AirplaneModeEvent { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required bool enabled = 2 + */ + enabled: boolean; +} +/** + * @generated from protobuf message BatteryEvent + */ +export interface BatteryEvent { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required string status = 2 + */ + status: string; + /** + * @generated from protobuf field: required string health = 3 + */ + health: string; + /** + * @generated from protobuf field: required string source = 4 + */ + source: string; + /** + * @generated from protobuf field: required uint32 level = 5 + */ + level: number; + /** + * @generated from protobuf field: required uint32 scale = 6 + */ + scale: number; + /** + * @generated from protobuf field: required double temp = 7 + */ + temp: number; + /** + * @generated from protobuf field: optional double voltage = 8 + */ + voltage?: number; +} +/** + * @generated from protobuf message ConnectivityEvent + */ +export interface ConnectivityEvent { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required bool connected = 2 + */ + connected: boolean; + /** + * @generated from protobuf field: optional string type = 3 + */ + type?: string; + /** + * @generated from protobuf field: optional string subtype = 4 + */ + subtype?: string; + /** + * @generated from protobuf field: optional bool failover = 5 + */ + failover?: boolean; + /** + * @generated from protobuf field: optional bool roaming = 6 + */ + roaming?: boolean; +} +/** + * @generated from protobuf message PhoneStateEvent + */ +export interface PhoneStateEvent { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required string state = 2 + */ + state: string; + /** + * @generated from protobuf field: required bool manual = 3 + */ + manual: boolean; + /** + * @generated from protobuf field: optional string operator = 4 + */ + operator?: string; +} +/** + * @generated from protobuf message RotationEvent + */ +export interface RotationEvent { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required int32 rotation = 2 + */ + rotation: number; + /** + * @generated from protobuf field: optional int32 width = 3 + */ + width?: number; + /** + * @generated from protobuf field: optional int32 height = 4 + */ + height?: number; +} +/** + * @generated from protobuf message SetDeviceDisplay + */ +export interface SetDeviceDisplay { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required string channel = 2 + */ + channel: string; + /** + * @generated from protobuf field: required int32 width = 3 + */ + width: number; + /** + * @generated from protobuf field: required int32 height = 4 + */ + height: number; +} +/** + * @generated from protobuf message IosDevicePorts + */ +export interface IosDevicePorts { + /** + * @generated from protobuf field: required int32 screenPort = 2 + */ + screenPort: number; + /** + * @generated from protobuf field: required int32 connectPort = 3 + */ + connectPort: number; +} +/** + * @generated from protobuf message StartStreaming + */ +export interface StartStreaming { + /** + * @generated from protobuf field: required int32 port = 1 + */ + port: number; + /** + * @generated from protobuf field: required string channel = 2 + */ + channel: string; +} +/** + * @generated from protobuf message DeleteDevice + */ +export interface DeleteDevice { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; +} +/** + * @generated from protobuf message SetAbsentDisconnectedDevices + */ +export interface SetAbsentDisconnectedDevices { +} +/** + * @generated from protobuf message Applications + */ +export interface Applications { + /** + * @generated from protobuf field: required string bundleId = 1 + */ + bundleId: string; + /** + * @generated from protobuf field: required string bundleName = 2 + */ + bundleName: string; +} +/** + * @generated from protobuf message InstalledApplications + */ +export interface InstalledApplications { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: repeated Applications applications = 2 + */ + applications: Applications[]; +} +/** + * @generated from protobuf message TransportInstalledApps + */ +export interface TransportInstalledApps { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; +} +/** + * @generated from protobuf message SetDeviceApp + */ +export interface SetDeviceApp { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required string bundleId = 2 + */ + bundleId: string; + /** + * @generated from protobuf field: required string bundleName = 3 + */ + bundleName: string; + /** + * @generated from protobuf field: required string pathToApp = 4 + */ + pathToApp: string; +} +/** + * @generated from protobuf message GetIosDeviceApps + */ +export interface GetIosDeviceApps { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required string bundleId = 2 + */ + bundleId: string; + /** + * @generated from protobuf field: required string bundleName = 3 + */ + bundleName: string; + /** + * @generated from protobuf field: required string pathToApp = 4 + */ + pathToApp: string; +} +/** + * @generated from protobuf message TransationGetMessage + */ +export interface TransationGetMessage { + /** + * @generated from protobuf field: required string source = 1 + */ + source: string; + /** + * @generated from protobuf field: required string data = 2 + */ + data: string; +} +/** + * required string serial = 1; + * optional string channel = 2; + * + * @generated from protobuf message GetInstalledApplications + */ +export interface GetInstalledApplications { +} +/** + * @generated from protobuf message UpdateIosDevice + */ +export interface UpdateIosDevice { + /** + * @generated from protobuf field: required string id = 1 + */ + id: string; + /** + * @generated from protobuf field: required string name = 2 + */ + name: string; + /** + * @generated from protobuf field: required string platform = 3 + */ + platform: string; + /** + * @generated from protobuf field: required string architecture = 4 + */ + architecture: string; + /** + * @generated from protobuf field: required string sdk = 5 + */ + sdk: string; + /** + * @generated from protobuf field: required IosServiceMessage service = 6 + */ + service?: IosServiceMessage; +} +/** + * @generated from protobuf message SdkIosVersion + */ +export interface SdkIosVersion { + /** + * @generated from protobuf field: required string id = 1 + */ + id: string; + /** + * @generated from protobuf field: required string sdkVersion = 2 + */ + sdkVersion: string; +} +/** + * @generated from protobuf message SizeIosDevice + */ +export interface SizeIosDevice { + /** + * @generated from protobuf field: required string id = 1 + */ + id: string; + /** + * @generated from protobuf field: required double height = 2 + */ + height: number; + /** + * @generated from protobuf field: required double width = 3 + */ + width: number; + /** + * @generated from protobuf field: required int32 scale = 4 + */ + scale: number; +} +/** + * @generated from protobuf message DashboardOpenMessage + */ +export interface DashboardOpenMessage { +} +/** + * @generated from protobuf message GetIosTreeElements + */ +export interface GetIosTreeElements { +} +/** + * @generated from protobuf message TapDeviceTreeElement + */ +export interface TapDeviceTreeElement { + /** + * @generated from protobuf field: required string label = 1 + */ + label: string; +} +/** + * @generated from protobuf message TemporarilyUnavailableMessage + */ +export interface TemporarilyUnavailableMessage { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; +} +/** + * @generated from protobuf message UpdateRemoteConnectUrl + */ +export interface UpdateRemoteConnectUrl { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; +} +/** + * @generated from protobuf message IosServiceMessage + */ +export interface IosServiceMessage { + /** + * @generated from protobuf field: required bool hasAPNS = 1 + */ + hasAPNS: boolean; +} +/** + * @generated from protobuf message LaunchDeviceApp + */ +export interface LaunchDeviceApp { + /** + * @generated from protobuf field: required string pkg = 1 + */ + pkg: string; +} +/** + * @generated from protobuf message TerminateDeviceApp + */ +export interface TerminateDeviceApp { +} +/** + * @generated from protobuf message KillDeviceApp + */ +export interface KillDeviceApp { +} +/** + * @generated from protobuf message GetAppAsset + */ +export interface GetAppAsset { + /** + * @generated from protobuf field: required string url = 1 + */ + url: string; +} +/** + * @generated from protobuf message GetAppAssetsList + */ +export interface GetAppAssetsList { +} +/** + * @generated from protobuf message GetAppHTML + */ +export interface GetAppHTML { +} +/** + * @generated from protobuf message GetAppInspectServerUrl + */ +export interface GetAppInspectServerUrl { +} +/** + * @generated from protobuf enum DeviceStatus + */ +export enum DeviceStatus { + /** + * @generated synthetic value - protobuf-ts requires all enums to have a 0 value + */ + UNSPECIFIED$ = 0, + /** + * @generated from protobuf enum value: OFFLINE = 1; + */ + OFFLINE = 1, + /** + * @generated from protobuf enum value: UNAUTHORIZED = 2; + */ + UNAUTHORIZED = 2, + /** + * @generated from protobuf enum value: ONLINE = 3; + */ + ONLINE = 3, + /** + * @generated from protobuf enum value: CONNECTING = 4; + */ + CONNECTING = 4, + /** + * @generated from protobuf enum value: AUTHORIZING = 5; + */ + AUTHORIZING = 5, + /** + * @generated from protobuf enum value: PREPARING = 6; + */ + PREPARING = 6, + /** + * @generated from protobuf enum value: UNHEALTHY = 7; + */ + UNHEALTHY = 7 +} +// Grouping + +/** + * @generated from protobuf enum RequirementType + */ +export enum RequirementType { + /** + * @generated synthetic value - protobuf-ts requires all enums to have a 0 value + */ + UNSPECIFIED$ = 0, + /** + * @generated from protobuf enum value: SEMVER = 1; + */ + SEMVER = 1, + /** + * @generated from protobuf enum value: GLOB = 2; + */ + GLOB = 2, + /** + * @generated from protobuf enum value: EXACT = 3; + */ + EXACT = 3 +} +/** + * @generated from protobuf enum RingerMode + */ +export enum RingerMode { + /** + * @generated from protobuf enum value: SILENT = 0; + */ + SILENT = 0, + /** + * @generated from protobuf enum value: VIBRATE = 1; + */ + VIBRATE = 1, + /** + * @generated from protobuf enum value: NORMAL = 2; + */ + NORMAL = 2 +} +// @generated message type with reflection information, may provide speed optimized methods +class Envelope$Type extends MessageType { + constructor() { + super("Envelope", [ + { no: 2, name: "message", kind: "message", T: () => Any }, + { no: 3, name: "channel", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): Envelope { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: Envelope): Envelope { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required google.protobuf.Any message */ 2: + message.message = Any.internalBinaryRead(reader, reader.uint32(), options, message.message); + break; + case /* optional string channel */ 3: + message.channel = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: Envelope, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required google.protobuf.Any message = 2; */ + if (message.message) + Any.internalBinaryWrite(message.message, writer.tag(2, WireType.LengthDelimited).fork(), options).join(); + /* optional string channel = 3; */ + if (message.channel !== undefined) + writer.tag(3, WireType.LengthDelimited).string(message.channel); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message Envelope + */ +export const Envelope = new Envelope$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class UpdateAccessTokenMessage$Type extends MessageType { + constructor() { + super("UpdateAccessTokenMessage", []); + } + create(value?: PartialMessage): UpdateAccessTokenMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: UpdateAccessTokenMessage): UpdateAccessTokenMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: UpdateAccessTokenMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message UpdateAccessTokenMessage + */ +export const UpdateAccessTokenMessage = new UpdateAccessTokenMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class UnlockDeviceMessage$Type extends MessageType { + constructor() { + super("UnlockDeviceMessage", []); + } + create(value?: PartialMessage): UnlockDeviceMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: UnlockDeviceMessage): UnlockDeviceMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: UnlockDeviceMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message UnlockDeviceMessage + */ +export const UnlockDeviceMessage = new UnlockDeviceMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeleteUserMessage$Type extends MessageType { + constructor() { + super("DeleteUserMessage", [ + { no: 1, name: "email", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeleteUserMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.email = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeleteUserMessage): DeleteUserMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string email */ 1: + message.email = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeleteUserMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string email = 1; */ + if (message.email !== "") + writer.tag(1, WireType.LengthDelimited).string(message.email); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeleteUserMessage + */ +export const DeleteUserMessage = new DeleteUserMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceOriginGroupMessage$Type extends MessageType { + constructor() { + super("DeviceOriginGroupMessage", [ + { no: 1, name: "signature", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceOriginGroupMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.signature = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceOriginGroupMessage): DeviceOriginGroupMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string signature */ 1: + message.signature = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceOriginGroupMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string signature = 1; */ + if (message.signature !== "") + writer.tag(1, WireType.LengthDelimited).string(message.signature); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceOriginGroupMessage + */ +export const DeviceOriginGroupMessage = new DeviceOriginGroupMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class UserQuotasDetailField$Type extends MessageType { + constructor() { + super("UserQuotasDetailField", [ + { no: 1, name: "duration", kind: "scalar", T: 1 /*ScalarType.DOUBLE*/ }, + { no: 2, name: "number", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): UserQuotasDetailField { + const message = globalThis.Object.create((this.messagePrototype!)); + message.duration = 0; + message.number = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: UserQuotasDetailField): UserQuotasDetailField { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required double duration */ 1: + message.duration = reader.double(); + break; + case /* required uint32 number */ 2: + message.number = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: UserQuotasDetailField, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required double duration = 1; */ + if (message.duration !== 0) + writer.tag(1, WireType.Bit64).double(message.duration); + /* required uint32 number = 2; */ + if (message.number !== 0) + writer.tag(2, WireType.Varint).uint32(message.number); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message UserQuotasDetailField + */ +export const UserQuotasDetailField = new UserQuotasDetailField$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class UserQuotasField$Type extends MessageType { + constructor() { + super("UserQuotasField", [ + { no: 1, name: "allocated", kind: "message", T: () => UserQuotasDetailField }, + { no: 2, name: "consumed", kind: "message", T: () => UserQuotasDetailField }, + { no: 3, name: "defaultGroupsDuration", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 4, name: "defaultGroupsNumber", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 5, name: "defaultGroupsRepetitions", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 6, name: "repetitions", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): UserQuotasField { + const message = globalThis.Object.create((this.messagePrototype!)); + message.defaultGroupsDuration = 0; + message.defaultGroupsNumber = 0; + message.defaultGroupsRepetitions = 0; + message.repetitions = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: UserQuotasField): UserQuotasField { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required UserQuotasDetailField allocated */ 1: + message.allocated = UserQuotasDetailField.internalBinaryRead(reader, reader.uint32(), options, message.allocated); + break; + case /* required UserQuotasDetailField consumed */ 2: + message.consumed = UserQuotasDetailField.internalBinaryRead(reader, reader.uint32(), options, message.consumed); + break; + case /* required uint32 defaultGroupsDuration */ 3: + message.defaultGroupsDuration = reader.uint32(); + break; + case /* required uint32 defaultGroupsNumber */ 4: + message.defaultGroupsNumber = reader.uint32(); + break; + case /* required uint32 defaultGroupsRepetitions */ 5: + message.defaultGroupsRepetitions = reader.uint32(); + break; + case /* required uint32 repetitions */ 6: + message.repetitions = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: UserQuotasField, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required UserQuotasDetailField allocated = 1; */ + if (message.allocated) + UserQuotasDetailField.internalBinaryWrite(message.allocated, writer.tag(1, WireType.LengthDelimited).fork(), options).join(); + /* required UserQuotasDetailField consumed = 2; */ + if (message.consumed) + UserQuotasDetailField.internalBinaryWrite(message.consumed, writer.tag(2, WireType.LengthDelimited).fork(), options).join(); + /* required uint32 defaultGroupsDuration = 3; */ + if (message.defaultGroupsDuration !== 0) + writer.tag(3, WireType.Varint).uint32(message.defaultGroupsDuration); + /* required uint32 defaultGroupsNumber = 4; */ + if (message.defaultGroupsNumber !== 0) + writer.tag(4, WireType.Varint).uint32(message.defaultGroupsNumber); + /* required uint32 defaultGroupsRepetitions = 5; */ + if (message.defaultGroupsRepetitions !== 0) + writer.tag(5, WireType.Varint).uint32(message.defaultGroupsRepetitions); + /* required uint32 repetitions = 6; */ + if (message.repetitions !== 0) + writer.tag(6, WireType.Varint).uint32(message.repetitions); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message UserQuotasField + */ +export const UserQuotasField = new UserQuotasField$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class UserGroupsField$Type extends MessageType { + constructor() { + super("UserGroupsField", [ + { no: 1, name: "quotas", kind: "message", T: () => UserQuotasField }, + { no: 2, name: "subscribed", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): UserGroupsField { + const message = globalThis.Object.create((this.messagePrototype!)); + message.subscribed = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: UserGroupsField): UserGroupsField { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required UserQuotasField quotas */ 1: + message.quotas = UserQuotasField.internalBinaryRead(reader, reader.uint32(), options, message.quotas); + break; + case /* repeated string subscribed */ 2: + message.subscribed.push(reader.string()); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: UserGroupsField, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required UserQuotasField quotas = 1; */ + if (message.quotas) + UserQuotasField.internalBinaryWrite(message.quotas, writer.tag(1, WireType.LengthDelimited).fork(), options).join(); + /* repeated string subscribed = 2; */ + for (let i = 0; i < message.subscribed.length; i++) + writer.tag(2, WireType.LengthDelimited).string(message.subscribed[i]); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message UserGroupsField + */ +export const UserGroupsField = new UserGroupsField$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class AlertMessageField$Type extends MessageType { + constructor() { + super("AlertMessageField", [ + { no: 1, name: "activation", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "data", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "level", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): AlertMessageField { + const message = globalThis.Object.create((this.messagePrototype!)); + message.activation = ""; + message.data = ""; + message.level = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AlertMessageField): AlertMessageField { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string activation */ 1: + message.activation = reader.string(); + break; + case /* required string data */ 2: + message.data = reader.string(); + break; + case /* required string level */ 3: + message.level = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: AlertMessageField, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string activation = 1; */ + if (message.activation !== "") + writer.tag(1, WireType.LengthDelimited).string(message.activation); + /* required string data = 2; */ + if (message.data !== "") + writer.tag(2, WireType.LengthDelimited).string(message.data); + /* required string level = 3; */ + if (message.level !== "") + writer.tag(3, WireType.LengthDelimited).string(message.level); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message AlertMessageField + */ +export const AlertMessageField = new AlertMessageField$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class UserSettingsField$Type extends MessageType { + constructor() { + super("UserSettingsField", [ + { no: 1, name: "alertMessage", kind: "message", T: () => AlertMessageField } + ]); + } + create(value?: PartialMessage): UserSettingsField { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: UserSettingsField): UserSettingsField { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* optional AlertMessageField alertMessage */ 1: + message.alertMessage = AlertMessageField.internalBinaryRead(reader, reader.uint32(), options, message.alertMessage); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: UserSettingsField, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* optional AlertMessageField alertMessage = 1; */ + if (message.alertMessage) + AlertMessageField.internalBinaryWrite(message.alertMessage, writer.tag(1, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message UserSettingsField + */ +export const UserSettingsField = new UserSettingsField$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class UserField$Type extends MessageType { + constructor() { + super("UserField", [ + { no: 1, name: "email", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "privilege", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "groups", kind: "message", T: () => UserGroupsField }, + { no: 5, name: "settings", kind: "message", T: () => UserSettingsField } + ]); + } + create(value?: PartialMessage): UserField { + const message = globalThis.Object.create((this.messagePrototype!)); + message.email = ""; + message.name = ""; + message.privilege = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: UserField): UserField { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string email */ 1: + message.email = reader.string(); + break; + case /* required string name */ 2: + message.name = reader.string(); + break; + case /* required string privilege */ 3: + message.privilege = reader.string(); + break; + case /* required UserGroupsField groups */ 4: + message.groups = UserGroupsField.internalBinaryRead(reader, reader.uint32(), options, message.groups); + break; + case /* optional UserSettingsField settings */ 5: + message.settings = UserSettingsField.internalBinaryRead(reader, reader.uint32(), options, message.settings); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: UserField, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string email = 1; */ + if (message.email !== "") + writer.tag(1, WireType.LengthDelimited).string(message.email); + /* required string name = 2; */ + if (message.name !== "") + writer.tag(2, WireType.LengthDelimited).string(message.name); + /* required string privilege = 3; */ + if (message.privilege !== "") + writer.tag(3, WireType.LengthDelimited).string(message.privilege); + /* required UserGroupsField groups = 4; */ + if (message.groups) + UserGroupsField.internalBinaryWrite(message.groups, writer.tag(4, WireType.LengthDelimited).fork(), options).join(); + /* optional UserSettingsField settings = 5; */ + if (message.settings) + UserSettingsField.internalBinaryWrite(message.settings, writer.tag(5, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message UserField + */ +export const UserField = new UserField$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class UserChangeMessage$Type extends MessageType { + constructor() { + super("UserChangeMessage", [ + { no: 1, name: "user", kind: "message", T: () => UserField }, + { no: 2, name: "isAddedGroup", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 3, name: "groups", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "action", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "targets", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ }, + { no: 6, name: "timeStamp", kind: "scalar", T: 1 /*ScalarType.DOUBLE*/ } + ]); + } + create(value?: PartialMessage): UserChangeMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.isAddedGroup = false; + message.groups = []; + message.action = ""; + message.targets = []; + message.timeStamp = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: UserChangeMessage): UserChangeMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required UserField user */ 1: + message.user = UserField.internalBinaryRead(reader, reader.uint32(), options, message.user); + break; + case /* required bool isAddedGroup */ 2: + message.isAddedGroup = reader.bool(); + break; + case /* repeated string groups */ 3: + message.groups.push(reader.string()); + break; + case /* required string action */ 4: + message.action = reader.string(); + break; + case /* repeated string targets */ 5: + message.targets.push(reader.string()); + break; + case /* required double timeStamp */ 6: + message.timeStamp = reader.double(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: UserChangeMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required UserField user = 1; */ + if (message.user) + UserField.internalBinaryWrite(message.user, writer.tag(1, WireType.LengthDelimited).fork(), options).join(); + /* required bool isAddedGroup = 2; */ + if (message.isAddedGroup !== false) + writer.tag(2, WireType.Varint).bool(message.isAddedGroup); + /* repeated string groups = 3; */ + for (let i = 0; i < message.groups.length; i++) + writer.tag(3, WireType.LengthDelimited).string(message.groups[i]); + /* required string action = 4; */ + if (message.action !== "") + writer.tag(4, WireType.LengthDelimited).string(message.action); + /* repeated string targets = 5; */ + for (let i = 0; i < message.targets.length; i++) + writer.tag(5, WireType.LengthDelimited).string(message.targets[i]); + /* required double timeStamp = 6; */ + if (message.timeStamp !== 0) + writer.tag(6, WireType.Bit64).double(message.timeStamp); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message UserChangeMessage + */ +export const UserChangeMessage = new UserChangeMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceNetworkField$Type extends MessageType { + constructor() { + super("DeviceNetworkField", [ + { no: 1, name: "type", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "subtype", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceNetworkField { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceNetworkField): DeviceNetworkField { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* optional string type */ 1: + message.type = reader.string(); + break; + case /* optional string subtype */ 2: + message.subtype = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceNetworkField, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* optional string type = 1; */ + if (message.type !== undefined) + writer.tag(1, WireType.LengthDelimited).string(message.type); + /* optional string subtype = 2; */ + if (message.subtype !== undefined) + writer.tag(2, WireType.LengthDelimited).string(message.subtype); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceNetworkField + */ +export const DeviceNetworkField = new DeviceNetworkField$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceDisplayField$Type extends MessageType { + constructor() { + super("DeviceDisplayField", [ + { no: 1, name: "height", kind: "scalar", opt: true, T: 13 /*ScalarType.UINT32*/ }, + { no: 2, name: "width", kind: "scalar", opt: true, T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): DeviceDisplayField { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceDisplayField): DeviceDisplayField { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* optional uint32 height */ 1: + message.height = reader.uint32(); + break; + case /* optional uint32 width */ 2: + message.width = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceDisplayField, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* optional uint32 height = 1; */ + if (message.height !== undefined) + writer.tag(1, WireType.Varint).uint32(message.height); + /* optional uint32 width = 2; */ + if (message.width !== undefined) + writer.tag(2, WireType.Varint).uint32(message.width); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceDisplayField + */ +export const DeviceDisplayField = new DeviceDisplayField$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DevicePhoneField$Type extends MessageType { + constructor() { + super("DevicePhoneField", [ + { no: 1, name: "imei", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DevicePhoneField { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DevicePhoneField): DevicePhoneField { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* optional string imei */ 1: + message.imei = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DevicePhoneField, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* optional string imei = 1; */ + if (message.imei !== undefined) + writer.tag(1, WireType.LengthDelimited).string(message.imei); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DevicePhoneField + */ +export const DevicePhoneField = new DevicePhoneField$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceProviderField$Type extends MessageType { + constructor() { + super("DeviceProviderField", [ + { no: 1, name: "name", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceProviderField { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceProviderField): DeviceProviderField { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* optional string name */ 1: + message.name = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceProviderField, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* optional string name = 1; */ + if (message.name !== undefined) + writer.tag(1, WireType.LengthDelimited).string(message.name); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceProviderField + */ +export const DeviceProviderField = new DeviceProviderField$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceGroupField$Type extends MessageType { + constructor() { + super("DeviceGroupField", [ + { no: 1, name: "id", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "name", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "origin", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "originName", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "owner", kind: "message", T: () => GroupOwnerField } + ]); + } + create(value?: PartialMessage): DeviceGroupField { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceGroupField): DeviceGroupField { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* optional string id */ 1: + message.id = reader.string(); + break; + case /* optional string name */ 2: + message.name = reader.string(); + break; + case /* optional string origin */ 3: + message.origin = reader.string(); + break; + case /* optional string originName */ 4: + message.originName = reader.string(); + break; + case /* optional GroupOwnerField owner */ 5: + message.owner = GroupOwnerField.internalBinaryRead(reader, reader.uint32(), options, message.owner); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceGroupField, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* optional string id = 1; */ + if (message.id !== undefined) + writer.tag(1, WireType.LengthDelimited).string(message.id); + /* optional string name = 2; */ + if (message.name !== undefined) + writer.tag(2, WireType.LengthDelimited).string(message.name); + /* optional string origin = 3; */ + if (message.origin !== undefined) + writer.tag(3, WireType.LengthDelimited).string(message.origin); + /* optional string originName = 4; */ + if (message.originName !== undefined) + writer.tag(4, WireType.LengthDelimited).string(message.originName); + /* optional GroupOwnerField owner = 5; */ + if (message.owner) + GroupOwnerField.internalBinaryWrite(message.owner, writer.tag(5, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceGroupField + */ +export const DeviceGroupField = new DeviceGroupField$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceField$Type extends MessageType { + constructor() { + super("DeviceField", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "model", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "version", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "operator", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "network", kind: "message", T: () => DeviceNetworkField }, + { no: 6, name: "display", kind: "message", T: () => DeviceDisplayField }, + { no: 7, name: "manufacturer", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 8, name: "sdk", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 9, name: "abi", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 10, name: "cpuPlatform", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 11, name: "openGLESVersion", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 12, name: "phone", kind: "message", T: () => DevicePhoneField }, + { no: 13, name: "provider", kind: "message", T: () => DeviceProviderField }, + { no: 14, name: "group", kind: "message", T: () => DeviceGroupField }, + { no: 15, name: "marketName", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceField { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceField): DeviceField { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* optional string model */ 2: + message.model = reader.string(); + break; + case /* optional string version */ 3: + message.version = reader.string(); + break; + case /* optional string operator */ 4: + message.operator = reader.string(); + break; + case /* optional DeviceNetworkField network */ 5: + message.network = DeviceNetworkField.internalBinaryRead(reader, reader.uint32(), options, message.network); + break; + case /* optional DeviceDisplayField display */ 6: + message.display = DeviceDisplayField.internalBinaryRead(reader, reader.uint32(), options, message.display); + break; + case /* optional string manufacturer */ 7: + message.manufacturer = reader.string(); + break; + case /* optional string sdk */ 8: + message.sdk = reader.string(); + break; + case /* optional string abi */ 9: + message.abi = reader.string(); + break; + case /* optional string cpuPlatform */ 10: + message.cpuPlatform = reader.string(); + break; + case /* optional string openGLESVersion */ 11: + message.openGLESVersion = reader.string(); + break; + case /* optional DevicePhoneField phone */ 12: + message.phone = DevicePhoneField.internalBinaryRead(reader, reader.uint32(), options, message.phone); + break; + case /* optional DeviceProviderField provider */ 13: + message.provider = DeviceProviderField.internalBinaryRead(reader, reader.uint32(), options, message.provider); + break; + case /* optional DeviceGroupField group */ 14: + message.group = DeviceGroupField.internalBinaryRead(reader, reader.uint32(), options, message.group); + break; + case /* optional string marketName */ 15: + message.marketName = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceField, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* optional string model = 2; */ + if (message.model !== undefined) + writer.tag(2, WireType.LengthDelimited).string(message.model); + /* optional string version = 3; */ + if (message.version !== undefined) + writer.tag(3, WireType.LengthDelimited).string(message.version); + /* optional string operator = 4; */ + if (message.operator !== undefined) + writer.tag(4, WireType.LengthDelimited).string(message.operator); + /* optional DeviceNetworkField network = 5; */ + if (message.network) + DeviceNetworkField.internalBinaryWrite(message.network, writer.tag(5, WireType.LengthDelimited).fork(), options).join(); + /* optional DeviceDisplayField display = 6; */ + if (message.display) + DeviceDisplayField.internalBinaryWrite(message.display, writer.tag(6, WireType.LengthDelimited).fork(), options).join(); + /* optional string manufacturer = 7; */ + if (message.manufacturer !== undefined) + writer.tag(7, WireType.LengthDelimited).string(message.manufacturer); + /* optional string sdk = 8; */ + if (message.sdk !== undefined) + writer.tag(8, WireType.LengthDelimited).string(message.sdk); + /* optional string abi = 9; */ + if (message.abi !== undefined) + writer.tag(9, WireType.LengthDelimited).string(message.abi); + /* optional string cpuPlatform = 10; */ + if (message.cpuPlatform !== undefined) + writer.tag(10, WireType.LengthDelimited).string(message.cpuPlatform); + /* optional string openGLESVersion = 11; */ + if (message.openGLESVersion !== undefined) + writer.tag(11, WireType.LengthDelimited).string(message.openGLESVersion); + /* optional DevicePhoneField phone = 12; */ + if (message.phone) + DevicePhoneField.internalBinaryWrite(message.phone, writer.tag(12, WireType.LengthDelimited).fork(), options).join(); + /* optional DeviceProviderField provider = 13; */ + if (message.provider) + DeviceProviderField.internalBinaryWrite(message.provider, writer.tag(13, WireType.LengthDelimited).fork(), options).join(); + /* optional DeviceGroupField group = 14; */ + if (message.group) + DeviceGroupField.internalBinaryWrite(message.group, writer.tag(14, WireType.LengthDelimited).fork(), options).join(); + /* optional string marketName = 15; */ + if (message.marketName !== undefined) + writer.tag(15, WireType.LengthDelimited).string(message.marketName); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceField + */ +export const DeviceField = new DeviceField$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceChangeMessage$Type extends MessageType { + constructor() { + super("DeviceChangeMessage", [ + { no: 1, name: "device", kind: "message", T: () => DeviceField }, + { no: 2, name: "action", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "oldOriginGroupId", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "timeStamp", kind: "scalar", T: 1 /*ScalarType.DOUBLE*/ } + ]); + } + create(value?: PartialMessage): DeviceChangeMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.action = ""; + message.oldOriginGroupId = ""; + message.timeStamp = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceChangeMessage): DeviceChangeMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required DeviceField device */ 1: + message.device = DeviceField.internalBinaryRead(reader, reader.uint32(), options, message.device); + break; + case /* required string action */ 2: + message.action = reader.string(); + break; + case /* required string oldOriginGroupId */ 3: + message.oldOriginGroupId = reader.string(); + break; + case /* required double timeStamp */ 4: + message.timeStamp = reader.double(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceChangeMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required DeviceField device = 1; */ + if (message.device) + DeviceField.internalBinaryWrite(message.device, writer.tag(1, WireType.LengthDelimited).fork(), options).join(); + /* required string action = 2; */ + if (message.action !== "") + writer.tag(2, WireType.LengthDelimited).string(message.action); + /* required string oldOriginGroupId = 3; */ + if (message.oldOriginGroupId !== "") + writer.tag(3, WireType.LengthDelimited).string(message.oldOriginGroupId); + /* required double timeStamp = 4; */ + if (message.timeStamp !== 0) + writer.tag(4, WireType.Bit64).double(message.timeStamp); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceChangeMessage + */ +export const DeviceChangeMessage = new DeviceChangeMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GroupDateField$Type extends MessageType { + constructor() { + super("GroupDateField", [ + { no: 1, name: "start", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "stop", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): GroupDateField { + const message = globalThis.Object.create((this.messagePrototype!)); + message.start = ""; + message.stop = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GroupDateField): GroupDateField { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string start */ 1: + message.start = reader.string(); + break; + case /* required string stop */ 2: + message.stop = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GroupDateField, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string start = 1; */ + if (message.start !== "") + writer.tag(1, WireType.LengthDelimited).string(message.start); + /* required string stop = 2; */ + if (message.stop !== "") + writer.tag(2, WireType.LengthDelimited).string(message.stop); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GroupDateField + */ +export const GroupDateField = new GroupDateField$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GroupOwnerField$Type extends MessageType { + constructor() { + super("GroupOwnerField", [ + { no: 1, name: "email", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): GroupOwnerField { + const message = globalThis.Object.create((this.messagePrototype!)); + message.email = ""; + message.name = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GroupOwnerField): GroupOwnerField { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string email */ 1: + message.email = reader.string(); + break; + case /* required string name */ 2: + message.name = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GroupOwnerField, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string email = 1; */ + if (message.email !== "") + writer.tag(1, WireType.LengthDelimited).string(message.email); + /* required string name = 2; */ + if (message.name !== "") + writer.tag(2, WireType.LengthDelimited).string(message.name); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GroupOwnerField + */ +export const GroupOwnerField = new GroupOwnerField$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GroupField$Type extends MessageType { + constructor() { + super("GroupField", [ + { no: 1, name: "id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "class", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "privilege", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "owner", kind: "message", T: () => GroupOwnerField }, + { no: 6, name: "dates", kind: "message", repeat: 2 /*RepeatType.UNPACKED*/, T: () => GroupDateField }, + { no: 7, name: "duration", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 8, name: "repetitions", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 9, name: "devices", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ }, + { no: 10, name: "users", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ }, + { no: 11, name: "state", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 12, name: "isActive", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 13, name: "moderators", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): GroupField { + const message = globalThis.Object.create((this.messagePrototype!)); + message.id = ""; + message.name = ""; + message.class = ""; + message.privilege = ""; + message.dates = []; + message.duration = 0; + message.repetitions = 0; + message.devices = []; + message.users = []; + message.state = ""; + message.isActive = false; + message.moderators = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GroupField): GroupField { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string id */ 1: + message.id = reader.string(); + break; + case /* required string name */ 2: + message.name = reader.string(); + break; + case /* required string class */ 3: + message.class = reader.string(); + break; + case /* required string privilege */ 4: + message.privilege = reader.string(); + break; + case /* required GroupOwnerField owner */ 5: + message.owner = GroupOwnerField.internalBinaryRead(reader, reader.uint32(), options, message.owner); + break; + case /* repeated GroupDateField dates */ 6: + message.dates.push(GroupDateField.internalBinaryRead(reader, reader.uint32(), options)); + break; + case /* required uint32 duration */ 7: + message.duration = reader.uint32(); + break; + case /* required uint32 repetitions */ 8: + message.repetitions = reader.uint32(); + break; + case /* repeated string devices */ 9: + message.devices.push(reader.string()); + break; + case /* repeated string users */ 10: + message.users.push(reader.string()); + break; + case /* required string state */ 11: + message.state = reader.string(); + break; + case /* required bool isActive */ 12: + message.isActive = reader.bool(); + break; + case /* repeated string moderators */ 13: + message.moderators.push(reader.string()); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GroupField, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string id = 1; */ + if (message.id !== "") + writer.tag(1, WireType.LengthDelimited).string(message.id); + /* required string name = 2; */ + if (message.name !== "") + writer.tag(2, WireType.LengthDelimited).string(message.name); + /* required string class = 3; */ + if (message.class !== "") + writer.tag(3, WireType.LengthDelimited).string(message.class); + /* required string privilege = 4; */ + if (message.privilege !== "") + writer.tag(4, WireType.LengthDelimited).string(message.privilege); + /* required GroupOwnerField owner = 5; */ + if (message.owner) + GroupOwnerField.internalBinaryWrite(message.owner, writer.tag(5, WireType.LengthDelimited).fork(), options).join(); + /* repeated GroupDateField dates = 6; */ + for (let i = 0; i < message.dates.length; i++) + GroupDateField.internalBinaryWrite(message.dates[i], writer.tag(6, WireType.LengthDelimited).fork(), options).join(); + /* required uint32 duration = 7; */ + if (message.duration !== 0) + writer.tag(7, WireType.Varint).uint32(message.duration); + /* required uint32 repetitions = 8; */ + if (message.repetitions !== 0) + writer.tag(8, WireType.Varint).uint32(message.repetitions); + /* repeated string devices = 9; */ + for (let i = 0; i < message.devices.length; i++) + writer.tag(9, WireType.LengthDelimited).string(message.devices[i]); + /* repeated string users = 10; */ + for (let i = 0; i < message.users.length; i++) + writer.tag(10, WireType.LengthDelimited).string(message.users[i]); + /* required string state = 11; */ + if (message.state !== "") + writer.tag(11, WireType.LengthDelimited).string(message.state); + /* required bool isActive = 12; */ + if (message.isActive !== false) + writer.tag(12, WireType.Varint).bool(message.isActive); + /* repeated string moderators = 13; */ + for (let i = 0; i < message.moderators.length; i++) + writer.tag(13, WireType.LengthDelimited).string(message.moderators[i]); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GroupField + */ +export const GroupField = new GroupField$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GroupChangeMessage$Type extends MessageType { + constructor() { + super("GroupChangeMessage", [ + { no: 1, name: "group", kind: "message", T: () => GroupField }, + { no: 2, name: "action", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "subscribers", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "isChangedDates", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 5, name: "isChangedClass", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 6, name: "isAddedUser", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 7, name: "users", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ }, + { no: 8, name: "isAddedDevice", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 9, name: "devices", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ }, + { no: 10, name: "timeStamp", kind: "scalar", T: 1 /*ScalarType.DOUBLE*/ } + ]); + } + create(value?: PartialMessage): GroupChangeMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.action = ""; + message.subscribers = []; + message.isChangedDates = false; + message.isChangedClass = false; + message.isAddedUser = false; + message.users = []; + message.isAddedDevice = false; + message.devices = []; + message.timeStamp = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GroupChangeMessage): GroupChangeMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required GroupField group */ 1: + message.group = GroupField.internalBinaryRead(reader, reader.uint32(), options, message.group); + break; + case /* required string action */ 2: + message.action = reader.string(); + break; + case /* repeated string subscribers */ 3: + message.subscribers.push(reader.string()); + break; + case /* required bool isChangedDates */ 4: + message.isChangedDates = reader.bool(); + break; + case /* required bool isChangedClass */ 5: + message.isChangedClass = reader.bool(); + break; + case /* required bool isAddedUser */ 6: + message.isAddedUser = reader.bool(); + break; + case /* repeated string users */ 7: + message.users.push(reader.string()); + break; + case /* required bool isAddedDevice */ 8: + message.isAddedDevice = reader.bool(); + break; + case /* repeated string devices */ 9: + message.devices.push(reader.string()); + break; + case /* required double timeStamp */ 10: + message.timeStamp = reader.double(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GroupChangeMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required GroupField group = 1; */ + if (message.group) + GroupField.internalBinaryWrite(message.group, writer.tag(1, WireType.LengthDelimited).fork(), options).join(); + /* required string action = 2; */ + if (message.action !== "") + writer.tag(2, WireType.LengthDelimited).string(message.action); + /* repeated string subscribers = 3; */ + for (let i = 0; i < message.subscribers.length; i++) + writer.tag(3, WireType.LengthDelimited).string(message.subscribers[i]); + /* required bool isChangedDates = 4; */ + if (message.isChangedDates !== false) + writer.tag(4, WireType.Varint).bool(message.isChangedDates); + /* required bool isChangedClass = 5; */ + if (message.isChangedClass !== false) + writer.tag(5, WireType.Varint).bool(message.isChangedClass); + /* required bool isAddedUser = 6; */ + if (message.isAddedUser !== false) + writer.tag(6, WireType.Varint).bool(message.isAddedUser); + /* repeated string users = 7; */ + for (let i = 0; i < message.users.length; i++) + writer.tag(7, WireType.LengthDelimited).string(message.users[i]); + /* required bool isAddedDevice = 8; */ + if (message.isAddedDevice !== false) + writer.tag(8, WireType.Varint).bool(message.isAddedDevice); + /* repeated string devices = 9; */ + for (let i = 0; i < message.devices.length; i++) + writer.tag(9, WireType.LengthDelimited).string(message.devices[i]); + /* required double timeStamp = 10; */ + if (message.timeStamp !== 0) + writer.tag(10, WireType.Bit64).double(message.timeStamp); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GroupChangeMessage + */ +export const GroupChangeMessage = new GroupChangeMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceGroupChangeMessage$Type extends MessageType { + constructor() { + super("DeviceGroupChangeMessage", [ + { no: 1, name: "id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "group", kind: "message", T: () => DeviceGroupMessage }, + { no: 3, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceGroupChangeMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.id = ""; + message.serial = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceGroupChangeMessage): DeviceGroupChangeMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string id */ 1: + message.id = reader.string(); + break; + case /* required DeviceGroupMessage group */ 2: + message.group = DeviceGroupMessage.internalBinaryRead(reader, reader.uint32(), options, message.group); + break; + case /* required string serial */ 3: + message.serial = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceGroupChangeMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string id = 1; */ + if (message.id !== "") + writer.tag(1, WireType.LengthDelimited).string(message.id); + /* required DeviceGroupMessage group = 2; */ + if (message.group) + DeviceGroupMessage.internalBinaryWrite(message.group, writer.tag(2, WireType.LengthDelimited).fork(), options).join(); + /* required string serial = 3; */ + if (message.serial !== "") + writer.tag(3, WireType.LengthDelimited).string(message.serial); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceGroupChangeMessage + */ +export const DeviceGroupChangeMessage = new DeviceGroupChangeMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GroupUserChangeMessage$Type extends MessageType { + constructor() { + super("GroupUserChangeMessage", [ + { no: 1, name: "users", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "isAdded", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 3, name: "id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "isDeletedLater", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 5, name: "devices", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): GroupUserChangeMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.users = []; + message.isAdded = false; + message.id = ""; + message.isDeletedLater = false; + message.devices = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GroupUserChangeMessage): GroupUserChangeMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* repeated string users */ 1: + message.users.push(reader.string()); + break; + case /* required bool isAdded */ 2: + message.isAdded = reader.bool(); + break; + case /* required string id */ 3: + message.id = reader.string(); + break; + case /* required bool isDeletedLater */ 4: + message.isDeletedLater = reader.bool(); + break; + case /* repeated string devices */ 5: + message.devices.push(reader.string()); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GroupUserChangeMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* repeated string users = 1; */ + for (let i = 0; i < message.users.length; i++) + writer.tag(1, WireType.LengthDelimited).string(message.users[i]); + /* required bool isAdded = 2; */ + if (message.isAdded !== false) + writer.tag(2, WireType.Varint).bool(message.isAdded); + /* required string id = 3; */ + if (message.id !== "") + writer.tag(3, WireType.LengthDelimited).string(message.id); + /* required bool isDeletedLater = 4; */ + if (message.isDeletedLater !== false) + writer.tag(4, WireType.Varint).bool(message.isDeletedLater); + /* repeated string devices = 5; */ + for (let i = 0; i < message.devices.length; i++) + writer.tag(5, WireType.LengthDelimited).string(message.devices[i]); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GroupUserChangeMessage + */ +export const GroupUserChangeMessage = new GroupUserChangeMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ConnectStartedMessage$Type extends MessageType { + constructor() { + super("ConnectStartedMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "url", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): ConnectStartedMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.url = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ConnectStartedMessage): ConnectStartedMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required string url */ 2: + message.url = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ConnectStartedMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required string url = 2; */ + if (message.url !== "") + writer.tag(2, WireType.LengthDelimited).string(message.url); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ConnectStartedMessage + */ +export const ConnectStartedMessage = new ConnectStartedMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class InstallResultMessage$Type extends MessageType { + constructor() { + super("InstallResultMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "result", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): InstallResultMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.result = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: InstallResultMessage): InstallResultMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required string result */ 2: + message.result = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: InstallResultMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required string result = 2; */ + if (message.result !== "") + writer.tag(2, WireType.LengthDelimited).string(message.result); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message InstallResultMessage + */ +export const InstallResultMessage = new InstallResultMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ConnectStoppedMessage$Type extends MessageType { + constructor() { + super("ConnectStoppedMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): ConnectStoppedMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ConnectStoppedMessage): ConnectStoppedMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ConnectStoppedMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ConnectStoppedMessage + */ +export const ConnectStoppedMessage = new ConnectStoppedMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class FileSystemListMessage$Type extends MessageType { + constructor() { + super("FileSystemListMessage", [ + { no: 1, name: "dir", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): FileSystemListMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.dir = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: FileSystemListMessage): FileSystemListMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string dir */ 1: + message.dir = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: FileSystemListMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string dir = 1; */ + if (message.dir !== "") + writer.tag(1, WireType.LengthDelimited).string(message.dir); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message FileSystemListMessage + */ +export const FileSystemListMessage = new FileSystemListMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class FileSystemGetMessage$Type extends MessageType { + constructor() { + super("FileSystemGetMessage", [ + { no: 1, name: "file", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "jwt", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): FileSystemGetMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.file = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: FileSystemGetMessage): FileSystemGetMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string file */ 1: + message.file = reader.string(); + break; + case /* optional string jwt */ 2: + message.jwt = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: FileSystemGetMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string file = 1; */ + if (message.file !== "") + writer.tag(1, WireType.LengthDelimited).string(message.file); + /* optional string jwt = 2; */ + if (message.jwt !== undefined) + writer.tag(2, WireType.LengthDelimited).string(message.jwt); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message FileSystemGetMessage + */ +export const FileSystemGetMessage = new FileSystemGetMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TransactionProgressMessage$Type extends MessageType { + constructor() { + super("TransactionProgressMessage", [ + { no: 1, name: "source", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "seq", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 3, name: "data", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "progress", kind: "scalar", opt: true, T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): TransactionProgressMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.source = ""; + message.seq = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TransactionProgressMessage): TransactionProgressMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string source */ 1: + message.source = reader.string(); + break; + case /* required uint32 seq */ 2: + message.seq = reader.uint32(); + break; + case /* optional string data */ 3: + message.data = reader.string(); + break; + case /* optional uint32 progress = 4 [default = 0] */ 4: + message.progress = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TransactionProgressMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string source = 1; */ + if (message.source !== "") + writer.tag(1, WireType.LengthDelimited).string(message.source); + /* required uint32 seq = 2; */ + if (message.seq !== 0) + writer.tag(2, WireType.Varint).uint32(message.seq); + /* optional string data = 3; */ + if (message.data !== undefined) + writer.tag(3, WireType.LengthDelimited).string(message.data); + /* optional uint32 progress = 4 [default = 0]; */ + if (message.progress !== undefined) + writer.tag(4, WireType.Varint).uint32(message.progress); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message TransactionProgressMessage + */ +export const TransactionProgressMessage = new TransactionProgressMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TransactionDoneMessage$Type extends MessageType { + constructor() { + super("TransactionDoneMessage", [ + { no: 1, name: "source", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "seq", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 3, name: "success", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 4, name: "data", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "body", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): TransactionDoneMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.source = ""; + message.seq = 0; + message.success = false; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TransactionDoneMessage): TransactionDoneMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string source */ 1: + message.source = reader.string(); + break; + case /* required uint32 seq */ 2: + message.seq = reader.uint32(); + break; + case /* required bool success */ 3: + message.success = reader.bool(); + break; + case /* optional string data */ 4: + message.data = reader.string(); + break; + case /* optional string body */ 5: + message.body = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TransactionDoneMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string source = 1; */ + if (message.source !== "") + writer.tag(1, WireType.LengthDelimited).string(message.source); + /* required uint32 seq = 2; */ + if (message.seq !== 0) + writer.tag(2, WireType.Varint).uint32(message.seq); + /* required bool success = 3; */ + if (message.success !== false) + writer.tag(3, WireType.Varint).bool(message.success); + /* optional string data = 4; */ + if (message.data !== undefined) + writer.tag(4, WireType.LengthDelimited).string(message.data); + /* optional string body = 5; */ + if (message.body !== undefined) + writer.tag(5, WireType.LengthDelimited).string(message.body); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message TransactionDoneMessage + */ +export const TransactionDoneMessage = new TransactionDoneMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TransactionTreeMessage$Type extends MessageType { + constructor() { + super("TransactionTreeMessage", [ + { no: 1, name: "source", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "seq", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 3, name: "success", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 4, name: "data", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "body", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): TransactionTreeMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.source = ""; + message.seq = 0; + message.success = false; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TransactionTreeMessage): TransactionTreeMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string source */ 1: + message.source = reader.string(); + break; + case /* required uint32 seq */ 2: + message.seq = reader.uint32(); + break; + case /* required bool success */ 3: + message.success = reader.bool(); + break; + case /* optional string data */ 4: + message.data = reader.string(); + break; + case /* optional string body */ 5: + message.body = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TransactionTreeMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string source = 1; */ + if (message.source !== "") + writer.tag(1, WireType.LengthDelimited).string(message.source); + /* required uint32 seq = 2; */ + if (message.seq !== 0) + writer.tag(2, WireType.Varint).uint32(message.seq); + /* required bool success = 3; */ + if (message.success !== false) + writer.tag(3, WireType.Varint).bool(message.success); + /* optional string data = 4; */ + if (message.data !== undefined) + writer.tag(4, WireType.LengthDelimited).string(message.data); + /* optional string body = 5; */ + if (message.body !== undefined) + writer.tag(5, WireType.LengthDelimited).string(message.body); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message TransactionTreeMessage + */ +export const TransactionTreeMessage = new TransactionTreeMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceLogMessage$Type extends MessageType { + constructor() { + super("DeviceLogMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "timestamp", kind: "scalar", T: 1 /*ScalarType.DOUBLE*/ }, + { no: 3, name: "priority", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 4, name: "tag", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "pid", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 6, name: "message", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 7, name: "identifier", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceLogMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.timestamp = 0; + message.priority = 0; + message.tag = ""; + message.pid = 0; + message.message = ""; + message.identifier = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceLogMessage): DeviceLogMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required double timestamp */ 2: + message.timestamp = reader.double(); + break; + case /* required uint32 priority */ 3: + message.priority = reader.uint32(); + break; + case /* required string tag */ 4: + message.tag = reader.string(); + break; + case /* required uint32 pid */ 5: + message.pid = reader.uint32(); + break; + case /* required string message */ 6: + message.message = reader.string(); + break; + case /* required string identifier */ 7: + message.identifier = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceLogMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required double timestamp = 2; */ + if (message.timestamp !== 0) + writer.tag(2, WireType.Bit64).double(message.timestamp); + /* required uint32 priority = 3; */ + if (message.priority !== 0) + writer.tag(3, WireType.Varint).uint32(message.priority); + /* required string tag = 4; */ + if (message.tag !== "") + writer.tag(4, WireType.LengthDelimited).string(message.tag); + /* required uint32 pid = 5; */ + if (message.pid !== 0) + writer.tag(5, WireType.Varint).uint32(message.pid); + /* required string message = 6; */ + if (message.message !== "") + writer.tag(6, WireType.LengthDelimited).string(message.message); + /* required string identifier = 7; */ + if (message.identifier !== "") + writer.tag(7, WireType.LengthDelimited).string(message.identifier); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceLogMessage + */ +export const DeviceLogMessage = new DeviceLogMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceGroupOwnerMessage$Type extends MessageType { + constructor() { + super("DeviceGroupOwnerMessage", [ + { no: 1, name: "email", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceGroupOwnerMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.email = ""; + message.name = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceGroupOwnerMessage): DeviceGroupOwnerMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string email */ 1: + message.email = reader.string(); + break; + case /* required string name */ 2: + message.name = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceGroupOwnerMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string email = 1; */ + if (message.email !== "") + writer.tag(1, WireType.LengthDelimited).string(message.email); + /* required string name = 2; */ + if (message.name !== "") + writer.tag(2, WireType.LengthDelimited).string(message.name); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceGroupOwnerMessage + */ +export const DeviceGroupOwnerMessage = new DeviceGroupOwnerMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceGroupLifetimeMessage$Type extends MessageType { + constructor() { + super("DeviceGroupLifetimeMessage", [ + { no: 1, name: "start", kind: "scalar", T: 1 /*ScalarType.DOUBLE*/ }, + { no: 2, name: "stop", kind: "scalar", T: 1 /*ScalarType.DOUBLE*/ } + ]); + } + create(value?: PartialMessage): DeviceGroupLifetimeMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.start = 0; + message.stop = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceGroupLifetimeMessage): DeviceGroupLifetimeMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required double start */ 1: + message.start = reader.double(); + break; + case /* required double stop */ 2: + message.stop = reader.double(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceGroupLifetimeMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required double start = 1; */ + if (message.start !== 0) + writer.tag(1, WireType.Bit64).double(message.start); + /* required double stop = 2; */ + if (message.stop !== 0) + writer.tag(2, WireType.Bit64).double(message.stop); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceGroupLifetimeMessage + */ +export const DeviceGroupLifetimeMessage = new DeviceGroupLifetimeMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceGroupMessage$Type extends MessageType { + constructor() { + super("DeviceGroupMessage", [ + { no: 1, name: "id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "owner", kind: "message", T: () => DeviceGroupOwnerMessage }, + { no: 4, name: "lifeTime", kind: "message", T: () => DeviceGroupLifetimeMessage }, + { no: 5, name: "class", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 6, name: "repetitions", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 7, name: "originName", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceGroupMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.id = ""; + message.name = ""; + message.class = ""; + message.repetitions = 0; + message.originName = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceGroupMessage): DeviceGroupMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string id */ 1: + message.id = reader.string(); + break; + case /* required string name */ 2: + message.name = reader.string(); + break; + case /* required DeviceGroupOwnerMessage owner */ 3: + message.owner = DeviceGroupOwnerMessage.internalBinaryRead(reader, reader.uint32(), options, message.owner); + break; + case /* required DeviceGroupLifetimeMessage lifeTime */ 4: + message.lifeTime = DeviceGroupLifetimeMessage.internalBinaryRead(reader, reader.uint32(), options, message.lifeTime); + break; + case /* required string class */ 5: + message.class = reader.string(); + break; + case /* required uint32 repetitions */ 6: + message.repetitions = reader.uint32(); + break; + case /* required string originName */ 7: + message.originName = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceGroupMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string id = 1; */ + if (message.id !== "") + writer.tag(1, WireType.LengthDelimited).string(message.id); + /* required string name = 2; */ + if (message.name !== "") + writer.tag(2, WireType.LengthDelimited).string(message.name); + /* required DeviceGroupOwnerMessage owner = 3; */ + if (message.owner) + DeviceGroupOwnerMessage.internalBinaryWrite(message.owner, writer.tag(3, WireType.LengthDelimited).fork(), options).join(); + /* required DeviceGroupLifetimeMessage lifeTime = 4; */ + if (message.lifeTime) + DeviceGroupLifetimeMessage.internalBinaryWrite(message.lifeTime, writer.tag(4, WireType.LengthDelimited).fork(), options).join(); + /* required string class = 5; */ + if (message.class !== "") + writer.tag(5, WireType.LengthDelimited).string(message.class); + /* required uint32 repetitions = 6; */ + if (message.repetitions !== 0) + writer.tag(6, WireType.Varint).uint32(message.repetitions); + /* required string originName = 7; */ + if (message.originName !== "") + writer.tag(7, WireType.LengthDelimited).string(message.originName); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceGroupMessage + */ +export const DeviceGroupMessage = new DeviceGroupMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ProviderMessage$Type extends MessageType { + constructor() { + super("ProviderMessage", [ + { no: 1, name: "channel", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): ProviderMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.channel = ""; + message.name = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ProviderMessage): ProviderMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string channel */ 1: + message.channel = reader.string(); + break; + case /* required string name */ 2: + message.name = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ProviderMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string channel = 1; */ + if (message.channel !== "") + writer.tag(1, WireType.LengthDelimited).string(message.channel); + /* required string name = 2; */ + if (message.name !== "") + writer.tag(2, WireType.LengthDelimited).string(message.name); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ProviderMessage + */ +export const ProviderMessage = new ProviderMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ProviderIosMessage$Type extends MessageType { + constructor() { + super("ProviderIosMessage", [ + { no: 1, name: "channel", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "screenWsUrlPattern", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): ProviderIosMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.channel = ""; + message.name = ""; + message.screenWsUrlPattern = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ProviderIosMessage): ProviderIosMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string channel */ 1: + message.channel = reader.string(); + break; + case /* required string name */ 2: + message.name = reader.string(); + break; + case /* required string screenWsUrlPattern */ 3: + message.screenWsUrlPattern = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ProviderIosMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string channel = 1; */ + if (message.channel !== "") + writer.tag(1, WireType.LengthDelimited).string(message.channel); + /* required string name = 2; */ + if (message.name !== "") + writer.tag(2, WireType.LengthDelimited).string(message.name); + /* required string screenWsUrlPattern = 3; */ + if (message.screenWsUrlPattern !== "") + writer.tag(3, WireType.LengthDelimited).string(message.screenWsUrlPattern); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ProviderIosMessage + */ +export const ProviderIosMessage = new ProviderIosMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceHeartbeatMessage$Type extends MessageType { + constructor() { + super("DeviceHeartbeatMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceHeartbeatMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceHeartbeatMessage): DeviceHeartbeatMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceHeartbeatMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceHeartbeatMessage + */ +export const DeviceHeartbeatMessage = new DeviceHeartbeatMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceIntroductionMessage$Type extends MessageType { + constructor() { + super("DeviceIntroductionMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "status", kind: "enum", T: () => ["DeviceStatus", DeviceStatus] }, + { no: 3, name: "provider", kind: "message", T: () => ProviderMessage } + ]); + } + create(value?: PartialMessage): DeviceIntroductionMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.status = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceIntroductionMessage): DeviceIntroductionMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required DeviceStatus status */ 2: + message.status = reader.int32(); + break; + case /* required ProviderMessage provider */ 3: + message.provider = ProviderMessage.internalBinaryRead(reader, reader.uint32(), options, message.provider); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceIntroductionMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required DeviceStatus status = 2; */ + if (message.status !== 0) + writer.tag(2, WireType.Varint).int32(message.status); + /* required ProviderMessage provider = 3; */ + if (message.provider) + ProviderMessage.internalBinaryWrite(message.provider, writer.tag(3, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceIntroductionMessage + */ +export const DeviceIntroductionMessage = new DeviceIntroductionMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceIosIntroductionMessage$Type extends MessageType { + constructor() { + super("DeviceIosIntroductionMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "status", kind: "enum", T: () => ["DeviceStatus", DeviceStatus] }, + { no: 3, name: "provider", kind: "message", T: () => ProviderMessage } + ]); + } + create(value?: PartialMessage): DeviceIosIntroductionMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.status = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceIosIntroductionMessage): DeviceIosIntroductionMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required DeviceStatus status */ 2: + message.status = reader.int32(); + break; + case /* required ProviderMessage provider */ 3: + message.provider = ProviderMessage.internalBinaryRead(reader, reader.uint32(), options, message.provider); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceIosIntroductionMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required DeviceStatus status = 2; */ + if (message.status !== 0) + writer.tag(2, WireType.Varint).int32(message.status); + /* required ProviderMessage provider = 3; */ + if (message.provider) + ProviderMessage.internalBinaryWrite(message.provider, writer.tag(3, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceIosIntroductionMessage + */ +export const DeviceIosIntroductionMessage = new DeviceIosIntroductionMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class InitializeIosDeviceState$Type extends MessageType { + constructor() { + super("InitializeIosDeviceState", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "status", kind: "enum", T: () => ["DeviceStatus", DeviceStatus] }, + { no: 3, name: "provider", kind: "message", T: () => ProviderIosMessage }, + { no: 4, name: "ports", kind: "message", T: () => IosDevicePorts }, + { no: 5, name: "options", kind: "message", T: () => UpdateIosDevice } + ]); + } + create(value?: PartialMessage): InitializeIosDeviceState { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.status = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: InitializeIosDeviceState): InitializeIosDeviceState { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required DeviceStatus status */ 2: + message.status = reader.int32(); + break; + case /* required ProviderIosMessage provider */ 3: + message.provider = ProviderIosMessage.internalBinaryRead(reader, reader.uint32(), options, message.provider); + break; + case /* required IosDevicePorts ports */ 4: + message.ports = IosDevicePorts.internalBinaryRead(reader, reader.uint32(), options, message.ports); + break; + case /* required UpdateIosDevice options */ 5: + message.options = UpdateIosDevice.internalBinaryRead(reader, reader.uint32(), options, message.options); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: InitializeIosDeviceState, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required DeviceStatus status = 2; */ + if (message.status !== 0) + writer.tag(2, WireType.Varint).int32(message.status); + /* required ProviderIosMessage provider = 3; */ + if (message.provider) + ProviderIosMessage.internalBinaryWrite(message.provider, writer.tag(3, WireType.LengthDelimited).fork(), options).join(); + /* required IosDevicePorts ports = 4; */ + if (message.ports) + IosDevicePorts.internalBinaryWrite(message.ports, writer.tag(4, WireType.LengthDelimited).fork(), options).join(); + /* required UpdateIosDevice options = 5; */ + if (message.options) + UpdateIosDevice.internalBinaryWrite(message.options, writer.tag(5, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message InitializeIosDeviceState + */ +export const InitializeIosDeviceState = new InitializeIosDeviceState$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceRegisteredMessage$Type extends MessageType { + constructor() { + super("DeviceRegisteredMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceRegisteredMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceRegisteredMessage): DeviceRegisteredMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceRegisteredMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceRegisteredMessage + */ +export const DeviceRegisteredMessage = new DeviceRegisteredMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DevicePresentMessage$Type extends MessageType { + constructor() { + super("DevicePresentMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DevicePresentMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DevicePresentMessage): DevicePresentMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DevicePresentMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DevicePresentMessage + */ +export const DevicePresentMessage = new DevicePresentMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceAbsentMessage$Type extends MessageType { + constructor() { + super("DeviceAbsentMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceAbsentMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceAbsentMessage): DeviceAbsentMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceAbsentMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceAbsentMessage + */ +export const DeviceAbsentMessage = new DeviceAbsentMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceReadyMessage$Type extends MessageType { + constructor() { + super("DeviceReadyMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "channel", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceReadyMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.channel = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceReadyMessage): DeviceReadyMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required string channel */ 2: + message.channel = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceReadyMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required string channel = 2; */ + if (message.channel !== "") + writer.tag(2, WireType.LengthDelimited).string(message.channel); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceReadyMessage + */ +export const DeviceReadyMessage = new DeviceReadyMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ProbeMessage$Type extends MessageType { + constructor() { + super("ProbeMessage", []); + } + create(value?: PartialMessage): ProbeMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ProbeMessage): ProbeMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ProbeMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ProbeMessage + */ +export const ProbeMessage = new ProbeMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceStatusMessage$Type extends MessageType { + constructor() { + super("DeviceStatusMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "status", kind: "enum", T: () => ["DeviceStatus", DeviceStatus] } + ]); + } + create(value?: PartialMessage): DeviceStatusMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.status = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceStatusMessage): DeviceStatusMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required DeviceStatus status */ 2: + message.status = reader.int32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceStatusMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required DeviceStatus status = 2; */ + if (message.status !== 0) + writer.tag(2, WireType.Varint).int32(message.status); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceStatusMessage + */ +export const DeviceStatusMessage = new DeviceStatusMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceTypeMessage$Type extends MessageType { + constructor() { + super("DeviceTypeMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "type", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceTypeMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.type = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceTypeMessage): DeviceTypeMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required string type */ 2: + message.type = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceTypeMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required string type = 2; */ + if (message.type !== "") + writer.tag(2, WireType.LengthDelimited).string(message.type); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceTypeMessage + */ +export const DeviceTypeMessage = new DeviceTypeMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceDisplayMessage$Type extends MessageType { + constructor() { + super("DeviceDisplayMessage", [ + { no: 1, name: "id", kind: "scalar", T: 5 /*ScalarType.INT32*/ }, + { no: 2, name: "width", kind: "scalar", T: 5 /*ScalarType.INT32*/ }, + { no: 3, name: "height", kind: "scalar", T: 5 /*ScalarType.INT32*/ }, + { no: 4, name: "rotation", kind: "scalar", T: 5 /*ScalarType.INT32*/ }, + { no: 5, name: "xdpi", kind: "scalar", T: 2 /*ScalarType.FLOAT*/ }, + { no: 6, name: "ydpi", kind: "scalar", T: 2 /*ScalarType.FLOAT*/ }, + { no: 7, name: "fps", kind: "scalar", T: 2 /*ScalarType.FLOAT*/ }, + { no: 8, name: "density", kind: "scalar", T: 2 /*ScalarType.FLOAT*/ }, + { no: 9, name: "secure", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 10, name: "url", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 11, name: "size", kind: "scalar", opt: true, T: 2 /*ScalarType.FLOAT*/ } + ]); + } + create(value?: PartialMessage): DeviceDisplayMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.id = 0; + message.width = 0; + message.height = 0; + message.rotation = 0; + message.xdpi = 0; + message.ydpi = 0; + message.fps = 0; + message.density = 0; + message.secure = false; + message.url = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceDisplayMessage): DeviceDisplayMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required int32 id */ 1: + message.id = reader.int32(); + break; + case /* required int32 width */ 2: + message.width = reader.int32(); + break; + case /* required int32 height */ 3: + message.height = reader.int32(); + break; + case /* required int32 rotation */ 4: + message.rotation = reader.int32(); + break; + case /* required float xdpi */ 5: + message.xdpi = reader.float(); + break; + case /* required float ydpi */ 6: + message.ydpi = reader.float(); + break; + case /* required float fps */ 7: + message.fps = reader.float(); + break; + case /* required float density */ 8: + message.density = reader.float(); + break; + case /* required bool secure */ 9: + message.secure = reader.bool(); + break; + case /* required string url */ 10: + message.url = reader.string(); + break; + case /* optional float size */ 11: + message.size = reader.float(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceDisplayMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required int32 id = 1; */ + if (message.id !== 0) + writer.tag(1, WireType.Varint).int32(message.id); + /* required int32 width = 2; */ + if (message.width !== 0) + writer.tag(2, WireType.Varint).int32(message.width); + /* required int32 height = 3; */ + if (message.height !== 0) + writer.tag(3, WireType.Varint).int32(message.height); + /* required int32 rotation = 4; */ + if (message.rotation !== 0) + writer.tag(4, WireType.Varint).int32(message.rotation); + /* required float xdpi = 5; */ + if (message.xdpi !== 0) + writer.tag(5, WireType.Bit32).float(message.xdpi); + /* required float ydpi = 6; */ + if (message.ydpi !== 0) + writer.tag(6, WireType.Bit32).float(message.ydpi); + /* required float fps = 7; */ + if (message.fps !== 0) + writer.tag(7, WireType.Bit32).float(message.fps); + /* required float density = 8; */ + if (message.density !== 0) + writer.tag(8, WireType.Bit32).float(message.density); + /* required bool secure = 9; */ + if (message.secure !== false) + writer.tag(9, WireType.Varint).bool(message.secure); + /* required string url = 10; */ + if (message.url !== "") + writer.tag(10, WireType.LengthDelimited).string(message.url); + /* optional float size = 11; */ + if (message.size !== undefined) + writer.tag(11, WireType.Bit32).float(message.size); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceDisplayMessage + */ +export const DeviceDisplayMessage = new DeviceDisplayMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceBrowserAppMessage$Type extends MessageType { + constructor() { + super("DeviceBrowserAppMessage", [ + { no: 1, name: "id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "type", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "selected", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 5, name: "system", kind: "scalar", T: 8 /*ScalarType.BOOL*/ } + ]); + } + create(value?: PartialMessage): DeviceBrowserAppMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.id = ""; + message.type = ""; + message.name = ""; + message.selected = false; + message.system = false; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceBrowserAppMessage): DeviceBrowserAppMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string id */ 1: + message.id = reader.string(); + break; + case /* required string type */ 2: + message.type = reader.string(); + break; + case /* required string name */ 3: + message.name = reader.string(); + break; + case /* required bool selected */ 4: + message.selected = reader.bool(); + break; + case /* required bool system */ 5: + message.system = reader.bool(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceBrowserAppMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string id = 1; */ + if (message.id !== "") + writer.tag(1, WireType.LengthDelimited).string(message.id); + /* required string type = 2; */ + if (message.type !== "") + writer.tag(2, WireType.LengthDelimited).string(message.type); + /* required string name = 3; */ + if (message.name !== "") + writer.tag(3, WireType.LengthDelimited).string(message.name); + /* required bool selected = 4; */ + if (message.selected !== false) + writer.tag(4, WireType.Varint).bool(message.selected); + /* required bool system = 5; */ + if (message.system !== false) + writer.tag(5, WireType.Varint).bool(message.system); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceBrowserAppMessage + */ +export const DeviceBrowserAppMessage = new DeviceBrowserAppMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceBrowserMessage$Type extends MessageType { + constructor() { + super("DeviceBrowserMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "selected", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 3, name: "apps", kind: "message", repeat: 2 /*RepeatType.UNPACKED*/, T: () => DeviceBrowserAppMessage } + ]); + } + create(value?: PartialMessage): DeviceBrowserMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.selected = false; + message.apps = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceBrowserMessage): DeviceBrowserMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required bool selected */ 2: + message.selected = reader.bool(); + break; + case /* repeated DeviceBrowserAppMessage apps */ 3: + message.apps.push(DeviceBrowserAppMessage.internalBinaryRead(reader, reader.uint32(), options)); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceBrowserMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required bool selected = 2; */ + if (message.selected !== false) + writer.tag(2, WireType.Varint).bool(message.selected); + /* repeated DeviceBrowserAppMessage apps = 3; */ + for (let i = 0; i < message.apps.length; i++) + DeviceBrowserAppMessage.internalBinaryWrite(message.apps[i], writer.tag(3, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceBrowserMessage + */ +export const DeviceBrowserMessage = new DeviceBrowserMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GetServicesAvailabilityMessage$Type extends MessageType { + constructor() { + super("GetServicesAvailabilityMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "hasGMS", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 3, name: "hasHMS", kind: "scalar", T: 8 /*ScalarType.BOOL*/ } + ]); + } + create(value?: PartialMessage): GetServicesAvailabilityMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.hasGMS = false; + message.hasHMS = false; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GetServicesAvailabilityMessage): GetServicesAvailabilityMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required bool hasGMS */ 2: + message.hasGMS = reader.bool(); + break; + case /* required bool hasHMS */ 3: + message.hasHMS = reader.bool(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GetServicesAvailabilityMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required bool hasGMS = 2; */ + if (message.hasGMS !== false) + writer.tag(2, WireType.Varint).bool(message.hasGMS); + /* required bool hasHMS = 3; */ + if (message.hasHMS !== false) + writer.tag(3, WireType.Varint).bool(message.hasHMS); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GetServicesAvailabilityMessage + */ +export const GetServicesAvailabilityMessage = new GetServicesAvailabilityMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DevicePhoneMessage$Type extends MessageType { + constructor() { + super("DevicePhoneMessage", [ + { no: 1, name: "imei", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "imsi", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "phoneNumber", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "iccid", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "network", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DevicePhoneMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DevicePhoneMessage): DevicePhoneMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* optional string imei */ 1: + message.imei = reader.string(); + break; + case /* optional string imsi */ 5: + message.imsi = reader.string(); + break; + case /* optional string phoneNumber */ 2: + message.phoneNumber = reader.string(); + break; + case /* optional string iccid */ 3: + message.iccid = reader.string(); + break; + case /* optional string network */ 4: + message.network = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DevicePhoneMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* optional string imei = 1; */ + if (message.imei !== undefined) + writer.tag(1, WireType.LengthDelimited).string(message.imei); + /* optional string phoneNumber = 2; */ + if (message.phoneNumber !== undefined) + writer.tag(2, WireType.LengthDelimited).string(message.phoneNumber); + /* optional string iccid = 3; */ + if (message.iccid !== undefined) + writer.tag(3, WireType.LengthDelimited).string(message.iccid); + /* optional string network = 4; */ + if (message.network !== undefined) + writer.tag(4, WireType.LengthDelimited).string(message.network); + /* optional string imsi = 5; */ + if (message.imsi !== undefined) + writer.tag(5, WireType.LengthDelimited).string(message.imsi); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DevicePhoneMessage + */ +export const DevicePhoneMessage = new DevicePhoneMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceIdentityMessage$Type extends MessageType { + constructor() { + super("DeviceIdentityMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "platform", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "manufacturer", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "operator", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "model", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 6, name: "version", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 7, name: "abi", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 8, name: "sdk", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 9, name: "display", kind: "message", T: () => DeviceDisplayMessage }, + { no: 11, name: "phone", kind: "message", T: () => DevicePhoneMessage }, + { no: 12, name: "product", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 13, name: "cpuPlatform", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 14, name: "openGLESVersion", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 15, name: "marketName", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 16, name: "macAddress", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 17, name: "ram", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceIdentityMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.platform = ""; + message.manufacturer = ""; + message.model = ""; + message.version = ""; + message.abi = ""; + message.sdk = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceIdentityMessage): DeviceIdentityMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required string platform */ 2: + message.platform = reader.string(); + break; + case /* required string manufacturer */ 3: + message.manufacturer = reader.string(); + break; + case /* optional string operator */ 4: + message.operator = reader.string(); + break; + case /* required string model */ 5: + message.model = reader.string(); + break; + case /* required string version */ 6: + message.version = reader.string(); + break; + case /* required string abi */ 7: + message.abi = reader.string(); + break; + case /* required string sdk */ 8: + message.sdk = reader.string(); + break; + case /* required DeviceDisplayMessage display */ 9: + message.display = DeviceDisplayMessage.internalBinaryRead(reader, reader.uint32(), options, message.display); + break; + case /* required DevicePhoneMessage phone */ 11: + message.phone = DevicePhoneMessage.internalBinaryRead(reader, reader.uint32(), options, message.phone); + break; + case /* optional string product */ 12: + message.product = reader.string(); + break; + case /* optional string cpuPlatform */ 13: + message.cpuPlatform = reader.string(); + break; + case /* optional string openGLESVersion */ 14: + message.openGLESVersion = reader.string(); + break; + case /* optional string marketName */ 15: + message.marketName = reader.string(); + break; + case /* optional string macAddress */ 16: + message.macAddress = reader.string(); + break; + case /* optional string ram */ 17: + message.ram = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceIdentityMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required string platform = 2; */ + if (message.platform !== "") + writer.tag(2, WireType.LengthDelimited).string(message.platform); + /* required string manufacturer = 3; */ + if (message.manufacturer !== "") + writer.tag(3, WireType.LengthDelimited).string(message.manufacturer); + /* optional string operator = 4; */ + if (message.operator !== undefined) + writer.tag(4, WireType.LengthDelimited).string(message.operator); + /* required string model = 5; */ + if (message.model !== "") + writer.tag(5, WireType.LengthDelimited).string(message.model); + /* required string version = 6; */ + if (message.version !== "") + writer.tag(6, WireType.LengthDelimited).string(message.version); + /* required string abi = 7; */ + if (message.abi !== "") + writer.tag(7, WireType.LengthDelimited).string(message.abi); + /* required string sdk = 8; */ + if (message.sdk !== "") + writer.tag(8, WireType.LengthDelimited).string(message.sdk); + /* required DeviceDisplayMessage display = 9; */ + if (message.display) + DeviceDisplayMessage.internalBinaryWrite(message.display, writer.tag(9, WireType.LengthDelimited).fork(), options).join(); + /* required DevicePhoneMessage phone = 11; */ + if (message.phone) + DevicePhoneMessage.internalBinaryWrite(message.phone, writer.tag(11, WireType.LengthDelimited).fork(), options).join(); + /* optional string product = 12; */ + if (message.product !== undefined) + writer.tag(12, WireType.LengthDelimited).string(message.product); + /* optional string cpuPlatform = 13; */ + if (message.cpuPlatform !== undefined) + writer.tag(13, WireType.LengthDelimited).string(message.cpuPlatform); + /* optional string openGLESVersion = 14; */ + if (message.openGLESVersion !== undefined) + writer.tag(14, WireType.LengthDelimited).string(message.openGLESVersion); + /* optional string marketName = 15; */ + if (message.marketName !== undefined) + writer.tag(15, WireType.LengthDelimited).string(message.marketName); + /* optional string macAddress = 16; */ + if (message.macAddress !== undefined) + writer.tag(16, WireType.LengthDelimited).string(message.macAddress); + /* optional string ram = 17; */ + if (message.ram !== undefined) + writer.tag(17, WireType.LengthDelimited).string(message.ram); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceIdentityMessage + */ +export const DeviceIdentityMessage = new DeviceIdentityMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceProperty$Type extends MessageType { + constructor() { + super("DeviceProperty", [ + { no: 1, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "value", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceProperty { + const message = globalThis.Object.create((this.messagePrototype!)); + message.name = ""; + message.value = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceProperty): DeviceProperty { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string name */ 1: + message.name = reader.string(); + break; + case /* required string value */ 2: + message.value = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceProperty, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string name = 1; */ + if (message.name !== "") + writer.tag(1, WireType.LengthDelimited).string(message.name); + /* required string value = 2; */ + if (message.value !== "") + writer.tag(2, WireType.LengthDelimited).string(message.value); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceProperty + */ +export const DeviceProperty = new DeviceProperty$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DevicePropertiesMessage$Type extends MessageType { + constructor() { + super("DevicePropertiesMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "properties", kind: "message", repeat: 2 /*RepeatType.UNPACKED*/, T: () => DeviceProperty } + ]); + } + create(value?: PartialMessage): DevicePropertiesMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.properties = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DevicePropertiesMessage): DevicePropertiesMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* repeated DeviceProperty properties */ 2: + message.properties.push(DeviceProperty.internalBinaryRead(reader, reader.uint32(), options)); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DevicePropertiesMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* repeated DeviceProperty properties = 2; */ + for (let i = 0; i < message.properties.length; i++) + DeviceProperty.internalBinaryWrite(message.properties[i], writer.tag(2, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DevicePropertiesMessage + */ +export const DevicePropertiesMessage = new DevicePropertiesMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceRequirement$Type extends MessageType { + constructor() { + super("DeviceRequirement", [ + { no: 1, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "value", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "type", kind: "enum", T: () => ["RequirementType", RequirementType] } + ]); + } + create(value?: PartialMessage): DeviceRequirement { + const message = globalThis.Object.create((this.messagePrototype!)); + message.name = ""; + message.value = ""; + message.type = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceRequirement): DeviceRequirement { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string name */ 1: + message.name = reader.string(); + break; + case /* required string value */ 2: + message.value = reader.string(); + break; + case /* required RequirementType type */ 3: + message.type = reader.int32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceRequirement, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string name = 1; */ + if (message.name !== "") + writer.tag(1, WireType.LengthDelimited).string(message.name); + /* required string value = 2; */ + if (message.value !== "") + writer.tag(2, WireType.LengthDelimited).string(message.value); + /* required RequirementType type = 3; */ + if (message.type !== 0) + writer.tag(3, WireType.Varint).int32(message.type); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceRequirement + */ +export const DeviceRequirement = new DeviceRequirement$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class OwnerMessage$Type extends MessageType { + constructor() { + super("OwnerMessage", [ + { no: 1, name: "email", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "group", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): OwnerMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.email = ""; + message.name = ""; + message.group = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: OwnerMessage): OwnerMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string email */ 1: + message.email = reader.string(); + break; + case /* required string name */ 2: + message.name = reader.string(); + break; + case /* required string group */ 3: + message.group = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: OwnerMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string email = 1; */ + if (message.email !== "") + writer.tag(1, WireType.LengthDelimited).string(message.email); + /* required string name = 2; */ + if (message.name !== "") + writer.tag(2, WireType.LengthDelimited).string(message.name); + /* required string group = 3; */ + if (message.group !== "") + writer.tag(3, WireType.LengthDelimited).string(message.group); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message OwnerMessage + */ +export const OwnerMessage = new OwnerMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GroupMessage$Type extends MessageType { + constructor() { + super("GroupMessage", [ + { no: 1, name: "owner", kind: "message", T: () => OwnerMessage }, + { no: 2, name: "timeout", kind: "scalar", opt: true, T: 13 /*ScalarType.UINT32*/ }, + { no: 3, name: "requirements", kind: "message", repeat: 2 /*RepeatType.UNPACKED*/, T: () => DeviceRequirement }, + { no: 4, name: "usage", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): GroupMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.requirements = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GroupMessage): GroupMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required OwnerMessage owner */ 1: + message.owner = OwnerMessage.internalBinaryRead(reader, reader.uint32(), options, message.owner); + break; + case /* optional uint32 timeout */ 2: + message.timeout = reader.uint32(); + break; + case /* repeated DeviceRequirement requirements */ 3: + message.requirements.push(DeviceRequirement.internalBinaryRead(reader, reader.uint32(), options)); + break; + case /* optional string usage */ 4: + message.usage = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GroupMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required OwnerMessage owner = 1; */ + if (message.owner) + OwnerMessage.internalBinaryWrite(message.owner, writer.tag(1, WireType.LengthDelimited).fork(), options).join(); + /* optional uint32 timeout = 2; */ + if (message.timeout !== undefined) + writer.tag(2, WireType.Varint).uint32(message.timeout); + /* repeated DeviceRequirement requirements = 3; */ + for (let i = 0; i < message.requirements.length; i++) + DeviceRequirement.internalBinaryWrite(message.requirements[i], writer.tag(3, WireType.LengthDelimited).fork(), options).join(); + /* optional string usage = 4; */ + if (message.usage !== undefined) + writer.tag(4, WireType.LengthDelimited).string(message.usage); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GroupMessage + */ +export const GroupMessage = new GroupMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class AutoGroupMessage$Type extends MessageType { + constructor() { + super("AutoGroupMessage", [ + { no: 1, name: "owner", kind: "message", T: () => OwnerMessage }, + { no: 2, name: "identifier", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): AutoGroupMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.identifier = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AutoGroupMessage): AutoGroupMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required OwnerMessage owner */ 1: + message.owner = OwnerMessage.internalBinaryRead(reader, reader.uint32(), options, message.owner); + break; + case /* required string identifier */ 2: + message.identifier = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: AutoGroupMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required OwnerMessage owner = 1; */ + if (message.owner) + OwnerMessage.internalBinaryWrite(message.owner, writer.tag(1, WireType.LengthDelimited).fork(), options).join(); + /* required string identifier = 2; */ + if (message.identifier !== "") + writer.tag(2, WireType.LengthDelimited).string(message.identifier); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message AutoGroupMessage + */ +export const AutoGroupMessage = new AutoGroupMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class UngroupMessage$Type extends MessageType { + constructor() { + super("UngroupMessage", [ + { no: 2, name: "requirements", kind: "message", repeat: 2 /*RepeatType.UNPACKED*/, T: () => DeviceRequirement } + ]); + } + create(value?: PartialMessage): UngroupMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.requirements = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: UngroupMessage): UngroupMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* repeated DeviceRequirement requirements */ 2: + message.requirements.push(DeviceRequirement.internalBinaryRead(reader, reader.uint32(), options)); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: UngroupMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* repeated DeviceRequirement requirements = 2; */ + for (let i = 0; i < message.requirements.length; i++) + DeviceRequirement.internalBinaryWrite(message.requirements[i], writer.tag(2, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message UngroupMessage + */ +export const UngroupMessage = new UngroupMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class JoinGroupMessage$Type extends MessageType { + constructor() { + super("JoinGroupMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "owner", kind: "message", T: () => OwnerMessage }, + { no: 3, name: "usage", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): JoinGroupMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: JoinGroupMessage): JoinGroupMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required OwnerMessage owner */ 2: + message.owner = OwnerMessage.internalBinaryRead(reader, reader.uint32(), options, message.owner); + break; + case /* optional string usage */ 3: + message.usage = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: JoinGroupMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required OwnerMessage owner = 2; */ + if (message.owner) + OwnerMessage.internalBinaryWrite(message.owner, writer.tag(2, WireType.LengthDelimited).fork(), options).join(); + /* optional string usage = 3; */ + if (message.usage !== undefined) + writer.tag(3, WireType.LengthDelimited).string(message.usage); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message JoinGroupMessage + */ +export const JoinGroupMessage = new JoinGroupMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class JoinGroupByAdbFingerprintMessage$Type extends MessageType { + constructor() { + super("JoinGroupByAdbFingerprintMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "fingerprint", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "comment", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "currentGroup", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): JoinGroupByAdbFingerprintMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.fingerprint = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: JoinGroupByAdbFingerprintMessage): JoinGroupByAdbFingerprintMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required string fingerprint */ 2: + message.fingerprint = reader.string(); + break; + case /* optional string comment */ 3: + message.comment = reader.string(); + break; + case /* optional string currentGroup */ 4: + message.currentGroup = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: JoinGroupByAdbFingerprintMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required string fingerprint = 2; */ + if (message.fingerprint !== "") + writer.tag(2, WireType.LengthDelimited).string(message.fingerprint); + /* optional string comment = 3; */ + if (message.comment !== undefined) + writer.tag(3, WireType.LengthDelimited).string(message.comment); + /* optional string currentGroup = 4; */ + if (message.currentGroup !== undefined) + writer.tag(4, WireType.LengthDelimited).string(message.currentGroup); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message JoinGroupByAdbFingerprintMessage + */ +export const JoinGroupByAdbFingerprintMessage = new JoinGroupByAdbFingerprintMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class JoinGroupByVncAuthResponseMessage$Type extends MessageType { + constructor() { + super("JoinGroupByVncAuthResponseMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "response", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "currentGroup", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): JoinGroupByVncAuthResponseMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.response = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: JoinGroupByVncAuthResponseMessage): JoinGroupByVncAuthResponseMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required string response */ 2: + message.response = reader.string(); + break; + case /* optional string currentGroup */ 4: + message.currentGroup = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: JoinGroupByVncAuthResponseMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required string response = 2; */ + if (message.response !== "") + writer.tag(2, WireType.LengthDelimited).string(message.response); + /* optional string currentGroup = 4; */ + if (message.currentGroup !== undefined) + writer.tag(4, WireType.LengthDelimited).string(message.currentGroup); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message JoinGroupByVncAuthResponseMessage + */ +export const JoinGroupByVncAuthResponseMessage = new JoinGroupByVncAuthResponseMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class AdbKeysUpdatedMessage$Type extends MessageType { + constructor() { + super("AdbKeysUpdatedMessage", []); + } + create(value?: PartialMessage): AdbKeysUpdatedMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AdbKeysUpdatedMessage): AdbKeysUpdatedMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: AdbKeysUpdatedMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message AdbKeysUpdatedMessage + */ +export const AdbKeysUpdatedMessage = new AdbKeysUpdatedMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class VncAuthResponsesUpdatedMessage$Type extends MessageType { + constructor() { + super("VncAuthResponsesUpdatedMessage", []); + } + create(value?: PartialMessage): VncAuthResponsesUpdatedMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: VncAuthResponsesUpdatedMessage): VncAuthResponsesUpdatedMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: VncAuthResponsesUpdatedMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message VncAuthResponsesUpdatedMessage + */ +export const VncAuthResponsesUpdatedMessage = new VncAuthResponsesUpdatedMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class LeaveGroupMessage$Type extends MessageType { + constructor() { + super("LeaveGroupMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "owner", kind: "message", T: () => OwnerMessage }, + { no: 3, name: "reason", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): LeaveGroupMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.reason = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: LeaveGroupMessage): LeaveGroupMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required OwnerMessage owner */ 2: + message.owner = OwnerMessage.internalBinaryRead(reader, reader.uint32(), options, message.owner); + break; + case /* required string reason */ 3: + message.reason = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: LeaveGroupMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required OwnerMessage owner = 2; */ + if (message.owner) + OwnerMessage.internalBinaryWrite(message.owner, writer.tag(2, WireType.LengthDelimited).fork(), options).join(); + /* required string reason = 3; */ + if (message.reason !== "") + writer.tag(3, WireType.LengthDelimited).string(message.reason); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message LeaveGroupMessage + */ +export const LeaveGroupMessage = new LeaveGroupMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class PhysicalIdentifyMessage$Type extends MessageType { + constructor() { + super("PhysicalIdentifyMessage", []); + } + create(value?: PartialMessage): PhysicalIdentifyMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: PhysicalIdentifyMessage): PhysicalIdentifyMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: PhysicalIdentifyMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message PhysicalIdentifyMessage + */ +export const PhysicalIdentifyMessage = new PhysicalIdentifyMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TouchDownMessage$Type extends MessageType { + constructor() { + super("TouchDownMessage", [ + { no: 1, name: "seq", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 2, name: "contact", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 3, name: "x", kind: "scalar", T: 2 /*ScalarType.FLOAT*/ }, + { no: 4, name: "y", kind: "scalar", T: 2 /*ScalarType.FLOAT*/ }, + { no: 5, name: "pressure", kind: "scalar", opt: true, T: 2 /*ScalarType.FLOAT*/ } + ]); + } + create(value?: PartialMessage): TouchDownMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.seq = 0; + message.contact = 0; + message.x = 0; + message.y = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TouchDownMessage): TouchDownMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required uint32 seq */ 1: + message.seq = reader.uint32(); + break; + case /* required uint32 contact */ 2: + message.contact = reader.uint32(); + break; + case /* required float x */ 3: + message.x = reader.float(); + break; + case /* required float y */ 4: + message.y = reader.float(); + break; + case /* optional float pressure */ 5: + message.pressure = reader.float(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TouchDownMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required uint32 seq = 1; */ + if (message.seq !== 0) + writer.tag(1, WireType.Varint).uint32(message.seq); + /* required uint32 contact = 2; */ + if (message.contact !== 0) + writer.tag(2, WireType.Varint).uint32(message.contact); + /* required float x = 3; */ + if (message.x !== 0) + writer.tag(3, WireType.Bit32).float(message.x); + /* required float y = 4; */ + if (message.y !== 0) + writer.tag(4, WireType.Bit32).float(message.y); + /* optional float pressure = 5; */ + if (message.pressure !== undefined) + writer.tag(5, WireType.Bit32).float(message.pressure); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message TouchDownMessage + */ +export const TouchDownMessage = new TouchDownMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TouchMoveMessage$Type extends MessageType { + constructor() { + super("TouchMoveMessage", [ + { no: 1, name: "seq", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 2, name: "contact", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 3, name: "x", kind: "scalar", T: 2 /*ScalarType.FLOAT*/ }, + { no: 4, name: "y", kind: "scalar", T: 2 /*ScalarType.FLOAT*/ }, + { no: 5, name: "pressure", kind: "scalar", opt: true, T: 2 /*ScalarType.FLOAT*/ } + ]); + } + create(value?: PartialMessage): TouchMoveMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.seq = 0; + message.contact = 0; + message.x = 0; + message.y = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TouchMoveMessage): TouchMoveMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required uint32 seq */ 1: + message.seq = reader.uint32(); + break; + case /* required uint32 contact */ 2: + message.contact = reader.uint32(); + break; + case /* required float x */ 3: + message.x = reader.float(); + break; + case /* required float y */ 4: + message.y = reader.float(); + break; + case /* optional float pressure */ 5: + message.pressure = reader.float(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TouchMoveMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required uint32 seq = 1; */ + if (message.seq !== 0) + writer.tag(1, WireType.Varint).uint32(message.seq); + /* required uint32 contact = 2; */ + if (message.contact !== 0) + writer.tag(2, WireType.Varint).uint32(message.contact); + /* required float x = 3; */ + if (message.x !== 0) + writer.tag(3, WireType.Bit32).float(message.x); + /* required float y = 4; */ + if (message.y !== 0) + writer.tag(4, WireType.Bit32).float(message.y); + /* optional float pressure = 5; */ + if (message.pressure !== undefined) + writer.tag(5, WireType.Bit32).float(message.pressure); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message TouchMoveMessage + */ +export const TouchMoveMessage = new TouchMoveMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TouchMoveIosMessage$Type extends MessageType { + constructor() { + super("TouchMoveIosMessage", [ + { no: 1, name: "toX", kind: "scalar", T: 2 /*ScalarType.FLOAT*/ }, + { no: 2, name: "toY", kind: "scalar", T: 2 /*ScalarType.FLOAT*/ }, + { no: 3, name: "fromX", kind: "scalar", T: 2 /*ScalarType.FLOAT*/ }, + { no: 4, name: "fromY", kind: "scalar", T: 2 /*ScalarType.FLOAT*/ }, + { no: 5, name: "duration", kind: "scalar", opt: true, T: 2 /*ScalarType.FLOAT*/ } + ]); + } + create(value?: PartialMessage): TouchMoveIosMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.toX = 0; + message.toY = 0; + message.fromX = 0; + message.fromY = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TouchMoveIosMessage): TouchMoveIosMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required float toX */ 1: + message.toX = reader.float(); + break; + case /* required float toY */ 2: + message.toY = reader.float(); + break; + case /* required float fromX */ 3: + message.fromX = reader.float(); + break; + case /* required float fromY */ 4: + message.fromY = reader.float(); + break; + case /* optional float duration */ 5: + message.duration = reader.float(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TouchMoveIosMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required float toX = 1; */ + if (message.toX !== 0) + writer.tag(1, WireType.Bit32).float(message.toX); + /* required float toY = 2; */ + if (message.toY !== 0) + writer.tag(2, WireType.Bit32).float(message.toY); + /* required float fromX = 3; */ + if (message.fromX !== 0) + writer.tag(3, WireType.Bit32).float(message.fromX); + /* required float fromY = 4; */ + if (message.fromY !== 0) + writer.tag(4, WireType.Bit32).float(message.fromY); + /* optional float duration = 5; */ + if (message.duration !== undefined) + writer.tag(5, WireType.Bit32).float(message.duration); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message TouchMoveIosMessage + */ +export const TouchMoveIosMessage = new TouchMoveIosMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TouchUpMessage$Type extends MessageType { + constructor() { + super("TouchUpMessage", [ + { no: 1, name: "seq", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 2, name: "contact", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): TouchUpMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.seq = 0; + message.contact = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TouchUpMessage): TouchUpMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required uint32 seq */ 1: + message.seq = reader.uint32(); + break; + case /* required uint32 contact */ 2: + message.contact = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TouchUpMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required uint32 seq = 1; */ + if (message.seq !== 0) + writer.tag(1, WireType.Varint).uint32(message.seq); + /* required uint32 contact = 2; */ + if (message.contact !== 0) + writer.tag(2, WireType.Varint).uint32(message.contact); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message TouchUpMessage + */ +export const TouchUpMessage = new TouchUpMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TouchCommitMessage$Type extends MessageType { + constructor() { + super("TouchCommitMessage", [ + { no: 1, name: "seq", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): TouchCommitMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.seq = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TouchCommitMessage): TouchCommitMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required uint32 seq */ 1: + message.seq = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TouchCommitMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required uint32 seq = 1; */ + if (message.seq !== 0) + writer.tag(1, WireType.Varint).uint32(message.seq); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message TouchCommitMessage + */ +export const TouchCommitMessage = new TouchCommitMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TouchResetMessage$Type extends MessageType { + constructor() { + super("TouchResetMessage", [ + { no: 1, name: "seq", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): TouchResetMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.seq = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TouchResetMessage): TouchResetMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required uint32 seq */ 1: + message.seq = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TouchResetMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required uint32 seq = 1; */ + if (message.seq !== 0) + writer.tag(1, WireType.Varint).uint32(message.seq); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message TouchResetMessage + */ +export const TouchResetMessage = new TouchResetMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GestureStartMessage$Type extends MessageType { + constructor() { + super("GestureStartMessage", [ + { no: 1, name: "seq", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): GestureStartMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.seq = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GestureStartMessage): GestureStartMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required uint32 seq */ 1: + message.seq = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GestureStartMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required uint32 seq = 1; */ + if (message.seq !== 0) + writer.tag(1, WireType.Varint).uint32(message.seq); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GestureStartMessage + */ +export const GestureStartMessage = new GestureStartMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GestureStopMessage$Type extends MessageType { + constructor() { + super("GestureStopMessage", [ + { no: 1, name: "seq", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): GestureStopMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.seq = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GestureStopMessage): GestureStopMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required uint32 seq */ 1: + message.seq = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GestureStopMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required uint32 seq = 1; */ + if (message.seq !== 0) + writer.tag(1, WireType.Varint).uint32(message.seq); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GestureStopMessage + */ +export const GestureStopMessage = new GestureStopMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TypeMessage$Type extends MessageType { + constructor() { + super("TypeMessage", [ + { no: 1, name: "text", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): TypeMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.text = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TypeMessage): TypeMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string text */ 1: + message.text = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TypeMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string text = 1; */ + if (message.text !== "") + writer.tag(1, WireType.LengthDelimited).string(message.text); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message TypeMessage + */ +export const TypeMessage = new TypeMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class PasteMessage$Type extends MessageType { + constructor() { + super("PasteMessage", [ + { no: 1, name: "text", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): PasteMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.text = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: PasteMessage): PasteMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string text */ 1: + message.text = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: PasteMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string text = 1; */ + if (message.text !== "") + writer.tag(1, WireType.LengthDelimited).string(message.text); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message PasteMessage + */ +export const PasteMessage = new PasteMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class CopyMessage$Type extends MessageType { + constructor() { + super("CopyMessage", []); + } + create(value?: PartialMessage): CopyMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: CopyMessage): CopyMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: CopyMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message CopyMessage + */ +export const CopyMessage = new CopyMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class KeyDownMessage$Type extends MessageType { + constructor() { + super("KeyDownMessage", [ + { no: 1, name: "key", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): KeyDownMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.key = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: KeyDownMessage): KeyDownMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string key */ 1: + message.key = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: KeyDownMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string key = 1; */ + if (message.key !== "") + writer.tag(1, WireType.LengthDelimited).string(message.key); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message KeyDownMessage + */ +export const KeyDownMessage = new KeyDownMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class KeyUpMessage$Type extends MessageType { + constructor() { + super("KeyUpMessage", [ + { no: 1, name: "key", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): KeyUpMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.key = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: KeyUpMessage): KeyUpMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string key */ 1: + message.key = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: KeyUpMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string key = 1; */ + if (message.key !== "") + writer.tag(1, WireType.LengthDelimited).string(message.key); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message KeyUpMessage + */ +export const KeyUpMessage = new KeyUpMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class KeyPressMessage$Type extends MessageType { + constructor() { + super("KeyPressMessage", [ + { no: 1, name: "key", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): KeyPressMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.key = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: KeyPressMessage): KeyPressMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string key */ 1: + message.key = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: KeyPressMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string key = 1; */ + if (message.key !== "") + writer.tag(1, WireType.LengthDelimited).string(message.key); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message KeyPressMessage + */ +export const KeyPressMessage = new KeyPressMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class RebootMessage$Type extends MessageType { + constructor() { + super("RebootMessage", []); + } + create(value?: PartialMessage): RebootMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: RebootMessage): RebootMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: RebootMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message RebootMessage + */ +export const RebootMessage = new RebootMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceLogcatEntryMessage$Type extends MessageType { + constructor() { + super("DeviceLogcatEntryMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "date", kind: "scalar", T: 1 /*ScalarType.DOUBLE*/ }, + { no: 3, name: "pid", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 4, name: "tid", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 5, name: "priority", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 6, name: "tag", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 7, name: "message", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceLogcatEntryMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.date = 0; + message.pid = 0; + message.tid = 0; + message.priority = 0; + message.tag = ""; + message.message = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceLogcatEntryMessage): DeviceLogcatEntryMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required double date */ 2: + message.date = reader.double(); + break; + case /* required uint32 pid */ 3: + message.pid = reader.uint32(); + break; + case /* required uint32 tid */ 4: + message.tid = reader.uint32(); + break; + case /* required uint32 priority */ 5: + message.priority = reader.uint32(); + break; + case /* required string tag */ 6: + message.tag = reader.string(); + break; + case /* required string message */ 7: + message.message = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceLogcatEntryMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required double date = 2; */ + if (message.date !== 0) + writer.tag(2, WireType.Bit64).double(message.date); + /* required uint32 pid = 3; */ + if (message.pid !== 0) + writer.tag(3, WireType.Varint).uint32(message.pid); + /* required uint32 tid = 4; */ + if (message.tid !== 0) + writer.tag(4, WireType.Varint).uint32(message.tid); + /* required uint32 priority = 5; */ + if (message.priority !== 0) + writer.tag(5, WireType.Varint).uint32(message.priority); + /* required string tag = 6; */ + if (message.tag !== "") + writer.tag(6, WireType.LengthDelimited).string(message.tag); + /* required string message = 7; */ + if (message.message !== "") + writer.tag(7, WireType.LengthDelimited).string(message.message); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceLogcatEntryMessage + */ +export const DeviceLogcatEntryMessage = new DeviceLogcatEntryMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class LogcatFilter$Type extends MessageType { + constructor() { + super("LogcatFilter", [ + { no: 1, name: "tag", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "priority", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): LogcatFilter { + const message = globalThis.Object.create((this.messagePrototype!)); + message.tag = ""; + message.priority = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: LogcatFilter): LogcatFilter { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string tag */ 1: + message.tag = reader.string(); + break; + case /* required uint32 priority */ 2: + message.priority = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: LogcatFilter, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string tag = 1; */ + if (message.tag !== "") + writer.tag(1, WireType.LengthDelimited).string(message.tag); + /* required uint32 priority = 2; */ + if (message.priority !== 0) + writer.tag(2, WireType.Varint).uint32(message.priority); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message LogcatFilter + */ +export const LogcatFilter = new LogcatFilter$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class LogcatStartMessage$Type extends MessageType { + constructor() { + super("LogcatStartMessage", [ + { no: 1, name: "filters", kind: "message", repeat: 2 /*RepeatType.UNPACKED*/, T: () => LogcatFilter } + ]); + } + create(value?: PartialMessage): LogcatStartMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.filters = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: LogcatStartMessage): LogcatStartMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* repeated LogcatFilter filters */ 1: + message.filters.push(LogcatFilter.internalBinaryRead(reader, reader.uint32(), options)); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: LogcatStartMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* repeated LogcatFilter filters = 1; */ + for (let i = 0; i < message.filters.length; i++) + LogcatFilter.internalBinaryWrite(message.filters[i], writer.tag(1, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message LogcatStartMessage + */ +export const LogcatStartMessage = new LogcatStartMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class LogcatStopMessage$Type extends MessageType { + constructor() { + super("LogcatStopMessage", []); + } + create(value?: PartialMessage): LogcatStopMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: LogcatStopMessage): LogcatStopMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: LogcatStopMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message LogcatStopMessage + */ +export const LogcatStopMessage = new LogcatStopMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class LogcatApplyFiltersMessage$Type extends MessageType { + constructor() { + super("LogcatApplyFiltersMessage", [ + { no: 1, name: "filters", kind: "message", repeat: 2 /*RepeatType.UNPACKED*/, T: () => LogcatFilter } + ]); + } + create(value?: PartialMessage): LogcatApplyFiltersMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.filters = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: LogcatApplyFiltersMessage): LogcatApplyFiltersMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* repeated LogcatFilter filters */ 1: + message.filters.push(LogcatFilter.internalBinaryRead(reader, reader.uint32(), options)); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: LogcatApplyFiltersMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* repeated LogcatFilter filters = 1; */ + for (let i = 0; i < message.filters.length; i++) + LogcatFilter.internalBinaryWrite(message.filters[i], writer.tag(1, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message LogcatApplyFiltersMessage + */ +export const LogcatApplyFiltersMessage = new LogcatApplyFiltersMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ShellCommandMessage$Type extends MessageType { + constructor() { + super("ShellCommandMessage", [ + { no: 1, name: "command", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "timeout", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): ShellCommandMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.command = ""; + message.timeout = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ShellCommandMessage): ShellCommandMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string command */ 1: + message.command = reader.string(); + break; + case /* required uint32 timeout */ 2: + message.timeout = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ShellCommandMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string command = 1; */ + if (message.command !== "") + writer.tag(1, WireType.LengthDelimited).string(message.command); + /* required uint32 timeout = 2; */ + if (message.timeout !== 0) + writer.tag(2, WireType.Varint).uint32(message.timeout); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ShellCommandMessage + */ +export const ShellCommandMessage = new ShellCommandMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ShellKeepAliveMessage$Type extends MessageType { + constructor() { + super("ShellKeepAliveMessage", [ + { no: 1, name: "timeout", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): ShellKeepAliveMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.timeout = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ShellKeepAliveMessage): ShellKeepAliveMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required uint32 timeout */ 1: + message.timeout = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ShellKeepAliveMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required uint32 timeout = 1; */ + if (message.timeout !== 0) + writer.tag(1, WireType.Varint).uint32(message.timeout); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ShellKeepAliveMessage + */ +export const ShellKeepAliveMessage = new ShellKeepAliveMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class InstallMessage$Type extends MessageType { + constructor() { + super("InstallMessage", [ + { no: 1, name: "href", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "launch", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 3, name: "isApi", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 4, name: "manifest", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "installFlags", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ }, + { no: 6, name: "jwt", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 7, name: "pkg", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): InstallMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.href = ""; + message.launch = false; + message.isApi = false; + message.installFlags = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: InstallMessage): InstallMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string href */ 1: + message.href = reader.string(); + break; + case /* required bool launch */ 2: + message.launch = reader.bool(); + break; + case /* required bool isApi */ 3: + message.isApi = reader.bool(); + break; + case /* optional string manifest */ 4: + message.manifest = reader.string(); + break; + case /* repeated string installFlags */ 5: + message.installFlags.push(reader.string()); + break; + case /* optional string jwt */ 6: + message.jwt = reader.string(); + break; + case /* optional string pkg */ 7: + message.pkg = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: InstallMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string href = 1; */ + if (message.href !== "") + writer.tag(1, WireType.LengthDelimited).string(message.href); + /* required bool launch = 2; */ + if (message.launch !== false) + writer.tag(2, WireType.Varint).bool(message.launch); + /* required bool isApi = 3; */ + if (message.isApi !== false) + writer.tag(3, WireType.Varint).bool(message.isApi); + /* optional string manifest = 4; */ + if (message.manifest !== undefined) + writer.tag(4, WireType.LengthDelimited).string(message.manifest); + /* repeated string installFlags = 5; */ + for (let i = 0; i < message.installFlags.length; i++) + writer.tag(5, WireType.LengthDelimited).string(message.installFlags[i]); + /* optional string jwt = 6; */ + if (message.jwt !== undefined) + writer.tag(6, WireType.LengthDelimited).string(message.jwt); + /* optional string pkg = 7; */ + if (message.pkg !== undefined) + writer.tag(7, WireType.LengthDelimited).string(message.pkg); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message InstallMessage + */ +export const InstallMessage = new InstallMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class UninstallMessage$Type extends MessageType { + constructor() { + super("UninstallMessage", [ + { no: 1, name: "packageName", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): UninstallMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.packageName = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: UninstallMessage): UninstallMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string packageName */ 1: + message.packageName = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: UninstallMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string packageName = 1; */ + if (message.packageName !== "") + writer.tag(1, WireType.LengthDelimited).string(message.packageName); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message UninstallMessage + */ +export const UninstallMessage = new UninstallMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class UninstallIosMessage$Type extends MessageType { + constructor() { + super("UninstallIosMessage", [ + { no: 1, name: "packageName", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): UninstallIosMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.packageName = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: UninstallIosMessage): UninstallIosMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string packageName */ 1: + message.packageName = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: UninstallIosMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string packageName = 1; */ + if (message.packageName !== "") + writer.tag(1, WireType.LengthDelimited).string(message.packageName); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message UninstallIosMessage + */ +export const UninstallIosMessage = new UninstallIosMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class LaunchActivityMessage$Type extends MessageType { + constructor() { + super("LaunchActivityMessage", [ + { no: 1, name: "action", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "component", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "category", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "flags", kind: "scalar", opt: true, T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): LaunchActivityMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.action = ""; + message.component = ""; + message.category = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: LaunchActivityMessage): LaunchActivityMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string action */ 1: + message.action = reader.string(); + break; + case /* required string component */ 2: + message.component = reader.string(); + break; + case /* repeated string category */ 3: + message.category.push(reader.string()); + break; + case /* optional uint32 flags */ 4: + message.flags = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: LaunchActivityMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string action = 1; */ + if (message.action !== "") + writer.tag(1, WireType.LengthDelimited).string(message.action); + /* required string component = 2; */ + if (message.component !== "") + writer.tag(2, WireType.LengthDelimited).string(message.component); + /* repeated string category = 3; */ + for (let i = 0; i < message.category.length; i++) + writer.tag(3, WireType.LengthDelimited).string(message.category[i]); + /* optional uint32 flags = 4; */ + if (message.flags !== undefined) + writer.tag(4, WireType.Varint).uint32(message.flags); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message LaunchActivityMessage + */ +export const LaunchActivityMessage = new LaunchActivityMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class RotateMessage$Type extends MessageType { + constructor() { + super("RotateMessage", [ + { no: 1, name: "rotation", kind: "scalar", T: 5 /*ScalarType.INT32*/ } + ]); + } + create(value?: PartialMessage): RotateMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.rotation = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: RotateMessage): RotateMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required int32 rotation */ 1: + message.rotation = reader.int32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: RotateMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required int32 rotation = 1; */ + if (message.rotation !== 0) + writer.tag(1, WireType.Varint).int32(message.rotation); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message RotateMessage + */ +export const RotateMessage = new RotateMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ChangeQualityMessage$Type extends MessageType { + constructor() { + super("ChangeQualityMessage", [ + { no: 1, name: "quality", kind: "scalar", T: 5 /*ScalarType.INT32*/ } + ]); + } + create(value?: PartialMessage): ChangeQualityMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.quality = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ChangeQualityMessage): ChangeQualityMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required int32 quality */ 1: + message.quality = reader.int32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ChangeQualityMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required int32 quality = 1; */ + if (message.quality !== 0) + writer.tag(1, WireType.Varint).int32(message.quality); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ChangeQualityMessage + */ +export const ChangeQualityMessage = new ChangeQualityMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ForwardTestMessage$Type extends MessageType { + constructor() { + super("ForwardTestMessage", [ + { no: 1, name: "targetHost", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "targetPort", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): ForwardTestMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.targetHost = ""; + message.targetPort = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ForwardTestMessage): ForwardTestMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string targetHost */ 1: + message.targetHost = reader.string(); + break; + case /* required uint32 targetPort */ 2: + message.targetPort = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ForwardTestMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string targetHost = 1; */ + if (message.targetHost !== "") + writer.tag(1, WireType.LengthDelimited).string(message.targetHost); + /* required uint32 targetPort = 2; */ + if (message.targetPort !== 0) + writer.tag(2, WireType.Varint).uint32(message.targetPort); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ForwardTestMessage + */ +export const ForwardTestMessage = new ForwardTestMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ForwardCreateMessage$Type extends MessageType { + constructor() { + super("ForwardCreateMessage", [ + { no: 1, name: "id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "devicePort", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 3, name: "targetHost", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "targetPort", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): ForwardCreateMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.id = ""; + message.devicePort = 0; + message.targetHost = ""; + message.targetPort = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ForwardCreateMessage): ForwardCreateMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string id */ 1: + message.id = reader.string(); + break; + case /* required uint32 devicePort */ 2: + message.devicePort = reader.uint32(); + break; + case /* required string targetHost */ 3: + message.targetHost = reader.string(); + break; + case /* required uint32 targetPort */ 4: + message.targetPort = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ForwardCreateMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string id = 1; */ + if (message.id !== "") + writer.tag(1, WireType.LengthDelimited).string(message.id); + /* required uint32 devicePort = 2; */ + if (message.devicePort !== 0) + writer.tag(2, WireType.Varint).uint32(message.devicePort); + /* required string targetHost = 3; */ + if (message.targetHost !== "") + writer.tag(3, WireType.LengthDelimited).string(message.targetHost); + /* required uint32 targetPort = 4; */ + if (message.targetPort !== 0) + writer.tag(4, WireType.Varint).uint32(message.targetPort); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ForwardCreateMessage + */ +export const ForwardCreateMessage = new ForwardCreateMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ForwardRemoveMessage$Type extends MessageType { + constructor() { + super("ForwardRemoveMessage", [ + { no: 1, name: "id", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): ForwardRemoveMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.id = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ForwardRemoveMessage): ForwardRemoveMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string id */ 1: + message.id = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ForwardRemoveMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string id = 1; */ + if (message.id !== "") + writer.tag(1, WireType.LengthDelimited).string(message.id); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ForwardRemoveMessage + */ +export const ForwardRemoveMessage = new ForwardRemoveMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ReverseForward$Type extends MessageType { + constructor() { + super("ReverseForward", [ + { no: 1, name: "id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "devicePort", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 3, name: "targetHost", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "targetPort", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): ReverseForward { + const message = globalThis.Object.create((this.messagePrototype!)); + message.id = ""; + message.devicePort = 0; + message.targetHost = ""; + message.targetPort = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ReverseForward): ReverseForward { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string id */ 1: + message.id = reader.string(); + break; + case /* required uint32 devicePort */ 2: + message.devicePort = reader.uint32(); + break; + case /* required string targetHost */ 3: + message.targetHost = reader.string(); + break; + case /* required uint32 targetPort */ 4: + message.targetPort = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ReverseForward, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string id = 1; */ + if (message.id !== "") + writer.tag(1, WireType.LengthDelimited).string(message.id); + /* required uint32 devicePort = 2; */ + if (message.devicePort !== 0) + writer.tag(2, WireType.Varint).uint32(message.devicePort); + /* required string targetHost = 3; */ + if (message.targetHost !== "") + writer.tag(3, WireType.LengthDelimited).string(message.targetHost); + /* required uint32 targetPort = 4; */ + if (message.targetPort !== 0) + writer.tag(4, WireType.Varint).uint32(message.targetPort); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ReverseForward + */ +export const ReverseForward = new ReverseForward$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ReverseForwardsEvent$Type extends MessageType { + constructor() { + super("ReverseForwardsEvent", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "forwards", kind: "message", repeat: 2 /*RepeatType.UNPACKED*/, T: () => ReverseForward } + ]); + } + create(value?: PartialMessage): ReverseForwardsEvent { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.forwards = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ReverseForwardsEvent): ReverseForwardsEvent { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* repeated ReverseForward forwards */ 2: + message.forwards.push(ReverseForward.internalBinaryRead(reader, reader.uint32(), options)); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ReverseForwardsEvent, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* repeated ReverseForward forwards = 2; */ + for (let i = 0; i < message.forwards.length; i++) + ReverseForward.internalBinaryWrite(message.forwards[i], writer.tag(2, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ReverseForwardsEvent + */ +export const ReverseForwardsEvent = new ReverseForwardsEvent$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class BrowserOpenMessage$Type extends MessageType { + constructor() { + super("BrowserOpenMessage", [ + { no: 1, name: "url", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "browser", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): BrowserOpenMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.url = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: BrowserOpenMessage): BrowserOpenMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string url */ 1: + message.url = reader.string(); + break; + case /* optional string browser */ 2: + message.browser = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: BrowserOpenMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string url = 1; */ + if (message.url !== "") + writer.tag(1, WireType.LengthDelimited).string(message.url); + /* optional string browser = 2; */ + if (message.browser !== undefined) + writer.tag(2, WireType.LengthDelimited).string(message.browser); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message BrowserOpenMessage + */ +export const BrowserOpenMessage = new BrowserOpenMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class BrowserClearMessage$Type extends MessageType { + constructor() { + super("BrowserClearMessage", [ + { no: 1, name: "browser", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): BrowserClearMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: BrowserClearMessage): BrowserClearMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* optional string browser */ 1: + message.browser = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: BrowserClearMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* optional string browser = 1; */ + if (message.browser !== undefined) + writer.tag(1, WireType.LengthDelimited).string(message.browser); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message BrowserClearMessage + */ +export const BrowserClearMessage = new BrowserClearMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class StoreOpenMessage$Type extends MessageType { + constructor() { + super("StoreOpenMessage", []); + } + create(value?: PartialMessage): StoreOpenMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: StoreOpenMessage): StoreOpenMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: StoreOpenMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message StoreOpenMessage + */ +export const StoreOpenMessage = new StoreOpenMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ScreenCaptureMessage$Type extends MessageType { + constructor() { + super("ScreenCaptureMessage", []); + } + create(value?: PartialMessage): ScreenCaptureMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ScreenCaptureMessage): ScreenCaptureMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ScreenCaptureMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ScreenCaptureMessage + */ +export const ScreenCaptureMessage = new ScreenCaptureMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ConnectStartMessage$Type extends MessageType { + constructor() { + super("ConnectStartMessage", []); + } + create(value?: PartialMessage): ConnectStartMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ConnectStartMessage): ConnectStartMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ConnectStartMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ConnectStartMessage + */ +export const ConnectStartMessage = new ConnectStartMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ConnectGetForwardUrlMessage$Type extends MessageType { + constructor() { + super("ConnectGetForwardUrlMessage", []); + } + create(value?: PartialMessage): ConnectGetForwardUrlMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ConnectGetForwardUrlMessage): ConnectGetForwardUrlMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ConnectGetForwardUrlMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ConnectGetForwardUrlMessage + */ +export const ConnectGetForwardUrlMessage = new ConnectGetForwardUrlMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ConnectStopMessage$Type extends MessageType { + constructor() { + super("ConnectStopMessage", []); + } + create(value?: PartialMessage): ConnectStopMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ConnectStopMessage): ConnectStopMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ConnectStopMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ConnectStopMessage + */ +export const ConnectStopMessage = new ConnectStopMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class AccountAddMenuMessage$Type extends MessageType { + constructor() { + super("AccountAddMenuMessage", []); + } + create(value?: PartialMessage): AccountAddMenuMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AccountAddMenuMessage): AccountAddMenuMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: AccountAddMenuMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message AccountAddMenuMessage + */ +export const AccountAddMenuMessage = new AccountAddMenuMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class AccountAddMessage$Type extends MessageType { + constructor() { + super("AccountAddMessage", [ + { no: 1, name: "user", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "password", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): AccountAddMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.user = ""; + message.password = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AccountAddMessage): AccountAddMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string user */ 1: + message.user = reader.string(); + break; + case /* required string password */ 2: + message.password = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: AccountAddMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string user = 1; */ + if (message.user !== "") + writer.tag(1, WireType.LengthDelimited).string(message.user); + /* required string password = 2; */ + if (message.password !== "") + writer.tag(2, WireType.LengthDelimited).string(message.password); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message AccountAddMessage + */ +export const AccountAddMessage = new AccountAddMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class AccountCheckMessage$Type extends MessageType { + constructor() { + super("AccountCheckMessage", [ + { no: 1, name: "type", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "account", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): AccountCheckMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.type = ""; + message.account = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AccountCheckMessage): AccountCheckMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string type */ 1: + message.type = reader.string(); + break; + case /* required string account */ 2: + message.account = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: AccountCheckMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string type = 1; */ + if (message.type !== "") + writer.tag(1, WireType.LengthDelimited).string(message.type); + /* required string account = 2; */ + if (message.account !== "") + writer.tag(2, WireType.LengthDelimited).string(message.account); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message AccountCheckMessage + */ +export const AccountCheckMessage = new AccountCheckMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class AccountGetMessage$Type extends MessageType { + constructor() { + super("AccountGetMessage", [ + { no: 1, name: "type", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): AccountGetMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AccountGetMessage): AccountGetMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* optional string type */ 1: + message.type = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: AccountGetMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* optional string type = 1; */ + if (message.type !== undefined) + writer.tag(1, WireType.LengthDelimited).string(message.type); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message AccountGetMessage + */ +export const AccountGetMessage = new AccountGetMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class AccountRemoveMessage$Type extends MessageType { + constructor() { + super("AccountRemoveMessage", [ + { no: 1, name: "type", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "account", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): AccountRemoveMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.type = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AccountRemoveMessage): AccountRemoveMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string type */ 1: + message.type = reader.string(); + break; + case /* optional string account */ 2: + message.account = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: AccountRemoveMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string type = 1; */ + if (message.type !== "") + writer.tag(1, WireType.LengthDelimited).string(message.type); + /* optional string account = 2; */ + if (message.account !== undefined) + writer.tag(2, WireType.LengthDelimited).string(message.account); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message AccountRemoveMessage + */ +export const AccountRemoveMessage = new AccountRemoveMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class SdStatusMessage$Type extends MessageType { + constructor() { + super("SdStatusMessage", []); + } + create(value?: PartialMessage): SdStatusMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: SdStatusMessage): SdStatusMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: SdStatusMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message SdStatusMessage + */ +export const SdStatusMessage = new SdStatusMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class AirplaneSetMessage$Type extends MessageType { + constructor() { + super("AirplaneSetMessage", [ + { no: 1, name: "enabled", kind: "scalar", T: 8 /*ScalarType.BOOL*/ } + ]); + } + create(value?: PartialMessage): AirplaneSetMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.enabled = false; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AirplaneSetMessage): AirplaneSetMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required bool enabled */ 1: + message.enabled = reader.bool(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: AirplaneSetMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required bool enabled = 1; */ + if (message.enabled !== false) + writer.tag(1, WireType.Varint).bool(message.enabled); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message AirplaneSetMessage + */ +export const AirplaneSetMessage = new AirplaneSetMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class RingerSetMessage$Type extends MessageType { + constructor() { + super("RingerSetMessage", [ + { no: 1, name: "mode", kind: "enum", T: () => ["RingerMode", RingerMode] } + ]); + } + create(value?: PartialMessage): RingerSetMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.mode = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: RingerSetMessage): RingerSetMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required RingerMode mode */ 1: + message.mode = reader.int32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: RingerSetMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required RingerMode mode = 1; */ + if (message.mode !== 0) + writer.tag(1, WireType.Varint).int32(message.mode); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message RingerSetMessage + */ +export const RingerSetMessage = new RingerSetMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class RingerGetMessage$Type extends MessageType { + constructor() { + super("RingerGetMessage", []); + } + create(value?: PartialMessage): RingerGetMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: RingerGetMessage): RingerGetMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: RingerGetMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message RingerGetMessage + */ +export const RingerGetMessage = new RingerGetMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class WifiSetEnabledMessage$Type extends MessageType { + constructor() { + super("WifiSetEnabledMessage", [ + { no: 1, name: "enabled", kind: "scalar", T: 8 /*ScalarType.BOOL*/ } + ]); + } + create(value?: PartialMessage): WifiSetEnabledMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.enabled = false; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: WifiSetEnabledMessage): WifiSetEnabledMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required bool enabled */ 1: + message.enabled = reader.bool(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: WifiSetEnabledMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required bool enabled = 1; */ + if (message.enabled !== false) + writer.tag(1, WireType.Varint).bool(message.enabled); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message WifiSetEnabledMessage + */ +export const WifiSetEnabledMessage = new WifiSetEnabledMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class WifiGetStatusMessage$Type extends MessageType { + constructor() { + super("WifiGetStatusMessage", []); + } + create(value?: PartialMessage): WifiGetStatusMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: WifiGetStatusMessage): WifiGetStatusMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: WifiGetStatusMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message WifiGetStatusMessage + */ +export const WifiGetStatusMessage = new WifiGetStatusMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class BluetoothSetEnabledMessage$Type extends MessageType { + constructor() { + super("BluetoothSetEnabledMessage", [ + { no: 1, name: "enabled", kind: "scalar", T: 8 /*ScalarType.BOOL*/ } + ]); + } + create(value?: PartialMessage): BluetoothSetEnabledMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.enabled = false; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: BluetoothSetEnabledMessage): BluetoothSetEnabledMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required bool enabled */ 1: + message.enabled = reader.bool(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: BluetoothSetEnabledMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required bool enabled = 1; */ + if (message.enabled !== false) + writer.tag(1, WireType.Varint).bool(message.enabled); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message BluetoothSetEnabledMessage + */ +export const BluetoothSetEnabledMessage = new BluetoothSetEnabledMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class BluetoothGetStatusMessage$Type extends MessageType { + constructor() { + super("BluetoothGetStatusMessage", []); + } + create(value?: PartialMessage): BluetoothGetStatusMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: BluetoothGetStatusMessage): BluetoothGetStatusMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: BluetoothGetStatusMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message BluetoothGetStatusMessage + */ +export const BluetoothGetStatusMessage = new BluetoothGetStatusMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class BluetoothCleanBondedMessage$Type extends MessageType { + constructor() { + super("BluetoothCleanBondedMessage", []); + } + create(value?: PartialMessage): BluetoothCleanBondedMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: BluetoothCleanBondedMessage): BluetoothCleanBondedMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: BluetoothCleanBondedMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message BluetoothCleanBondedMessage + */ +export const BluetoothCleanBondedMessage = new BluetoothCleanBondedMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class CapabilitiesMessage$Type extends MessageType { + constructor() { + super("CapabilitiesMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "hasTouch", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 3, name: "hasCursor", kind: "scalar", T: 8 /*ScalarType.BOOL*/ } + ]); + } + create(value?: PartialMessage): CapabilitiesMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.hasTouch = false; + message.hasCursor = false; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: CapabilitiesMessage): CapabilitiesMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required bool hasTouch */ 2: + message.hasTouch = reader.bool(); + break; + case /* required bool hasCursor */ 3: + message.hasCursor = reader.bool(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: CapabilitiesMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required bool hasTouch = 2; */ + if (message.hasTouch !== false) + writer.tag(2, WireType.Varint).bool(message.hasTouch); + /* required bool hasCursor = 3; */ + if (message.hasCursor !== false) + writer.tag(3, WireType.Varint).bool(message.hasCursor); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message CapabilitiesMessage + */ +export const CapabilitiesMessage = new CapabilitiesMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class AirplaneModeEvent$Type extends MessageType { + constructor() { + super("AirplaneModeEvent", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "enabled", kind: "scalar", T: 8 /*ScalarType.BOOL*/ } + ]); + } + create(value?: PartialMessage): AirplaneModeEvent { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.enabled = false; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AirplaneModeEvent): AirplaneModeEvent { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required bool enabled */ 2: + message.enabled = reader.bool(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: AirplaneModeEvent, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required bool enabled = 2; */ + if (message.enabled !== false) + writer.tag(2, WireType.Varint).bool(message.enabled); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message AirplaneModeEvent + */ +export const AirplaneModeEvent = new AirplaneModeEvent$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class BatteryEvent$Type extends MessageType { + constructor() { + super("BatteryEvent", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "status", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "health", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "source", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "level", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 6, name: "scale", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }, + { no: 7, name: "temp", kind: "scalar", T: 1 /*ScalarType.DOUBLE*/ }, + { no: 8, name: "voltage", kind: "scalar", opt: true, T: 1 /*ScalarType.DOUBLE*/ } + ]); + } + create(value?: PartialMessage): BatteryEvent { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.status = ""; + message.health = ""; + message.source = ""; + message.level = 0; + message.scale = 0; + message.temp = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: BatteryEvent): BatteryEvent { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required string status */ 2: + message.status = reader.string(); + break; + case /* required string health */ 3: + message.health = reader.string(); + break; + case /* required string source */ 4: + message.source = reader.string(); + break; + case /* required uint32 level */ 5: + message.level = reader.uint32(); + break; + case /* required uint32 scale */ 6: + message.scale = reader.uint32(); + break; + case /* required double temp */ 7: + message.temp = reader.double(); + break; + case /* optional double voltage */ 8: + message.voltage = reader.double(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: BatteryEvent, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required string status = 2; */ + if (message.status !== "") + writer.tag(2, WireType.LengthDelimited).string(message.status); + /* required string health = 3; */ + if (message.health !== "") + writer.tag(3, WireType.LengthDelimited).string(message.health); + /* required string source = 4; */ + if (message.source !== "") + writer.tag(4, WireType.LengthDelimited).string(message.source); + /* required uint32 level = 5; */ + if (message.level !== 0) + writer.tag(5, WireType.Varint).uint32(message.level); + /* required uint32 scale = 6; */ + if (message.scale !== 0) + writer.tag(6, WireType.Varint).uint32(message.scale); + /* required double temp = 7; */ + if (message.temp !== 0) + writer.tag(7, WireType.Bit64).double(message.temp); + /* optional double voltage = 8; */ + if (message.voltage !== undefined) + writer.tag(8, WireType.Bit64).double(message.voltage); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message BatteryEvent + */ +export const BatteryEvent = new BatteryEvent$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ConnectivityEvent$Type extends MessageType { + constructor() { + super("ConnectivityEvent", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "connected", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 3, name: "type", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "subtype", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "failover", kind: "scalar", opt: true, T: 8 /*ScalarType.BOOL*/ }, + { no: 6, name: "roaming", kind: "scalar", opt: true, T: 8 /*ScalarType.BOOL*/ } + ]); + } + create(value?: PartialMessage): ConnectivityEvent { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.connected = false; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ConnectivityEvent): ConnectivityEvent { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required bool connected */ 2: + message.connected = reader.bool(); + break; + case /* optional string type */ 3: + message.type = reader.string(); + break; + case /* optional string subtype */ 4: + message.subtype = reader.string(); + break; + case /* optional bool failover */ 5: + message.failover = reader.bool(); + break; + case /* optional bool roaming */ 6: + message.roaming = reader.bool(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ConnectivityEvent, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required bool connected = 2; */ + if (message.connected !== false) + writer.tag(2, WireType.Varint).bool(message.connected); + /* optional string type = 3; */ + if (message.type !== undefined) + writer.tag(3, WireType.LengthDelimited).string(message.type); + /* optional string subtype = 4; */ + if (message.subtype !== undefined) + writer.tag(4, WireType.LengthDelimited).string(message.subtype); + /* optional bool failover = 5; */ + if (message.failover !== undefined) + writer.tag(5, WireType.Varint).bool(message.failover); + /* optional bool roaming = 6; */ + if (message.roaming !== undefined) + writer.tag(6, WireType.Varint).bool(message.roaming); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message ConnectivityEvent + */ +export const ConnectivityEvent = new ConnectivityEvent$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class PhoneStateEvent$Type extends MessageType { + constructor() { + super("PhoneStateEvent", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "state", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "manual", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 4, name: "operator", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): PhoneStateEvent { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.state = ""; + message.manual = false; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: PhoneStateEvent): PhoneStateEvent { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required string state */ 2: + message.state = reader.string(); + break; + case /* required bool manual */ 3: + message.manual = reader.bool(); + break; + case /* optional string operator */ 4: + message.operator = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: PhoneStateEvent, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required string state = 2; */ + if (message.state !== "") + writer.tag(2, WireType.LengthDelimited).string(message.state); + /* required bool manual = 3; */ + if (message.manual !== false) + writer.tag(3, WireType.Varint).bool(message.manual); + /* optional string operator = 4; */ + if (message.operator !== undefined) + writer.tag(4, WireType.LengthDelimited).string(message.operator); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message PhoneStateEvent + */ +export const PhoneStateEvent = new PhoneStateEvent$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class RotationEvent$Type extends MessageType { + constructor() { + super("RotationEvent", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "rotation", kind: "scalar", T: 5 /*ScalarType.INT32*/ }, + { no: 3, name: "width", kind: "scalar", opt: true, T: 5 /*ScalarType.INT32*/ }, + { no: 4, name: "height", kind: "scalar", opt: true, T: 5 /*ScalarType.INT32*/ } + ]); + } + create(value?: PartialMessage): RotationEvent { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.rotation = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: RotationEvent): RotationEvent { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required int32 rotation */ 2: + message.rotation = reader.int32(); + break; + case /* optional int32 width */ 3: + message.width = reader.int32(); + break; + case /* optional int32 height */ 4: + message.height = reader.int32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: RotationEvent, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required int32 rotation = 2; */ + if (message.rotation !== 0) + writer.tag(2, WireType.Varint).int32(message.rotation); + /* optional int32 width = 3; */ + if (message.width !== undefined) + writer.tag(3, WireType.Varint).int32(message.width); + /* optional int32 height = 4; */ + if (message.height !== undefined) + writer.tag(4, WireType.Varint).int32(message.height); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message RotationEvent + */ +export const RotationEvent = new RotationEvent$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class SetDeviceDisplay$Type extends MessageType { + constructor() { + super("SetDeviceDisplay", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "channel", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "width", kind: "scalar", T: 5 /*ScalarType.INT32*/ }, + { no: 4, name: "height", kind: "scalar", T: 5 /*ScalarType.INT32*/ } + ]); + } + create(value?: PartialMessage): SetDeviceDisplay { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.channel = ""; + message.width = 0; + message.height = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: SetDeviceDisplay): SetDeviceDisplay { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required string channel */ 2: + message.channel = reader.string(); + break; + case /* required int32 width */ 3: + message.width = reader.int32(); + break; + case /* required int32 height */ 4: + message.height = reader.int32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: SetDeviceDisplay, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required string channel = 2; */ + if (message.channel !== "") + writer.tag(2, WireType.LengthDelimited).string(message.channel); + /* required int32 width = 3; */ + if (message.width !== 0) + writer.tag(3, WireType.Varint).int32(message.width); + /* required int32 height = 4; */ + if (message.height !== 0) + writer.tag(4, WireType.Varint).int32(message.height); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message SetDeviceDisplay + */ +export const SetDeviceDisplay = new SetDeviceDisplay$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class IosDevicePorts$Type extends MessageType { + constructor() { + super("IosDevicePorts", [ + { no: 2, name: "screenPort", kind: "scalar", T: 5 /*ScalarType.INT32*/ }, + { no: 3, name: "connectPort", kind: "scalar", T: 5 /*ScalarType.INT32*/ } + ]); + } + create(value?: PartialMessage): IosDevicePorts { + const message = globalThis.Object.create((this.messagePrototype!)); + message.screenPort = 0; + message.connectPort = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: IosDevicePorts): IosDevicePorts { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required int32 screenPort */ 2: + message.screenPort = reader.int32(); + break; + case /* required int32 connectPort */ 3: + message.connectPort = reader.int32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: IosDevicePorts, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required int32 screenPort = 2; */ + if (message.screenPort !== 0) + writer.tag(2, WireType.Varint).int32(message.screenPort); + /* required int32 connectPort = 3; */ + if (message.connectPort !== 0) + writer.tag(3, WireType.Varint).int32(message.connectPort); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message IosDevicePorts + */ +export const IosDevicePorts = new IosDevicePorts$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class StartStreaming$Type extends MessageType { + constructor() { + super("StartStreaming", [ + { no: 1, name: "port", kind: "scalar", T: 5 /*ScalarType.INT32*/ }, + { no: 2, name: "channel", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): StartStreaming { + const message = globalThis.Object.create((this.messagePrototype!)); + message.port = 0; + message.channel = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: StartStreaming): StartStreaming { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required int32 port */ 1: + message.port = reader.int32(); + break; + case /* required string channel */ 2: + message.channel = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: StartStreaming, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required int32 port = 1; */ + if (message.port !== 0) + writer.tag(1, WireType.Varint).int32(message.port); + /* required string channel = 2; */ + if (message.channel !== "") + writer.tag(2, WireType.LengthDelimited).string(message.channel); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message StartStreaming + */ +export const StartStreaming = new StartStreaming$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeleteDevice$Type extends MessageType { + constructor() { + super("DeleteDevice", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeleteDevice { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeleteDevice): DeleteDevice { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeleteDevice, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeleteDevice + */ +export const DeleteDevice = new DeleteDevice$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class SetAbsentDisconnectedDevices$Type extends MessageType { + constructor() { + super("SetAbsentDisconnectedDevices", []); + } + create(value?: PartialMessage): SetAbsentDisconnectedDevices { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: SetAbsentDisconnectedDevices): SetAbsentDisconnectedDevices { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: SetAbsentDisconnectedDevices, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message SetAbsentDisconnectedDevices + */ +export const SetAbsentDisconnectedDevices = new SetAbsentDisconnectedDevices$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class Applications$Type extends MessageType { + constructor() { + super("Applications", [ + { no: 1, name: "bundleId", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "bundleName", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): Applications { + const message = globalThis.Object.create((this.messagePrototype!)); + message.bundleId = ""; + message.bundleName = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: Applications): Applications { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string bundleId */ 1: + message.bundleId = reader.string(); + break; + case /* required string bundleName */ 2: + message.bundleName = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: Applications, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string bundleId = 1; */ + if (message.bundleId !== "") + writer.tag(1, WireType.LengthDelimited).string(message.bundleId); + /* required string bundleName = 2; */ + if (message.bundleName !== "") + writer.tag(2, WireType.LengthDelimited).string(message.bundleName); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message Applications + */ +export const Applications = new Applications$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class InstalledApplications$Type extends MessageType { + constructor() { + super("InstalledApplications", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "applications", kind: "message", repeat: 2 /*RepeatType.UNPACKED*/, T: () => Applications } + ]); + } + create(value?: PartialMessage): InstalledApplications { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.applications = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: InstalledApplications): InstalledApplications { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* repeated Applications applications */ 2: + message.applications.push(Applications.internalBinaryRead(reader, reader.uint32(), options)); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: InstalledApplications, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* repeated Applications applications = 2; */ + for (let i = 0; i < message.applications.length; i++) + Applications.internalBinaryWrite(message.applications[i], writer.tag(2, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message InstalledApplications + */ +export const InstalledApplications = new InstalledApplications$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TransportInstalledApps$Type extends MessageType { + constructor() { + super("TransportInstalledApps", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): TransportInstalledApps { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TransportInstalledApps): TransportInstalledApps { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TransportInstalledApps, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message TransportInstalledApps + */ +export const TransportInstalledApps = new TransportInstalledApps$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class SetDeviceApp$Type extends MessageType { + constructor() { + super("SetDeviceApp", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "bundleId", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "bundleName", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "pathToApp", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): SetDeviceApp { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.bundleId = ""; + message.bundleName = ""; + message.pathToApp = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: SetDeviceApp): SetDeviceApp { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required string bundleId */ 2: + message.bundleId = reader.string(); + break; + case /* required string bundleName */ 3: + message.bundleName = reader.string(); + break; + case /* required string pathToApp */ 4: + message.pathToApp = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: SetDeviceApp, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required string bundleId = 2; */ + if (message.bundleId !== "") + writer.tag(2, WireType.LengthDelimited).string(message.bundleId); + /* required string bundleName = 3; */ + if (message.bundleName !== "") + writer.tag(3, WireType.LengthDelimited).string(message.bundleName); + /* required string pathToApp = 4; */ + if (message.pathToApp !== "") + writer.tag(4, WireType.LengthDelimited).string(message.pathToApp); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message SetDeviceApp + */ +export const SetDeviceApp = new SetDeviceApp$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GetIosDeviceApps$Type extends MessageType { + constructor() { + super("GetIosDeviceApps", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "bundleId", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "bundleName", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "pathToApp", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): GetIosDeviceApps { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.bundleId = ""; + message.bundleName = ""; + message.pathToApp = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GetIosDeviceApps): GetIosDeviceApps { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required string bundleId */ 2: + message.bundleId = reader.string(); + break; + case /* required string bundleName */ 3: + message.bundleName = reader.string(); + break; + case /* required string pathToApp */ 4: + message.pathToApp = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GetIosDeviceApps, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required string bundleId = 2; */ + if (message.bundleId !== "") + writer.tag(2, WireType.LengthDelimited).string(message.bundleId); + /* required string bundleName = 3; */ + if (message.bundleName !== "") + writer.tag(3, WireType.LengthDelimited).string(message.bundleName); + /* required string pathToApp = 4; */ + if (message.pathToApp !== "") + writer.tag(4, WireType.LengthDelimited).string(message.pathToApp); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GetIosDeviceApps + */ +export const GetIosDeviceApps = new GetIosDeviceApps$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TransationGetMessage$Type extends MessageType { + constructor() { + super("TransationGetMessage", [ + { no: 1, name: "source", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "data", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): TransationGetMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.source = ""; + message.data = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TransationGetMessage): TransationGetMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string source */ 1: + message.source = reader.string(); + break; + case /* required string data */ 2: + message.data = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TransationGetMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string source = 1; */ + if (message.source !== "") + writer.tag(1, WireType.LengthDelimited).string(message.source); + /* required string data = 2; */ + if (message.data !== "") + writer.tag(2, WireType.LengthDelimited).string(message.data); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message TransationGetMessage + */ +export const TransationGetMessage = new TransationGetMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GetInstalledApplications$Type extends MessageType { + constructor() { + super("GetInstalledApplications", []); + } + create(value?: PartialMessage): GetInstalledApplications { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GetInstalledApplications): GetInstalledApplications { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GetInstalledApplications, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GetInstalledApplications + */ +export const GetInstalledApplications = new GetInstalledApplications$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class UpdateIosDevice$Type extends MessageType { + constructor() { + super("UpdateIosDevice", [ + { no: 1, name: "id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "platform", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "architecture", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "sdk", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 6, name: "service", kind: "message", T: () => IosServiceMessage } + ]); + } + create(value?: PartialMessage): UpdateIosDevice { + const message = globalThis.Object.create((this.messagePrototype!)); + message.id = ""; + message.name = ""; + message.platform = ""; + message.architecture = ""; + message.sdk = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: UpdateIosDevice): UpdateIosDevice { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string id */ 1: + message.id = reader.string(); + break; + case /* required string name */ 2: + message.name = reader.string(); + break; + case /* required string platform */ 3: + message.platform = reader.string(); + break; + case /* required string architecture */ 4: + message.architecture = reader.string(); + break; + case /* required string sdk */ 5: + message.sdk = reader.string(); + break; + case /* required IosServiceMessage service */ 6: + message.service = IosServiceMessage.internalBinaryRead(reader, reader.uint32(), options, message.service); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: UpdateIosDevice, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string id = 1; */ + if (message.id !== "") + writer.tag(1, WireType.LengthDelimited).string(message.id); + /* required string name = 2; */ + if (message.name !== "") + writer.tag(2, WireType.LengthDelimited).string(message.name); + /* required string platform = 3; */ + if (message.platform !== "") + writer.tag(3, WireType.LengthDelimited).string(message.platform); + /* required string architecture = 4; */ + if (message.architecture !== "") + writer.tag(4, WireType.LengthDelimited).string(message.architecture); + /* required string sdk = 5; */ + if (message.sdk !== "") + writer.tag(5, WireType.LengthDelimited).string(message.sdk); + /* required IosServiceMessage service = 6; */ + if (message.service) + IosServiceMessage.internalBinaryWrite(message.service, writer.tag(6, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message UpdateIosDevice + */ +export const UpdateIosDevice = new UpdateIosDevice$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class SdkIosVersion$Type extends MessageType { + constructor() { + super("SdkIosVersion", [ + { no: 1, name: "id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "sdkVersion", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): SdkIosVersion { + const message = globalThis.Object.create((this.messagePrototype!)); + message.id = ""; + message.sdkVersion = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: SdkIosVersion): SdkIosVersion { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string id */ 1: + message.id = reader.string(); + break; + case /* required string sdkVersion */ 2: + message.sdkVersion = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: SdkIosVersion, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string id = 1; */ + if (message.id !== "") + writer.tag(1, WireType.LengthDelimited).string(message.id); + /* required string sdkVersion = 2; */ + if (message.sdkVersion !== "") + writer.tag(2, WireType.LengthDelimited).string(message.sdkVersion); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message SdkIosVersion + */ +export const SdkIosVersion = new SdkIosVersion$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class SizeIosDevice$Type extends MessageType { + constructor() { + super("SizeIosDevice", [ + { no: 1, name: "id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "height", kind: "scalar", T: 1 /*ScalarType.DOUBLE*/ }, + { no: 3, name: "width", kind: "scalar", T: 1 /*ScalarType.DOUBLE*/ }, + { no: 4, name: "scale", kind: "scalar", T: 5 /*ScalarType.INT32*/ } + ]); + } + create(value?: PartialMessage): SizeIosDevice { + const message = globalThis.Object.create((this.messagePrototype!)); + message.id = ""; + message.height = 0; + message.width = 0; + message.scale = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: SizeIosDevice): SizeIosDevice { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string id */ 1: + message.id = reader.string(); + break; + case /* required double height */ 2: + message.height = reader.double(); + break; + case /* required double width */ 3: + message.width = reader.double(); + break; + case /* required int32 scale */ 4: + message.scale = reader.int32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: SizeIosDevice, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string id = 1; */ + if (message.id !== "") + writer.tag(1, WireType.LengthDelimited).string(message.id); + /* required double height = 2; */ + if (message.height !== 0) + writer.tag(2, WireType.Bit64).double(message.height); + /* required double width = 3; */ + if (message.width !== 0) + writer.tag(3, WireType.Bit64).double(message.width); + /* required int32 scale = 4; */ + if (message.scale !== 0) + writer.tag(4, WireType.Varint).int32(message.scale); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message SizeIosDevice + */ +export const SizeIosDevice = new SizeIosDevice$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DashboardOpenMessage$Type extends MessageType { + constructor() { + super("DashboardOpenMessage", []); + } + create(value?: PartialMessage): DashboardOpenMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DashboardOpenMessage): DashboardOpenMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DashboardOpenMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DashboardOpenMessage + */ +export const DashboardOpenMessage = new DashboardOpenMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GetIosTreeElements$Type extends MessageType { + constructor() { + super("GetIosTreeElements", []); + } + create(value?: PartialMessage): GetIosTreeElements { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GetIosTreeElements): GetIosTreeElements { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GetIosTreeElements, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GetIosTreeElements + */ +export const GetIosTreeElements = new GetIosTreeElements$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TapDeviceTreeElement$Type extends MessageType { + constructor() { + super("TapDeviceTreeElement", [ + { no: 1, name: "label", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): TapDeviceTreeElement { + const message = globalThis.Object.create((this.messagePrototype!)); + message.label = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TapDeviceTreeElement): TapDeviceTreeElement { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string label */ 1: + message.label = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TapDeviceTreeElement, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string label = 1; */ + if (message.label !== "") + writer.tag(1, WireType.LengthDelimited).string(message.label); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message TapDeviceTreeElement + */ +export const TapDeviceTreeElement = new TapDeviceTreeElement$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TemporarilyUnavailableMessage$Type extends MessageType { + constructor() { + super("TemporarilyUnavailableMessage", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): TemporarilyUnavailableMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TemporarilyUnavailableMessage): TemporarilyUnavailableMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TemporarilyUnavailableMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message TemporarilyUnavailableMessage + */ +export const TemporarilyUnavailableMessage = new TemporarilyUnavailableMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class UpdateRemoteConnectUrl$Type extends MessageType { + constructor() { + super("UpdateRemoteConnectUrl", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): UpdateRemoteConnectUrl { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: UpdateRemoteConnectUrl): UpdateRemoteConnectUrl { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: UpdateRemoteConnectUrl, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message UpdateRemoteConnectUrl + */ +export const UpdateRemoteConnectUrl = new UpdateRemoteConnectUrl$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class IosServiceMessage$Type extends MessageType { + constructor() { + super("IosServiceMessage", [ + { no: 1, name: "hasAPNS", kind: "scalar", T: 8 /*ScalarType.BOOL*/ } + ]); + } + create(value?: PartialMessage): IosServiceMessage { + const message = globalThis.Object.create((this.messagePrototype!)); + message.hasAPNS = false; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: IosServiceMessage): IosServiceMessage { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required bool hasAPNS */ 1: + message.hasAPNS = reader.bool(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: IosServiceMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required bool hasAPNS = 1; */ + if (message.hasAPNS !== false) + writer.tag(1, WireType.Varint).bool(message.hasAPNS); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message IosServiceMessage + */ +export const IosServiceMessage = new IosServiceMessage$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class LaunchDeviceApp$Type extends MessageType { + constructor() { + super("LaunchDeviceApp", [ + { no: 1, name: "pkg", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): LaunchDeviceApp { + const message = globalThis.Object.create((this.messagePrototype!)); + message.pkg = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: LaunchDeviceApp): LaunchDeviceApp { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string pkg */ 1: + message.pkg = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: LaunchDeviceApp, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string pkg = 1; */ + if (message.pkg !== "") + writer.tag(1, WireType.LengthDelimited).string(message.pkg); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message LaunchDeviceApp + */ +export const LaunchDeviceApp = new LaunchDeviceApp$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TerminateDeviceApp$Type extends MessageType { + constructor() { + super("TerminateDeviceApp", []); + } + create(value?: PartialMessage): TerminateDeviceApp { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TerminateDeviceApp): TerminateDeviceApp { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TerminateDeviceApp, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message TerminateDeviceApp + */ +export const TerminateDeviceApp = new TerminateDeviceApp$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class KillDeviceApp$Type extends MessageType { + constructor() { + super("KillDeviceApp", []); + } + create(value?: PartialMessage): KillDeviceApp { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: KillDeviceApp): KillDeviceApp { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: KillDeviceApp, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message KillDeviceApp + */ +export const KillDeviceApp = new KillDeviceApp$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GetAppAsset$Type extends MessageType { + constructor() { + super("GetAppAsset", [ + { no: 1, name: "url", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): GetAppAsset { + const message = globalThis.Object.create((this.messagePrototype!)); + message.url = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GetAppAsset): GetAppAsset { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string url */ 1: + message.url = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GetAppAsset, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string url = 1; */ + if (message.url !== "") + writer.tag(1, WireType.LengthDelimited).string(message.url); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GetAppAsset + */ +export const GetAppAsset = new GetAppAsset$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GetAppAssetsList$Type extends MessageType { + constructor() { + super("GetAppAssetsList", []); + } + create(value?: PartialMessage): GetAppAssetsList { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GetAppAssetsList): GetAppAssetsList { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GetAppAssetsList, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GetAppAssetsList + */ +export const GetAppAssetsList = new GetAppAssetsList$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GetAppHTML$Type extends MessageType { + constructor() { + super("GetAppHTML", []); + } + create(value?: PartialMessage): GetAppHTML { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GetAppHTML): GetAppHTML { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GetAppHTML, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GetAppHTML + */ +export const GetAppHTML = new GetAppHTML$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GetAppInspectServerUrl$Type extends MessageType { + constructor() { + super("GetAppInspectServerUrl", []); + } + create(value?: PartialMessage): GetAppInspectServerUrl { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GetAppInspectServerUrl): GetAppInspectServerUrl { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GetAppInspectServerUrl, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GetAppInspectServerUrl + */ +export const GetAppInspectServerUrl = new GetAppInspectServerUrl$Type(); diff --git a/package-lock.json b/package-lock.json index 495b9cffc9..18b4acae70 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "@irdk/usbmux": "^0.2.2", "@julusian/jpeg-turbo": "2.1.0", "@node-saml/passport-saml": "5.1.0", + "@protobuf-ts/plugin": "^2.11.1", "@sentry/node": "^8.34.0", "@types/chrome-remote-interface": "^0.31.14", "@u4/adbkit": "^5.1.7", @@ -97,7 +98,6 @@ "temp": "0.9.4", "tmp-promise": "^3.0.3", "transliteration": "2.2.0", - "ts-proto": "^2.6.1", "tsx": "4.20.3", "underscore.string": "3.3.6", "url-join": "1.1.0", @@ -117,7 +117,7 @@ }, "devDependencies": { "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.30.1", + "@eslint/js": "^9.33.0", "@playwright/test": "^1.52.0", "@types/bluebird": "^3.5.42", "@types/chalk": "^0.4.31", @@ -133,14 +133,14 @@ "async": "2.6.4", "cli-docs-generator": "1.0.7", "esbuild": "0.25.8", - "eslint": "9.30.1", + "eslint": "^9.30.1", "event-stream": "3.3.5", "exports-loader": "^4.0.0", "fs-extra": "8.1.0", "globals": "^15.11.0", "http-https": "1.0.0", "imports-loader": "^4.0.1", - "typescript": "^5.5.3", + "typescript": "^5.9.2", "typescript-eslint": "^8.39.1" }, "engines": { @@ -1276,11 +1276,35 @@ } }, "node_modules/@bufbuild/protobuf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.6.2.tgz", - "integrity": "sha512-vLu7SRY84CV/Dd+NUdgtidn2hS5hSMUC1vDBY0VcviTdgRYkU43vIz3vIFbmx14cX1r+mM7WjzE5Fl1fGEM0RQ==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.6.3.tgz", + "integrity": "sha512-w/gJKME9mYN7ZoUAmSMAWXk4hkVpxRKvEJCb3dV5g9wwWdxTJJ0ayOJAVcNxtdqaxDyFuC0uz4RSGVacJ030PQ==", "license": "(Apache-2.0 AND BSD-3-Clause)" }, + "node_modules/@bufbuild/protoplugin": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@bufbuild/protoplugin/-/protoplugin-2.6.3.tgz", + "integrity": "sha512-VceMuxeRukxGeABfo34SXq0VqY1MU+mzS+PBf0HAWo97ylFut8F6sQ3mV0tKiM08UQ/xQco7lxCn83BkoxrWrA==", + "license": "Apache-2.0", + "dependencies": { + "@bufbuild/protobuf": "2.6.3", + "@typescript/vfs": "^1.5.2", + "typescript": "5.4.5" + } + }, + "node_modules/@bufbuild/protoplugin/node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/@devicefarmer/adbkit-apkreader": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit-apkreader/-/adbkit-apkreader-3.2.4.tgz", @@ -1497,70 +1521,6 @@ "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==", "license": "MIT" }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz", - "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz", - "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz", - "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz", - "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/@esbuild/darwin-arm64": { "version": "0.25.8", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz", @@ -1577,342 +1537,6 @@ "node": ">=18" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz", - "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz", - "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz", - "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz", - "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz", - "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz", - "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz", - "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz", - "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz", - "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz", - "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz", - "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz", - "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz", - "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz", - "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz", - "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz", - "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz", - "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz", - "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz", - "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz", - "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz", - "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", @@ -2031,9 +1655,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz", - "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==", + "version": "9.33.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.33.0.tgz", + "integrity": "sha512-5K1/mKhWaMfreBGJTwval43JJmkip0RmM+3+IuqupeSKNC/Th2Kc7ucaq5ovTSra/OOKB9c58CGSz3QMVbWt0A==", "dev": true, "license": "MIT", "engines": { @@ -3692,6 +3316,61 @@ "@opentelemetry/api": "^1.3.0" } }, + "node_modules/@protobuf-ts/plugin": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/@protobuf-ts/plugin/-/plugin-2.11.1.tgz", + "integrity": "sha512-HyuprDcw0bEEJqkOWe1rnXUP0gwYLij8YhPuZyZk6cJbIgc/Q0IFgoHQxOXNIXAcXM4Sbehh6kjVnCzasElw1A==", + "license": "Apache-2.0", + "dependencies": { + "@bufbuild/protobuf": "^2.4.0", + "@bufbuild/protoplugin": "^2.4.0", + "@protobuf-ts/protoc": "^2.11.1", + "@protobuf-ts/runtime": "^2.11.1", + "@protobuf-ts/runtime-rpc": "^2.11.1", + "typescript": "^3.9" + }, + "bin": { + "protoc-gen-dump": "bin/protoc-gen-dump", + "protoc-gen-ts": "bin/protoc-gen-ts" + } + }, + "node_modules/@protobuf-ts/plugin/node_modules/typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/@protobuf-ts/protoc": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/@protobuf-ts/protoc/-/protoc-2.11.1.tgz", + "integrity": "sha512-mUZJaV0daGO6HUX90o/atzQ6A7bbN2RSuHtdwo8SSF2Qoe3zHwa4IHyCN1evftTeHfLmdz+45qo47sL+5P8nyg==", + "license": "Apache-2.0", + "bin": { + "protoc": "protoc.js" + } + }, + "node_modules/@protobuf-ts/runtime": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/@protobuf-ts/runtime/-/runtime-2.11.1.tgz", + "integrity": "sha512-KuDaT1IfHkugM2pyz+FwiY80ejWrkH1pAtOBOZFuR6SXEFTsnb/jiQWQ1rCIrcKx2BtyxnxW6BWwsVSA/Ie+WQ==", + "license": "(Apache-2.0 AND BSD-3-Clause)" + }, + "node_modules/@protobuf-ts/runtime-rpc": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/@protobuf-ts/runtime-rpc/-/runtime-rpc-2.11.1.tgz", + "integrity": "sha512-4CqqUmNA+/uMz00+d3CYKgElXO9VrEbucjnBFEjqI4GuDrEQ32MaI3q+9qPBvIGOlL4PmHXrzM32vBPWRhQKWQ==", + "license": "Apache-2.0", + "dependencies": { + "@protobuf-ts/runtime": "^2.11.1" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -5466,6 +5145,18 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript/vfs": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@typescript/vfs/-/vfs-1.6.1.tgz", + "integrity": "sha512-JwoxboBh7Oz1v38tPbkrZ62ZXNHAk9bJ7c9x0eI5zBfBnBYGhURdbnh7Z4smN/MV48Y5OCcZb58n972UtbazsA==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.1" + }, + "peerDependencies": { + "typescript": "*" + } + }, "node_modules/@u4/adbkit": { "version": "5.1.7", "resolved": "https://registry.npmjs.org/@u4/adbkit/-/adbkit-5.1.7.tgz", @@ -14501,9 +14192,9 @@ } }, "node_modules/ts-proto": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-2.7.5.tgz", - "integrity": "sha512-FoRxSaNW+P3m+GiXIZjUjhaHXT67Ah4zMGKzn4yklbGRQTS+PqpUhKo5AJnwfUDUByjEUG7ch36byFUYWRH9Nw==", + "version": "2.7.7", + "resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-2.7.7.tgz", + "integrity": "sha512-/OfN9/Yriji2bbpOysZ/Jzc96isOKz+eBTJEcKaIZ0PR6x1TNgVm4Lz0zfbo+J0jwFO7fJjJyssefBPQ0o1V9A==", "license": "ISC", "dependencies": { "@bufbuild/protobuf": "^2.0.0", @@ -14605,10 +14296,9 @@ } }, "node_modules/typescript": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", - "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", - "dev": true, + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index 44e205fe0b..250090d328 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "build:swagger:tests": "cd ./test/api && poetry run just regen-schema", "build:swagger:ui": "cd ./ui && npm run generate-api", "build:swagger": "cd ./lib/units/api && python3 ./gen_routes.py & npm run build:swagger:ui", + "protoc": "npx protoc --ts_out ./lib/wire --ts_opt generate_dependencies --proto_path ./lib/wire ./lib/wire/wire.proto", "build": "tsc", "dev": "tsx ./bin/devstf.mjs" }, @@ -44,6 +45,7 @@ "@irdk/usbmux": "^0.2.2", "@julusian/jpeg-turbo": "2.1.0", "@node-saml/passport-saml": "5.1.0", + "@protobuf-ts/plugin": "^2.11.1", "@sentry/node": "^8.34.0", "@types/chrome-remote-interface": "^0.31.14", "@u4/adbkit": "^5.1.7", @@ -119,7 +121,6 @@ "temp": "0.9.4", "tmp-promise": "^3.0.3", "transliteration": "2.2.0", - "ts-proto": "^2.6.1", "tsx": "4.20.3", "underscore.string": "3.3.6", "url-join": "1.1.0", @@ -134,7 +135,7 @@ }, "devDependencies": { "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.30.1", + "@eslint/js": "^9.33.0", "@playwright/test": "^1.52.0", "@types/bluebird": "^3.5.42", "@types/chalk": "^0.4.31", @@ -150,14 +151,14 @@ "async": "2.6.4", "cli-docs-generator": "1.0.7", "esbuild": "0.25.8", - "eslint": "9.30.1", + "eslint": "^9.30.1", "event-stream": "3.3.5", "exports-loader": "^4.0.0", "fs-extra": "8.1.0", "globals": "^15.11.0", "http-https": "1.0.0", "imports-loader": "^4.0.1", - "typescript": "^5.5.3", + "typescript": "^5.9.2", "typescript-eslint": "^8.39.1" }, "overrides": { @@ -189,4 +190,4 @@ "pre-commit": "true" } } -} +} \ No newline at end of file diff --git a/ui/src/store/device-connection.ts b/ui/src/store/device-connection.ts index d8060c09be..e14f1fe52c 100644 --- a/ui/src/store/device-connection.ts +++ b/ui/src/store/device-connection.ts @@ -30,9 +30,9 @@ export class DeviceConnection { async useDevice(): Promise { const device = await this.deviceBySerialStore.fetch() - if (!device?.channel) return - try { + if (!device?.channel) throw new Error('Device is not cooperating.') + const startRemoteConnectResult = await this.deviceControlStore.startRemoteConnect() startRemoteConnectResult.donePromise.then(({ data }) => { From 0fa7a73119ade19ebe433da9fdeefada65321306 Mon Sep 17 00:00:00 2001 From: Elmir Khalilov <52529096+e-khalilov@users.noreply.github.com> Date: Fri, 12 Sep 2025 21:19:41 +0300 Subject: [PATCH 02/13] hotfix (#361) Co-authored-by: e.khalilov --- lib/units/device/plugins/service.ts | 30 +++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/units/device/plugins/service.ts b/lib/units/device/plugins/service.ts index 7971808d8c..5a6d5bcafe 100644 --- a/lib/units/device/plugins/service.ts +++ b/lib/units/device/plugins/service.ts @@ -16,6 +16,15 @@ import service from '../resources/service.js' import {Duplex} from 'node:stream' import EventEmitter from 'events' import {GRPC_WAIT_TIMEOUT} from '../../../util/apiutil.js' +import { + PhysicalIdentifyMessage, + KeyDownMessage, + KeyUpMessage, + KeyPressMessage, + TypeMessage, + RotateMessage, + UnlockDeviceMessage +} from "../../../wire/wire.js"; interface Service { socket: Duplex | null @@ -230,7 +239,6 @@ export default syrup.serial() getDisplay = (id: string) => runServiceCommand(apk.wire.MessageType.GET_DISPLAY, new apk.wire.GetDisplayRequest(id)) .then((data) => { - log.info('DISPLAY RESPONSE !') const response = apk.wire.GetDisplayResponse.decode(data) if (response.success) { return { @@ -367,8 +375,10 @@ export default syrup.serial() } const mapped = response.properties.reduce( - (acc: any, property: any) => - acc[property.name] = property.value, {} + (acc: any, property: any) => { + acc[property.name] = property.value + return acc + }, {} ) if (mapped.imei) { return mapped @@ -636,14 +646,14 @@ export default syrup.serial() await openService() router - .on(wire.PhysicalIdentifyMessage, (channel) => { + .on(PhysicalIdentifyMessage, (channel) => { plugin.identity() push.send([ channel, wireutil.reply(options.serial).okay() ]) }) - .on(wire.KeyDownMessage, (channel, message) => { + .on(KeyDownMessage, (channel, message) => { try { keyEvent({ event: apk.wire.KeyEvent.DOWN, @@ -654,7 +664,7 @@ export default syrup.serial() log.warn(e.message) } }) - .on(wire.KeyUpMessage, (channel, message) => { + .on(KeyUpMessage, (channel, message) => { try { keyEvent({ event: apk.wire.KeyEvent.UP, @@ -665,7 +675,7 @@ export default syrup.serial() log.warn(e.message) } }) - .on(wire.KeyPressMessage, (channel, message) => { + .on(KeyPressMessage, (channel, message) => { try { keyEvent({ event: apk.wire.KeyEvent.PRESS, @@ -676,13 +686,13 @@ export default syrup.serial() log.warn(e.message) } }) - .on(wire.TypeMessage, (channel, message) => + .on(TypeMessage, (channel, message) => plugin.type(message.text) ) - .on(wire.RotateMessage, (channel, message) => + .on(RotateMessage, (channel, message) => plugin.rotate(message.rotation) ) - .on(wire.UnlockDeviceMessage, (channel, message) => + .on(UnlockDeviceMessage, (channel, message) => plugin.unlockDevice() ) return plugin From af9350ec83647521cd9f74ced033b0cd1e75a5ad Mon Sep 17 00:00:00 2001 From: Elmir Khalilov <52529096+e-khalilov@users.noreply.github.com> Date: Tue, 23 Sep 2025 16:02:53 +0300 Subject: [PATCH 03/13] Remove all DB connections from device side (#368) * hotfix imei * Decrease apt install list in dockerfile (#365) * remove gm and jdk11 * remove libs * Remove console-feed & react dependencies [backend only] (#366) * remove dep console-feed * minor fix * linter fix --------- Co-authored-by: e.khalilov * fix default quotas hierarchy QA-19255 (#367) * -fix quotas -fix lock -fix test -fix lint * -fix test --------- Co-authored-by: a.chistov * dev units without db conn * fix types * minor fix * minor fix * minor fix * remove useless sockets --------- Co-authored-by: Maksim Alzhanov Co-authored-by: Maxim Co-authored-by: Daniil <8039921+DaniilSmirnov@users.noreply.github.com> Co-authored-by: e.khalilov Co-authored-by: Alexey Chistov <33050834+Alk2017@users.noreply.github.com> Co-authored-by: a.chistov --- Dockerfile | 6 - docker-compose-macos.yaml | 8 +- docker-compose-prod.yaml | 6 +- lib/cli/doctor/index.js | 8 - lib/cli/groups-engine/index.js | 14 - lib/cli/local/index.js | 8 +- lib/cli/processor/index.js | 28 - lib/db/index.ts | 95 ++- lib/db/models/all/model.js | 103 +-- lib/units/api/controllers/user.js | 19 +- lib/units/api/controllers/users.js | 10 +- lib/units/api/helpers/useDevice.js | 5 +- lib/units/base-device/plugins/group.js | 156 ----- lib/units/base-device/plugins/group.ts | 252 ++++++++ .../device/plugins/{connect.js => connect.ts} | 119 ++-- lib/units/device/plugins/group.js | 214 ------- lib/units/device/plugins/group.ts | 96 +++ lib/units/device/plugins/service.ts | 2 +- lib/units/groups-engine/index.js | 6 +- lib/units/groups-engine/watchers/devices.js | 2 +- lib/units/ios-device/plugins/info/index.js | 3 + lib/units/ios-device/plugins/wda/client.js | 49 +- lib/units/processor/{index.js => index.ts} | 227 ++++--- lib/units/provider/ADBObserver.ts | 18 +- lib/units/provider/index.ts | 6 +- lib/units/reaper/index.js | 109 ---- lib/units/reaper/index.ts | 120 ++++ lib/units/tizen-device/plugins/launcher.js | 2 +- .../plugins/webinspector/Replicator.ts | 588 ++++++++++++++++++ .../index.ts} | 111 ++-- .../plugins/webinspector/transform/BigInt.ts | 23 + .../webinspector/transform/Function.ts | 85 +++ .../plugins/webinspector/transform/HTML.ts | 93 +++ .../plugins/webinspector/transform/Map.ts | 59 ++ .../webinspector/transform/arithmetic.ts | 48 ++ .../plugins/webinspector/transform/index.ts | 17 + lib/units/websocket/index.js | 13 +- lib/util/grouputil.js | 60 -- lib/util/grouputil.ts | 67 ++ lib/util/lifecycle.js | 0 lib/util/ttlset.js | 94 --- lib/util/ttlset.ts | 113 ++++ lib/wire/router.ts | 2 +- lib/wire/transmanager.js | 58 -- lib/wire/transmanager.ts | 122 ++++ lib/wire/wire.proto | 16 +- lib/wire/wire.ts | 209 ++++++- package-lock.json | 381 +----------- package.json | 2 +- test/api/conftest.py | 18 + .../users/test_user_lifecycle_management.py | 8 +- tsconfig.json | 5 +- 52 files changed, 2354 insertions(+), 1529 deletions(-) create mode 100755 lib/units/base-device/plugins/group.ts rename lib/units/device/plugins/{connect.js => connect.ts} (54%) create mode 100644 lib/units/device/plugins/group.ts rename lib/units/processor/{index.js => index.ts} (57%) delete mode 100644 lib/units/reaper/index.js create mode 100644 lib/units/reaper/index.ts create mode 100644 lib/units/tizen-device/plugins/webinspector/Replicator.ts rename lib/units/tizen-device/plugins/{webinspector.js => webinspector/index.ts} (67%) create mode 100644 lib/units/tizen-device/plugins/webinspector/transform/BigInt.ts create mode 100644 lib/units/tizen-device/plugins/webinspector/transform/Function.ts create mode 100644 lib/units/tizen-device/plugins/webinspector/transform/HTML.ts create mode 100644 lib/units/tizen-device/plugins/webinspector/transform/Map.ts create mode 100644 lib/units/tizen-device/plugins/webinspector/transform/arithmetic.ts create mode 100644 lib/units/tizen-device/plugins/webinspector/transform/index.ts delete mode 100644 lib/util/grouputil.js create mode 100644 lib/util/grouputil.ts create mode 100644 lib/util/lifecycle.js delete mode 100644 lib/util/ttlset.js create mode 100644 lib/util/ttlset.ts delete mode 100644 lib/wire/transmanager.js create mode 100644 lib/wire/transmanager.ts diff --git a/Dockerfile b/Dockerfile index 468f7ee0b3..eac6f90dca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,13 +5,7 @@ WORKDIR /app RUN apt-get update && apt-get install -y \ python3 \ - build-essential \ git \ - graphicsmagick \ - openjdk-11-jdk \ - yasm \ - libzmq3-dev \ - libprotobuf-dev \ && rm -rf /var/lib/apt/lists/* COPY . . diff --git a/docker-compose-macos.yaml b/docker-compose-macos.yaml index 7bf9ca00b1..f61f37477b 100644 --- a/docker-compose-macos.yaml +++ b/docker-compose-macos.yaml @@ -108,7 +108,7 @@ services: container_name: devicehub-processor env_file: - scripts/variables.env - command: stf processor --name processor --connect-app-dealer tcp://devicehub-triproxy-app:7160 --connect-dev-dealer tcp://devicehub-triproxy-dev:7260 --connect-sub tcp://devicehub-triproxy-app:7150 --connect-push tcp://devicehub-triproxy-app:7170 --connect-sub-dev tcp://devicehub-triproxy-dev:7250 --connect-push-dev tcp://devicehub-triproxy-dev:7270 + command: stf processor --name processor --connect-app-dealer tcp://devicehub-triproxy-app:7160 --connect-dev-dealer tcp://devicehub-triproxy-dev:7260 depends_on: devicehub-migrate: condition: service_completed_successfully @@ -121,7 +121,7 @@ services: container_name: devicehub-reaper env_file: - scripts/variables.env - command: stf reaper --name reaper001 --connect-push tcp://devicehub-triproxy-dev:7270 --connect-sub tcp://devicehub-triproxy-app:7150 --heartbeat-timeout 30000 + command: stf reaper --name reaper001 --connect-push tcp://devicehub-triproxy-dev:7270 --connect-sub tcp://devicehub-triproxy-dev:7250 --heartbeat-timeout 30000 depends_on: devicehub-migrate: condition: service_completed_successfully @@ -233,7 +233,7 @@ services: container_name: devicehub-api-groups-engine env_file: - scripts/variables.env - command: stf groups-engine --connect-sub tcp://devicehub-triproxy-app:7150 --connect-push tcp://devicehub-triproxy-app:7170 --connect-sub-dev tcp://devicehub-triproxy-dev:7250 --connect-push-dev tcp://devicehub-triproxy-dev:7270 + command: stf groups-engine --connect-push tcp://devicehub-triproxy-app:7170 --connect-push-dev tcp://devicehub-triproxy-dev:7270 depends_on: devicehub-migrate: condition: service_completed_successfully @@ -263,4 +263,4 @@ services: - certs:/certs:rw volumes: devicehub-db-volume: - certs: \ No newline at end of file + certs: diff --git a/docker-compose-prod.yaml b/docker-compose-prod.yaml index 0f3dd25b53..acdd35dc65 100644 --- a/docker-compose-prod.yaml +++ b/docker-compose-prod.yaml @@ -124,7 +124,7 @@ services: container_name: devicehub-processor env_file: - scripts/variables.env - command: stf processor --name processor --connect-app-dealer tcp://devicehub-triproxy-app:7160 --connect-dev-dealer tcp://devicehub-triproxy-dev:7260 --connect-sub tcp://devicehub-triproxy-app:7150 --connect-push tcp://devicehub-triproxy-app:7170 --connect-sub-dev tcp://devicehub-triproxy-dev:7250 --connect-push-dev tcp://devicehub-triproxy-dev:7270 + command: stf processor --name processor --connect-app-dealer tcp://devicehub-triproxy-app:7160 --connect-dev-dealer tcp://devicehub-triproxy-dev:7260 depends_on: devicehub-migrate: condition: service_completed_successfully @@ -137,7 +137,7 @@ services: container_name: devicehub-reaper env_file: - scripts/variables.env - command: stf reaper --name reaper001 --connect-push tcp://devicehub-triproxy-dev:7270 --connect-sub tcp://devicehub-triproxy-app:7150 --heartbeat-timeout 30000 + command: stf reaper --name reaper001 --connect-push tcp://devicehub-triproxy-dev:7270 --connect-sub tcp://devicehub-triproxy-dev:7250 --heartbeat-timeout 30000 depends_on: devicehub-migrate: condition: service_completed_successfully @@ -249,7 +249,7 @@ services: container_name: devicehub-api-groups-engine env_file: - scripts/variables.env - command: stf groups-engine --connect-sub tcp://devicehub-triproxy-app:7150 --connect-push tcp://devicehub-triproxy-app:7170 --connect-sub-dev tcp://devicehub-triproxy-dev:7250 --connect-push-dev tcp://devicehub-triproxy-dev:7270 + command: stf groups-engine --connect-push tcp://devicehub-triproxy-app:7170 --connect-push-dev tcp://devicehub-triproxy-dev:7270 depends_on: devicehub-migrate: condition: service_completed_successfully diff --git a/lib/cli/doctor/index.js b/lib/cli/doctor/index.js index 11c35c1412..f698d2bc13 100644 --- a/lib/cli/doctor/index.js +++ b/lib/cli/doctor/index.js @@ -111,13 +111,6 @@ export const handler = function() { return checker.version(pkg.externalDependencies.monogdb)(pkg.dependencies.mongodb) }) } - function checkGraphicsMagick() { - return check('GraphicsMagick', function(checker) { - return checker.call('gm', ['-version']) - .then(checker.extract('version', /GraphicsMagick ([^\s]+)/)) - .then(checker.version(pkg.externalDependencies.gm)) - }) - } function checkZeroMQ() { return check('ZeroMQ', function(checker) { return checker.version(pkg.externalDependencies.zeromq)(zmq.version) @@ -143,7 +136,6 @@ export const handler = function() { checkOSRelease(), checkNodeVersion(), checkLocalMongoDBVersion(), - checkGraphicsMagick(), checkZeroMQ(), checkProtoBuf(), checkADB() diff --git a/lib/cli/groups-engine/index.js b/lib/cli/groups-engine/index.js index 62abfefb87..e523713502 100644 --- a/lib/cli/groups-engine/index.js +++ b/lib/cli/groups-engine/index.js @@ -11,24 +11,12 @@ export const builder = function(yargs) { array: true, demand: true }) - .option('connect-sub', { - alias: 'u', - describe: 'App-side ZeroMQ PUB endpoint to connect to.', - array: true, - demand: true - }) .option('connect-push-dev', { alias: 'pd', describe: 'Device-side ZeroMQ PULL endpoint to connect to.', array: true, demand: true }) - .option('connect-sub-dev', { - alias: 'sd', - describe: 'Device-side ZeroMQ PUB endpoint to connect to.', - array: true, - demand: true - }) .epilog('Each option can be be overwritten with an environment variable ' + 'by converting the option to uppercase, replacing dashes with ' + 'underscores and prefixing it with `STF_GROUPS_ENGINE_` .)') @@ -37,9 +25,7 @@ export const handler = function(argv) { return groupsEngine({ endpoints: { push: argv.connectPush, - sub: argv.connectSub, pushdev: argv.connectPushDev, - subdev: argv.connectSubDev } }) } diff --git a/lib/cli/local/index.js b/lib/cli/local/index.js index 6fb69c93a4..5acc202e36 100644 --- a/lib/cli/local/index.js +++ b/lib/cli/local/index.js @@ -338,16 +338,12 @@ export const handler = function(argv) { 'processor', 'proc001', '--connect-app-dealer', argv.bindAppDealer, '--connect-dev-dealer', argv.bindDevDealer, - '--connect-push', argv.bindAppPull, - '--connect-push-dev', argv.bindDevPull, - '--connect-sub', argv.bindAppPub, - '--connect-sub-dev', argv.bindDevPub, '--public-ip', argv.publicIp ], [ // reaper one 'reaper', 'reaper001', '--connect-push', argv.bindDevPull, - '--connect-sub', argv.bindAppPub + '--connect-sub', argv.bindDevPub ], [ // provider 'provider', @@ -412,9 +408,7 @@ export const handler = function(argv) { [ // groups engine 'groups-engine', '--connect-push', argv.bindAppPull, - '--connect-sub', argv.bindAppPub, '--connect-push-dev', argv.bindDevPull, - '--connect-sub-dev', argv.bindDevPub ], [ // websocket 'websocket', diff --git a/lib/cli/processor/index.js b/lib/cli/processor/index.js index 5092bc1ba5..a420e9e587 100644 --- a/lib/cli/processor/index.js +++ b/lib/cli/processor/index.js @@ -18,30 +18,6 @@ export const builder = function(yargs) { array: true, demand: true }) - .option('connect-push', { - alias: 'c', - describe: 'App-side ZeroMQ PULL endpoint to connect to.', - array: true, - demand: true - }) - .option('connect-push-dev', { - alias: 'pd', - describe: 'Device-side ZeroMQ PULL endpoint to connect to.', - array: true, - demand: true - }) - .option('connect-sub', { - alias: 'u', - describe: 'App-side ZeroMQ PUB endpoint to connect to.', - array: true, - demand: true - }) - .option('connect-sub-dev', { - alias: 'sd', - describe: 'Device-side ZeroMQ PUB endpoint to connect to.', - array: true, - demand: true - }) .option('name', { describe: 'An easily identifiable name for log output.', type: 'string', @@ -64,10 +40,6 @@ export const handler = function(argv) { endpoints: { appDealer: argv.connectAppDealer, devDealer: argv.connectDevDealer, - push: argv.connectPush, - pushdev: argv.connectPushDev, - sub: argv.connectSub, - subdev: argv.connectSubDev }, publicIp: argv.publicIp }) diff --git a/lib/db/index.ts b/lib/db/index.ts index a4964c96d0..2928f5abab 100644 --- a/lib/db/index.ts +++ b/lib/db/index.ts @@ -117,21 +117,18 @@ export default class DbClient { pushdev, channelRouter, }: { - sub: SocketWrapper | string[]; - subdev: SocketWrapper | string[]; + sub?: SocketWrapper | string[]; + subdev?: SocketWrapper | string[]; push: SocketWrapper | string[]; pushdev: SocketWrapper | string[]; channelRouter?: EventEmitter; }, _log: ReturnType | undefined = log - ): Promise<{ - sub: SocketWrapper; - subdev: SocketWrapper; - push: SocketWrapper; - pushdev: SocketWrapper; - channelRouter: EventEmitter; - }> { - if (Array.isArray(sub)) { + ) { + let finalSub: SocketWrapper | undefined + let finalSubdev: SocketWrapper | undefined + + if (sub && Array.isArray(sub)) { const _sub = zmqutil.socket('sub') await Promise.all( sub.map(async(endpoint) => { @@ -153,10 +150,13 @@ export default class DbClient { } }) ) - sub = _sub + finalSub = _sub + } + else if (sub) { + finalSub = sub as SocketWrapper } - if (Array.isArray(subdev)) { + if (subdev && Array.isArray(subdev)) { const _subdev = zmqutil.socket('sub') await Promise.all( subdev.map(async(endpoint) => { @@ -178,12 +178,15 @@ export default class DbClient { } }) ) - subdev = _subdev + finalSubdev = _subdev + } + else if (subdev) { + finalSubdev = subdev as SocketWrapper } if (Array.isArray(push)) { const _push = zmqutil.socket('push') - Promise.all( + await Promise.all( push.map(async(endpoint) => { try { srv.attempt( @@ -205,7 +208,7 @@ export default class DbClient { if (Array.isArray(pushdev)) { const _pushdev = zmqutil.socket('push') - Promise.all( + await Promise.all( pushdev.map(async(endpoint) => { try { srv.attempt( @@ -229,23 +232,48 @@ export default class DbClient { } if (!channelRouter) { - channelRouter = new EventEmitter(); - [wireutil.global].forEach((channel) => { - _log.info('Subscribing to permanent channel "%s"', channel) - sub.subscribe(channel) - subdev.subscribe(channel) - }) + channelRouter = new EventEmitter() - sub.on('message', (channel, data) => { - channelRouter?.emit(channel.toString(), channel, data) - }) + if (finalSub || finalSubdev) { + ;[wireutil.global].forEach((channel) => { + _log.info('Subscribing to permanent channel "%s"', channel) + if (finalSub) { + finalSub.subscribe(channel) + } + if (finalSubdev) { + finalSubdev.subscribe(channel) + } + }) + + if (finalSub) { + finalSub.on('message', (channel, data) => { + channelRouter?.emit(channel.toString(), channel, data) + }) + } - subdev.on('message', (channel, data) => { - channelRouter?.emit(channel.toString(), channel, data) - }) + if (finalSubdev) { + finalSubdev.on('message', (channel, data) => { + channelRouter?.emit(channel.toString(), channel, data) + }) + } + } } - return {sub, subdev, push, pushdev, channelRouter} + const result: { + sub?: SocketWrapper; + subdev?: SocketWrapper; + push: SocketWrapper; + pushdev: SocketWrapper; + channelRouter: EventEmitter; + } = { + push, + pushdev, + channelRouter, + ... !!finalSub && {sub: finalSub}, + ... !!finalSubdev && {subdev: finalSubdev} + } + + return result } // Verifies that we can form a connection. Useful if it's necessary to make @@ -254,11 +282,12 @@ export default class DbClient { // an issue with the processor unit, as it started processing messages before // it was actually truly able to save anything to the database. This lead to // lost messages in certain situations. - static ensureConnectivity = async (fn: T) => { - await DbClient.connect() - log.info("Db is up") - return fn - } + static ensureConnectivity = any>(fn: T) => + async(...args: Parameters): Promise> => { + await DbClient.connect(); + log.info("Db is up"); + return fn(...args); + } // Sets up the database static setup = () => DbClient.connect().then((conn) => _setup(conn)) diff --git a/lib/db/models/all/model.js b/lib/db/models/all/model.js index fb15bb75ce..4cb3b46f63 100644 --- a/lib/db/models/all/model.js +++ b/lib/db/models/all/model.js @@ -84,10 +84,10 @@ export const createBootStrap = function(env) { 'groups.quotas.allocated.duration': group?.envUserGroupsDuration, 'groups.quotas.consumed.duration': 0, 'groups.quotas.consumed.number': 0, - 'groups.defaultGroupsNumber': user?.email !== group?.owner.email ? 0 : group?.envUserGroupsNumber, - 'groups.defaultGroupsDuration': user?.email !== group?.owner.email ? 0 : group?.envUserGroupsDuration, - 'groups.defaultGroupsRepetitions': user?.email !== group?.owner.email ? 0 : group?.envUserGroupsRepetitions, - 'groups.repetitions': group?.envUserGroupsRepetitions + 'groups.quotas.defaultGroupsNumber': user?.email !== group?.owner.email ? 0 : group?.envUserGroupsNumber, + 'groups.quotas.defaultGroupsDuration': user?.email !== group?.owner.email ? 0 : group?.envUserGroupsDuration, + 'groups.quotas.defaultGroupsRepetitions': user?.email !== group?.owner.email ? 0 : group?.envUserGroupsRepetitions, + 'groups.quotas.repetitions': group?.envUserGroupsRepetitions } await db.users.updateOne( @@ -178,11 +178,6 @@ export const createBootStrap = function(env) { }) } -// dbapi.deleteDevice = function(serial) { -export const deleteDevice = function(serial) { - return db.devices.deleteOne({serial: serial}) -} - export const deleteUser = function(email) { return db.users.deleteOne({email: email}) } @@ -425,17 +420,17 @@ export const createUser = function(email, name, ip, privilege) { lock: false, quotas: { allocated: { - number: group?.envUserGroupsNumber, - duration: group?.envUserGroupsDuration + number: adminUser ? adminUser.groups.quotas.defaultGroupsNumber : group?.envUserGroupsNumber, + duration: adminUser ? adminUser.groups.quotas.defaultGroupsDuration : group?.envUserGroupsDuration }, consumed: { number: 0, duration: 0 }, - defaultGroupsNumber: group?.envUserGroupsNumber, - defaultGroupsDuration: group?.envUserGroupsDuration, - defaultGroupsRepetitions: group?.envUserGroupsRepetitions, - repetitions: group?.envUserGroupsRepetitions + defaultGroupsNumber: adminUser ? 0 : group?.envUserGroupsNumber, + defaultGroupsDuration: adminUser ? 0 : group?.envUserGroupsDuration, + defaultGroupsRepetitions: adminUser ? 0 : group?.envUserGroupsRepetitions, + repetitions: adminUser ? adminUser.groups.quotas.defaultGroupsRepetitions : group?.envUserGroupsRepetitions } } } @@ -533,6 +528,11 @@ export const resetUserSettings = function(email) { }) } +export const getUserAdbKeys = function(email) { + return db.users.findOne({email: email}) + .then(user => user?.adbKeys || []) +} + // dbapi.insertUserAdbKey = function(email, key) { export const insertUserAdbKey = function(email, key) { let data = { @@ -824,6 +824,8 @@ export const setDeviceAbsent = function(serial) { { $set: { owner: null, + usage: null, + logs_enabled: false, present: false, presenceChangedAt: getNow() } @@ -832,27 +834,22 @@ export const setDeviceAbsent = function(serial) { } // dbapi.setDeviceUsage = function(serial, usage) { -export const setDeviceUsage = function(serial, usage) { - return db.devices.updateOne( - {serial: serial}, - { - $set: { - usage: usage, - usageChangedAt: getNow() - } - } - ) -} +export const setDeviceState = function(serial, {usage, owner, timeout}) { + const usageSet = typeof usage === 'undefined' ? {} : { + usage, usageChangedAt: getNow(), + ... !usage && {logs_enabled: false} + } -// dbapi.unsetDeviceUsage = function(serial) { -export const unsetDeviceUsage = function(serial) { return db.devices.updateOne( {serial: serial}, { $set: { - usage: null, - usageChangedAt: getNow(), - logs_enabled: false + owner, + ...usageSet, + ... typeof timeout === 'number' && { + statusChangedAt: getNow(), + bookedBefore: timeout + }, } } ) @@ -1449,29 +1446,6 @@ export const generateIndexes = function() { }) } -// dbapi.setDeviceSocketDisplay = function(data) { -export const setDeviceSocketDisplay = function(data) { - return db.devices.updateOne( - {serial: data.serial}, - { - $set: { - 'display.density': 2, - 'display.fps': 60, - 'display.id': 0, - 'display.rotation': 0, - 'display.secure': true, - 'display.size': 4.971253395080566, - 'display.xdpi': 294.9670104980469, - 'display.ydpi': 295.56298828125, - 'display.width': data.width, - 'display.height': data.height - } - } - ).then(() => { - loadDeviceBySerial(data.serial) - }) -} - // dbapi.setDeviceSocketPorts = function(data, publicIp) { export const setDeviceSocketPorts = function(data, publicIp) { return db.devices.updateOne( @@ -1543,21 +1517,6 @@ export const getDeviceDisplaySize = function(serial) { }) } -// TODO Check usage. Probably dead code -export const setAbsentDisconnectedDevices = function() { - return db.devices.updateOne( - { - platform: 'iOS' - }, - { - $set: { - present: false, - ready: false - } - } - ) -} - // dbapi.getInstalledApplications = function(message) { export const getInstalledApplications = function(message) { return loadDeviceBySerial(message.serial) @@ -1742,7 +1701,7 @@ export const updateDefaultUserGroupsQuotas = async(email, duration, number, repe {email: email} , [{ $set: { - defaultGroupsDuration: { + 'groups.quotas.defaultGroupsDuration': { $cond: [ { $ne: [duration, null] @@ -1751,7 +1710,7 @@ export const updateDefaultUserGroupsQuotas = async(email, duration, number, repe '$groups.quotas.defaultGroupsDuration' ] }, - defaultGroupsNumber: { + 'groups.quotas.defaultGroupsNumber': { $cond: [ { $ne: [number, null] @@ -1760,7 +1719,7 @@ export const updateDefaultUserGroupsQuotas = async(email, duration, number, repe '$groups.quotas.defaultGroupsNumber' ] }, - defaultGroupsRepetitions: { + 'groups.quotas.defaultGroupsRepetitions': { $cond: [ { $ne: [repetitions, null] diff --git a/lib/units/api/controllers/user.js b/lib/units/api/controllers/user.js index 6d1c7dd080..8aef72fb95 100644 --- a/lib/units/api/controllers/user.js +++ b/lib/units/api/controllers/user.js @@ -149,12 +149,19 @@ function addUserDevice(req, res) { let usage = 'automation' req.options.push.send([ device.channel, - wireutil.envelope(new wire.GroupMessage(new wire.OwnerMessage(req.user.email, req.user.name, req.user.group), timeout, wireutil.toDeviceRequirements({ - serial: { - value: serial, - match: 'exact' - } - }), usage)) + wireutil.envelope(new wire.GroupMessage( + new wire.OwnerMessage(req.user.email, req.user.name, req.user.group), + timeout, + wireutil.toDeviceRequirements({ + serial: { + value: serial, + match: 'exact' + } + }), + usage, + req.user.adbKeys + .map(key => key.fingerprint) + )) ]) } return false diff --git a/lib/units/api/controllers/users.js b/lib/units/api/controllers/users.js index a0f41a9bf2..7eff6be078 100644 --- a/lib/units/api/controllers/users.js +++ b/lib/units/api/controllers/users.js @@ -142,14 +142,12 @@ function revokeAdmin(req, res) { }) } function lockStfAdminUser(res) { - const lock = {} - dbapi.lockUser(apiutil.STF_ADMIN_EMAIL).then(function(stats) { + return dbapi.lockUser(apiutil.STF_ADMIN_EMAIL).then(function(stats) { if (stats.modifiedCount === 0) { return apiutil.lightComputeStats(res, stats) } - lock.user = stats.changes[0].new_val + return {user: stats.changes[0].new_val} }) - return lock } function updateUsersAlertMessage(req, res) { if (req.user.privilege !== apiutil.ADMIN) { @@ -191,9 +189,9 @@ function getUserInfo(req, email) { } function getUsersAlertMessage(req, res) { const fields = req.query.fields - return dbapi.loadUser(apiutil.STF_ADMIN_EMAIL).then(function(user) { + return dbapi.loadUser(apiutil.STF_ADMIN_EMAIL).then(async function(user) { if (user?.settings?.alertMessage === undefined) { - const lock = lockStfAdminUser(res) + const lock = await lockStfAdminUser(res) const alertMessage = { activation: 'False', data: '*** this site is currently under maintenance, please wait ***', diff --git a/lib/units/api/helpers/useDevice.js b/lib/units/api/helpers/useDevice.js index 41e10af9b5..93c3a267a7 100644 --- a/lib/units/api/helpers/useDevice.js +++ b/lib/units/api/helpers/useDevice.js @@ -52,8 +52,8 @@ const useDevice = ({user, device, channelRouter, push, sub, usage = null, log}) try { await runTransaction(device.channel, new wire.UngroupMessage(deviceRequirements), {sub, push, channelRouter}) } - catch (e) { - log?.info(e) + catch (/** @type {any} */e) { + log?.info('Transaction failed: $s', e?.message) } const responseTimeout = setTimeout(function() { @@ -107,6 +107,7 @@ const useDevice = ({user, device, channelRouter, push, sub, usage = null, log}) , timeout , deviceRequirements , usage + , user.adbKeys.map((/** @type {{ fingerprint: string }} */ k) => k.fingerprint) ), {sub, push, channelRouter}) }) diff --git a/lib/units/base-device/plugins/group.js b/lib/units/base-device/plugins/group.js index d01d8a6012..e69de29bb2 100755 --- a/lib/units/base-device/plugins/group.js +++ b/lib/units/base-device/plugins/group.js @@ -1,156 +0,0 @@ -import events from 'events' -import Promise from 'bluebird' -import syrup from '@devicefarmer/stf-syrup' -import logger from '../../../util/logger.js' -import wire from '../../../wire/index.js' -import wireutil from '../../../wire/util.js' -import * as grouputil from '../../../util/grouputil.js' -import lifecycle from '../../../util/lifecycle.js' -import db from '../../../db/index.js' -import dbapi from '../../../db/api.js' -import * as apiutil from '../../../util/apiutil.js' -import solo from './solo.js' -import router from '../support/router.js' -import push from '../support/push.js' -import sub from '../support/sub.js' -import channels from '../support/channels.js' -import {AutoGroupMessage, GroupMessage, UngroupMessage} from '../../../wire/wire.js' -export default syrup.serial() - .dependency(solo) - .dependency(router) - .dependency(push) - .dependency(sub) - .dependency(channels) - .define(async(options, solo, router, push, sub, channels) => { - const log = logger.createLogger('base-device:plugins:group') - let currentGroup = null - - /** @type {any} */ - let plugin = new events.EventEmitter() - - await db.connect() - - plugin.get = Promise.method(function() { - if (!currentGroup) { - throw new grouputil.NoGroupError() - } - return currentGroup - }) - plugin.join = (newGroup, timeout, usage) => { - return plugin.get() - .then(() => { - if (currentGroup.group !== newGroup.group) { - throw new grouputil.AlreadyGroupedError() - } - log.info('Update timeout for ', apiutil.QUARTER_MINUTES) - channels.updateTimeout(currentGroup.group, apiutil.QUARTER_MINUTES) - let newTimeout = channels.getTimeout(currentGroup.group) - plugin.emit('join', currentGroup) - dbapi.enhanceStatusChangedAt(options.serial, newTimeout).then(() => { - return currentGroup - }) - }) - .catch(grouputil.NoGroupError, () => { - currentGroup = newGroup - log.important('Now owned by "%s"', currentGroup.email) - log.important('Device now in group "%s"', currentGroup.name) - log.info('Rent time is ' + timeout) - log.info('Subscribing to group channel "%s"', currentGroup.group) - channels.register(currentGroup.group, { - timeout: timeout || options.groupTimeout, - alias: solo.channel - }) - dbapi.enhanceStatusChangedAt(options.serial, timeout) - sub.subscribe(currentGroup.group) - push.send([ - wireutil.global, - wireutil.envelope(new wire.JoinGroupMessage(options.serial, currentGroup, usage)) - ]) - plugin.emit('join', currentGroup) - return currentGroup - }) - } - plugin.keepalive = () => { - if (currentGroup) { - channels.keepalive(currentGroup.group) - } - } - plugin.leave = (reason) => { - return plugin.get() - .then(group => { - log.important('No longer owned by "%s"', group.email) - log.info('Unsubscribing from group channel "%s"', group.group) - channels.unregister(group.group) - sub.unsubscribe(group.group) - push.send([ - wireutil.global, - wireutil.envelope(new wire.LeaveGroupMessage(options.serial, group, reason)) - ]) - currentGroup = null - plugin.emit('leave', group) - return group - }) - } - router - .on(GroupMessage, (channel, message) => { - let reply = wireutil.reply(options.serial) - // grouputil.match(ident, message.requirements) - plugin.join(message.owner, message.timeout, message.usage) - .then(() => { - push.send([ - channel, - reply.okay() - ]) - }) - .catch(grouputil.RequirementMismatchError, (err) => { - push.send([ - channel, - reply.fail(err.message) - ]) - }) - .catch(grouputil.AlreadyGroupedError, (err) => { - push.send([ - channel, - reply.fail(err.message) - ]) - }) - }) - .on(AutoGroupMessage, (channel, message) => { - return plugin.join(message.owner, message.timeout, message.identifier) - .then(() => { - plugin.emit('autojoin', message.identifier, true) - }) - .catch(grouputil.AlreadyGroupedError, () => { - plugin.emit('autojoin', message.identifier, false) - }) - }) - .on(UngroupMessage, (channel, message) => { - let reply = wireutil.reply(options.serial) - Promise.method(() => { - return plugin.leave('ungroup_request') - })() - .then(() => { - push.send([ - channel, - reply.okay() - ]) - }) - .catch(grouputil.NoGroupError, err => { - push.send([ - channel, - reply.fail(err.message) - ]) - }) - }) - // @ts-ignore - channels.on('timeout', channel => { - if (currentGroup && channel === currentGroup.group) { - plugin.leave('automatic_timeout') - } - }) - lifecycle.observe(() => { - return plugin.leave('device_absent') - .catch(grouputil.NoGroupError, () => true) - }) - return plugin - }) diff --git a/lib/units/base-device/plugins/group.ts b/lib/units/base-device/plugins/group.ts new file mode 100755 index 0000000000..1ffbd304ed --- /dev/null +++ b/lib/units/base-device/plugins/group.ts @@ -0,0 +1,252 @@ +import syrup from '@devicefarmer/stf-syrup' +import logger from '../../../util/logger.js' +import { + AutoGroupMessage, + DeviceStatusChange, + GroupMessage, + JoinGroupMessage, + LeaveGroupMessage, UngroupMessage +} from '../../../wire/wire.js' +import wireutil from '../../../wire/util.js' +import * as grouputil from '../../../util/grouputil.js' +import lifecycle from '../../../util/lifecycle.js' +import * as apiutil from '../../../util/apiutil.js' +import solo from './solo.js' +import router from '../support/router.js' +import push from '../support/push.js' +import sub from '../support/sub.js' +import channels from '../support/channels.js' +import EventEmitter from 'events' + +interface GroupState { + email: string + name: string + group: string +} + +type ADBKey = string +type Joined = boolean + +interface GroupEvents { + join: [GroupState, ADBKey[]] + leave: [GroupState | null] + autojoin: [ADBKey, Joined] +} + +export default syrup.serial() + .dependency(solo) + .dependency(router) + .dependency(push) + .dependency(sub) + .dependency(channels) + .define(async(options, solo, router, push, sub, channels) => { + const log = logger.createLogger('base-device:plugins:group') + + const plugin = new class GroupManager extends EventEmitter { + private currentGroup: GroupState | null = null + + keepalive = () => { + if (this.currentGroup) { + channels.keepalive(this.currentGroup.group) + } + } + + get = async() => { + if (!this.currentGroup) { + throw new grouputil.NoGroupError() + return + } + + return this.currentGroup + } + + join = async(newGroup: GroupState, timeout: number, usage: string, keys: string[]) => { + try { + if (!newGroup?.group) { + throw new Error(`New group is not valid: ${JSON.stringify(newGroup)}`) + } + + if (!!this.currentGroup?.group) { // if device in group + if (this.currentGroup.group !== newGroup.group) { // and is not same + log.error(`Cannot join group ${JSON.stringify(newGroup)} since this device is in group ${JSON.stringify(this.currentGroup)}`) + throw new grouputil.AlreadyGroupedError() + } + + log.info('Update timeout for %s', apiutil.QUARTER_MINUTES) + channels.updateTimeout(this.currentGroup.group, apiutil.QUARTER_MINUTES) + + const newTimeout = channels.getTimeout(this.currentGroup.group) + push.send([ + wireutil.global, + wireutil.pack(DeviceStatusChange, { + serial: options.serial, + timeout: newTimeout || undefined + }) + ]) + + return this.currentGroup + } + + this.currentGroup = newGroup + + log.important('Now owned by "%s"', this.currentGroup.email) + log.important('Device now in group "%s"', this.currentGroup.name) + log.info(`Rent time is ${timeout}`) + log.info('Subscribing to group channel "%s"', this.currentGroup.group) + + channels.register(this.currentGroup.group, { + timeout: timeout || options.groupTimeout, + alias: solo.channel + }) + + sub.subscribe(this.currentGroup.group) + plugin.emit('join', this.currentGroup, keys) + + push.send([ + wireutil.global, + wireutil.pack(JoinGroupMessage, { + serial: options.serial, + owner: this.currentGroup, + usage, + timeout + }) + ]) + + return this.currentGroup + } + catch (err: any) { + log.error(`Failed to join group ${JSON.stringify(newGroup)}, Error: %s`, err?.message) + return this.currentGroup + } + } + + leave = async(reason: string) => { + if (!this.currentGroup) { + throw new grouputil.NoGroupError() + } + + log.important('No longer owned by "%s"', this.currentGroup.email) + log.info('Unsubscribing from group channel "%s"', this.currentGroup.group) + + push.send([ + wireutil.global, + wireutil.pack(LeaveGroupMessage, { + serial: options.serial, + owner: this.currentGroup, + reason + }) + ]) + + channels.unregister(this.currentGroup.group) + sub.unsubscribe(this.currentGroup.group) + + this.currentGroup = null + plugin.emit('leave', this.currentGroup) + return this.currentGroup + } + + beforeActionCheck = + async(message: any) => true + + // Set that for custom checks before GroupMessage/UngroupMessage processed (optional) + setCheckBeforeAction = + (cb: (message: any) => Promise) => { + this.beforeActionCheck = cb + } + + checkBeforeAction = + (msgName: string, message: any, channel: string, reply: ReturnType) => + this.beforeActionCheck(message) + .catch((err: any) => { + log.error('Error before processing %s: %s', msgName, err?.message) + push.send([ + channel, + reply.fail(err.message) + ]) + + return false + }) + }() + + router + .on(GroupMessage, async(channel, message) => { + const reply = wireutil.reply(options.serial) + try { + if (!await plugin.checkBeforeAction('GroupMessage', message, channel, reply)) { + return + } + + await plugin.join(message.owner!, message.timeout!, message.usage!, message.keys) + push.send([ + channel, + reply.okay() + ]) + } + catch (err: any) { + log.error('Failed processing GroupMessage: %s', err?.message) + if (err instanceof grouputil.AlreadyGroupedError) { + push.send([ + channel, + reply.fail(err.message) + ]) + } + } + }) + .on(AutoGroupMessage, async(channel, message) => { + try { + await plugin.join(message.owner!, 0, message.identifier, []) + plugin.emit('autojoin', message.identifier, true) + } + catch (err: any) { + log.error('Failed processing AutoGroupMessage: %s', err?.message) + if (err instanceof grouputil.AlreadyGroupedError) { + plugin.emit('autojoin', message.identifier, false) + } + } + }) + .on(UngroupMessage, async(channel, message) => { + const reply = wireutil.reply(options.serial) + try { + if (!await plugin.checkBeforeAction('UngroupMessage', message, channel, reply)) { + return + } + + await plugin.leave('ungroup_request') + push.send([ + channel, + reply.okay() + ]) + } + catch (err: any) { + log.error('Failed processing UngroupMessage: %s', err?.message) + if (err instanceof grouputil.NoGroupError) { + push.send([ + channel, + reply.fail(err.message) + ]) + } + } + }) + + // @ts-ignore + channels.on('timeout', async(channel) => { + const currentGroup = await plugin.get() + if (currentGroup && channel === currentGroup.group) { + plugin.leave('automatic_timeout') + } + }) + + lifecycle.observe(async() => { + try { + await plugin.leave('device_absent') + } + catch (err: any) { + log.error('Failed leave from group on process exit: %s', err?.message) + if (err instanceof grouputil.NoGroupError) { + return true + } + } + }) + + return plugin + }) diff --git a/lib/units/device/plugins/connect.js b/lib/units/device/plugins/connect.ts similarity index 54% rename from lib/units/device/plugins/connect.js rename to lib/units/device/plugins/connect.ts index 51be539ca8..8dd727d575 100644 --- a/lib/units/device/plugins/connect.js +++ b/lib/units/device/plugins/connect.ts @@ -1,10 +1,9 @@ import util from 'util' import syrup from '@devicefarmer/stf-syrup' import logger from '../../../util/logger.js' -import wire from '../../../wire/index.js' +import {JoinGroupByAdbFingerprintMessage} from '../../../wire/wire.js' import wireutil from '../../../wire/util.js' import lifecycle from '../../../util/lifecycle.js' -import db from '../../../db/index.js' import adb from '../support/adb.js' import connector, {DEVICE_TYPE} from '../../base-device/support/connector.js' import push from '../../base-device/support/push.js' @@ -14,18 +13,13 @@ import solo from './solo.js' import urlformat from '../../base-device/support/urlformat.js' import identity from './util/identity.js' import data from './util/data.js' -import {GRPC_WAIT_TIMEOUT} from '../../../util/apiutil.js' +import type TcpUsbServer from '@u4/adbkit/dist/adb/tcpusb/server.d.ts' import {AdbKeysUpdatedMessage} from '../../../wire/wire.js' -// The promise passed as an argument will not be cancelled after the time has elapsed, -// only the second promise will be rejected. -const promiseTimeout = (promise, ms, message = 'Timeout exceeded') => Promise.race([ - promise, - new Promise((_, reject) => { - const id = setTimeout(() => reject(new Error(message)), ms) - promise.finally(() => clearTimeout(id)) - }) -]) +interface Key { + fingerprint: string + comment: string +} export default syrup.serial() .dependency(adb) @@ -37,56 +31,58 @@ export default syrup.serial() .dependency(connector) .dependency(identity) .dependency(data) - .define(async function(options, adb, router, push, group, solo, urlformat, connector, identity, data) { + .define(async(options, adb, router, push, group, solo, urlformat, connector, identity, data) => { const log = logger.createLogger('device:plugins:connect') - let activeServer = null - - await db.connect() + let activeServer: TcpUsbServer | null = null - const notify = async(key) => { + const notify = async(key: Key) => { try { - const currentGroup = group.get() + const currentGroup = await group.get() push.send([ solo.channel, - wireutil.envelope(new wire.JoinGroupByAdbFingerprintMessage(options.serial, key.fingerprint, key.comment, currentGroup.group)) + wireutil.pack(JoinGroupByAdbFingerprintMessage, { + serial: options.serial, + fingerprint: key.fingerprint, + comment: key.comment, + currentGroup: currentGroup?.group + }) ]) } catch(e) { push.send([ solo.channel, - wireutil.envelope(new wire.JoinGroupByAdbFingerprintMessage(options.serial, key.fingerprint, key.comment)) + wireutil.pack(JoinGroupByAdbFingerprintMessage, { + serial: options.serial, + fingerprint: key.fingerprint, + comment: key.comment + }) ]) } } - const joinListener = (_, identifier, key, reject) => { - if (identifier !== key.fingerprint) { - reject(new Error('Somebody else took the device')) - } - } - - const autojoinListener = (identifier, joined, key, resolve, reject) => { - if (identifier === key.fingerprint) { - if (joined) { - return resolve() - } - reject(new Error('Device is already in use')) - } - } - const plugin = { serial: options.serial, port: options.connectPort, url: urlformat(options.connectUrlPattern, options.connectPort, identity.model, data ? data.name.id : ''), - auth: (key, resolve, reject) => reject(), + auth: (key: Key): boolean => false, start: () => new Promise((resolve, reject) => { log.info('Starting connect plugin') - const auth = key => promiseTimeout(new Promise((resolve, reject) => { - plugin.auth(key, resolve, reject) + // If Auth failed - the entire unit device will fall + // TODO: fix + const auth = (key: Key) => new Promise(async(resolve, reject) => { + // TODO: Dangerous, discuss and remove router.on(AdbKeysUpdatedMessage, () => notify(key)) - notify(key) - }), GRPC_WAIT_TIMEOUT) // reject after 2 minutes if autojoin event doesn't fire + await notify(key) + + if (plugin.auth(key)) { + resolve() + return + } + + // Connection rejected by user-defined auth handler + reject('Auth failed') + }) activeServer = adb.createTcpUsbBridge(plugin.serial, {auth}) .on('listening', () => resolve(plugin.url)) @@ -97,8 +93,7 @@ export default syrup.serial() conn.on('userActivity', () => group.keepalive()) }) - activeServer.listen(plugin.port) - lifecycle.share('Remote ADB', activeServer) + activeServer!.listen(plugin.port) log.info(util.format('Listening on port %d', plugin.port)) resolve(plugin.url) @@ -109,22 +104,19 @@ export default syrup.serial() } log.info('Stop connect plugin') - router.removeAllListeners(wire.AdbKeysUpdatedMessage) - let resolveClose = () => {} + // TODO: Not ideal way, need WireRouter.once + router.removeAllListeners(AdbKeysUpdatedMessage) - const waitCloseServer = new Promise((resolve) => { - // @ts-ignore - resolveClose = resolve - }) - - activeServer.on('close', () => { - resolveClose() + const waitServerClose = new Promise((resolve) => { + activeServer!.on('close', () => { + resolve() + }) }) activeServer.end() activeServer.close() - await waitCloseServer + await waitServerClose activeServer = null }, @@ -135,13 +127,24 @@ export default syrup.serial() } } - group.on('join', (g, id) => - plugin.auth = (key, resolve, reject) => - joinListener(g, id, key, resolve, reject) + group.on('join', (group, keys) => + plugin.auth = key => { + if (keys?.length && !keys.includes(key.fingerprint)) { + log.error('Invalid RSA key. Somebody else took the device') + return false + } + return true + } ) + group.on('autojoin', (id, joined) => - plugin.auth = (key, resolve, reject) => - autojoinListener(id, joined, key, resolve, reject) + plugin.auth = key => { + if (id === key.fingerprint && joined) { + return true + } + log.error('Device is already in use') + return false + } ) connector.init({ @@ -155,6 +158,6 @@ export default syrup.serial() lifecycle.observe(() => connector.stop()) group.on('leave', () => { connector.stop() - plugin.auth = (key, resolve, reject) => reject() + plugin.auth = (key) => false }) }) diff --git a/lib/units/device/plugins/group.js b/lib/units/device/plugins/group.js index 6a31e8a0aa..e69de29bb2 100644 --- a/lib/units/device/plugins/group.js +++ b/lib/units/device/plugins/group.js @@ -1,214 +0,0 @@ -import events from 'events' -import Promise from 'bluebird' -import syrup from '@devicefarmer/stf-syrup' -import logger from '../../../util/logger.js' -import wire from '../../../wire/index.js' -import wireutil from '../../../wire/util.js' -import * as grouputil from '../../../util/grouputil.js' -import lifecycle from '../../../util/lifecycle.js' -import db from '../../../db/index.js' -import dbapi from '../../../db/api.js' -import * as apiutil from '../../../util/apiutil.js' -import solo from './solo.js' -import identity from './util/identity.js' -import service from './service.js' -import router from '../../base-device/support/router.js' -import push from '../../base-device/support/push.js' -import sub from '../../base-device/support/sub.js' -import channels from '../../base-device/support/channels.js' -import {AutoGroupMessage, GroupMessage, UngroupMessage} from '../../../wire/wire.js' -export default syrup.serial() - .dependency(solo) - .dependency(identity) - .dependency(service) - .dependency(router) - .dependency(push) - .dependency(sub) - .dependency(channels) - .define(async function(options, solo, ident, /** @type {any} */ service, router, push, sub, channels) { - const log = logger.createLogger('device:plugins:group') - let currentGroup = null - - /** @type {any} */ - const plugin = new events.EventEmitter() - - await db.connect() - - plugin.get = Promise.method(function() { - if (!currentGroup) { - throw new grouputil.NoGroupError() - } - return currentGroup - }) - plugin.join = function(newGroup, timeout, usage) { - return plugin.get() - .then(function() { - if (currentGroup.group !== newGroup.group) { - log.error(`Cannot join group ${JSON.stringify(newGroup)} since this device is in group ${JSON.stringify(currentGroup)}`) - throw new grouputil.AlreadyGroupedError() - } - log.info('Update timeout for %s', apiutil.QUARTER_MINUTES) - channels.updateTimeout(currentGroup.group, apiutil.QUARTER_MINUTES) - - const newTimeout = channels.getTimeout(currentGroup.group) - dbapi.enhanceStatusChangedAt(options.serial, newTimeout) - }) - .catch(grouputil.NoGroupError, function() { - currentGroup = newGroup - log.important('Now owned by "%s"', currentGroup.email) - log.important('Device now in group "%s"', currentGroup.name) - log.info(`Rent time is ${timeout}`) - log.info('Subscribing to group channel "%s"', currentGroup.group) - channels.register(currentGroup.group, { - timeout: timeout || options.groupTimeout, - alias: solo.channel - }) - dbapi.enhanceStatusChangedAt(options.serial, timeout).then(() => { - sub.subscribe(currentGroup.group) - plugin.emit('join', currentGroup) - push.send([ - wireutil.global, - wireutil.envelope(new wire.JoinGroupMessage(options.serial, currentGroup, usage)) - ]) - service.freezeRotation(0) - return currentGroup - }) - }) - } - plugin.keepalive = function() { - if (currentGroup) { - channels.keepalive(currentGroup.group) - } - } - plugin.leave = function(reason) { - return plugin.get() - .then(function(group) { - log.important('No longer owned by "%s"', group.email) - log.info('Unsubscribing from group channel "%s"', group.group) - return dbapi.enhanceStatusChangedAt(options.serial, 0).then(() => { - push.send([ - wireutil.global, - wireutil.envelope(new wire.LeaveGroupMessage(options.serial, group, reason)) - ]) - channels.unregister(group.group) - sub.unsubscribe(group.group) - currentGroup = null - plugin.emit('leave', group) - return group - }) - }) - } - plugin.on('join', function() { - service.wake() - service.acquireWakeLock() - }) - plugin.on('leave', function() { - if (options.screenReset) { - service.pressKey('home') - service.thawRotation() - dbapi.loadDeviceBySerial(options.serial).then(device => { - if (device.group.id === device.origin) { - log.warn('Cleaning device') - service.sendCommand('settings put system screen_brightness_mode 0') - service.sendCommand('settings put system screen_brightness 0') - service.setMasterMute(true) - service.sendCommand('input keyevent 26') - service.sendCommand('settings put global http_proxy :0') - service.sendCommand('pm clear com.android.chrome') - service.sendCommand('pm clear com.chrome.beta') - service.sendCommand('pm clear com.sec.android.app.sbrowser') - service.sendCommand('pm uninstall com.vkontakte.android') - service.sendCommand('pm uninstall com.vk.im') - service.sendCommand('pm uninstall com.vk.clips') - service.sendCommand('pm uninstall com.vk.calls') - service.sendCommand('pm uninstall com.vk.admin') - service.sendCommand('pm clear com.mi.globalbrowser') - service.sendCommand('pm clear com.microsoft.emmx') - service.sendCommand('pm clear com.huawei.browser') - service.sendCommand('pm uninstall --user 0 com.samsung.clipboardsaveservice') - service.sendCommand('pm uninstall --user 0 com.samsung.android.clipboarduiservice') - service.sendCommand('rm -rf /sdcard/Downloads') - service.sendCommand('rm -rf /storage/emulated/legacy/Downloads') - service.sendCommand('settings put global always_finish_activities 0') - service.sendCommand('pm enable-user com.google.android.gms') - service.sendCommand('settings put system font_scale 1.0') - service.sendCommand('su') - service.sendCommand('echo "chrome --disable-fre --no-default-browser-check --no-first-run" > /data/local/tmp/chrome-command-line') - service.sendCommand('am set-debug-app --persistent com.android.chrome') - } - else { - log.warn('Device was not cleared because it in custom group') - } - }) - } - service.releaseWakeLock() - }) - router - .on(GroupMessage, function(channel, message) { - let reply = wireutil.reply(options.serial) - grouputil.match(ident, message.requirements) - .then(function() { - return plugin.join(message.owner, message.timeout, message.usage) - }) - .then(function() { - push.send([ - channel, - reply.okay() - ]) - }) - .catch(grouputil.RequirementMismatchError, function(err) { - push.send([ - channel, - reply.fail(err.message) - ]) - }) - .catch(grouputil.AlreadyGroupedError, function(err) { - push.send([ - channel, - reply.fail(err.message) - ]) - }) - }) - .on(AutoGroupMessage, function(channel, message) { - return plugin.join(message.owner, message.timeout, message.identifier) - .then(function() { - plugin.emit('autojoin', message.identifier, true) - }) - .catch(grouputil.AlreadyGroupedError, function() { - plugin.emit('autojoin', message.identifier, false) - }) - }) - .on(UngroupMessage, function(channel, message) { - let reply = wireutil.reply(options.serial) - grouputil.match(ident, message.requirements) - .then(function() { - return plugin.leave('ungroup_request') - }) - .then(function() { - push.send([ - channel, - reply.okay() - ]) - }) - .catch(grouputil.NoGroupError, function(err) { - push.send([ - channel, - reply.fail(err.message) - ]) - }) - }) - - // @ts-ignore - channels.on('timeout', function(channel) { - if (currentGroup && channel === currentGroup.group) { - plugin.leave('automatic_timeout') - } - }) - lifecycle.observe(function() { - return plugin.leave('device_absent') - .catch(grouputil.NoGroupError, function() { - return true - }) - }) - return plugin - }) diff --git a/lib/units/device/plugins/group.ts b/lib/units/device/plugins/group.ts new file mode 100644 index 0000000000..c628918805 --- /dev/null +++ b/lib/units/device/plugins/group.ts @@ -0,0 +1,96 @@ +import syrup from '@devicefarmer/stf-syrup' +import logger from '../../../util/logger.js' +import {DeviceGetIsInOrigin} from '../../../wire/wire.js' +import wireutil from '../../../wire/util.js' +import * as grouputil from '../../../util/grouputil.js' +import solo from './solo.js' +import identity from './util/identity.js' +import service from './service.js' +import router from '../../base-device/support/router.js' +import push from '../../base-device/support/push.js' +import sub from '../../base-device/support/sub.js' +import channels from '../../base-device/support/channels.js' +import group from '../../base-device/plugins/group.js' +import {runTransactionDev} from '../../../wire/transmanager.js' + +export default syrup.serial() + .dependency(solo) + .dependency(identity) + .dependency(service) + .dependency(router) + .dependency(push) + .dependency(sub) + .dependency(channels) + .dependency(group) + .define(async(options, solo, ident, /** @type {any} */ service, router, push, sub, channels, group) => { + const log = logger.createLogger('device:plugins:group') + + group.setCheckBeforeAction(async(message: any) => + !message.requirements || grouputil.match(ident, message.requirements) + ) + + group.on('join', () => { + service.freezeRotation(0) + service.wake() + service.acquireWakeLock() + }) + + group.on('leave', async() => { + try { + if (options.screenReset) { + service.pressKey('home') + service.thawRotation() + + const {isInOrigin} = await runTransactionDev( + wireutil.global, + DeviceGetIsInOrigin, + {serial: options.serial}, + {sub, push, router} + ) as { isInOrigin: boolean } + + if (isInOrigin) { + log.warn('Cleaning device') + await Promise.all([ + service.sendCommand('settings put system screen_brightness_mode 0'), + service.sendCommand('settings put system screen_brightness 0'), + service.setMasterMute(true), + service.sendCommand('input keyevent 26'), + service.sendCommand('settings put global http_proxy :0'), + service.sendCommand('pm clear com.android.chrome'), + service.sendCommand('pm clear com.chrome.beta'), + service.sendCommand('pm clear com.sec.android.app.sbrowser'), + service.sendCommand('pm uninstall com.vkontakte.android'), + service.sendCommand('pm uninstall com.vk.im'), + service.sendCommand('pm uninstall com.vk.clips'), + service.sendCommand('pm uninstall com.vk.calls'), + service.sendCommand('pm uninstall com.vk.admin'), + service.sendCommand('pm clear com.mi.globalbrowser'), + service.sendCommand('pm clear com.microsoft.emmx'), + service.sendCommand('pm clear com.huawei.browser'), + service.sendCommand('pm uninstall --user 0 com.samsung.clipboardsaveservice'), + service.sendCommand('pm uninstall --user 0 com.samsung.android.clipboarduiservice'), + service.sendCommand('rm -rf /sdcard/Downloads'), + service.sendCommand('rm -rf /storage/emulated/legacy/Downloads'), + service.sendCommand('settings put global always_finish_activities 0'), + service.sendCommand('pm enable-user com.google.android.gms'), + service.sendCommand('settings put system font_scale 1.0'), + service.sendCommand('su'), + service.sendCommand('echo "chrome --disable-fre --no-default-browser-check --no-first-run" > /data/local/tmp/chrome-command-line'), + service.sendCommand('am set-debug-app --persistent com.android.chrome') + ]) + } + else { + log.warn('Device was not cleared because it in custom group') + } + } + } + catch (err: any) { + log.error('Clear device on group.leave failed: %s', err?.message) + } + finally { + service.releaseWakeLock() + } + }) + + return group + }) diff --git a/lib/units/device/plugins/service.ts b/lib/units/device/plugins/service.ts index 5a6d5bcafe..4187b9224f 100644 --- a/lib/units/device/plugins/service.ts +++ b/lib/units/device/plugins/service.ts @@ -373,13 +373,13 @@ export default syrup.serial() if (!response.success) { throw new Error('Unable to get properties') } - const mapped = response.properties.reduce( (acc: any, property: any) => { acc[property.name] = property.value return acc }, {} ) + if (mapped.imei) { return mapped } diff --git a/lib/units/groups-engine/index.js b/lib/units/groups-engine/index.js index f2aa35adb3..ee3d1f877c 100644 --- a/lib/units/groups-engine/index.js +++ b/lib/units/groups-engine/index.js @@ -10,17 +10,15 @@ export default (async function(options) { const { push , pushdev - , sub - , subdev , channelRouter } = await db.createZMQSockets(options.endpoints, log) - await db.connect(push, pushdev, channelRouter) + await db.connect() devicesWatcher(push, pushdev, channelRouter) usersWatcher(pushdev) lifecycle.observe(() => - [push, sub, pushdev, subdev].forEach((sock) => sock.close()) + [push, pushdev].forEach((sock) => sock.close()) ) log.info('Groups engine started') }) diff --git a/lib/units/groups-engine/watchers/devices.js b/lib/units/groups-engine/watchers/devices.js index d76ce6a9b3..ee6470403f 100644 --- a/lib/units/groups-engine/watchers/devices.js +++ b/lib/units/groups-engine/watchers/devices.js @@ -37,7 +37,7 @@ export default (function(push, pushdev, channelRouter) { delete device.group.lifeTime return device } - pushdev.send([ + push.send([ wireutil.global, wireutil.envelope(new wire.DeviceChangeMessage(publishDevice(), action, device2.group.origin, timeutil.now('nano'))) ]) diff --git a/lib/units/ios-device/plugins/info/index.js b/lib/units/ios-device/plugins/info/index.js index 6557014b97..d857a01937 100644 --- a/lib/units/ios-device/plugins/info/index.js +++ b/lib/units/ios-device/plugins/info/index.js @@ -120,7 +120,10 @@ export default syrup.serial() let scale = parsedResponse.value.scale height *= scale width *= scale + + Object.assign(extendedInfo, {width, height, scale}) log.info('Storing device size/scale') + push.send([ wireutil.global, wireutil.envelope(new wire.SizeIosDevice(options.serial, height, width, scale)) diff --git a/lib/units/ios-device/plugins/wda/client.js b/lib/units/ios-device/plugins/wda/client.js index c67e829af7..cf1d48c2ce 100644 --- a/lib/units/ios-device/plugins/wda/client.js +++ b/lib/units/ios-device/plugins/wda/client.js @@ -10,12 +10,14 @@ import lifecycle from '../../../../util/lifecycle.js' import db from '../../../../db/index.js' import dbapi from '../../../../db/api.js' import devicenotifier from '../devicenotifier.js' +import info from '../info/index.js' import push from '../../../base-device/support/push.js' const LOG_REQUEST_MSG = 'Request has been sent to WDA with data: ' export default syrup.serial() .dependency(devicenotifier) .dependency(push) - .define(async(options, notifier, push) => { + .dependency(info) + .define(async(options, notifier, push, info) => { const log = logger.createLogger('wdaClient') log.info('WdaClient.js initializing...') await db.connect() @@ -422,34 +424,23 @@ export default syrup.serial() return this.deviceSize } log.info('getting device window size...') - return dbapi.getDeviceDisplaySize(options.serial).then((deviceSize) => { - if (!deviceSize) { - return null - } - let dbHeight = deviceSize.height - let dbWidth = deviceSize.width - let dbScale = deviceSize.scale - if (!dbHeight || !dbWidth || !dbScale) { - return null - } - // Reuse DB values: - log.info('Reusing device size/scale') - // Set device size based on orientation, default is PORTRAIT - if (this.orientation === 'PORTRAIT' || !this.orientation) { - this.deviceSize = {height: dbHeight /= dbScale, width: dbWidth /= dbScale} - } - else if (this.orientation === 'LANDSCAPE') { - this.deviceSize = {height: dbWidth /= dbScale, width: dbHeight /= dbScale} - } - else if (this.deviceType === 'Apple TV') { - this.deviceSize = {height: dbHeight, width: dbWidth} - } - return this.deviceSize - }) - .catch((err) => { - log.error('Error getting device size from DB') - return lifecycle.fatal(err) - }) + const {width, height, scale} = info.extendedInfo + + if (!width || !height || !scale) { + return null + } + + // Set device size based on orientation, default is PORTRAIT + if (this.orientation === 'PORTRAIT' || !this.orientation) { + this.deviceSize = {height: height / scale, width: width / scale} + } + else if (this.orientation === 'LANDSCAPE') { + this.deviceSize = {height: width / scale, width: height / scale} + } + else if (this.deviceType === 'Apple TV') { + this.deviceSize = {height: height, width: width} + } + return this.deviceSize } setVersion(currentSession) { log.info('Setting current device version: ' + currentSession.value.capabilities.sdkVersion) diff --git a/lib/units/processor/index.js b/lib/units/processor/index.ts similarity index 57% rename from lib/units/processor/index.js rename to lib/units/processor/index.ts index 0b714c6be1..266594b347 100644 --- a/lib/units/processor/index.js +++ b/lib/units/processor/index.ts @@ -8,68 +8,116 @@ import dbapi from '../../db/models/all/index.js' import lifecycle from '../../util/lifecycle.js' import srv from '../../util/srv.js' import * as zmqutil from '../../util/zmqutil.js' -import {UpdateAccessTokenMessage, DeleteUserMessage, DeviceChangeMessage, UserChangeMessage, GroupChangeMessage, DeviceGroupChangeMessage, GroupUserChangeMessage, DeviceHeartbeatMessage, DeviceLogMessage, TransactionProgressMessage, TransactionDoneMessage, TransactionTreeMessage, InstallResultMessage, DeviceLogcatEntryMessage, TemporarilyUnavailableMessage, UpdateRemoteConnectUrl, InstalledApplications, DeviceIntroductionMessage, InitializeIosDeviceState, DevicePresentMessage, DeviceAbsentMessage, DeviceStatusMessage, DeviceReadyMessage, JoinGroupByAdbFingerprintMessage, JoinGroupByVncAuthResponseMessage, ConnectStartedMessage, ConnectStoppedMessage, JoinGroupMessage, LeaveGroupMessage, DeviceIdentityMessage, AirplaneModeEvent, BatteryEvent, DeviceBrowserMessage, ConnectivityEvent, PhoneStateEvent, RotationEvent, CapabilitiesMessage, ReverseForwardsEvent, SetDeviceDisplay, UpdateIosDevice, SdkIosVersion, SizeIosDevice, DeviceTypeMessage, DeleteDevice, SetAbsentDisconnectedDevices, GetServicesAvailabilityMessage} from '../../wire/wire.js' +import { + UserChangeMessage, + GroupChangeMessage, + DeviceGroupChangeMessage, + GroupUserChangeMessage, + DeviceHeartbeatMessage, + DeviceLogMessage, + TransactionProgressMessage, + TransactionDoneMessage, + TransactionTreeMessage, + InstallResultMessage, + DeviceLogcatEntryMessage, + TemporarilyUnavailableMessage, + UpdateRemoteConnectUrl, + InstalledApplications, + DeviceIntroductionMessage, + InitializeIosDeviceState, + DevicePresentMessage, + DeviceAbsentMessage, + DeviceStatusMessage, + DeviceReadyMessage, + JoinGroupByAdbFingerprintMessage, + JoinGroupByVncAuthResponseMessage, + ConnectStartedMessage, + ConnectStoppedMessage, + JoinGroupMessage, + LeaveGroupMessage, + DeviceIdentityMessage, + AirplaneModeEvent, + BatteryEvent, + DeviceBrowserMessage, + ConnectivityEvent, + PhoneStateEvent, + RotationEvent, + CapabilitiesMessage, + ReverseForwardsEvent, + SetDeviceDisplay, + UpdateIosDevice, + SdkIosVersion, + SizeIosDevice, + DeviceTypeMessage, + DeleteDevice, + SetAbsentDisconnectedDevices, + GetServicesAvailabilityMessage, + DeviceRegisteredMessage, GetPresentDevices, DeviceGetIsInOrigin +} from '../../wire/wire.js' -export default await db.ensureConnectivity(async function(options) { +interface Options { + name: string + endpoints: { + appDealer: string[] + devDealer: string[] + } + publicIp: string +} + +export default db.ensureConnectivity(async(options: Options) => { const log = logger.createLogger('processor') if (options.name) { logger.setGlobalIdentifier(options.name) } - const { - push - , pushdev - , sub - , subdev - , channelRouter - } = await db.createZMQSockets(options.endpoints, log) - await db.connect({push, pushdev, channelRouter}) + await db.connect() // App side const appDealer = zmqutil.socket('dealer') - Promise.all(options.endpoints.appDealer.map(async(endpoint) => { + await Promise.all(options.endpoints.appDealer.map(async(endpoint: string) => { try { - return srv.resolve(endpoint).then(function(records) { - return srv.attempt(records, async function(record) { + return await srv.resolve(endpoint).then((records) => + srv.attempt(records, (record) => { log.info('App dealer connected to "%s"', record.url) appDealer.connect(record.url) return true }) - }) + ) } - catch (err) { - log.fatal('Unable to connect to app dealer endpoint', err) + catch (err: any) { + log.fatal('Unable to connect to app dealer endpoint %s', err?.message) lifecycle.fatal() } })) // Device side const devDealer = zmqutil.socket('dealer') - appDealer.on('message', function(channel, data) { + appDealer.on('message', (channel, data) => { devDealer.send([channel, data]) }) - Promise.all(options.endpoints.devDealer.map(async(endpoint) => { + + const reply = wireutil.reply(wireutil.global) + await Promise.all(options.endpoints.devDealer.map(async(endpoint: string) => { try { - return srv.resolve(endpoint).then(function(records) { - return srv.attempt(records, async function(record) { + return await srv.resolve(endpoint).then((records) => + srv.attempt(records, (record) => { log.info('Device dealer connected to "%s"', record.url) devDealer.connect(record.url) return true }) - }) + ) } - catch (err) { - log.fatal('Unable to connect to dev dealer endpoint', err) + catch (err: any) { + log.fatal('Unable to connect to dev dealer endpoint %s', err?.message) lifecycle.fatal() } })) - const defaultWireHandler = (channel, _, data) => appDealer.send([channel, data]) + const defaultWireHandler = + (channel: string, _: any, data: any) => + appDealer.send([channel, data]) const router = new WireRouter() - .on(UpdateAccessTokenMessage, defaultWireHandler) - .on(DeleteUserMessage, defaultWireHandler) - .on(DeviceChangeMessage, defaultWireHandler) .on(UserChangeMessage, defaultWireHandler) .on(GroupChangeMessage, defaultWireHandler) .on(DeviceGroupChangeMessage, defaultWireHandler) @@ -84,37 +132,35 @@ export default await db.ensureConnectivity(async function(options) { .on(TemporarilyUnavailableMessage, defaultWireHandler) .on(UpdateRemoteConnectUrl, defaultWireHandler) .on(InstalledApplications, defaultWireHandler) - .on(DeviceIntroductionMessage, async(channel, message, data) => { + .on(DeviceIntroductionMessage, async (channel, message, data) => { await dbapi.saveDeviceInitialState(message.serial, message) devDealer.send([ - message.provider.channel, - wireutil.envelope(new wire.DeviceRegisteredMessage(message.serial)) + message.provider!.channel, + wireutil.pack(DeviceRegisteredMessage, {serial: message.serial}) ]) appDealer.send([channel, data]) }) .on(InitializeIosDeviceState, (channel, message, data) => { dbapi.initializeIosDeviceState(options.publicIp, message) }) - .on(DevicePresentMessage, async(channel, message, data) => { + .on(DevicePresentMessage, async (channel, message, data) => { await dbapi.setDevicePresent(message.serial) appDealer.send([channel, data]) }) - .on(DeviceAbsentMessage, async(channel, message, data) => { - if (!message.applications) { - await dbapi.setDeviceAbsent(message.serial) - appDealer.send([channel, data]) - } + .on(DeviceAbsentMessage, async (channel, message, data) => { + await dbapi.setDeviceAbsent(message.serial) + appDealer.send([channel, data]) }) .on(DeviceStatusMessage, (channel, message, data) => { dbapi.saveDeviceStatus(message.serial, message.status) appDealer.send([channel, data]) }) - .on(DeviceReadyMessage, async(channel, message, data) => { + .on(DeviceReadyMessage, async (channel, message, data) => { await dbapi.setDeviceReady(message.serial, message.channel) devDealer.send([message.channel, wireutil.envelope(new wire.ProbeMessage())]) appDealer.send([channel, data]) }) - .on(JoinGroupByAdbFingerprintMessage, async(channel, message, data) => { + .on(JoinGroupByAdbFingerprintMessage, async (channel, message) => { try { const user = await dbapi.lookupUserByAdbFingerprint(message.fingerprint) if (user) { @@ -128,12 +174,11 @@ export default await db.ensureConnectivity(async function(options) { message.currentGroup, wireutil.envelope(new wire.JoinGroupByAdbFingerprintMessage(message.serial, message.fingerprint, message.comment)) ]) - } - catch (/** @type any */ err) { - log.error('Unable to lookup user by ADB fingerprint "%s"', message.fingerprint, err.stack) + } catch (err: any) { + log.error('Unable to lookup user by ADB fingerprint "%s": %s', message.fingerprint, err?.message) } }) - .on(JoinGroupByVncAuthResponseMessage, async(channel, message, data) => { + .on(JoinGroupByVncAuthResponseMessage, async (channel, message) => { try { const user = await dbapi.lookupUserByVncAuthResponse(message.response, message.serial) if (user) { @@ -148,46 +193,48 @@ export default await db.ensureConnectivity(async function(options) { message.currentGroup, wireutil.envelope(new wire.JoinGroupByVncAuthResponseMessage(message.serial, message.response)) ]) - } - catch (/** @type any */ err) { - log.error('Unable to lookup user by VNC auth response "%s"', message.response, err.stack) + } catch (err: any) { + log.error('Unable to lookup user by VNC auth response "%s": %s', message.response, err?.message) } }) - .on(ConnectStartedMessage, async(channel, message, data) => { + .on(ConnectStartedMessage, async (channel, message, data) => { await dbapi.setDeviceConnectUrl(message.serial, message.url) appDealer.send([channel, data]) }) - .on(ConnectStoppedMessage, async(channel, message, data) => { + .on(ConnectStoppedMessage, async (channel, message, data) => { await dbapi.unsetDeviceConnectUrl(message.serial) appDealer.send([channel, data]) }) - .on(JoinGroupMessage, async(channel, message, data) => { - await Promise.all([ - dbapi.setDeviceOwner(message.serial, message.owner), - - message.usage && - dbapi.setDeviceUsage(message.serial, message.usage), - + .on(JoinGroupMessage, async (channel, message, data) => { + await Promise.all([ // @ts-ignore + dbapi.setDeviceState(message.serial, message), dbapi.sendEvent(`device_${message.usage || 'use'}` , {} - , {deviceSerial: message.serial, userEmail: message.owner.email, groupId: message.owner.group} + , {deviceSerial: message.serial, userEmail: message.owner!.email, groupId: message.owner!.group} , Date.now() ) ]) appDealer.send([channel, data]) }) - .on(LeaveGroupMessage, async(channel, message, data) => { + .on(LeaveGroupMessage, async (channel, message, data) => { await Promise.all([ - dbapi.unsetDeviceOwner(message.serial), - dbapi.unsetDeviceUsage(message.serial), + dbapi.setDeviceState(message.serial, {owner: null, usage: null, timeout: 0}), dbapi.sendEvent('device_leave' , {} - , {deviceSerial: message.serial, userEmail: message.owner.email, groupId: message.owner.group} + , {deviceSerial: message.serial, userEmail: message.owner!.email, groupId: message.owner!.group} , Date.now() ) ]) appDealer.send([channel, data]) }) + .on(DeviceGetIsInOrigin, async (channel, message) => { + const device = await dbapi.loadDeviceBySerial(message.serial) + const isInOrigin = device.group.id === device.group.origin + devDealer.send([ + channel, + reply.okay('success', {isInOrigin}) + ]) + }) .on(DeviceIdentityMessage, (channel, message, data) => { dbapi.saveDeviceIdentity(message.serial, message) appDealer.send([channel, data]) @@ -224,68 +271,42 @@ export default await db.ensureConnectivity(async function(options) { dbapi.setDeviceReverseForwards(message.serial, message.forwards) appDealer.send([channel, data]) }) - .on(SetDeviceDisplay, (channel, message, data) => { - dbapi - .setDeviceSocketDisplay(message) - .then(function(response) { - log.info('setDeviceSocketDisplay response: %s', response) - }) - .catch(function(err) { - log.error('setDeviceSocketDisplay', err) - }) - }) - .on(UpdateIosDevice, (channel, message, data) => { - dbapi - .updateIosDevice(message) - .then(result => { - log.info('UpdateIosDevice: %s', result) - }) - .catch(err => { - log.info('UpdateIosDevice error: %s', err?.message) - }) - }) + .on(UpdateIosDevice, (channel, message, data) => + dbapi.updateIosDevice(message) + ) .on(SdkIosVersion, (channel, message, data) => { - dbapi - .setDeviceIosVersion(message) - .then(result => { - log.info('SdkIosVersion: %s', result) - }) - .catch(err => { - log.info('SdkIosVersion error: %s', err?.message) - }) + dbapi.setDeviceIosVersion(message) }) .on(SizeIosDevice, (channel, message, data) => { - dbapi.sizeIosDevice(message.id, message.height, message.width, message.scale).then(result => { - log.info('SizeIosDevice: %s', result) - }).catch(err => { - log.info('SizeIosDevice: %s', err?.message) - }) + dbapi.sizeIosDevice(message.id, message.height, message.width, message.scale) appDealer.send([channel, data]) }) .on(DeviceTypeMessage, (channel, message, data) => { dbapi.setDeviceType(message.serial, message.type) }) - .on(DeleteDevice, (channel, message, data) => { - dbapi.deleteDevice(message.serial) - }) - .on(SetAbsentDisconnectedDevices, (channel, message, data) => { - dbapi.setAbsentDisconnectedDevices() - }) .on(GetServicesAvailabilityMessage, (channel, message, data) => { dbapi.setDeviceServicesAvailability(message.serial, message) appDealer.send([channel, data]) }) - .handler() + .on(GetPresentDevices, async (channel, message, data) => { + const devices = await dbapi.loadPresentDevices() + .then(devices => devices.map(d => d.serial)) + devDealer.send([ + channel, + reply.okay('success', {devices}) + ]) + }) + .handler(); devDealer.on('message', router) - lifecycle.observe(function() { - [appDealer, devDealer, push, pushdev, sub, subdev].forEach(function(sock) { + lifecycle.observe(() => { + ;[appDealer, devDealer].forEach(function(sock) { try { sock.close() } - catch (err) { - log.error('Error while closing socket "%s"', err.stack) + catch (err: any) { + log.error('Error while closing socket "%s"', err?.message) } }) }) diff --git a/lib/units/provider/ADBObserver.ts b/lib/units/provider/ADBObserver.ts index 33fcfade03..6600448e88 100644 --- a/lib/units/provider/ADBObserver.ts +++ b/lib/units/provider/ADBObserver.ts @@ -14,7 +14,16 @@ interface ADBDeviceEntry { state: ADBDevice['type'] } -class ADBObserver extends EventEmitter { +type PrevADBDeviceType = ADBDevice['type'] + +interface ADBEvents { + connect: [ADBDevice] + update: [ADBDevice, PrevADBDeviceType] + disconnect: [ADBDevice] + error: [Error] +} + +class ADBObserver extends EventEmitter { static instance: ADBObserver | null = null private readonly intervalMs: number = 1000 // Default 1 second polling @@ -28,7 +37,10 @@ class ADBObserver extends EventEmitter { private shouldContinuePolling: boolean = false private connection: Socket | null = null private isConnecting: boolean = false - private pendingRequests: Map void; reject: (error: Error) => void}> = new Map() + private pendingRequests: Map void + reject: (error: Error) => void + }> = new Map() constructor(options?: {intervalMs?: number; host?: string; port?: number}) { if (ADBObserver.instance) { @@ -136,7 +148,7 @@ class ADBObserver extends EventEmitter { } } } - catch (error) { + catch (error: any) { this.emit('error', error) } finally { diff --git a/lib/units/provider/index.ts b/lib/units/provider/index.ts index 9156a0884f..912abc50d3 100644 --- a/lib/units/provider/index.ts +++ b/lib/units/provider/index.ts @@ -6,8 +6,6 @@ import * as procutil from '../../util/procutil.js' import lifecycle from '../../util/lifecycle.js' import srv from '../../util/srv.js' import * as zmqutil from '../../util/zmqutil.js' -import db from '../../db/index.js' -import dbapi from '../../db/api.js' import {ChildProcess} from 'node:child_process' import ADBObserver, {ADBDevice} from './ADBObserver.js' import { DeviceRegisteredMessage } from '../../wire/wire.ts' @@ -39,7 +37,6 @@ export interface Options { export default (async function(options: Options) { const log = logger.createLogger('provider') - await db.connect() // Check whether the ipv4 address contains a port indication if (options.adbHost.includes(':')) { @@ -133,10 +130,9 @@ export default (async function(options: Options) { // Tell others we found a device push.send([ wireutil.global, - wireutil.envelope(new wire.DeviceIntroductionMessage(device.serial, wireutil.toDeviceStatus(device.type), new wire.ProviderMessage(solo, options.name))) + wireutil.envelope(new wire.DeviceIntroductionMessage(device.serial, wireutil.toDeviceStatus(device.type), new wire.ProviderMessage(solo, options.name), options.deviceType)) ]) - dbapi.setDeviceType(device.serial, options.deviceType) process.nextTick(() => { // after creating workers[device.serial] obj if (workers[device.serial]) { workers[device.serial].resolveRegister = () => resolve() diff --git a/lib/units/reaper/index.js b/lib/units/reaper/index.js deleted file mode 100644 index af4a59f442..0000000000 --- a/lib/units/reaper/index.js +++ /dev/null @@ -1,109 +0,0 @@ -import Promise from 'bluebird' -import logger from '../../util/logger.js' -import wire from '../../wire/index.js' -import wireutil from '../../wire/util.js' -import {WireRouter} from '../../wire/router.js' -import dbapi from '../../db/api.js' -import lifecycle from '../../util/lifecycle.js' -import srv from '../../util/srv.js' -import TtlSet from '../../util/ttlset.js' -import * as zmqutil from '../../util/zmqutil.js' -import db from '../../db/index.js' -import {DeviceIntroductionMessage, DeviceHeartbeatMessage, DeviceAbsentMessage} from '../../wire/wire.js' - -const log = logger.createLogger('reaper') -export default (async function(options) { - await db.connect() - - /** @type {any} */ - const ttlset = new TtlSet(options.heartbeatTimeout) - - // Input - const sub = zmqutil.socket('sub') - Promise.map(options.endpoints.sub, function(endpoint) { - return srv.resolve(endpoint).then(function(records) { - return srv.attempt(records, function(record) { - log.info('Receiving input from "%s"', record.url) - sub.connect(record.url) - return Promise.resolve(true) - }) - }) - }) - .catch(function(err) { - log.fatal('Unable to connect to sub endpoint', err) - lifecycle.fatal() - }); - [wireutil.global].forEach(function(channel) { - log.info('Subscribing to permanent channel "%s"', channel) - sub.subscribe(channel) - }) - // Output - const push = zmqutil.socket('push') - Promise.map(options.endpoints.push, function(endpoint) { - return srv.resolve(endpoint).then(function(records) { - return srv.attempt(records, function(record) { - log.info('Sending output to "%s"', record.url) - push.connect(record.url) - return Promise.resolve(true) - }) - }) - }) - .catch(function(err) { - log.fatal('Unable to connect to push endpoint', err) - lifecycle.fatal() - }) - ttlset.on('insert', function(serial) { - log.info('Device "%s" is present', serial) - push.send([ - wireutil.global, - wireutil.envelope(new wire.DevicePresentMessage(serial)) - ]) - }) - ttlset.on('drop', function(serial) { - log.info('Reaping device "%s" due to heartbeat timeout', serial) - push.send([ - wireutil.global, - wireutil.envelope(new wire.DeviceAbsentMessage(serial)) - ]) - }) - function loadInitialState() { - return dbapi.loadPresentDevices() - .then(function(devices) { - let now = Date.now() - devices.forEach(function(device) { - ttlset.bump(device.serial, now, TtlSet.SILENT) - }) - }) - } - function listenToChanges() { - sub.on('message', new WireRouter() - .on(DeviceIntroductionMessage, function(channel, message) { - message.status = 3 - ttlset.drop(message.serial, TtlSet.SILENT) - ttlset.bump(message.serial, Date.now()) - }) - .on(DeviceHeartbeatMessage, function(channel, message) { - ttlset.bump(message.serial, Date.now()) - }) - .on(DeviceAbsentMessage, function(channel, message) { - ttlset.drop(message.serial, TtlSet.SILENT) - }) - .handler()) - } - log.info('Reaping devices with no heartbeat') - lifecycle.observe(function() { - [push, sub].forEach(function(sock) { - try { - sock.close() - } - catch (err) { - log.error(err) - } - }) - ttlset.stop() - }) - loadInitialState().then(listenToChanges).catch(function(err) { - log.fatal('Unable to load initial state', err) - lifecycle.fatal() - }) -}) diff --git a/lib/units/reaper/index.ts b/lib/units/reaper/index.ts new file mode 100644 index 0000000000..0db7898f36 --- /dev/null +++ b/lib/units/reaper/index.ts @@ -0,0 +1,120 @@ +import logger from '../../util/logger.js' +import { + DeviceAbsentMessage, + DeviceHeartbeatMessage, + DeviceIntroductionMessage, DevicePresentMessage, + GetPresentDevices +} from '../../wire/wire.js' +import wireutil from '../../wire/util.js' +import {WireRouter} from '../../wire/router.js' +import lifecycle from '../../util/lifecycle.js' +import srv from '../../util/srv.js' +import TTLSet from '../../util/ttlset.js' +import * as zmqutil from '../../util/zmqutil.js' +import {runTransactionDev} from '../../wire/transmanager.js' + +const log = logger.createLogger('reaper') + +interface Options { + heartbeatTimeout: number + endpoints: { + sub: string[] + push: string[] + } +} + +export default (async(options: Options) => { + const ttlset = new TTLSet(options.heartbeatTimeout) + + // Input + const sub = zmqutil.socket('sub') + await Promise.all(options.endpoints.sub.map((endpoint: string) => + srv.resolve(endpoint).then(records => + srv.attempt(records, (record) => { + log.info('Receiving input from "%s"', record.url) + sub.connect(record.url) + }) + ) + )).catch((err) => { + log.fatal('Unable to connect to sub endpoint %s', err?.message) + lifecycle.fatal() + }) + + ;[wireutil.global].forEach(channel => { + log.info('Subscribing to permanent channel "%s"', channel) + sub.subscribe(channel) + }) + + // Output + const push = zmqutil.socket('push') + await Promise.all(options.endpoints.push.map((endpoint: string) => + srv.resolve(endpoint).then(records => + srv.attempt(records, (record) => { + log.info('Sending output to "%s"', record.url) + push.connect(record.url) + }) + ) + )).catch((err) => { + log.fatal('Unable to connect to push endpoint: %s', err?.message) + lifecycle.fatal() + }) + + ttlset.on('insert', (serial) => { + log.info('Device "%s" is present', serial) + push.send([ + wireutil.global, + wireutil.pack(DevicePresentMessage, {serial}) + ]) + }) + + ttlset.on('drop', (serial) => { + log.info('Reaping device "%s" due to heartbeat timeout', serial) + push.send([ + wireutil.global, + wireutil.pack(DeviceAbsentMessage, {serial}) + ]) + }) + + lifecycle.observe(() => { + [push, sub].forEach(sock => { + try { + sock.close() + } + catch (err: any) { + // no-op + } + }) + ttlset.stop() + }) + + try { + log.info('Reaping devices with no heartbeat') + + const router = new WireRouter() + .on(DeviceIntroductionMessage, (channel, message) => { + ttlset.drop(message.serial, TTLSet.SILENT) + ttlset.bump(message.serial, Date.now()) + }) + .on(DeviceHeartbeatMessage, (channel, message) => { + ttlset.bump(message.serial, Date.now()) + }) + .on(DeviceAbsentMessage, (channel, message) => { + ttlset.drop(message.serial, TTLSet.SILENT) + }) + + // Listen to changes + sub.on('message', router.handler()) + + // Load initial state + const {devices} = await runTransactionDev(wireutil.global, GetPresentDevices, {}, {sub, push, router}) + + const now = Date.now() + devices.forEach((serial: string) => { + ttlset.bump(serial, now, TTLSet.SILENT) + }) + } + catch (err: any) { + log.fatal('Unable to load initial state: %s', err?.message) + lifecycle.fatal() + } +}) diff --git a/lib/units/tizen-device/plugins/launcher.js b/lib/units/tizen-device/plugins/launcher.js index ae9839a883..42339ccf40 100644 --- a/lib/units/tizen-device/plugins/launcher.js +++ b/lib/units/tizen-device/plugins/launcher.js @@ -5,7 +5,7 @@ import group from '../../base-device/plugins/group.js' import sdb from './sdb/index.js' import wire from '../../../wire/index.js' import wireutil from '../../../wire/util.js' -import webinspector from './webinspector.js' +import webinspector from './webinspector/index.js' import {GetInstalledApplications, KillDeviceApp, LaunchDeviceApp, TerminateDeviceApp} from '../../../wire/wire.js' export default syrup.serial() diff --git a/lib/units/tizen-device/plugins/webinspector/Replicator.ts b/lib/units/tizen-device/plugins/webinspector/Replicator.ts new file mode 100644 index 0000000000..4cb8800f01 --- /dev/null +++ b/lib/units/tizen-device/plugins/webinspector/Replicator.ts @@ -0,0 +1,588 @@ +import {Transform} from './transform/index.js' + +// Constants +const TRANSFORMED_TYPE_KEY = '@t' +const CIRCULAR_REF_KEY = '@r' +const KEY_REQUIRE_ESCAPING_RE = /^#*@(t|r)$/ +const REMAINING_KEY = '__console_feed_remaining__' +const GLOBAL = (function getGlobal() { + // NOTE: see http://www.ecma-international.org/ecma-262/6.0/index.html#sec-performeval step 10 + // eslint-disable-next-line no-eval + const savedEval = eval + return savedEval('this') +})() +const ARRAY_BUFFER_SUPPORTED = typeof ArrayBuffer === 'function' +const MAP_SUPPORTED = typeof Map === 'function' +const SET_SUPPORTED = typeof Set === 'function' +const TYPED_ARRAY_CTORS = [ + 'Int8Array', + 'Uint8Array', + 'Uint8ClampedArray', + 'Int16Array', + 'Uint16Array', + 'Int32Array', + 'Uint32Array', + 'Float32Array', + 'Float64Array', +] as const + +const arrSlice = Array.prototype.slice + +interface Serializer { + serialize(val: any): string + deserialize(val: string): any +} + +interface CircularCandidateDescriptor { + parent: any + key: string | number + refIdx: number +} + +interface TransformedObject { + [TRANSFORMED_TYPE_KEY]: string + data: any +} + +interface CircularReference { + [CIRCULAR_REF_KEY]: number +} + +// Default serializer +const JSONSerializer: Serializer = { + serialize: (val: any): string => JSON.stringify(val), + deserialize: (val: string): any => JSON.parse(val) +} + +class EncodingTransformer { + private readonly references: any + private readonly transforms: Transform[] + private readonly transformsMap: Map | undefined + private readonly circularCandidates: any[] = [] + private readonly circularCandidatesDescrs: CircularCandidateDescriptor[] = [] + private circularRefCount: number = 0 + private readonly limit: number + + constructor(val: any, transforms: Transform[], limit?: number) { + this.references = val + this.transforms = transforms + this.transformsMap = this._makeTransformsMap() + this.limit = limit ?? Infinity + } + + private static _createRefMark(idx: number): CircularReference { + const obj = Object.create(null) + obj[CIRCULAR_REF_KEY] = idx + return obj + } + + private _createCircularCandidate(val: any, parent: any, key: string | number): void { + this.circularCandidates.push(val) + this.circularCandidatesDescrs.push({parent, key, refIdx: -1}) + } + + private _applyTransform(val: any, parent: any, key: string | number, transform: Transform): TransformedObject { + const result = Object.create(null) + const serializableVal = transform.toSerializable(val) + + if (typeof serializableVal === 'object' && serializableVal !== null) { + this._createCircularCandidate(val, parent, key) + } + + result[TRANSFORMED_TYPE_KEY] = transform.type + result.data = this._handleValue(() => serializableVal, parent, key) + return result + } + + private _handleArray = (arr: any[]): any[] => { + const result: any[] = [] + const arrayLimit = Math.min(arr.length, this.limit) + const remaining = arr.length - arrayLimit + + for (let i = 0; i < arrayLimit; i++) { + result[i] = this._handleValue(() => arr[i], result, i) + } + + result[arrayLimit] = REMAINING_KEY + remaining + + return result + } + + private _handlePlainObject(obj: Record): Record { + const result = Object.create(null) + let counter = 0 + let total = 0 + + for (const key in obj) { + if (Reflect.has(obj, key)) { + if (counter >= this.limit) { + total++ + continue + } + + const resultKey = KEY_REQUIRE_ESCAPING_RE.test(key) ? '#' + key : key + result[resultKey] = this._handleValue(() => obj[key], result, resultKey) + counter++ + total++ + } + } + + const remaining = total - counter + // eslint-disable-next-line no-proto + const name = obj?.__proto__?.constructor?.name + + if (name && name !== 'Object') { + result.constructor = {name} + } + + if (remaining) { + result[REMAINING_KEY] = remaining + } + + return result + } + + private _handleObject(obj: any, parent: any, key: string | number): any { + this._createCircularCandidate(obj, parent, key) + return Array.isArray(obj) ? this._handleArray(obj) : this._handlePlainObject(obj) + } + + private _ensureCircularReference(obj: any): CircularReference | null { + const circularCandidateIdx = this.circularCandidates.indexOf(obj) + + if (circularCandidateIdx > -1) { + const descr = this.circularCandidatesDescrs[circularCandidateIdx] + + if (descr.refIdx === -1) { + descr.refIdx = descr.parent ? ++this.circularRefCount : 0 + } + + return EncodingTransformer._createRefMark(descr.refIdx) + } + + return null + } + + private _handleValue(getVal: () => any, parent: any, key: string | number): any { + try { + const val = getVal() + const type = typeof val + const isObject = type === 'object' && val !== null + + if (isObject) { + const refMark = this._ensureCircularReference(val) + if (refMark) { + return refMark + } + } + + const transform = this._findTransform(type, val) + if (transform) { + return this._applyTransform(val, parent, key, transform) + } + + if (isObject) { + return this._handleObject(val, parent, key) + } + + return val + } + catch (e) { + try { + return this._handleValue(() => (e instanceof Error ? e : new Error(String(e))), parent, key as string | number) + } + catch { + return null + } + } + } + + private _makeTransformsMap(): Map | undefined { + if (!MAP_SUPPORTED) { + return undefined + } + + const map = new Map() + this.transforms.forEach(transform => { + if (transform.lookup) { + map.set(transform.lookup, transform) + } + }) + + return map + } + + private _findTransform(type: string, val: any): Transform | undefined { + if (MAP_SUPPORTED && this.transformsMap) { + if (val?.constructor) { + const transform = this.transformsMap.get(val.constructor) + if (transform?.shouldTransform(type, val)) { + return transform + } + } + } + + for (const transform of this.transforms) { + if (transform.shouldTransform(type, val)) { + return transform + } + } + + return undefined + } + + transform(): any[] { + const references = [this._handleValue(() => this.references, null, 0)] + + for (const descr of this.circularCandidatesDescrs) { + if (descr.refIdx > 0) { + references[descr.refIdx] = descr.parent[descr.key] + descr.parent[descr.key] = EncodingTransformer._createRefMark(descr.refIdx) + } + } + + return references + } +} + +class DecodingTransformer { + private readonly activeTransformsStack: any[] = [] + private readonly visitedRefs: Record = Object.create(null) + private readonly references: any[] + private readonly transformMap: Record + + constructor(references: any[], transformsMap: Record) { + this.references = references + this.transformMap = transformsMap + } + + private _handlePlainObject(obj: Record): void { + const unescaped: Record = Object.create(null) + + if ('constructor' in obj) { + if (!obj.constructor || typeof obj.constructor.name !== 'string') { + // @ts-ignore + obj.constructor = {name: 'Object'} + } + } + + for (const key in obj) { + if (obj.hasOwnProperty(key)) { + this._handleValue(obj[key], obj, key) + + if (KEY_REQUIRE_ESCAPING_RE.test(key)) { + // NOTE: use intermediate object to avoid unescaped and escaped keys interference + // E.g. unescaped "##@t" will be "#@t" which can overwrite escaped "#@t". + unescaped[key.substring(1)] = obj[key] + delete obj[key] + } + } + } + + for (const unescapedKey in unescaped) { + obj[unescapedKey] = unescaped[unescapedKey] + } + } + + private _handleTransformedObject(obj: TransformedObject, parent: any, key: string | number): void { + const transformType = obj[TRANSFORMED_TYPE_KEY] + const transform = this.transformMap[transformType] + + if (!transform) { + throw new Error(`Can't find transform for "${transformType}" type.`) + } + + this.activeTransformsStack.push(obj) + this._handleValue(obj.data, obj, 'data') + this.activeTransformsStack.pop() + parent[key] = transform.fromSerializable(obj.data) + } + + private _handleCircularSelfRefDuringTransform(refIdx: number, parent: any, key: string | number): void { + // NOTE: we've hit a hard case: object reference itself during transformation. + // We can't dereference it since we don't have resulting object yet. And we'll + // not be able to restore reference lately because we will need to traverse + // transformed object again and reference might be unreachable or new object contain + // new circular references. As a workaround we create getter, so once transformation + // complete, dereferenced property will point to correct transformed object. + const references = this.references + + Object.defineProperty(parent, key, { // @ts-ignore + val: undefined, + configurable: true, + enumerable: true, + get(this: { val: any }) { + if (this.val === undefined) { + this.val = references[refIdx] + } + return this.val + }, + set(this: { val: any }, value: any) { + this.val = value + } + }) + } + + private _handleCircularRef(refIdx: number, parent: any, key: string | number): void { + if (this.activeTransformsStack.includes(this.references[refIdx])) { + this._handleCircularSelfRefDuringTransform(refIdx, parent, key) + } + else { + if (!this.visitedRefs[refIdx]) { + this.visitedRefs[refIdx] = true + this._handleValue(this.references[refIdx], this.references, refIdx) + } + parent[key] = this.references[refIdx] + } + } + + private _handleValue(val: any, parent: any, key: string | number): void { + if (typeof val !== 'object' || val === null) { + return + } + + const refIdx = (val as CircularReference)[CIRCULAR_REF_KEY] + + if (refIdx !== undefined) { + this._handleCircularRef(refIdx, parent, key) + } + else if ((val as TransformedObject)[TRANSFORMED_TYPE_KEY]) { + this._handleTransformedObject(val as TransformedObject, parent, key) + } + else if (Array.isArray(val)) { + for (let i = 0; i < val.length; i++) { + this._handleValue(val[i], val, i) + } + } + else { + this._handlePlainObject(val) + } + } + + transform(): any { + this.visitedRefs[0] = true + this._handleValue(this.references[0], this.references, 0) + return this.references[0] + } +} + +// Built-in transforms with optimized implementations +const builtInTransforms: Transform[] = [ + { + type: '[[NaN]]', + shouldTransform: (type: string, val: any): boolean => type === 'number' && isNaN(val), + toSerializable: (): string => '', + fromSerializable: (): number => NaN + }, + { + type: '[[undefined]]', + shouldTransform: (type: string): boolean => type === 'undefined', + toSerializable: (): string => '', + fromSerializable: (): undefined => undefined + }, + { + type: '[[Date]]', + lookup: Date, + shouldTransform: (type: string, val: any): boolean => val instanceof Date, + toSerializable: (date: Date): number => date.getTime(), + fromSerializable: (val: number): Date => { + const date = new Date() + date.setTime(val) + return date + } + }, + { + type: '[[RegExp]]', + lookup: RegExp, + shouldTransform: (type: string, val: any): boolean => val instanceof RegExp, + toSerializable: (re: RegExp): { src: string; flags: string } => { + const result = { + src: re.source, + flags: '' + } + + if (re.global) { + result.flags += 'g' + } + if (re.ignoreCase) { + result.flags += 'i' + } + if (re.multiline) { + result.flags += 'm' + } + + return result + }, + fromSerializable: (val: { src: string; flags: string }): RegExp => new RegExp(val.src, val.flags) + }, + { + type: '[[Error]]', + lookup: Error, + shouldTransform: (type: string, val: any): boolean => val instanceof Error, + toSerializable: (err: Error): { name: string; message: string; stack?: string } => { + if (!err.stack) { + (Error as any).captureStackTrace?.(err) + } + + return { + name: err.name, + message: err.message, + stack: err.stack + } + }, + fromSerializable: (val: { name: string; message: string; stack?: string }): Error => { + const Ctor = (GLOBAL as any)[val.name] || Error + const err = new Ctor(val.message) + err.stack = val.stack + return err + } + }, + { + type: '[[ArrayBuffer]]', + lookup: ARRAY_BUFFER_SUPPORTED && ArrayBuffer, + shouldTransform: (type: string, val: any): boolean => ARRAY_BUFFER_SUPPORTED && val instanceof ArrayBuffer, + toSerializable: (buffer: ArrayBuffer): number[] => { + const view = new Int8Array(buffer) + return arrSlice.call(view) + }, + fromSerializable: (val: number[]): ArrayBuffer | number[] => { + if (ARRAY_BUFFER_SUPPORTED) { + const buffer = new ArrayBuffer(val.length) + const view = new Int8Array(buffer) + view.set(val) + return buffer + } + return val + } + }, + { + type: '[[TypedArray]]', + shouldTransform: (type: string, val: any): boolean => { + if (ARRAY_BUFFER_SUPPORTED) { + return ArrayBuffer.isView(val) && !(val instanceof DataView) + } + + for (const ctorName of TYPED_ARRAY_CTORS) { + if (typeof (GLOBAL as any)[ctorName] === 'function' && val instanceof (GLOBAL as any)[ctorName]) { + return true + } + } + + return false + }, + toSerializable: (arr: any): { ctorName: string; arr: any[] } => ({ + ctorName: arr.constructor.name, + arr: arrSlice.call(arr) + }), + fromSerializable: (val: { ctorName: string; arr: any[] }): any => { + return typeof (GLOBAL as any)[val.ctorName] === 'function' ? + new (GLOBAL as any)[val.ctorName](val.arr) : + val.arr + } + }, + { + type: '[[Map]]', + lookup: MAP_SUPPORTED && Map, + shouldTransform: (type: string, val: any): boolean => MAP_SUPPORTED && val instanceof Map, + toSerializable: (map: Map): any[] => { + const flattenedKVArr: any[] = [] + map.forEach((val, key) => { + flattenedKVArr.push(key, val) + }) + return flattenedKVArr + }, + fromSerializable: (val: any[]): Map | any[][] => { + if (MAP_SUPPORTED) { + // NOTE: new Map(iterable) is not supported by all browsers + const map = new Map() + for (let i = 0; i < val.length; i += 2) { + map.set(val[i], val[i + 1]) + } + return map + } + + const kvArr: any[][] = [] + for (let j = 0; j < val.length; j += 2) { + kvArr.push([val[j], val[j + 1]]) + } + return kvArr + } + }, + { + type: '[[Set]]', + lookup: SET_SUPPORTED && Set, + shouldTransform: (type: string, val: any): boolean => SET_SUPPORTED && val instanceof Set, + toSerializable: (set: Set): any[] => { + const arr: any[] = [] + set.forEach(val => arr.push(val)) + return arr + }, + fromSerializable: (val: any[]): Set | any[] => { + if (SET_SUPPORTED) { + // NOTE: new Set(iterable) is not supported by all browsers + const set = new Set() + for (const item of val) { + set.add(item) + } + return set + } + return val + } + } +] + +class Replicator { + private readonly transforms: Transform[] = [] + private readonly transformsMap: Record = Object.create(null) + private readonly serializer: Serializer + + constructor(serializer?: Serializer) { + this.serializer = serializer || JSONSerializer + this.addTransforms(builtInTransforms) + } + + addTransforms(transforms: Transform | Transform[]): this { + const transformsArray = Array.isArray(transforms) ? transforms : [transforms] + + for (const transform of transformsArray) { + if (this.transformsMap[transform.type]) { + throw new Error(`Transform with type "${transform.type}" was already added.`) + } + + this.transforms.push(transform) + this.transformsMap[transform.type] = transform + } + + return this + } + + removeTransforms(transforms: Transform | Transform[]): this { + const transformsArray = Array.isArray(transforms) ? transforms : [transforms] + + for (const transform of transformsArray) { + const idx = this.transforms.indexOf(transform) + + if (idx > -1) { + this.transforms.splice(idx, 1) + } + + delete this.transformsMap[transform.type] + } + + return this + } + + encode(val: any, limit?: number): string { + const transformer = new EncodingTransformer(val, this.transforms, limit) + const references = transformer.transform() + return this.serializer.serialize(references) + } + + decode(val: string): any { + const references = this.serializer.deserialize(val) + const transformer = new DecodingTransformer(references, this.transformsMap) + return transformer.transform() + } +} + +export default Replicator diff --git a/lib/units/tizen-device/plugins/webinspector.js b/lib/units/tizen-device/plugins/webinspector/index.ts similarity index 67% rename from lib/units/tizen-device/plugins/webinspector.js rename to lib/units/tizen-device/plugins/webinspector/index.ts index 0d3c4944e2..29d029187b 100644 --- a/lib/units/tizen-device/plugins/webinspector.js +++ b/lib/units/tizen-device/plugins/webinspector/index.ts @@ -1,20 +1,23 @@ -import push from '../../base-device/support/push.js' -import router from '../../base-device/support/router.js' -import group from '../../base-device/plugins/group.js' -import cdp from './cdp/index.js' -import wire from '../../../wire/index.js' -import wireutil from '../../../wire/util.js' -import logger from '../../../util/logger.js' - -import {Encode} from 'console-feed' +import push from '../../../base-device/support/push.js' +import router from '../../../base-device/support/router.js' +import group from '../../../base-device/plugins/group.js' +import cdp, {CDPClient} from '../cdp/index.js' +import wireutil from '../../../../wire/util.js' +import logger from '../../../../util/logger.js' + import syrup from '@devicefarmer/stf-syrup' import webSocketServer from 'ws' import _ from 'lodash' -import urlformat from '../../base-device/support/urlformat.js' +import urlformat from '../../../base-device/support/urlformat.js' +import MyReplicator from './Replicator.js' +import * as transform from './transform/index.js' +import {GetAppAsset, GetAppAssetsList, GetAppHTML, GetAppInspectServerUrl} from "../../../../wire/wire.js"; const consoleListeners = new Map() +const replicator = new MyReplicator() +replicator.addTransforms(Object.values(transform)) -const inspectServer = (port, cdp, log) => +const inspectServer = (port: number, cdp: CDPClient, log: any) => new webSocketServer.Server({port}) .on('connection', async(ws, req) => { try { @@ -45,12 +48,11 @@ const inspectServer = (port, cdp, log) => const out = Object.keys(result)?.length === 1 && 'type' in result ? result.type : (result?.value || result) - // eslint-disable-next-line new-cap - ws.send(JSON.stringify(Encode({ + ws.send(replicator.encode({ method: 'log', timestamp: new Date().toISOString(), data: [out] - })), () => {}) + }), () => {}) }) ws.on('close', () => { @@ -59,20 +61,20 @@ const inspectServer = (port, cdp, log) => }) if (!consoleListeners.has(remoteAddress)) { - consoleListeners.set(remoteAddress, (arg, method, timestamp) => { - if (arg.value === '--mut--') { + consoleListeners.set(remoteAddress, (arg: any, method: string, timestamp: number) => { + if (arg?.value === '--mut--') { sendHTML() return } - // eslint-disable-next-line new-cap - ws.send(JSON.stringify(Encode({ + + ws.send(replicator.encode({ method, timestamp, data: [arg], - }))) + })) }) } } - catch (/** @type {any} */ err) { + catch (err: any) { log.error('Updates server :', err) ws.send(JSON.stringify({error: err?.message || err})) } @@ -87,11 +89,11 @@ export default syrup.serial() .define((options, push, router, cdp, group, urlformat) => { const log = logger.createLogger('tizen-device:plugins:webinspector') const reply = wireutil.reply(options.serial) - let frameId + let frameId: string | null = null - const success = (channel, body) => + const success = (channel: string, body: any) => push.send([channel, reply.okay('success', body)]) - const fail = (channel, err) => + const fail = (channel: string, err: any) => push.send([channel, reply.fail('fail', err?.message || err)]) const getAssetsList = async() => { @@ -102,7 +104,7 @@ export default syrup.serial() return result } - const getAsset = async(url) => { + const getAsset = async(url: string) => { if (!frameId) { await getAssetsList() } @@ -111,36 +113,39 @@ export default syrup.serial() } const wsUrl = urlformat(options.updWsUrlPattern, options.publicPort) + let inspServer: webSocketServer.Server | null = null - const handlers = { - + router // TODO: Create download endpoint - [wire.GetAppAsset .$code]: (channel, message) => getAsset(message.url).then(asset => - success(channel, asset) - ).catch(err => - fail(channel, err) - ), - - [wire.GetAppAssetsList .$code]: (channel) => getAssetsList().then(list => - success(channel, list) - ).catch(err => - fail(channel, err) - ), - - [wire.GetAppHTML .$code]: (channel) => cdp.getHTML().then(content => - success(channel, {content, base64Encoded: false}) - ).catch(err => - fail(channel, err) - ), - - [wire.GetAppInspectServerUrl .$code]: (channel) => - success(channel, wsUrl) - } - let inspServer = null + .on(GetAppAsset, (channel: string, message: any) => !!inspServer && + getAsset(message.url).then(asset => + success(channel, asset) + ).catch(err => + fail(channel, err) + )) + + .on(GetAppAssetsList, (channel: string) => !!inspServer && + getAssetsList().then(list => + success(channel, list) + ).catch(err => + fail(channel, err) + )) + + .on(GetAppHTML, (channel: string) => !!inspServer && + cdp.getHTML().then(content => + success(channel, {content, base64Encoded: false}) + ).catch(err => + fail(channel, err) + )) + + .on(GetAppInspectServerUrl, (channel: string) => + !!inspServer && success(channel, wsUrl) + ) + const plugin = { host: '', port: 0, - start: async(port, host = options.host) => { + start: async(port: number, host = options.host) => { plugin.host = host plugin.port = port @@ -149,15 +154,9 @@ export default syrup.serial() if (!inspServer) { inspServer = inspectServer(options.publicPort, cdp, log) } - - Object.entries(handlers) - .map(([event, handler]) => router.on(event, handler)) }, stop: async() => { - Object.entries(handlers) - .map(([event, handler]) => router.removeListener(event, handler)) - frameId = null await new Promise(r => { inspServer?.close(() => r) @@ -174,7 +173,7 @@ export default syrup.serial() const {Runtime} = cdp.client Runtime.on('consoleAPICalled', _.debounce((event) => { log.info('Send console output to listeners [ %s ]', event.type) - event.args.forEach((arg) => + event.args.forEach((arg: any) => consoleListeners.forEach(fn => fn(arg, event.type, event.timestamp) ) diff --git a/lib/units/tizen-device/plugins/webinspector/transform/BigInt.ts b/lib/units/tizen-device/plugins/webinspector/transform/BigInt.ts new file mode 100644 index 0000000000..cd7db82677 --- /dev/null +++ b/lib/units/tizen-device/plugins/webinspector/transform/BigInt.ts @@ -0,0 +1,23 @@ +import {Transform} from './index.js' + +/** + * Optimized BigInt transform for serialization/deserialization + * Serialize a `bigint` to a string with 'n' suffix for efficient parsing + */ +const BigIntTransform: Transform = { + type: 'BigInt', + + shouldTransform: (_type: string, obj: any): obj is bigint => { + return typeof obj === 'bigint' + }, + + toSerializable: (value: bigint): string => { + return `${value}n` + }, + + fromSerializable: (data: string): bigint => { + return BigInt(data.slice(0, -1)) + } +} + +export default BigIntTransform diff --git a/lib/units/tizen-device/plugins/webinspector/transform/Function.ts b/lib/units/tizen-device/plugins/webinspector/transform/Function.ts new file mode 100644 index 0000000000..1b2f80adb9 --- /dev/null +++ b/lib/units/tizen-device/plugins/webinspector/transform/Function.ts @@ -0,0 +1,85 @@ +import {Transform} from './index.js' + +/** + * Serialized function structure + */ +interface SerializedFunction { + name?: string + body?: string + proto?: string +} + +/** + * Transform for serializing functions into JSON-compatible format + * Note: This creates placeholder functions, not executable ones + */ +const FunctionTransform: Transform = { + type: 'Function', + lookup: Function, + + // Simple and fast function type check + shouldTransform: (type: string, obj: any): obj is Function => { + return typeof obj === 'function' + }, + + // Extract function metadata for serialization + toSerializable: (func: Function): SerializedFunction => { + let body = '' + + try { + // Extract function body between first { and last } + const funcString = func.toString() + const startIndex = funcString.indexOf('{') + 1 + const endIndex = funcString.lastIndexOf('}') + + if (startIndex > 0 && endIndex > startIndex) { + body = funcString.substring(startIndex, endIndex) + } + } + catch { + // Ignore errors in function stringification + } + + return { + name: func.name, + body, + proto: Object.getPrototypeOf(func).constructor.name + } + }, + + // Create placeholder function with metadata + fromSerializable: (data: SerializedFunction): Function | SerializedFunction => { + try { + const tempFunc = function() {} + + if (typeof data.name === 'string') { + Object.defineProperty(tempFunc, 'name', { + value: data.name, + writable: false, + configurable: true + }) + } + + if (typeof data.body === 'string') { + Object.defineProperty(tempFunc, 'body', { + value: data.body, + writable: false, + configurable: true + }) + } + + if (typeof data.proto === 'string') { // @ts-ignore + tempFunc.constructor = { + name: data.proto + } + } + + return tempFunc + } + catch { + return data + } + } +} + +export default FunctionTransform diff --git a/lib/units/tizen-device/plugins/webinspector/transform/HTML.ts b/lib/units/tizen-device/plugins/webinspector/transform/HTML.ts new file mode 100644 index 0000000000..f10911f9aa --- /dev/null +++ b/lib/units/tizen-device/plugins/webinspector/transform/HTML.ts @@ -0,0 +1,93 @@ +import {Transform} from './index.js' + +/** + * Serialized HTML element structure + */ +interface SerializedHTMLElement { + tagName: string + attributes: Record + innerHTML: string +} + +/** + * HTML element-like object for type checking + */ +interface HTMLElementLike { + children: any + innerHTML: string + tagName: string + attributes: ArrayLike<{ name: string; value: string }> & Iterable<{ name: string; value: string }> +} + +// Cached sandbox document for performance +let sandbox: Document | undefined + +/** + * Get or create sandbox document for safe HTML parsing + */ +const getSandbox = (): Document => { + return sandbox ??= document.implementation.createHTMLDocument('sandbox') +} + +/** + * Efficiently convert element attributes to plain object + */ +const objectifyAttributes = (element: HTMLElementLike): Record => { + const data: Record = {} + + // Use for...of for better performance with NamedNodeMap + for (const attribute of element.attributes) { + data[attribute.name] = attribute.value + } + + return data +} + +/** + * Transform for serializing HTML elements into JSON-compatible format + * Uses sandboxed document for safe deserialization + */ +const HTMLTransform: Transform = { + type: 'HTMLElement', + + // Optimized HTML element detection + shouldTransform: (type: string, obj: any): obj is HTMLElementLike => { + return obj && + obj.children && + typeof obj.innerHTML === 'string' && + typeof obj.tagName === 'string' + }, + + // Serialize HTML element to plain object + toSerializable: (element: HTMLElementLike): SerializedHTMLElement => { + return { + tagName: element.tagName.toLowerCase(), + attributes: objectifyAttributes(element), + innerHTML: element.innerHTML + } + }, + + // Deserialize to actual HTML element using sandbox + fromSerializable: (data: SerializedHTMLElement): HTMLElement | SerializedHTMLElement => { + try { + const element = getSandbox().createElement(data.tagName) + element.innerHTML = data.innerHTML + + for (const attributeName of Object.keys(data.attributes)) { + try { + element.setAttribute(attributeName, data.attributes[attributeName]) + } + catch { + // no-op + } + } + + return element + } + catch { + return data + } + } +} + +export default HTMLTransform diff --git a/lib/units/tizen-device/plugins/webinspector/transform/Map.ts b/lib/units/tizen-device/plugins/webinspector/transform/Map.ts new file mode 100644 index 0000000000..ffd5ffbcc8 --- /dev/null +++ b/lib/units/tizen-device/plugins/webinspector/transform/Map.ts @@ -0,0 +1,59 @@ +import {Transform} from './index.js' + +/** + * Serialized Map data structure + */ +interface SerializedMap { + name: 'Map' + body: Record + proto: string +} + +/** + * Transform for serializing Map objects into JSON-compatible format + * Handles object keys by JSON stringifying them + */ +const MapTransform: Transform = { + type: 'Map', + lookup: Map, + + // Optimized Map detection using constructor name + shouldTransform: (type: string, obj: any): obj is Map => { + return obj?.constructor?.name === 'Map' + }, + + // Convert Map to serializable object with stringified object keys + toSerializable: (map: Map): SerializedMap => { + const body: Record = {} + + // Optimize iteration with forEach for better performance + map.forEach((value, key) => { + // Stringify object keys, keep primitive keys as-is for efficiency + const serializedKey = typeof key === 'object' ? JSON.stringify(key) : key + body[serializedKey] = value + }) + + return { + name: 'Map', + body, + proto: Object.getPrototypeOf(map).constructor.name + } + }, + + // Convert serialized data back to object (not actual Map for compatibility) + fromSerializable: (data: SerializedMap): Record => { + const obj = {...data.body} + + // Restore constructor information if available + if (typeof data.proto === 'string') { + // @ts-ignore - Intentional constructor override for compatibility + obj.constructor = { + name: data.proto + } + } + + return obj + } +} + +export default MapTransform diff --git a/lib/units/tizen-device/plugins/webinspector/transform/arithmetic.ts b/lib/units/tizen-device/plugins/webinspector/transform/arithmetic.ts new file mode 100644 index 0000000000..60b4701621 --- /dev/null +++ b/lib/units/tizen-device/plugins/webinspector/transform/arithmetic.ts @@ -0,0 +1,48 @@ +import {Transform} from './index.js' + +const enum ArithmeticType { + infinity = 0, + minusInfinity = 1, + minusZero = 2 +} + +const isMinusZero = (value: number): boolean => 1 / value === -Infinity + +/** + * Transform for handling special arithmetic values: Infinity, -Infinity, and -0 + * These values need special handling as they don't serialize properly in JSON + */ +const ArithmeticTransform: Transform = { + type: 'Arithmetic', + lookup: Number, + + shouldTransform: (type: string, value: any): value is number => { + return type === 'number' && + (value === Infinity || value === -Infinity || isMinusZero(value)) + }, + + toSerializable: (value: number): ArithmeticType => { + if (value === Infinity) { + return ArithmeticType.infinity + } + if (value === -Infinity) { + return ArithmeticType.minusInfinity + } + return ArithmeticType.minusZero + }, + + fromSerializable: (data: ArithmeticType): number => { + switch (data) { + case ArithmeticType.infinity: + return Infinity + case ArithmeticType.minusInfinity: + return -Infinity + case ArithmeticType.minusZero: + return -0 + default: + return data as number + } + } +} + +export default ArithmeticTransform diff --git a/lib/units/tizen-device/plugins/webinspector/transform/index.ts b/lib/units/tizen-device/plugins/webinspector/transform/index.ts new file mode 100644 index 0000000000..81dd2dc6bc --- /dev/null +++ b/lib/units/tizen-device/plugins/webinspector/transform/index.ts @@ -0,0 +1,17 @@ +// Transform exports +export {default as ArithmeticTransform} from './arithmetic.js' +export {default as BigIntTransform} from './BigInt.js' +export {default as FunctionTransform} from './Function.js' +export {default as HTMLTransform} from './HTML.js' +export {default as MapTransform} from './Map.js' + +/** + * Transform interface matching the main Replicator requirements + */ +export interface Transform { + type: string + lookup?: any + shouldTransform(type: string, val: any): boolean + toSerializable(val: any): any + fromSerializable(val: any): any +} diff --git a/lib/units/websocket/index.js b/lib/units/websocket/index.js index 70243e570a..07e08e8c22 100644 --- a/lib/units/websocket/index.js +++ b/lib/units/websocket/index.js @@ -45,7 +45,7 @@ export default (async function(options) { , push , pushdev } = await db.createZMQSockets({...options.endpoints}, log) - await db.connect(push, pushdev, channelRouter) + await db.connect({push, pushdev, channelRouter}) ;[wireutil.global].forEach(function(channel) { log.info('Subscribing to permanent webosocket channel "%s"', channel) @@ -899,11 +899,18 @@ export default (async function(options) { wireutil.transaction(responseChannel, new wire.BluetoothCleanBondedMessage()) ]) }) - .on('group.invite', function(channel, responseChannel, data) { + .on('group.invite', async(channel, responseChannel, data) => { joinChannel(responseChannel) + const keys = await dbapi.getUserAdbKeys(user.email) push.send([ channel, - wireutil.transaction(responseChannel, new wire.GroupMessage(new wire.OwnerMessage(user.email, user.name, user.group), data.timeout || null, wireutil.toDeviceRequirements(data.requirements))) + wireutil.transaction(responseChannel, new wire.GroupMessage( + new wire.OwnerMessage(user.email, user.name, user.group), + data.timeout || null, + wireutil.toDeviceRequirements(data.requirements), + null, + keys.map(key => key.fingerprint) + )) ]) }) .on('group.kick', function(channel, responseChannel, data) { diff --git a/lib/util/grouputil.js b/lib/util/grouputil.js deleted file mode 100644 index caade52508..0000000000 --- a/lib/util/grouputil.js +++ /dev/null @@ -1,60 +0,0 @@ -import util from 'util' -import Promise from 'bluebird' -import semver from 'semver' -import minimatch from 'minimatch' -import wire from '../wire/index.js' -import {RequirementType} from '../wire/wire.js' -function RequirementMismatchError(name) { - Error.call(this) - this.name = 'RequirementMismatchError' - this.message = util.format('Requirement mismatch for "%s"', name) - Error.captureStackTrace(this, RequirementMismatchError) -} -util.inherits(RequirementMismatchError, Error) -function AlreadyGroupedError() { - Error.call(this) - this.name = 'AlreadyGroupedError' - this.message = 'Already a member of another group' - Error.captureStackTrace(this, AlreadyGroupedError) -} -util.inherits(AlreadyGroupedError, Error) -function NoGroupError() { - Error.call(this) - this.name = 'NoGroupError' - this.message = 'Not a member of any group' - Error.captureStackTrace(this, NoGroupError) -} -util.inherits(NoGroupError, Error) - -/** @type {(capabilities: any, requirements: any) => Promise} */ -export const match = Promise.method(function(capabilities, requirements) { - return requirements.every(function(req) { - var capability = capabilities[req.name] - if (!capability) { - throw new RequirementMismatchError(req.name) - } - switch (req.type) { - case RequirementType.SEMVER: - if (!semver.satisfies(capability, req.value)) { - throw new RequirementMismatchError(req.name) - } - break - case RequirementType.GLOB: - if (!minimatch(capability, req.value)) { - throw new RequirementMismatchError(req.name) - } - break - case RequirementType.EXACT: - if (capability !== req.value) { - throw new RequirementMismatchError(req.name) - } - break - default: - throw new RequirementMismatchError(req.name) - } - return true - }) -}) -export {RequirementMismatchError} -export {AlreadyGroupedError} -export {NoGroupError} diff --git a/lib/util/grouputil.ts b/lib/util/grouputil.ts new file mode 100644 index 0000000000..7c457eb1ec --- /dev/null +++ b/lib/util/grouputil.ts @@ -0,0 +1,67 @@ +import util from 'util' +import semver from 'semver' // @ts-ignore +import minimatch from 'minimatch' // TODO: update +import {RequirementType} from '../wire/wire.js' + +export class RequirementMismatchError extends Error { + constructor(name: string) { + super() + this.name = 'RequirementMismatchError' + this.message = util.format('Requirement mismatch for "%s"', name) + Error.captureStackTrace(this, RequirementMismatchError) + } +} + +export class AlreadyGroupedError extends Error { + constructor() { + super() + this.name = 'AlreadyGroupedError' + this.message = 'Already a member of another group' + Error.captureStackTrace(this, AlreadyGroupedError) + } +} + +export class NoGroupError extends Error { + constructor() { + super() + this.name = 'NoGroupError' + this.message = 'Not a member of any group' + Error.captureStackTrace(this, NoGroupError) + } +} + +interface Requirements { + name: string + value: string + type: RequirementType +} + +export const match = async(capabilities: any, requirements: Requirements[]) => { + return requirements.every((req) => { + const capability = capabilities[req.name] + if (!capability) { + throw new RequirementMismatchError(req.name) + } + + switch (req.type) { + case RequirementType.SEMVER: + if (!semver.satisfies(capability, req.value)) { + throw new RequirementMismatchError(req.name) + } + break + case RequirementType.GLOB: + if (!minimatch(capability, req.value)) { + throw new RequirementMismatchError(req.name) + } + break + case RequirementType.EXACT: + if (capability !== req.value) { + throw new RequirementMismatchError(req.name) + } + break + default: + throw new RequirementMismatchError(req.name) + } + return true + }) +} diff --git a/lib/util/lifecycle.js b/lib/util/lifecycle.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/util/ttlset.js b/lib/util/ttlset.js deleted file mode 100644 index 8643f10e1b..0000000000 --- a/lib/util/ttlset.js +++ /dev/null @@ -1,94 +0,0 @@ -import util from 'util' -import EventEmitter from 'eventemitter3' -function TtlItem(value) { - this.next = null - this.prev = null - this.time = null - this.value = value -} -function TtlSet(ttl) { - EventEmitter.call(this) - this.head = null - this.tail = null - this.mapping = Object.create(null) - this.ttl = ttl - this.timer = null -} -util.inherits(TtlSet, EventEmitter) -TtlSet.SILENT = 1 -TtlSet.prototype.bump = function(value, time, flags) { - var item = this._remove(this.mapping[value]) || this._create(value, flags) - item.time = time || Date.now() - item.prev = this.tail - this.tail = item - if (item.prev) { - item.prev.next = item - } - else { - this.head = item - this._scheduleCheck() - } -} -TtlSet.prototype.drop = function(value, flags) { - this._drop(this.mapping[value], flags) -} -TtlSet.prototype.stop = function() { - clearTimeout(this.timer) -} -TtlSet.prototype._scheduleCheck = function() { - clearTimeout(this.timer) - if (this.head) { - var delay = Math.max(0, this.ttl - (Date.now() - this.head.time)) - this.timer = setTimeout(this._check.bind(this), delay) - } -} -TtlSet.prototype._check = function() { - var now = Date.now() - var item - while ((item = this.head)) { - if (now - item.time > this.ttl) { - this._drop(item, 0) - } - else { - break - } - } - this._scheduleCheck() -} -TtlSet.prototype._create = function(value, flags) { - var item = new TtlItem(value) - this.mapping[value] = item - if ((flags & TtlSet.SILENT) !== TtlSet.SILENT) { - this.emit('insert', value) - } - return item -} -TtlSet.prototype._drop = function(item, flags) { - if (item) { - this._remove(item) - delete this.mapping[item.value] - if ((flags & TtlSet.SILENT) !== TtlSet.SILENT) { - this.emit('drop', item.value) - } - } -} -TtlSet.prototype._remove = function(item) { - if (!item) { - return null - } - if (item.prev) { - item.prev.next = item.next - } - if (item.next) { - item.next.prev = item.prev - } - if (item === this.head) { - this.head = item.next - } - if (item === this.tail) { - this.tail = item.prev - } - item.next = item.prev = null - return item -} -export default TtlSet diff --git a/lib/util/ttlset.ts b/lib/util/ttlset.ts new file mode 100644 index 0000000000..0c85c36b59 --- /dev/null +++ b/lib/util/ttlset.ts @@ -0,0 +1,113 @@ +import EventEmitter from 'events' + +class TTLItem { + constructor( + public value: string, + public time: number, + public prev: TTLItem | null, + public next: TTLItem | null + ) {} +} + +class TTLSet extends EventEmitter { + private head: TTLItem | null = null + private tail: TTLItem | null = null + private mapping: Record = {} + private timer: NodeJS.Timeout | null = null + + static SILENT = 1 + + constructor( + private ttl = 30_000 + ) { + super() + } + + bump(value: string, time: number, flags?: any) { + const item = + this.remove(this.mapping[value]) || + this.create(value, this.tail, flags) + + item.time = time || Date.now() + this.tail = item + if (item.prev) { + item.prev.next = item + } + else { + this.head = item + } + + this.scheduleCheck() + } + + drop(value: string, flags?: any) { + this._drop(this.mapping[value], flags) + } + + stop() { + clearTimeout(this.timer!) + } + + private scheduleCheck() { + clearTimeout(this.timer!) + if (this.head) { + const delay = Math.max(0, this.ttl - (Date.now() - this.head.time)) + this.timer = setTimeout(this.check.bind(this), delay) + } + } + + private check() { + const now = Date.now() + let item: TTLItem | null + while ((item = this.head)) { + if (now - item.time > this.ttl) { + this._drop(item, 0) + } + else { + break + } + } + this.scheduleCheck() + } + + private create(value: string, prev: TTLItem | null, flags: any) { + const item = new TTLItem(value, 0, prev, null) + this.mapping[value] = item + if ((flags & TTLSet.SILENT) !== TTLSet.SILENT) { + this.emit('insert', value) + } + return item + } + + private _drop(item: TTLItem, flags?: any) { + if (item) { + this.remove(item) + delete this.mapping[item.value] + if ((flags & TTLSet.SILENT) !== TTLSet.SILENT) { + this.emit('drop', item.value) + } + } + } + + private remove(item: TTLItem) { + if (!item) { + return null + } + if (item.prev) { + item.prev.next = item.next + } + if (item.next) { + item.next.prev = item.prev + } + if (item === this.head) { + this.head = item.next + } + if (item === this.tail) { + this.tail = item.prev + } + item.next = item.prev = null + return item + } +} + +export default TTLSet diff --git a/lib/wire/router.ts b/lib/wire/router.ts index eca2d22f87..10331747cb 100644 --- a/lib/wire/router.ts +++ b/lib/wire/router.ts @@ -6,7 +6,7 @@ import { Any } from "./google/protobuf/any.ts"; const log = logger.createLogger("wire:router"); -type MessageHandler = (channel: string, message: T) => unknown +type MessageHandler = (channel: string, message: T, data: Buffer) => unknown export class WireRouter { emitter = new EventEmitter() diff --git a/lib/wire/transmanager.js b/lib/wire/transmanager.js deleted file mode 100644 index 926b5ccfbb..0000000000 --- a/lib/wire/transmanager.js +++ /dev/null @@ -1,58 +0,0 @@ -import {v4 as uuidv4} from 'uuid' -import apiutil from '../util/apiutil.js' -import wire from './index.js' -import {WireRouter} from './router.js' -import * as Sentry from '@sentry/node' -import wireutil from './util.js' -import {TransactionDoneMessage} from './wire.js' - -export const runTransaction = (channel, message, {sub, push, channelRouter, timeout = apiutil.GRPC_WAIT_TIMEOUT}) => { - return Sentry.startSpan({ - op: 'wireTransaction', - name: message.$code, - attributes: { - message, - channel, - timeout - }, - forceTransaction: true, - }, () => { - const responseChannel = 'txn_' + uuidv4() - sub.subscribe(responseChannel) - return new Promise((resolve, reject) => { - const messageListener = new WireRouter() - .on(TransactionDoneMessage, function(channel, message) { - clearTimeout(trTimeout) - sub.unsubscribe(responseChannel) - channelRouter.removeListener(responseChannel, messageListener) - if (message.success) { - resolve(message) - } - else { - reject(message) - } - }) - .handler() - - const trTimeout = setTimeout(function() { - channelRouter.removeListener(responseChannel, messageListener) - sub.unsubscribe(responseChannel) - - Sentry.addBreadcrumb({ - data: {channel, message, timeout}, - message: 'Transaction context', - level: 'warning', - type: 'default' - }) - Sentry.captureMessage('Timeout when running transaction') - reject(new Error('Timeout when running transaction')) - }, timeout) - - channelRouter.on(responseChannel, messageListener) - push.send([ - channel, - wireutil.transaction(responseChannel, message) - ]) - }) - }) -} diff --git a/lib/wire/transmanager.ts b/lib/wire/transmanager.ts new file mode 100644 index 0000000000..27dc0eb88a --- /dev/null +++ b/lib/wire/transmanager.ts @@ -0,0 +1,122 @@ +import {v4 as uuidv4} from 'uuid' +import apiutil from '../util/apiutil.js' +import {TransactionDoneMessage} from './wire.js' +import {WireRouter} from './router.js' +import * as Sentry from '@sentry/node' +import wireutil from './util.js' +import type {SocketWrapper} from '../util/zmqutil.js' +import EventEmitter from 'events' +import {MessageType} from '@protobuf-ts/runtime' + +const sentryTransactionSpan = >(channel: string, message: any, timeout: number, cb: () => T): T => + Sentry.startSpan({ + op: 'wireTransaction', + name: message.$code, + attributes: { + message, + channel, + timeout + }, + forceTransaction: true, + }, cb) + +const sentryCaptureTimeout = (channel: string, message: any, timeout: number) => { + Sentry.addBreadcrumb({ + data: {channel, message, timeout}, + message: 'Transaction context', + level: 'warning', + type: 'default' + }) + Sentry.captureMessage('Timeout when running transaction') +} + +interface TransactionTransportOptions { + sub: SocketWrapper + push: SocketWrapper + channelRouter: EventEmitter + timeout?: number +} + +export const runTransaction = (channel: string, messageType: MessageType, message: T, {sub, push, channelRouter, timeout = apiutil.GRPC_WAIT_TIMEOUT}: TransactionTransportOptions) => + sentryTransactionSpan( + channel, + message, + timeout, + () => { + const responseChannel = 'txn_' + uuidv4() + sub.subscribe(responseChannel) + return new Promise((resolve, reject) => { + const messageListener = new WireRouter() + .on(TransactionDoneMessage, (channel: string, message: any) => { + clearTimeout(trTimeout) + sub.unsubscribe(responseChannel) + channelRouter.removeListener(responseChannel, messageListener) + if (message.success) { + resolve(message) + } + else { + reject(message) + } + }) + .handler() + + const trTimeout = setTimeout(function() { + channelRouter.removeListener(responseChannel, messageListener) + sub.unsubscribe(responseChannel) + + sentryCaptureTimeout(channel, message, timeout) + reject(new Error('Timeout when running transaction')) + }, timeout) + + channelRouter.on(responseChannel, messageListener) + push.send([ + channel, + wireutil.tr(responseChannel, messageType, message) + ]) + }) + } + ) + +type TransactionDevTransportOptions = Omit & { + router: WireRouter +} + +export const runTransactionDev = (channel: string, messageType: MessageType, message: T, {sub, push, router, timeout = apiutil.GRPC_WAIT_TIMEOUT}: TransactionDevTransportOptions): Promise => + sentryTransactionSpan( + channel, + message, + timeout, + () => { + const responseChannel = 'txn_' + uuidv4() + sub.subscribe(responseChannel) + return new Promise((resolve, reject) => { + const messageListener = (channel: string, message: any) => { + clearTimeout(trTimeout) + sub.unsubscribe(responseChannel) + router.removeListener(TransactionDoneMessage, messageListener) + + const body = message.body ? JSON.parse(message.body) : {} + if (message.success) { + resolve(body) + } + else { + reject(body) + } + } + router.on(TransactionDoneMessage, messageListener) + + const trTimeout = setTimeout(() => { + router.removeListener(TransactionDoneMessage, messageListener) + sub.unsubscribe(responseChannel) + + sentryCaptureTimeout(channel, message, timeout) + reject(new Error('Timeout when running transaction')) + }, timeout) + + push.send([ + channel, + wireutil.tr(responseChannel, messageType, message) + ]) + }) + } + ) diff --git a/lib/wire/wire.proto b/lib/wire/wire.proto index 2e87a0f41a..53be0505e9 100644 --- a/lib/wire/wire.proto +++ b/lib/wire/wire.proto @@ -277,7 +277,7 @@ message DeviceIntroductionMessage { required string serial = 1; required DeviceStatus status = 2; required ProviderMessage provider = 3; -// optional DeviceGroupMessage group = 4; + optional string deviceType = 4; } message DeviceIosIntroductionMessage { @@ -430,6 +430,7 @@ message GroupMessage { optional uint32 timeout = 2; repeated DeviceRequirement requirements = 3; optional string usage = 4; + repeated string keys = 5; } message AutoGroupMessage { @@ -445,6 +446,7 @@ message JoinGroupMessage { required string serial = 1; required OwnerMessage owner = 2; optional string usage = 3; + optional uint32 timeout = 4; } message JoinGroupByAdbFingerprintMessage { @@ -895,3 +897,15 @@ message GetAppHTML { message GetAppInspectServerUrl { } + +message DeviceStatusChange { + required string serial = 1; + required uint32 timeout = 2; +} + +message DeviceGetIsInOrigin { + required string serial = 1; +} + +message GetPresentDevices { +} diff --git a/lib/wire/wire.ts b/lib/wire/wire.ts index a005fb4e3c..85edad04eb 100644 --- a/lib/wire/wire.ts +++ b/lib/wire/wire.ts @@ -792,7 +792,11 @@ export interface DeviceIntroductionMessage { /** * @generated from protobuf field: required ProviderMessage provider = 3 */ - provider?: ProviderMessage; // optional DeviceGroupMessage group = 4; + provider?: ProviderMessage; + /** + * @generated from protobuf field: optional string deviceType = 4 + */ + deviceType?: string; } /** * @generated from protobuf message DeviceIosIntroductionMessage @@ -1189,6 +1193,10 @@ export interface GroupMessage { * @generated from protobuf field: optional string usage = 4 */ usage?: string; + /** + * @generated from protobuf field: repeated string keys = 5 + */ + keys: string[]; } /** * @generated from protobuf message AutoGroupMessage @@ -1228,6 +1236,10 @@ export interface JoinGroupMessage { * @generated from protobuf field: optional string usage = 3 */ usage?: string; + /** + * @generated from protobuf field: optional uint32 timeout = 4 + */ + timeout?: number; } /** * @generated from protobuf message JoinGroupByAdbFingerprintMessage @@ -2358,6 +2370,33 @@ export interface GetAppHTML { */ export interface GetAppInspectServerUrl { } +/** + * @generated from protobuf message DeviceStatusChange + */ +export interface DeviceStatusChange { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; + /** + * @generated from protobuf field: required uint32 timeout = 2 + */ + timeout: number; +} +/** + * @generated from protobuf message DeviceGetIsInOrigin + */ +export interface DeviceGetIsInOrigin { + /** + * @generated from protobuf field: required string serial = 1 + */ + serial: string; +} +/** + * @generated from protobuf message GetPresentDevices + */ +export interface GetPresentDevices { +} /** * @generated from protobuf enum DeviceStatus */ @@ -5072,7 +5111,8 @@ class DeviceIntroductionMessage$Type extends MessageType ["DeviceStatus", DeviceStatus] }, - { no: 3, name: "provider", kind: "message", T: () => ProviderMessage } + { no: 3, name: "provider", kind: "message", T: () => ProviderMessage }, + { no: 4, name: "deviceType", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } ]); } create(value?: PartialMessage): DeviceIntroductionMessage { @@ -5097,6 +5137,9 @@ class DeviceIntroductionMessage$Type extends MessageType { { no: 1, name: "owner", kind: "message", T: () => OwnerMessage }, { no: 2, name: "timeout", kind: "scalar", opt: true, T: 13 /*ScalarType.UINT32*/ }, { no: 3, name: "requirements", kind: "message", repeat: 2 /*RepeatType.UNPACKED*/, T: () => DeviceRequirement }, - { no: 4, name: "usage", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + { no: 4, name: "usage", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "keys", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ } ]); } create(value?: PartialMessage): GroupMessage { const message = globalThis.Object.create((this.messagePrototype!)); message.requirements = []; + message.keys = []; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -6443,6 +6491,9 @@ class GroupMessage$Type extends MessageType { case /* optional string usage */ 4: message.usage = reader.string(); break; + case /* repeated string keys */ 5: + message.keys.push(reader.string()); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -6467,6 +6518,9 @@ class GroupMessage$Type extends MessageType { /* optional string usage = 4; */ if (message.usage !== undefined) writer.tag(4, WireType.LengthDelimited).string(message.usage); + /* repeated string keys = 5; */ + for (let i = 0; i < message.keys.length; i++) + writer.tag(5, WireType.LengthDelimited).string(message.keys[i]); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -6584,7 +6638,8 @@ class JoinGroupMessage$Type extends MessageType { super("JoinGroupMessage", [ { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 2, name: "owner", kind: "message", T: () => OwnerMessage }, - { no: 3, name: "usage", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ } + { no: 3, name: "usage", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "timeout", kind: "scalar", opt: true, T: 13 /*ScalarType.UINT32*/ } ]); } create(value?: PartialMessage): JoinGroupMessage { @@ -6608,6 +6663,9 @@ class JoinGroupMessage$Type extends MessageType { case /* optional string usage */ 3: message.usage = reader.string(); break; + case /* optional uint32 timeout */ 4: + message.timeout = reader.uint32(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -6629,6 +6687,9 @@ class JoinGroupMessage$Type extends MessageType { /* optional string usage = 3; */ if (message.usage !== undefined) writer.tag(3, WireType.LengthDelimited).string(message.usage); + /* optional uint32 timeout = 4; */ + if (message.timeout !== undefined) + writer.tag(4, WireType.Varint).uint32(message.timeout); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -11543,3 +11604,143 @@ class GetAppInspectServerUrl$Type extends MessageType { * @generated MessageType for protobuf message GetAppInspectServerUrl */ export const GetAppInspectServerUrl = new GetAppInspectServerUrl$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceStatusChange$Type extends MessageType { + constructor() { + super("DeviceStatusChange", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "timeout", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): DeviceStatusChange { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + message.timeout = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceStatusChange): DeviceStatusChange { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + case /* required uint32 timeout */ 2: + message.timeout = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceStatusChange, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + /* required uint32 timeout = 2; */ + if (message.timeout !== 0) + writer.tag(2, WireType.Varint).uint32(message.timeout); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceStatusChange + */ +export const DeviceStatusChange = new DeviceStatusChange$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceGetIsInOrigin$Type extends MessageType { + constructor() { + super("DeviceGetIsInOrigin", [ + { no: 1, name: "serial", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): DeviceGetIsInOrigin { + const message = globalThis.Object.create((this.messagePrototype!)); + message.serial = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceGetIsInOrigin): DeviceGetIsInOrigin { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required string serial */ 1: + message.serial = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeviceGetIsInOrigin, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required string serial = 1; */ + if (message.serial !== "") + writer.tag(1, WireType.LengthDelimited).string(message.serial); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message DeviceGetIsInOrigin + */ +export const DeviceGetIsInOrigin = new DeviceGetIsInOrigin$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GetPresentDevices$Type extends MessageType { + constructor() { + super("GetPresentDevices", []); + } + create(value?: PartialMessage): GetPresentDevices { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GetPresentDevices): GetPresentDevices { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GetPresentDevices, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GetPresentDevices + */ +export const GetPresentDevices = new GetPresentDevices$Type(); diff --git a/package-lock.json b/package-lock.json index 18b4acae70..7d4e593f22 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,6 @@ "chalk": "1.1.3", "chrome-remote-interface": "^0.33.3", "compression": "1.7.4", - "console-feed": "^3.8.0", "cookie": "^1.0.1", "cookie-parser": "^1.4.6", "cookie-session": "2.0.0", @@ -126,6 +125,7 @@ "@types/http-proxy": "^1.17.16", "@types/lodash": "^4.17.16", "@types/node": "^22.15.17", + "@types/semver": "^7.7.1", "@types/split": "^1.0.5", "@types/temp": "^0.9.4", "@types/tmp": "^0.2.6", @@ -1150,53 +1150,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/generator": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", - "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.0", - "@babel/types": "^7.28.0", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-validator-identifier": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", @@ -1206,21 +1159,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/parser": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", - "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/runtime": { "version": "7.28.2", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz", @@ -1230,51 +1168,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", - "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.0", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.0", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", - "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@bufbuild/protobuf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.6.3.tgz", @@ -4751,6 +4644,13 @@ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "license": "MIT" }, + "node_modules/@types/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/send": { "version": "0.17.5", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", @@ -5979,41 +5879,6 @@ "proxy-from-env": "^1.1.0" } }, - "node_modules/babel-plugin-emotion": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.2.2.tgz", - "integrity": "sha512-SMSkGoqTbTyUTDeuVuPIWifPdUGkTk1Kf9BWRiXIOIcuyMfsdp2EjeiiFvOzX8NOBvEh/ypKYvUh2rkgAJMCLA==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.0.0", - "@emotion/hash": "0.8.0", - "@emotion/memoize": "0.7.4", - "@emotion/serialize": "^0.11.16", - "babel-plugin-macros": "^2.0.0", - "babel-plugin-syntax-jsx": "^6.18.0", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^1.0.5", - "find-root": "^1.1.0", - "source-map": "^0.5.7" - } - }, - "node_modules/babel-plugin-macros": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", - "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "cosmiconfig": "^6.0.0", - "resolve": "^1.12.0" - } - }, - "node_modules/babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==", - "license": "MIT" - }, "node_modules/backoff": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", @@ -7081,37 +6946,6 @@ "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "license": "ISC" }, - "node_modules/console-feed": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/console-feed/-/console-feed-3.8.0.tgz", - "integrity": "sha512-H7d5dbVOmsujpMdI252RGHKxGwTybRI9o1aDUe2xDeVC63Koqh/QC7Rvo48EYcU3aMCM4OgWHKKISsZ2dMLX7w==", - "license": "MIT", - "dependencies": { - "@emotion/core": "^10.0.10", - "@emotion/styled": "^10.0.12", - "emotion-theming": "^10.0.10", - "linkifyjs": "^2.1.6", - "react-inline-center": "1.0.1", - "react-inspector": "^5.1.0" - }, - "peerDependencies": { - "react": "^15.x || ^16.x || ^17.x || ^18.x || ^19.x" - } - }, - "node_modules/console-feed/node_modules/react-inspector": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-5.1.1.tgz", - "integrity": "sha512-GURDaYzoLbW8pMGXwYPDBIv6nqei4kK7LPRZ9q9HCZF54wqXz/dnylBp/kfE9XmekBhHvLDdcYeyIwSrvtOiWg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.0.0", - "is-dom": "^1.0.0", - "prop-types": "^15.0.0" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0" - } - }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -7153,12 +6987,6 @@ "node": ">= 0.6" } }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "license": "MIT" - }, "node_modules/cookie": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", @@ -7283,31 +7111,6 @@ "node": ">= 0.10" } }, - "node_modules/cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "license": "MIT", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cosmiconfig/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, "node_modules/crc-32": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", @@ -7361,12 +7164,6 @@ "node": ">= 0.8" } }, - "node_modules/csstype": { - "version": "2.6.21", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", - "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==", - "license": "MIT" - }, "node_modules/csurf": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/csurf/-/csurf-1.11.0.tgz", @@ -7707,21 +7504,6 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, - "node_modules/emotion-theming": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emotion-theming/-/emotion-theming-10.3.0.tgz", - "integrity": "sha512-mXiD2Oj7N9b6+h/dC6oLf9hwxbtKHQjoIqtodEyL8CpkN4F3V4IK/BT4D0C7zSs4BBFOu4UlPJbvvBLa88SGEA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.5.5", - "@emotion/weak-memoize": "0.2.5", - "hoist-non-react-statics": "^3.3.0" - }, - "peerDependencies": { - "@emotion/core": "^10.0.27", - "react": ">=16.3.0" - } - }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", @@ -8674,12 +8456,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "license": "MIT" - }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -9325,15 +9101,6 @@ "node": "*" } }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "license": "BSD-3-Clause", - "dependencies": { - "react-is": "^16.7.0" - } - }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -9725,16 +9492,6 @@ "integrity": "sha512-vLwCNpTNkFC5k7SBRxPubhOCryeulkOsSkjbGyZ8eOzZmzMS+hSEO/Kn9ZOVhFNAlRZTFc4ZKql48hESuYUPIQ==", "license": "MIT" }, - "node_modules/is-dom": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-dom/-/is-dom-1.1.0.tgz", - "integrity": "sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ==", - "license": "MIT", - "dependencies": { - "is-object": "^1.0.1", - "is-window": "^1.0.2" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -9783,27 +9540,12 @@ "node": ">=0.12.0" } }, - "node_modules/is-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "license": "MIT" }, - "node_modules/is-window": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-window/-/is-window-1.0.2.tgz", - "integrity": "sha512-uj00kdXyZb9t9RcAUAwMZAnkBUwdYGhYlt7djMXhfyhUCzwNba50tIiBKR7q0l7tdoBtFVw/3JmLY6fI3rmZmg==", - "license": "MIT" - }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -9903,13 +9645,6 @@ "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", "license": "BSD-3-Clause" }, - "node_modules/jquery": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", - "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", - "license": "MIT", - "peer": true - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -9934,18 +9669,6 @@ "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", "license": "MIT" }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/jsftp": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/jsftp/-/jsftp-2.1.3.tgz", @@ -10220,17 +9943,6 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "license": "MIT" }, - "node_modules/linkifyjs": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-2.1.9.tgz", - "integrity": "sha512-74ivurkK6WHvHFozVaGtQWV38FzBwSTGNmJolEgFp7QgR2bl6ArUWlvT4GcHKbPe1z3nWYi+VUdDZk16zDOVug==", - "license": "MIT", - "peerDependencies": { - "jquery": ">= 1.11.0", - "react": ">= 0.14.0", - "react-dom": ">= 0.14.0" - } - }, "node_modules/load-bmfont": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.2.tgz", @@ -10331,18 +10043,6 @@ "node": ">=0.6" } }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, "node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", @@ -12073,17 +11773,6 @@ "node": ">=10.0.0" } }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, "node_modules/proper-lockfile": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", @@ -12359,44 +12048,6 @@ "node": ">=0.10.0" } }, - "node_modules/react": { - "version": "19.1.1", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz", - "integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "19.1.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz", - "integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==", - "license": "MIT", - "peer": true, - "dependencies": { - "scheduler": "^0.26.0" - }, - "peerDependencies": { - "react": "^19.1.1" - } - }, - "node_modules/react-inline-center": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-inline-center/-/react-inline-center-1.0.1.tgz", - "integrity": "sha512-nMxG933OWuZET/CkvQTPBVEPNRI2zhfeeeiRqXKKzSdvIPHnHnDXZmh9KkRO2DDCjJFvZQ3KIe50lXaaxvnoNw==", - "license": "MIT", - "peerDependencies": { - "react": "*" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT" - }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -12898,13 +12549,6 @@ "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", "license": "ISC" }, - "node_modules/scheduler": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", - "license": "MIT", - "peer": true - }, "node_modules/schema-utils": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", @@ -13452,15 +13096,6 @@ "node": ">= 14" } }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", diff --git a/package.json b/package.json index 250090d328..257e9e1c0f 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,6 @@ "chalk": "1.1.3", "chrome-remote-interface": "^0.33.3", "compression": "1.7.4", - "console-feed": "^3.8.0", "cookie": "^1.0.1", "cookie-parser": "^1.4.6", "cookie-session": "2.0.0", @@ -144,6 +143,7 @@ "@types/http-proxy": "^1.17.16", "@types/lodash": "^4.17.16", "@types/node": "^22.15.17", + "@types/semver": "^7.7.1", "@types/split": "^1.0.5", "@types/temp": "^0.9.4", "@types/tmp": "^0.2.6", diff --git a/test/api/conftest.py b/test/api/conftest.py index d468c5816a..a9b3de0023 100644 --- a/test/api/conftest.py +++ b/test/api/conftest.py @@ -22,6 +22,10 @@ STF_SECRET = 'kute kittykat' +DEFAULT_GROUPS_NUMBER = 10 +DEFAULT_GROUPS_DURATION = 1296000000 +DEFAULT_GROUPS_REPETITIONS = 10 + def pytest_addoption(parser): parser.addoption("--token", action="store") @@ -440,3 +444,17 @@ def failure_response_check_func(response, status_code=401, message=None): return response_content return failure_response_check_func + +class Quotas: + def __init__(self, number, duration, repetitions): + self.number = number + self.duration = duration + self.repetitions = repetitions + +@pytest.fixture() +def default_quotas(): + return Quotas( + DEFAULT_GROUPS_NUMBER, + DEFAULT_GROUPS_DURATION, + DEFAULT_GROUPS_REPETITIONS + ) \ No newline at end of file diff --git a/test/api/users/test_user_lifecycle_management.py b/test/api/users/test_user_lifecycle_management.py index 7749cccb60..01a9ff8887 100644 --- a/test/api/users/test_user_lifecycle_management.py +++ b/test/api/users/test_user_lifecycle_management.py @@ -12,7 +12,7 @@ class TestUserLifecycleManagement: """Test suite for user creation, modification, and deletion""" def test_create_and_delete_user_complete_flow(self, api_client, random_user, successful_response_check, - common_group_id): + common_group_id, default_quotas): """Test complete user lifecycle from creation to deletion""" user = random_user() @@ -46,11 +46,11 @@ def test_create_and_delete_user_complete_flow(self, api_client, random_user, suc # Validate user quotas quotas = user_dict.get('groups').get('quotas') - equal(quotas.get('allocated').get('number'), quotas.get('defaultGroupsNumber')) - equal(quotas.get('allocated').get('duration'), quotas.get('defaultGroupsDuration')) + equal(quotas.get('allocated').get('number'), default_quotas.number) + equal(quotas.get('allocated').get('duration'), default_quotas.duration) equal(quotas.get('consumed').get('number'), 0) equal(quotas.get('consumed').get('duration'), 0) - equal(quotas.get('repetitions'), quotas.get('defaultGroupsRepetitions')) + equal(quotas.get('repetitions'), default_quotas.repetitions) # Delete created user response = delete_user.sync_detailed(client=api_client, email=user.email) diff --git a/tsconfig.json b/tsconfig.json index b52d9744e9..77913205eb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,7 +18,10 @@ "moduleResolution": "nodenext", "target": "es2022", "rewriteRelativeImportExtensions": true, - "lib": ["ES2022"], + "lib": ["ES2022", "DOM"], + "paths": { + "@u4/adbkit/*": ["./node_modules/@u4/adbkit/*"] + }, "types": ["node"] }, "include": [ From 6178fbf9ad8a75ac2c1ec582bfc5bf01d88b0922 Mon Sep 17 00:00:00 2001 From: Elmir Khalilov <52529096+e-khalilov@users.noreply.github.com> Date: Mon, 29 Sep 2025 16:41:54 +0300 Subject: [PATCH 04/13] fix device type & types (#374) Co-authored-by: e.khalilov --- lib/units/provider/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/units/provider/index.ts b/lib/units/provider/index.ts index 912abc50d3..69d1fe5bf7 100644 --- a/lib/units/provider/index.ts +++ b/lib/units/provider/index.ts @@ -85,7 +85,7 @@ export default (async function(options: Options) { }) sub.on('message', new WireRouter() - .on(DeviceRegisteredMessage, (channel, message) => { + .on(DeviceRegisteredMessage, (channel, message: {serial: string}) => { if (workers[message.serial]?.resolveRegister) { workers[message.serial].resolveRegister!() delete workers[message.serial]?.resolveRegister @@ -130,7 +130,7 @@ export default (async function(options: Options) { // Tell others we found a device push.send([ wireutil.global, - wireutil.envelope(new wire.DeviceIntroductionMessage(device.serial, wireutil.toDeviceStatus(device.type), new wire.ProviderMessage(solo, options.name), options.deviceType)) + wireutil.envelope(new wire.DeviceIntroductionMessage(device.serial, wireutil.toDeviceStatus(device.type) || 1, new wire.ProviderMessage(solo, options.name), options.deviceType)) ]) process.nextTick(() => { // after creating workers[device.serial] obj From 7cc21d641fd43201f6cecb841c3d9ea1d5303875 Mon Sep 17 00:00:00 2001 From: Elmir Khalilov <52529096+e-khalilov@users.noreply.github.com> Date: Wed, 1 Oct 2025 16:44:34 +0300 Subject: [PATCH 05/13] reconnect in ADBObserver (#376) Co-authored-by: e.khalilov --- lib/units/provider/ADBObserver.ts | 232 +++++++++++++++++++++++------- lib/units/provider/index.ts | 2 +- 2 files changed, 180 insertions(+), 54 deletions(-) diff --git a/lib/units/provider/ADBObserver.ts b/lib/units/provider/ADBObserver.ts index 6600448e88..dfa1fbab77 100644 --- a/lib/units/provider/ADBObserver.ts +++ b/lib/units/provider/ADBObserver.ts @@ -37,10 +37,17 @@ class ADBObserver extends EventEmitter { private shouldContinuePolling: boolean = false private connection: Socket | null = null private isConnecting: boolean = false - private pendingRequests: Map void reject: (error: Error) => void - }> = new Map() + timer?: NodeJS.Timeout // Set when request is in-flight + }> = [] + private readonly requestTimeoutMs: number = 5000 // 5 second timeout per request + private readonly maxReconnectAttempts: number = 8 + private readonly initialReconnectDelayMs: number = 100 + private reconnectAttempt: number = 0 + private isReconnecting: boolean = false constructor(options?: {intervalMs?: number; host?: string; port?: number}) { if (ADBObserver.instance) { @@ -70,9 +77,7 @@ class ADBObserver extends EventEmitter { this.shouldContinuePolling = true // Initial poll - this.pollDevices().catch(err => { - this.emit('error', err) - }) + this.pollDevices() this.scheduleNextPoll() } @@ -165,9 +170,7 @@ class ADBObserver extends EventEmitter { } this.pollTimeout = setTimeout(async() => { - await this.pollDevices().catch(err => { - this.emit('error', err) - }) + await this.pollDevices() if (this.shouldContinuePolling && !this.isDestroyed) { this.scheduleNextPoll() @@ -193,14 +196,14 @@ class ADBObserver extends EventEmitter { return this.connection } - if (this.isConnecting) { - // Wait for ongoing connection attempt + if (this.isConnecting || this.isReconnecting) { + // Wait for ongoing connection or reconnection attempt return new Promise((resolve, reject) => { const checkConnection = () => { if (this.connection && !this.connection.destroyed) { resolve(this.connection) } - else if (!this.isConnecting) { + else if (!this.isConnecting && !this.isReconnecting) { reject(new Error('Connection failed')) } else { @@ -224,6 +227,7 @@ class ADBObserver extends EventEmitter { const client = net.createConnection(this.port, this.host, () => { this.connection = client this.isConnecting = false + this.reconnectAttempt = 0 // Reset reconnection counter on successful connection this.setupConnectionHandlers(client) resolve(client) }) @@ -240,7 +244,7 @@ class ADBObserver extends EventEmitter { * Setup event handlers for persistent connection */ private setupConnectionHandlers(client: Socket): void { - let responseBuffer = Buffer.alloc(0) + let responseBuffer = Buffer.alloc(0) as Buffer client.on('data', (data) => { responseBuffer = Buffer.concat([responseBuffer, data]) @@ -249,17 +253,23 @@ class ADBObserver extends EventEmitter { client.on('close', () => { this.connection = null - // Reject any pending requests - for (const [, {reject}] of this.pendingRequests) { - reject(new Error('Connection closed')) + + // Clear the timeout of in-flight request but keep it for potential retry + if (this.requestQueue.length > 0 && this.requestQueue[0].timer) { + clearTimeout(this.requestQueue[0].timer) + delete this.requestQueue[0].timer } - this.pendingRequests.clear() - // Auto-reconnect if we should continue polling + // Attempt to reconnect if we should continue polling if (this.shouldContinuePolling && !this.isDestroyed) { - this.ensureConnection().catch(err => { - this.emit('error', err) - }) + this.attemptReconnect() + } + else { + // Reject all queued requests (including in-flight one) + for (const {reject} of this.requestQueue) { + reject(new Error('Connection closed')) + } + this.requestQueue = [] } }) @@ -272,7 +282,7 @@ class ADBObserver extends EventEmitter { /** * Process ADB protocol responses and return remaining buffer */ - private processADBResponses(buffer: Buffer): Buffer { + private processADBResponses(buffer: Buffer): Buffer { let offset = 0 while (offset < buffer.length) { @@ -293,20 +303,27 @@ class ADBObserver extends EventEmitter { const responseData = buffer.subarray(offset + 8, offset + 8 + dataLength).toString('utf-8') if (status === 'OKAY') { - // Find and resolve the corresponding request - const requestId = 'host:devices' // For now, we only handle device listing - const pending = this.pendingRequests.get(requestId) - if (pending) { - this.pendingRequests.delete(requestId) - pending.resolve(responseData) + // Resolve the in-flight request (first in queue) + if (this.requestQueue.length > 0) { + const request = this.requestQueue.shift()! + if (request.timer) { + clearTimeout(request.timer) + } + request.resolve(responseData) + // Process next request in queue + this.processNextRequest() } } else if (status === 'FAIL') { - const requestId = 'host:devices' - const pending = this.pendingRequests.get(requestId) - if (pending) { - this.pendingRequests.delete(requestId) - pending.reject(new Error(responseData || 'ADB command failed')) + // Reject the in-flight request (first in queue) + if (this.requestQueue.length > 0) { + const request = this.requestQueue.shift()! + if (request.timer) { + clearTimeout(request.timer) + } + request.reject(new Error(responseData || 'ADB command failed')) + // Process next request in queue + this.processNextRequest() } } @@ -319,30 +336,132 @@ class ADBObserver extends EventEmitter { /** * Send command to ADB server using persistent connection + * Requests are queued and processed sequentially */ private async sendADBCommand(command: string): Promise { - const connection = await this.ensureConnection() + await this.ensureConnection() return new Promise((resolve, reject) => { - // Store the request for response matching - this.pendingRequests.set(command, {resolve, reject}) - - const commandBuffer = Buffer.from(command, 'utf-8') - const lengthHex = commandBuffer.length.toString(16).padStart(4, '0') - const message = Buffer.concat([ - Buffer.from(lengthHex, 'ascii'), - commandBuffer - ]) - - connection.write(message, (err) => { - if (err) { - this.pendingRequests.delete(command) - reject(err) - } - }) + // Add request to the queue + this.requestQueue.push({command, resolve, reject}) + + // Try to process the queue if no request is currently in-flight + this.processNextRequest() + }) + } + + /** + * Process the next request in the queue if no request is currently in-flight + */ + private processNextRequest(): void { + // Don't process if queue is empty or first request already in-flight + if (this.requestQueue.length === 0 || this.requestQueue[0].timer) { + return + } + + // Don't process if connection is not available + if (!this.connection || this.connection.destroyed) { + return + } + + // Get the first request in queue (don't shift yet - only shift on response) + const request = this.requestQueue[0] + const {command, reject} = request + + // Set up timeout for this request + const timer = setTimeout(() => { + if (this.requestQueue.length > 0 && this.requestQueue[0] === request) { + this.requestQueue.shift() // Remove the timed-out request + reject(new Error(`Request timeout after ${this.requestTimeoutMs}ms: ${command}`)) + // Process next request in queue + this.processNextRequest() + } + }, this.requestTimeoutMs) + + // Mark request as in-flight by setting its timer + request.timer = timer + + // Send the command + const commandBuffer = Buffer.from(command, 'utf-8') + const lengthHex = commandBuffer.length.toString(16).padStart(4, '0') + const message = Buffer.concat([ + Buffer.from(lengthHex, 'ascii'), + commandBuffer + ]) + + this.connection.write(message, (err) => { + if (err && this.requestQueue.length > 0 && this.requestQueue[0] === request) { + clearTimeout(request.timer!) + this.requestQueue.shift() // Remove the failed request + reject(err) + // Process next request in queue + this.processNextRequest() + } }) } + /** + * Attempt to reconnect with exponential backoff + */ + private async attemptReconnect(): Promise { + if (this.isReconnecting || this.isDestroyed) { + return + } + + this.isReconnecting = true + + for (let attempt = 0; attempt < this.maxReconnectAttempts; attempt++) { + this.reconnectAttempt = attempt + 1 + + // Calculate exponential backoff delay + const delay = this.initialReconnectDelayMs * Math.pow(2, attempt) + + // Wait before attempting reconnection + await new Promise(resolve => setTimeout(resolve, delay)) + + if (!this.shouldContinuePolling || this.isDestroyed) { + this.isReconnecting = false + return + } + + try { + // Attempt to create a new connection + await this.createConnection() + this.reconnectAttempt = 0 + this.isReconnecting = false + + // Resend the in-flight request if it exists + if (this.requestQueue.length > 0 && !this.requestQueue[0].timer) { + // The first request was in-flight but timer was cleared on disconnect + // Resend it by calling processNextRequest + this.processNextRequest() + } + + return // Successfully reconnected + } + catch { + // Continue to next attempt + continue + } + } + + // All reconnection attempts failed + this.isReconnecting = false + this.reconnectAttempt = 0 + + const error = new Error(`Failed to reconnect to ADB server after ${this.maxReconnectAttempts} attempts`) + this.emit('error', error) + + // Reject all queued requests (including in-flight one) + for (const request of this.requestQueue) { + if (request.timer) { + clearTimeout(request.timer) + } + request.reject(error) + } + this.requestQueue = [] + } + /** * Close the persistent connection */ @@ -352,11 +471,18 @@ class ADBObserver extends EventEmitter { this.connection = null } - // Reject any pending requests - for (const [, {reject}] of this.pendingRequests) { - reject(new Error('Connection closed')) + // Reset reconnection state + this.isReconnecting = false + this.reconnectAttempt = 0 + + // Reject all queued requests (including in-flight one) + for (const request of this.requestQueue) { + if (request.timer) { + clearTimeout(request.timer) + } + request.reject(new Error('Connection closed')) } - this.pendingRequests.clear() + this.requestQueue = [] } /** diff --git a/lib/units/provider/index.ts b/lib/units/provider/index.ts index 69d1fe5bf7..86f55abb54 100644 --- a/lib/units/provider/index.ts +++ b/lib/units/provider/index.ts @@ -299,7 +299,7 @@ export default (async function(options: Options) { // Track and manage devices const tracker = new ADBObserver({ - intervalMs: 2000, + intervalMs: 3000, port: options.adbPort, host: options.adbHost }) From edd413f631d0736410ab28bb9049ab71d328d693 Mon Sep 17 00:00:00 2001 From: Alexey Chistov <33050834+Alk2017@users.noreply.github.com> Date: Wed, 1 Oct 2025 16:55:44 +0300 Subject: [PATCH 06/13] QA-10057 Remove users watcher groups-engine (#369) * -fix after rebase -remove user watcher -user handler for alert message default quotas handler -fix merge del handler update quoats handler user handler method some fix -move without change method of devices to separate class -fix after move users method -move db.users method to separate class * add missing db method --------- Co-authored-by: a.chistov Co-authored-by: e.khalilov --- lib/db/api.ts | 8 +- lib/db/handlers/group/scheduler.js | 3 +- lib/db/handlers/user/index.js | 103 +++++ lib/db/index.ts | 3 +- lib/db/models/all/model.js | 505 +--------------------- lib/db/models/device/index.js | 4 + lib/db/models/device/model.js | 127 ++++++ lib/db/models/group/model.js | 71 +-- lib/db/models/user/index.js | 4 + lib/db/models/user/model.js | 446 +++++++++++++++++++ lib/units/api/controllers/groups.js | 10 +- lib/units/api/controllers/users.js | 64 +-- lib/units/groups-engine/index.js | 2 - lib/units/groups-engine/watchers/users.js | 105 ----- lib/units/processor/index.ts | 3 +- lib/units/websocket/index.js | 41 +- 16 files changed, 819 insertions(+), 680 deletions(-) create mode 100644 lib/db/handlers/user/index.js create mode 100644 lib/db/models/device/index.js create mode 100644 lib/db/models/device/model.js create mode 100644 lib/db/models/user/index.js create mode 100644 lib/db/models/user/model.js delete mode 100644 lib/units/groups-engine/watchers/users.js diff --git a/lib/db/api.ts b/lib/db/api.ts index 1e2e3acaab..5200126262 100644 --- a/lib/db/api.ts +++ b/lib/db/api.ts @@ -1,6 +1,8 @@ import AllModel from './models/all/index.js' import GroupModel from './models/group/index.js' import TeamModel from './models/team/index.js' +import UserModel from './models/user/index.js' +import DeviceModel from './models/device/index.js' const concatModels = (...models: T) => Object.assign({}, ...models) @@ -12,5 +14,7 @@ const concatModels = (...models: T) => export default concatModels( AllModel, GroupModel, - TeamModel -) as typeof AllModel & typeof GroupModel & typeof TeamModel + TeamModel, + UserModel, + DeviceModel, +) as typeof AllModel & typeof GroupModel & typeof TeamModel & typeof UserModel & typeof DeviceModel diff --git a/lib/db/handlers/group/scheduler.js b/lib/db/handlers/group/scheduler.js index 3ac71e199b..ddfbca40f6 100644 --- a/lib/db/handlers/group/scheduler.js +++ b/lib/db/handlers/group/scheduler.js @@ -5,6 +5,7 @@ import db from '../../index.js' import logger from '../../../util/logger.js' import mongo from 'mongodb' +import UserModel from '../../models/user/index.js' const log = logger.createLogger('groups-scheduler') @@ -211,7 +212,7 @@ export default class GroupsScheduler { await dbapi.updateDevicesCurrentGroupFromOrigin(group.devices) } - await dbapi.updateUserGroupDuration(group.owner.email, group.duration, duration) + await UserModel.updateUserGroupDuration(group.owner.email, group.duration, duration) await this.scheduleAllGroupsTasks() } catch (err) { diff --git a/lib/db/handlers/user/index.js b/lib/db/handlers/user/index.js new file mode 100644 index 0000000000..132d9a35a0 --- /dev/null +++ b/lib/db/handlers/user/index.js @@ -0,0 +1,103 @@ +import _ from 'lodash' +import logger from '../../../util/logger.js' +import wireutil from '../../../wire/util.js' +import wire from '../../../wire/index.js' +import timeutil from '../../../util/timeutil.js' + +class UserChangeHandler { + + isPrepared = false + log = logger.createLogger('change-handler-users') + + init(push, pushdev, channelRouter) { + this.pushdev = pushdev + this.isPrepared = !!this.pushdev + } + + sendUserChange = (user, isAddedGroup, groups, action, targets) => { + function wireUserField() { + const wireUser = _.cloneDeep(user) + delete wireUser._id + delete wireUser.ip + delete wireUser.group + delete wireUser.lastLoggedInAt + delete wireUser.createdAt + delete wireUser.forwards + delete wireUser.acceptedPolicy + delete wireUser.groups.lock + delete wireUser.groups.defaultGroupsDuration + delete wireUser.groups.defaultGroupsNumber + delete wireUser.groups.defaultGroupsRepetitions + delete wireUser.groups.repetitions + return wireUser + } + const userField = wireUserField() + this.pushdev.send([ + wireutil.global, + wireutil.envelope(new wire.UserChangeMessage( + userField + , isAddedGroup + , groups + , action + , targets + , timeutil.now('nano') + )) + ]) + } + + updateUserHandler = (oldUser, newUser) => { + if (newUser === null && oldUser === null) { + this.log.info('New user doc and old user doc is NULL') + return false + } + const targets = [] + if (newUser?.groups && oldUser?.groups) { + if (newUser.groups.quotas && oldUser.groups.quotas) { + if (!_.isEqual(newUser.groups.quotas.allocated, oldUser.groups.quotas.allocated)) { + targets.push('settings') + targets.push('view') + } + else if (!_.isEqual(newUser.groups.quotas.consumed, oldUser.groups.quotas.consumed)) { + targets.push('view') + } + else if (newUser.groups.quotas.defaultGroupsNumber !== + oldUser.groups.quotas.defaultGroupsNumber || + newUser.groups.quotas.defaultGroupsDuration !== + oldUser.groups.quotas.defaultGroupsDuration || + newUser.groups.quotas.defaultGroupsRepetitions !== + oldUser.groups.quotas.defaultGroupsRepetitions || + newUser.groups.quotas.repetitions !== + oldUser.groups.quotas.repetitions || + !_.isEqual(newUser.groups.subscribed, oldUser.groups.subscribed)) { + targets.push('settings') + } + } + } + if (!_.isEqual(newUser?.settings.alertMessage, oldUser?.settings.alertMessage)) { + targets.push('menu') + } + if (targets.length) { + this.sendUserChange(newUser, newUser.groups.subscribed.length > oldUser.groups.subscribed.length + , _.xor(newUser.groups.subscribed, oldUser.groups.subscribed), 'updated', targets) + } + return !_.isEqual(newUser, oldUser) + } + +} + +// Temporary solution needed to avoid situations +// where a unit may not initialize the change handler, +// but use the db module. In this case, any methods of this handler +// do nothing and will not cause an error. +/** @type {UserChangeHandler} */ +export default new Proxy(new UserChangeHandler(), { + + /** @param {string} prop */ + get(target, prop) { + if (target.isPrepared || prop === 'init' || typeof target[prop] !== 'function') { + return target[prop] + } + + return () => {} + } +}) diff --git a/lib/db/index.ts b/lib/db/index.ts index 2928f5abab..8e3ab3b1bf 100644 --- a/lib/db/index.ts +++ b/lib/db/index.ts @@ -3,6 +3,7 @@ import _setup from './setup.js' import srv from '../util/srv.js' import EventEmitter from 'events' import GroupChangeHandler from './handlers/group/index.js' +import UserChangeHandler from './handlers/user/index.js' import * as zmqutil from '../util/zmqutil.js' import lifecycle from '../util/lifecycle.js' import logger from '../util/logger.js' @@ -27,7 +28,7 @@ const handlers: { channelRouter?: EventEmitter ) => Promise | void; isPrepared: boolean; -}[] = [GroupChangeHandler] +}[] = [GroupChangeHandler, UserChangeHandler] export default class DbClient { static connection: mongo.Db diff --git a/lib/db/models/all/model.js b/lib/db/models/all/model.js index 4cb3b46f63..1082680ac9 100644 --- a/lib/db/models/all/model.js +++ b/lib/db/models/all/model.js @@ -8,6 +8,7 @@ import wireutil from '../../../wire/util.js' import {v4 as uuidv4} from 'uuid' import * as apiutil from '../../../util/apiutil.js' import GroupModel from '../group/index.js' +import UserModel from '../user/index.js' import logger from '../../../util/logger.js' import {getRootGroup, getGroup} from '../group/model.js' @@ -51,7 +52,7 @@ export const unlockBookingObjects = function() { $set: {'group.lock': false} } ), - db.collection('groups').updateMany( + db.groups.updateMany( {}, { $set: { @@ -74,7 +75,7 @@ export const createBootStrap = function(env) { const now = Date.now() function updateUsersForMigration(group) { - return getUsers().then(function(users) { + return UserModel.getUsers().then(function(users) { return Promise.all(users.map(async(user) => { const data = { privilege: user?.email !== group?.owner.email ? apiutil.USER : apiutil.ADMIN, @@ -161,7 +162,7 @@ export const createBootStrap = function(env) { envUserGroupsRepetitions: apiutil.MAX_USER_GROUPS_REPETITIONS }) .then(function(group) { - return saveUserAfterLogin({ + return UserModel.saveUserAfterLogin({ name: group?.owner.name, email: group?.owner.email, ip: '127.0.0.1' @@ -173,42 +174,11 @@ export const createBootStrap = function(env) { return updateDevicesForMigration(group) }) .then(function() { - return reserveUserGroupInstance(group?.owner?.email) + return UserModel.reserveUserGroupInstance(group?.owner?.email) }) }) } -export const deleteUser = function(email) { - return db.users.deleteOne({email: email}) -} - -// dbapi.getUsers = function() { -export const getUsers = function() { - return db.users.find().toArray() -} - -// dbapi.getEmails = function() { -export const getEmails = function() { - return db.users - .find({ - privilege: { - $ne: apiutil.ADMIN - } - }) - .project({email: 1, _id: 0}) - .toArray() -} - -// dbapi.getAdmins = function() { -export const getAdmins = function() { - return db.users - .find({ - privilege: apiutil.ADMIN - }) - .project({email: 1, _id: 0}) - .toArray() -} - export const lockDeviceByCurrent = function(groups, serial) { function wrappedlockDeviceByCurrent() { return db.devices.findOne({serial: serial}).then(oldDoc => { @@ -345,39 +315,10 @@ export const setLockOnDevices = function(serials, lock) { ) } -/** - * @deprecated Do not use locks in database. - */ -function setLockOnUser(email, state) { - return db.users.findOne({email: email}).then(oldDoc => { - if (!oldDoc || !oldDoc.groups) { - throw new Error(`User with email ${email} not found or groups field is missing.`) - } - return db.users.updateOne( - {email: email}, - { - $set: { - 'groups.lock': oldDoc.groups.lock !== state ? state : oldDoc.groups.lock - } - } - ) - .then(updateStats => { - return db.users.findOne({email: email}).then(newDoc => { - // @ts-ignore - updateStats.changes = [ - {new_val: {...newDoc}, old_val: {...oldDoc}} - ] - return updateStats - }) - }) - }) -} - - // dbapi.lockUser = function(email) { export const lockUser = function(email) { function wrappedlockUser() { - return setLockOnUser(email, true) + return UserModel.setLockOnUser(email, true) .then(function(stats) { return apiutil.lockResult(stats) }) @@ -391,7 +332,7 @@ export const lockUser = function(email) { // dbapi.unlockUser = function(email) { export const unlockUser = function(email) { - return setLockOnUser(email, false) + return UserModel.setLockOnUser(email, false) } // dbapi.isDeviceBooked = function(serial) { @@ -400,197 +341,6 @@ export const isDeviceBooked = function(serial) { .then(groups => !!groups?.length) } -// dbapi.createUser = function(email, name, ip) { -export const createUser = function(email, name, ip, privilege) { - return GroupModel.getRootGroup().then(function(group) { - return loadUser(group?.owner.email).then(function(adminUser) { - let userObj = { - email: email, - name: name, - ip: ip, - group: wireutil.makePrivateChannel(), - lastLoggedInAt: getNow(), - createdAt: getNow(), - forwards: [], - settings: {}, - acceptedPolicy: false, - privilege: privilege || (adminUser ? apiutil.USER : apiutil.ADMIN), - groups: { - subscribed: [], - lock: false, - quotas: { - allocated: { - number: adminUser ? adminUser.groups.quotas.defaultGroupsNumber : group?.envUserGroupsNumber, - duration: adminUser ? adminUser.groups.quotas.defaultGroupsDuration : group?.envUserGroupsDuration - }, - consumed: { - number: 0, - duration: 0 - }, - defaultGroupsNumber: adminUser ? 0 : group?.envUserGroupsNumber, - defaultGroupsDuration: adminUser ? 0 : group?.envUserGroupsDuration, - defaultGroupsRepetitions: adminUser ? 0 : group?.envUserGroupsRepetitions, - repetitions: adminUser ? adminUser.groups.quotas.defaultGroupsRepetitions : group?.envUserGroupsRepetitions - } - } - } - return db.users.insertOne(userObj) - .then(function(stats) { - if (stats.insertedId) { - return GroupModel.addGroupUser(group?.id, email).then(function() { - return loadUser(email).then(function(user) { - // @ts-ignore - stats.changes = [ - {new_val: {...user}} - ] - return stats - }) - }) - } - return stats - }) - }) - }) -} - -// dbapi.saveUserAfterLogin = function(user) { -export const saveUserAfterLogin = function(user) { - const updateData = { - name: user?.name, - ip: user?.ip, - lastLoggedInAt: getNow() - } - - if (user?.privilege) { - updateData.privilege = user?.privilege - } - - return db.users.updateOne({email: user?.email}, {$set: updateData}) - // @ts-ignore - .then(stats => { - if (stats.modifiedCount === 0) { - return createUser(user?.email, user?.name, user?.ip, user?.privilege) - } - return stats - }) -} - -// dbapi.loadUser = function(email) { -export const loadUser = function(email) { - return db.users.findOne({email: email}) -} - -// dbapi.updateUsersAlertMessage = function(alertMessage) { -export const updateUsersAlertMessage = function(alertMessage) { - return db.users.updateOne( - { - email: apiutil.STF_ADMIN_EMAIL - } - , { - $set: Object.fromEntries(Object.entries(alertMessage).map(([key, value]) => - ['settings.alertMessage.' + key, value] - )), - } - ).then(updateStats => { - return db.users.findOne({email: apiutil.STF_ADMIN_EMAIL}).then(updatedMainAdmin => { - // @ts-ignore - updateStats.changes = [ - {new_val: {...updatedMainAdmin}} - ] - return updateStats - }) - }) -} - -// dbapi.updateUserSettings = function(email, changes) { -export const updateUserSettings = function(email, changes) { - return db.users.findOne({email: email}).then(user => { - return db.users.updateOne( - { - email: email - } - , { - $set: { - settings: {...user?.settings, ...changes} - } - } - ) - }) -} - -// dbapi.resetUserSettings = function(email) { -export const resetUserSettings = function(email) { - return db.users.updateOne({email: email}, - { - $set: { - settings: {} - } - }) -} - -export const getUserAdbKeys = function(email) { - return db.users.findOne({email: email}) - .then(user => user?.adbKeys || []) -} - -// dbapi.insertUserAdbKey = function(email, key) { -export const insertUserAdbKey = function(email, key) { - let data = { - title: key.title, - fingerprint: key.fingerprint - } - return db.users.findOne({email: email}).then(user => { - let adbKeys = user?.adbKeys ? user?.adbKeys : [] - adbKeys.push(data) - return db.users.updateOne( - {email: email} - , {$set: {adbKeys: user?.adbKeys ? adbKeys : [data]}} - ) - }) -} - -// dbapi.deleteUserAdbKey = function(email, fingerprint) { -export const deleteUserAdbKey = function(email, fingerprint) { - return db.users.findOne({email: email}).then(user => { - return db.users.updateOne( - {email: email} - , { - $set: { - adbKeys: user?.adbKeys ? user?.adbKeys.filter(key => { - return key.fingerprint !== fingerprint - }) : [] - } - } - ) - }) -} - -// dbapi.lookupUsersByAdbKey = function(fingerprint) { -export const lookupUsersByAdbKey = function(fingerprint) { - return db.users.find({ - adbKeys: fingerprint - }).toArray() -} - -// dbapi.lookupUserByAdbFingerprint = function(fingerprint) { -export const lookupUserByAdbFingerprint = function(fingerprint) { - return db.users.find( - {adbKeys: {$elemMatch: {fingerprint: fingerprint}}} - // @ts-ignore - , {email: 1, name: 1, group: 1, _id: 0} - ).toArray() - .then(function(users) { - switch (users.length) { - case 1: - return users[0] - case 0: - return null - default: - throw new Error('Found multiple users for same ADB fingerprint') - } - }) -} - // dbapi.lookupUserByVncAuthResponse = function(response, serial) { export const lookupUserByVncAuthResponse = function(response, serial) { return db.collection('vncauth').aggregate([ @@ -628,20 +378,6 @@ export const lookupUserByVncAuthResponse = function(response, serial) { }) } -// dbapi.loadUserDevices = function(email) { -export const loadUserDevices = function(email) { - return db.users.findOne({email: email}).then(user => { - let userGroups = user?.groups.subscribed - return db.devices.find( - { - 'owner.email': email, - present: true, - 'group.id': {$in: userGroups} - } - ).toArray() - }) -} - // dbapi.saveDeviceLog = function(serial, entry) { export const saveDeviceLog = function(serial, entry) { return db.connect().then(() => @@ -1161,11 +897,6 @@ export const loadDeviceBySerial = function(serial) { return findDevice({serial: serial}) } -// dbapi.loadDevicesBySerials = function(serials) { -export const loadDevicesBySerials = function(serials) { - return db.devices.find({serial: {$in: serials}}).toArray() -} - // dbapi.loadDevice = function(groups, serial) { export const loadDevice = function(groups, serial) { return findDevice({ @@ -1272,33 +1003,6 @@ export const loadAccessTokenByTitle = function(email, title) { return db.collection('accessTokens').findOne({email: email, title: title}) } -// dbapi.grantAdmin = function(email) { -export const grantAdmin = function(email) { - return db.users.findOneAndUpdate({email: email}, { - $set: { - privilege: apiutil.ADMIN - } - }, {returnDocument: 'after'}) -} - -// dbapi.revokeAdmin = function(email) { -export const revokeAdmin = function(email) { - return db.users.findOneAndUpdate({email: email}, { - $set: { - privilege: apiutil.USER - } - }, {returnDocument: 'after'}) -} - -// dbapi.acceptPolicy = function(email) { -export const acceptPolicy = function(email) { - return db.users.updateOne({email: email}, { - $set: { - acceptedPolicy: true - } - }) -} - // dbapi.writeStats = function(user, serial, action) { // { // event_type: string, @@ -1331,32 +1035,9 @@ export const sendEvent = function(eventType, eventDetails, linkedEntities, times }) } -// dbapi.getDevicesCount = function() { -export const getDevicesCount = function() { - return db.devices.find().count() -} - -// dbapi.getOfflineDevicesCount = function() { -export const getOfflineDevicesCount = function() { - return db.devices.find( - { - present: false - } - ).count() -} - -// dbapi.getOfflineDevices = function() { -export const getOfflineDevices = function() { - return db.devices.find( - {present: false}, - // @ts-ignore - {_id: 0, 'provider.name': 1} - ).toArray() -} - // dbapi.isPortExclusive = function(newPort) { export const isPortExclusive = function(newPort) { - return getAllocatedAdbPorts().then((ports) => { + return DeviceModel.getAllocatedAdbPorts().then((ports) => { let result = !!ports.find(port => port === newPort) return !result }) @@ -1364,7 +1045,7 @@ export const isPortExclusive = function(newPort) { // dbapi.getLastAdbPort = function() { export const getLastAdbPort = function() { - return getAllocatedAdbPorts().then((ports) => { + return DeviceModel.getAllocatedAdbPorts().then((ports) => { if (ports.length === 0) { return 0 } @@ -1372,27 +1053,6 @@ export const getLastAdbPort = function() { }) } -// dbapi.getAllocatedAdbPorts = function() { -export const getAllocatedAdbPorts = function() { - // @ts-ignore - return db.devices.find({}, {adbPort: 1, _id: 0}).toArray().then(ports => { - let result = [] - ports.forEach((port) => { - if (port.adbPort) { - let portNum - if (typeof port.adbPort === 'string') { - portNum = parseInt(port.adbPort.replace(/["']/g, ''), 10) - } - else { - portNum = port.adbPort - } - result.push(portNum) - } - }) - return result.sort((a, b) => a - b) - }) -} - // dbapi.initiallySetAdbPort = function(serial) { export const initiallySetAdbPort = function(serial) { return getFreeAdbPort() @@ -1509,12 +1169,19 @@ export const sizeIosDevice = function(serial, height, width, scale) { ) } -// dbapi.getDeviceDisplaySize = function(serial) { -export const getDeviceDisplaySize = function(serial) { - return db.devices.findOne({serial: serial}) - .then(result => { - return result?.display - }) +// TODO Check usage. Probably dead code +export const setAbsentDisconnectedDevices = function() { + return db.devices.updateOne( + { + platform: 'iOS' + }, + { + $set: { + present: false, + ready: false + } + } + ) } // dbapi.getInstalledApplications = function(message) { @@ -1536,14 +1203,6 @@ export const setDeviceType = function(serial, type) { ) } -// dbapi.getDeviceType = function(serial) { -export const getDeviceType = function(serial) { - return db.devices.findOne({serial: serial}) - .then(result => { - return result?.deviceType - }) -} - // dbapi.initializeIosDeviceState = function(publicIp, message) { export const initializeIosDeviceState = function(publicIp, message) { const screenWsUrlPattern = @@ -1621,126 +1280,6 @@ export const initializeIosDeviceState = function(publicIp, message) { }) } -export const reserveUserGroupInstance = async(email) => { - return db.users.updateMany( - {email} - , [{ - $set: {'groups.quotas.consumed.number': { - $min: [{ - $sum: ['$groups.quotas.consumed.number', 1] - }, '$groups.quotas.allocated.number']} - } - }] - ) -} - -export const releaseUserGroupInstance = async(email) => { - return db.users.updateMany( - { - email - } - , [{ - $set: {'groups.quotas.consumed.number': { - $max: [{ - $sum: ['$groups.quotas.consumed.number', -1] - }, 0]} - } - }] - ) -} - -export const updateUserGroupDuration = async(email, oldDuration, newDuration) => { - return db.users.updateOne( - {email: email} - , [{ - $set: { - 'groups.quotas.consumed.duration': { - $cond: [ - {$lte: [{$sum: ['$groups.quotas.consumed.duration', newDuration, -oldDuration]}, '$groups.quotas.allocated.duration']}, - {$sum: ['$groups.quotas.consumed.duration', newDuration, -oldDuration]}, - '$groups.quotas.consumed.duration' - ] - } - } - }] - ) -} - -export const updateUserGroupsQuotas = async(email, duration, number, repetitions) => { - const oldDoc = await db.users.findOne({email: email}) - - const consumed = oldDoc?.groups.quotas.consumed.duration - const allocated = oldDoc?.groups.quotas.allocated.duration - const consumedNumber = oldDoc?.groups.quotas.consumed.number - const allocatedNumber = oldDoc?.groups.quotas.allocated.number - - const updateStats = await db.users.updateOne( - {email: email} - , { - $set: { - 'groups.quotas.allocated.duration': duration && consumed <= duration && - (!number || consumedNumber <= number) ? duration : allocated, - 'groups.quotas.allocated.number': number && consumedNumber <= number && - (!duration || consumed <= duration) ? number : allocatedNumber, - 'groups.quotas.repetitions': repetitions || oldDoc?.groups.quotas.repetitions - } - } - ) - - const newDoc = await db.users.findOne({email: email}) - // @ts-ignore - updateStats.changes = [ - {new_val: {...newDoc}, old_val: {...oldDoc}} - ] - - return updateStats -} - -export const updateDefaultUserGroupsQuotas = async(email, duration, number, repetitions) => { - const updateStats = await db.users.updateOne( - {email: email} - , [{ - $set: { - 'groups.quotas.defaultGroupsDuration': { - $cond: [ - { - $ne: [duration, null] - }, - duration, - '$groups.quotas.defaultGroupsDuration' - ] - }, - 'groups.quotas.defaultGroupsNumber': { - $cond: [ - { - $ne: [number, null] - }, - number, - '$groups.quotas.defaultGroupsNumber' - ] - }, - 'groups.quotas.defaultGroupsRepetitions': { - $cond: [ - { - $ne: [repetitions, null] - }, - repetitions, - '$groups.quotas.defaultGroupsRepetitions' - ] - } - } - }] - ) - - const newDoc = await db.users.findOne({email: email}) - // @ts-ignore - updateStats.changes = [ - {new_val: {...newDoc}} - ] - - return updateStats -} - export const updateDeviceGroupName = async(serial, group) => { return db.devices.updateOne( {serial: serial} diff --git a/lib/db/models/device/index.js b/lib/db/models/device/index.js new file mode 100644 index 0000000000..61ca31630b --- /dev/null +++ b/lib/db/models/device/index.js @@ -0,0 +1,4 @@ +import proxiedModel from '../../proxiedModel.js' +import * as model from './model.js' + +export default proxiedModel(model) diff --git a/lib/db/models/device/model.js b/lib/db/models/device/model.js new file mode 100644 index 0000000000..ef29f27e49 --- /dev/null +++ b/lib/db/models/device/model.js @@ -0,0 +1,127 @@ +/* * + * Copyright 2025 contains code contributed by V Kontakte LLC - Licensed under the Apache license 2.0 + * */ +// @ts-nocheck +import logger from '../../../util/logger.js' +import db from '../../index.js' + +const log = logger.createLogger('dbapi:device') + +/* +=========================================================== +==================== without change DB ==================== +=========================================================== +*/ + +// dbapi.loadUserDevices = function(email) { +export const loadUserDevices = function(email) { + return db.users.findOne({email: email}).then(user => { + let userGroups = user?.groups.subscribed + return db.devices.find( + { + 'owner.email': email, + present: true, + 'group.id': {$in: userGroups} + } + ).toArray() + }) +} + +// dbapi.loadPresentDevices = function() { +export const loadPresentDevices = function() { + return db.devices.find({present: true}).toArray() +} + +// dbapi.loadDevicesBySerials = function(serials) { +export const loadDevicesBySerials = function(serials) { + return db.devices.find({serial: {$in: serials}}).toArray() +} + +// dbapi.getDevicesCount = function() { +export const getDevicesCount = function() { + return db.devices.countDocuments() +} + +// dbapi.getOfflineDevicesCount = function() { +export const getOfflineDevicesCount = function() { + return db.devices.countDocuments( + { + present: false + } + ) +} + +// dbapi.getOfflineDevices = function() { +export const getOfflineDevices = function() { + return db.devices.find( + {present: false}, + // @ts-ignore + {_id: 0, 'provider.name': 1} + ).toArray() +} + +// dbapi.getAllocatedAdbPorts = function() { +export const getAllocatedAdbPorts = function() { + // @ts-ignore + return db.devices.find({}, {adbPort: 1, _id: 0}).toArray().then(ports => { + let result = [] + ports.forEach((port) => { + if (port.adbPort) { + let portNum + if (typeof port.adbPort === 'string') { + portNum = parseInt(port.adbPort.replace(/["']/g, ''), 10) + } + else { + portNum = port.adbPort + } + result.push(portNum) + } + }) + return result.sort((a, b) => a - b) + }) +} + +// dbapi.getDeviceDisplaySize = function(serial) { +export const getDeviceDisplaySize = function(serial) { + return db.devices.findOne({serial: serial}) + .then(result => { + return result?.display + }) +} + +// dbapi.getDeviceType = function(serial) { +export const getDeviceType = function(serial) { + return db.devices.findOne({serial: serial}) + .then(result => { + return result?.deviceType + }) +} + +// dbapi.generateIndexes = function() { +export const generateIndexes = function() { + db.devices.createIndex({serial: -1}).then((result) => { + log.info('Created indexes with result - ' + result) + }) +} + +/* +==================================================================== +==================== changing DB - use handlers ==================== +==================================================================== +*/ + + + + +// dbapi.deleteDevice = function(serial) { +export const deleteDevice = function(serial) { + return db.devices.deleteOne({serial: serial}) +} + +/* +==================================================== +==================== deprecated ==================== +==================================================== +*/ + + diff --git a/lib/db/models/group/model.js b/lib/db/models/group/model.js index dbc836f85b..a68fd84eb8 100644 --- a/lib/db/models/group/model.js +++ b/lib/db/models/group/model.js @@ -2,14 +2,17 @@ * Copyright 2025 contains code contributed by V Kontakte LLC - Licensed under the Apache license 2.0 * */ + import {v4 as uuidv4} from 'uuid' import db from '../../index.js' import * as apiutil from '../../../util/apiutil.js' import logger from '../../../util/logger.js' import AllModel from '../all/index.js' +import UserModel from '../user/index.js' import _ from 'lodash' import util from 'util' import GroupChangeHandler from '../../handlers/group/index.js' +import UserChangeHandler from '../../handlers/user/index.js' import {isOriginGroup} from '../../../util/apiutil.js' import mongo from 'mongodb' @@ -54,7 +57,7 @@ export const getGroups = async(filter) => { export const addGroupUser = async(id, email) => { try { - const stats = await Promise.all([ + const [group, user] = await Promise.all([ db.groups.findOneAndUpdate( { id: id @@ -66,7 +69,7 @@ export const addGroupUser = async(id, email) => { }, {returnDocument: 'before'} ), - db.users.updateOne( + db.users.findOneAndUpdate( { email: email }, @@ -78,12 +81,17 @@ export const addGroupUser = async(id, email) => { ) ]) - if (stats[0]?.id) { - GroupChangeHandler.sendGroupChange(stats[0], stats[0].users.concat([email]), false, false, true, [email], false, [], 'updated') - GroupChangeHandler.treatGroupUsersChange(stats[0], [email], stats[0].isActive, true) + if (group?.id) { + GroupChangeHandler.sendGroupChange(group, group.users.concat([email]), false, false, true, [email], false, [], 'updated') + GroupChangeHandler.treatGroupUsersChange(group, [email], group.isActive, true) } - return stats[0] && stats[1].modifiedCount === 0 ? 'unchanged ' + email : 'added ' + email + var userModifided = false + if (user) { + const newUser = await UserModel.loadUser(email) + userModifided = UserChangeHandler.updateUserHandler(user, newUser) + } + return group && !userModifided ? 'unchanged ' + email : 'added ' + email } catch (err) { if (err instanceof TypeError) { @@ -96,7 +104,7 @@ export const addGroupUser = async(id, email) => { } export const addAdminsToGroup = async(id) => { - const admins = await AllModel.getAdmins() + const admins = await UserModel.getAdmins() const group = await db.groups.findOne({id: id}) const adminsEmails = Array.from( @@ -106,19 +114,19 @@ export const addAdminsToGroup = async(id) => { const newUsers = (group?.users || []).concat(adminsEmails) - await Promise.all( - adminsEmails.map( - email => db.users.findOne({email}) - .then(user => db.users.updateOne( - {email}, - { - $set: { - 'groups.subscribed': (user?.groups?.subscribed || []).concat([id]) - } - } - )) + adminsEmails.map(async email => { + const oldUser = await UserModel.loadUser(email) + const newUser = await db.users.findOneAndUpdate( + {email}, + { + $set: { + 'groups.subscribed': (oldUser?.groups?.subscribed || []).concat([id]) + } + }, + {returnDocument: 'after'} ) - ) + UserChangeHandler.updateUserHandler(oldUser, newUser) + }) const stats = await db.groups.updateOne( @@ -152,7 +160,7 @@ export const removeGroupUser = async(id, email) => { return "Can't remove owner of group." } - const [group] = await Promise.all([ + const [group, user] = await Promise.all([ db.groups.findOneAndUpdate( {id: id} , { @@ -163,7 +171,7 @@ export const removeGroupUser = async(id, email) => { } , {returnDocument: 'after'} ), - db.users.updateOne( + db.users.findOneAndUpdate( {email: email} , { $pull: {'groups.subscribed': id} @@ -174,6 +182,11 @@ export const removeGroupUser = async(id, email) => { GroupChangeHandler.sendGroupChange(group, group?.users, false, false, false, [email], false, [], 'updated') GroupChangeHandler.treatGroupUsersChange(group, [email], group?.isActive, false) + if (user) { + const newUser = await UserModel.loadUser(email) + UserChangeHandler.updateUserHandler(user, newUser) + } + return 'deleted' } @@ -239,7 +252,7 @@ export const addGroupDevices = async(group, serials) => { } const duration = apiutil.computeDuration(group, serials.length) - const stats = await AllModel.updateUserGroupDuration(group.owner.email, group.duration, duration) + const stats = await UserModel.updateUserGroupDuration(group.owner.email, group.duration, duration) if (!stats.modifiedCount) { throw 'quota is reached' } @@ -280,7 +293,7 @@ export const addGroupDevices = async(group, serials) => { /** @returns {Promise | null>} */ export const removeGroupDevices = async(group, serials) => { const duration = apiutil.computeDuration(group, -serials.length) - await AllModel.updateUserGroupDuration(group.owner.email, group.duration, duration) + await UserModel.updateUserGroupDuration(group.owner.email, group.duration, duration) const newGroup = await db.groups.findOneAndUpdate( {id: group.id} @@ -326,7 +339,7 @@ export const getUserGroup = async(email, id) => { export const getUserGroups = async(email) => { const pipeline = {users: {$in: [email]}} - const admins = await AllModel.getAdmins() + const admins = await UserModel.getAdmins() const adminEmails = admins.map(admin => admin.email) if (!adminEmails.includes(email)) { @@ -419,7 +432,7 @@ export const getGroupAsOwnerOrAdmin = async(email, id) => { return group } - const user = await AllModel.loadUser(email) + const user = await UserModel.loadUser(email) if (user && user.privilege === apiutil.ADMIN) { return group } @@ -462,7 +475,7 @@ export const createGroup = async(data) => { /** @returns {Promise | boolean | null>} */ export const createUserGroup = async(data) => { - const stats = await AllModel.reserveUserGroupInstance(data.owner.email) + const stats = await UserModel.reserveUserGroupInstance(data.owner.email) if (!stats.modifiedCount) { log.info(`Could not reserve group for user ${data.owner.email}`) return false @@ -501,7 +514,7 @@ export const updateDeviceOriginGroup = (serial, group, signature) => /** @returns {Promise | boolean | null>} */ export const updateUserGroup = async(group, data) => { - const stats = await AllModel.updateUserGroupDuration(group.owner.email, group.duration, data.duration) + const stats = await UserModel.updateUserGroupDuration(group.owner.email, group.duration, data.duration) if (!stats.modifiedCount && !stats.matchedCount || group.duration !== data.duration) { return false } @@ -563,8 +576,8 @@ export const deleteUserGroup = async(id) => { )) ) - await AllModel.releaseUserGroupInstance(group?.owner.email) - await AllModel.updateUserGroupDuration(group?.owner.email, group?.duration, 0) + await UserModel.releaseUserGroupInstance(group?.owner.email) + await UserModel.updateUserGroupDuration(group?.owner.email, group?.duration, 0) if (apiutil.isOriginGroup(group?.class)) { await AllModel.returnDevicesToRoot(group?.devices) diff --git a/lib/db/models/user/index.js b/lib/db/models/user/index.js new file mode 100644 index 0000000000..61ca31630b --- /dev/null +++ b/lib/db/models/user/index.js @@ -0,0 +1,4 @@ +import proxiedModel from '../../proxiedModel.js' +import * as model from './model.js' + +export default proxiedModel(model) diff --git a/lib/db/models/user/model.js b/lib/db/models/user/model.js new file mode 100644 index 0000000000..6513dc154c --- /dev/null +++ b/lib/db/models/user/model.js @@ -0,0 +1,446 @@ +/* * + * Copyright 2025 contains code contributed by V Kontakte LLC - Licensed under the Apache license 2.0 + * */ +import db from '../../index.js' +import * as apiutil from '../../../util/apiutil.js' +import logger from '../../../util/logger.js' + +import AllModel from '../all/index.js' +import GroupModel from '../group/index.js' +import wireutil from '../../../wire/util.js' +import UserChangeHandler from '../../handlers/user/index.js' + +const log = logger.createLogger('dbapi:user') + +/* +=========================================================== +==================== without change DB ==================== +=========================================================== +*/ + +// dbapi.getUsers = function() { +export const getUsers = function() { + return db.users.find().toArray() +} + +// dbapi.loadUser = function(email) { +export const loadUser = function(email) { + return db.users.findOne({email: email}) +} + +// dbapi.lookupUsersByAdbKey = function(fingerprint) { +export const lookupUsersByAdbKey = function(fingerprint) { + return db.users.find({ + adbKeys: fingerprint + }).toArray() +} + +// dbapi.lookupUserByAdbFingerprint = function(fingerprint) { +export const lookupUserByAdbFingerprint = function(fingerprint) { + return db.users.find( + {adbKeys: {$elemMatch: {fingerprint: fingerprint}}} + // @ts-ignore + , {email: 1, name: 1, group: 1, _id: 0} + ).toArray() + .then(function(users) { + switch (users.length) { + case 1: + return users[0] + case 0: + return null + default: + throw new Error('Found multiple users for same ADB fingerprint') + } + }) +} + +// dbapi.getEmails = function() { +export const getEmails = function() { + return db.users + .find({ + privilege: { + $ne: apiutil.ADMIN + } + }) + .project({email: 1, _id: 0}) + .toArray() +} + +// dbapi.getAdmins = function() { +export const getAdmins = function() { + return db.users + .find({ + privilege: apiutil.ADMIN + }) + .project({email: 1, _id: 0}) + .toArray() +} + +/* +==================================================================== +==================== changing DB - use handlers ==================== +==================================================================== +*/ + +// dbapi.createUser = function(email, name, ip) { +export const createUser = async(email, name, ip, privilege) => { + const rootGroup = await GroupModel.getRootGroup() + const adminUser = await loadUser(rootGroup?.owner.email) + let userObj = { + email: email, + name: name, + ip: ip, + group: wireutil.makePrivateChannel(), + lastLoggedInAt: AllModel.getNow(), + createdAt: AllModel.getNow(), + forwards: [], + settings: {}, + acceptedPolicy: false, + privilege: privilege || (adminUser ? apiutil.USER : apiutil.ADMIN), + groups: { + subscribed: [], + lock: false, + quotas: { + allocated: { + number: adminUser ? adminUser.groups.quotas.defaultGroupsNumber : rootGroup?.envUserGroupsNumber, + duration: adminUser ? adminUser.groups.quotas.defaultGroupsDuration : rootGroup?.envUserGroupsDuration + }, + consumed: { + number: 0, + duration: 0 + }, + defaultGroupsNumber: adminUser ? 0 : rootGroup?.envUserGroupsNumber, + defaultGroupsDuration: adminUser ? 0 : rootGroup?.envUserGroupsDuration, + defaultGroupsRepetitions: adminUser ? 0 : rootGroup?.envUserGroupsRepetitions, + repetitions: adminUser ? adminUser.groups.quotas.defaultGroupsRepetitions : rootGroup?.envUserGroupsRepetitions + } + } + } + const stats = await db.users.insertOne(userObj) + if (stats.insertedId) { + UserChangeHandler.sendUserChange(userObj, false, [], 'created', ['settings']) + + await GroupModel.addGroupUser(rootGroup?.id, email) + const newUser = await loadUser(email) + + // @ts-ignore + stats.changes = [ + {new_val: {...newUser}} + ] + } + return stats +} + + +// dbapi.saveUserAfterLogin = function(user) { +export const saveUserAfterLogin = function(user) { + const updateData = { + name: user?.name, + ip: user?.ip, + lastLoggedInAt: AllModel.getNow() + } + + if (user?.privilege) { + updateData.privilege = user?.privilege + } + + return db.users.updateOne({email: user?.email}, {$set: updateData}) + // @ts-ignore + .then(stats => { + if (stats.modifiedCount === 0) { + return createUser(user?.email, user?.name, user?.ip, user?.privilege) + } + return stats + }) +} + +// dbapi.updateUsersAlertMessage = function(alertMessage) { +export const updateUsersAlertMessage = async function(alertMessage) { + const oldUser = await db.users.findOne({email: apiutil.STF_ADMIN_EMAIL}) + const newUser = await db.users.findOneAndUpdate( + { + email: apiutil.STF_ADMIN_EMAIL + } + , { + $set: Object.fromEntries(Object.entries(alertMessage).map(([key, value]) => + ['settings.alertMessage.' + key, value] + )), + }, + {returnDocument: 'after'} + ) + + var userModifided = false + const userMatching = oldUser !== null + if (newUser) { + userModifided = UserChangeHandler.updateUserHandler(oldUser, newUser) + } + return {modifiedCount: userModifided ? 1 : 0, matchedCount: userMatching ? 1 : 0, newUser: newUser} +} + + +// dbapi.updateUserSettings = function(email, changes) { +export const updateUserSettings = async function(email, changes) { + const oldUser = await db.users.findOne({email: email}) + const newUser = await db.users.findOneAndUpdate( + { + email: email + } + , { + $set: { + settings: {...oldUser?.settings, ...changes} + } + }, + {returnDocument: 'after'} + ) + UserChangeHandler.updateUserHandler(oldUser, newUser) +} + +// dbapi.insertUserAdbKey = function(email, key) { +export const insertUserAdbKey = function(email, key) { + let data = { + title: key.title, + fingerprint: key.fingerprint + } + return db.users.findOne({email: email}).then(user => { + let adbKeys = user?.adbKeys ? user?.adbKeys : [] + adbKeys.push(data) + return db.users.updateOne( + {email: email} + , {$set: {adbKeys: user?.adbKeys ? adbKeys : [data]}} + ) + }) +} + +// dbapi.grantAdmin = function(email) { +export const grantAdmin = function(email) { + return db.users.findOneAndUpdate({email: email}, { + $set: { + privilege: apiutil.ADMIN + } + }, {returnDocument: 'after'}) +} + +// dbapi.revokeAdmin = function(email) { +export const revokeAdmin = function(email) { + return db.users.findOneAndUpdate({email: email}, { + $set: { + privilege: apiutil.USER + } + }, {returnDocument: 'after'}) +} + +// dbapi.acceptPolicy = function(email) { +export const acceptPolicy = function(email) { + return db.users.updateOne({email: email}, { + $set: { + acceptedPolicy: true + } + }) +} + +export const reserveUserGroupInstance = async(email) => { + const oldUser = await loadUser(email) + const newUser = await db.users.findOneAndUpdate( + {email} + , [{ + $set: {'groups.quotas.consumed.number': { + $min: [{ + $sum: ['$groups.quotas.consumed.number', 1] + }, '$groups.quotas.allocated.number']} + } + }], + {returnDocument: 'after'} + ) + const userModifided = UserChangeHandler.updateUserHandler(oldUser, newUser) + return {modifiedCount: userModifided ? 1 : 0} +} + +export const releaseUserGroupInstance = async(email) => { + const oldUser = await loadUser(email) + const newUser = await db.users.findOneAndUpdate( + { + email + } + , [{ + $set: {'groups.quotas.consumed.number': { + $max: [{ + $sum: ['$groups.quotas.consumed.number', -1] + }, 0]} + } + }], + {returnDocument: 'after'} + ) + const userModifided = UserChangeHandler.updateUserHandler(oldUser, newUser) + return {modifiedCount: userModifided ? 1 : 0} +} + +export const updateUserGroupDuration = async(email, oldDuration, newDuration) => { + const oldUser = await loadUser(email) + const newUser = await db.users.findOneAndUpdate( + {email: email} + , [{ + $set: { + 'groups.quotas.consumed.duration': { + $cond: [ + {$lte: [{$sum: ['$groups.quotas.consumed.duration', newDuration, -oldDuration]}, '$groups.quotas.allocated.duration']}, + {$sum: ['$groups.quotas.consumed.duration', newDuration, -oldDuration]}, + '$groups.quotas.consumed.duration' + ] + } + } + }], + {returnDocument: 'after'} + ) + var userModifided = false + const userMatching = oldUser !== null + if (newUser) { + userModifided = UserChangeHandler.updateUserHandler(oldUser, newUser) + } + return {modifiedCount: userModifided ? 1 : 0, matchedCount: userMatching ? 1 : 0} +} + +export const updateUserGroupsQuotas = async(email, duration, number, repetitions) => { + const oldUser = await db.users.findOne({email: email}) + + const consumed = oldUser?.groups.quotas.consumed.duration + const allocated = oldUser?.groups.quotas.allocated.duration + const consumedNumber = oldUser?.groups.quotas.consumed.number + const allocatedNumber = oldUser?.groups.quotas.allocated.number + + const newUser = await db.users.findOneAndUpdate( + {email: email} + , { + $set: { + 'groups.quotas.allocated.duration': duration && consumed <= duration && + (!number || consumedNumber <= number) ? duration : allocated, + 'groups.quotas.allocated.number': number && consumedNumber <= number && + (!duration || consumed <= duration) ? number : allocatedNumber, + 'groups.quotas.repetitions': repetitions || oldUser?.groups.quotas.repetitions + } + }, + {returnDocument: 'after'} + ) + + var userModifided = false + if (newUser) { + userModifided = UserChangeHandler.updateUserHandler(oldUser, newUser) + } + + return {modifiedCount: userModifided ? 1 : 0, newUser: newUser} +} + +export const updateDefaultUserGroupsQuotas = async(email, duration, number, repetitions) => { + const oldUser = await db.users.findOne({email: email}) + const newUser = await db.users.findOneAndUpdate( + {email: email} + , [{ + $set: { + 'groups.quotas.defaultGroupsDuration': { + $cond: [ + { + $ne: [duration, null] + }, + duration, + '$groups.quotas.defaultGroupsDuration' + ] + }, + 'groups.quotas.defaultGroupsNumber': { + $cond: [ + { + $ne: [number, null] + }, + number, + '$groups.quotas.defaultGroupsNumber' + ] + }, + 'groups.quotas.defaultGroupsRepetitions': { + $cond: [ + { + $ne: [repetitions, null] + }, + repetitions, + '$groups.quotas.defaultGroupsRepetitions' + ] + } + } + }], + {returnDocument: 'after'} + ) + var userModifided = false + if (newUser) { + userModifided = UserChangeHandler.updateUserHandler(oldUser, newUser) + } + return {modifiedCount: userModifided ? 1 : 0, newUser: newUser} +} + +// dbapi.deleteUserAdbKey = function(email, fingerprint) { +export const deleteUserAdbKey = function(email, fingerprint) { + return db.users.findOne({email: email}).then(user => { + return db.users.updateOne( + {email: email} + , { + $set: { + adbKeys: user?.adbKeys ? user?.adbKeys.filter(key => { + return key.fingerprint !== fingerprint + }) : [] + } + } + ) + }) +} + +// dbapi.resetUserSettings = function(email) { +export const resetUserSettings = function(email) { + return db.users.updateOne({email: email}, + { + $set: { + settings: {} + } + }) +} + +export const deleteUser = async function(email) { + const deletedUser = await db.users.findOneAndDelete({email: email}) + UserChangeHandler.sendUserChange(deletedUser, false, [], 'deleted', ['settings']) + return {deletedCount: deletedUser !== null ? 1 : 0} +} + + +/* +==================================================== +==================== deprecated ==================== +==================================================== +*/ + +/** + * @deprecated Do not use locks in database. + */ +export const setLockOnUser = function(email, state) { + return db.users.findOne({email: email}).then(oldDoc => { + if (!oldDoc || !oldDoc.groups) { + throw new Error(`User with email ${email} not found or groups field is missing.`) + } + return db.users.updateOne( + {email: email}, + { + $set: { + 'groups.lock': oldDoc.groups.lock !== state ? state : oldDoc.groups.lock + } + } + ) + .then(updateStats => { + return db.users.findOne({email: email}).then(newDoc => { + // @ts-ignore + updateStats.changes = [ + {new_val: {...newDoc}, old_val: {...oldDoc}} + ] + return updateStats + }) + }) + }) +} + +export const getUserAdbKeys = function(email) { + return db.users.findOne({email: email}) + .then(user => user?.adbKeys || []) +} diff --git a/lib/units/api/controllers/groups.js b/lib/units/api/controllers/groups.js index b39620ac78..c15b25db35 100644 --- a/lib/units/api/controllers/groups.js +++ b/lib/units/api/controllers/groups.js @@ -11,7 +11,7 @@ import {v4 as uuidv4} from 'uuid' import usersapi from './users.js' import lockutil from '../../../util/lockutil.js' import {isOriginGroup} from '../../../util/apiutil.js' -import {loadDevicesBySerials} from '../../../db/models/all/model.js' +import DeviceModel from '../../../db/models/device/index.js' const log = logger.createLogger('groups-controller:') /* ---------------------------------- PRIVATE FUNCTIONS --------------------------------- */ @@ -168,7 +168,7 @@ function addGroupDevices(req, res) { } if (isInternal) { - return loadDevicesBySerials(autotestsGroup?.devices) + return DeviceModel.loadDevicesBySerials(autotestsGroup?.devices) .then(devices => apiutil.respond(res, 200, `Added (group ${target})`, { group: { id: autotestsGroup?.id, @@ -824,7 +824,7 @@ function updateGroup(req, res) { .then(function(group) { if (group && typeof group !== 'boolean') { if (isInternal) { - loadDevicesBySerials(group.devices) + DeviceModel.loadDevicesBySerials(group.devices) .then(devices => apiutil.respond(res, 200, 'Updated (group)', {group: {id: group.id, devices: devices}})) } else { @@ -909,7 +909,7 @@ function updateGroup(req, res) { repetitions === group.repetitions ) { if (isInternal) { - return loadDevicesBySerials(group.devices) + return DeviceModel.loadDevicesBySerials(group.devices) .then(devices => apiutil.respond(res, 200, 'Unchanged (group)', {group: {id: group.id, devices: devices}})) } } @@ -999,7 +999,7 @@ function getGroupDevices(req, res) { }) } else { - loadDevicesBySerials(group.devices) + DeviceModel.loadDevicesBySerials(group.devices) .then(function(devices) { devices = devices.map(device => apiutil.filterDevice(req, device)) apiutil.respond(res, 200, 'Devices Information', {devices: devices}) diff --git a/lib/units/api/controllers/users.js b/lib/units/api/controllers/users.js index 7eff6be078..cbb3cecbc6 100644 --- a/lib/units/api/controllers/users.js +++ b/lib/units/api/controllers/users.js @@ -1,4 +1,3 @@ -import dbapi from '../../../db/api.js' import _ from 'lodash' import * as apiutil from '../../../util/apiutil.js' import * as lockutil from '../../../util/lockutil.js' @@ -8,11 +7,14 @@ import wireutil from '../../../wire/util.js' import userapi from './user.js' import * as service from '../../../util/serviceuser.js' import {MongoServerError} from 'mongodb' +import AllModel from '../../../db/models/all/index.js' +import GroupModel from '../../../db/models/group/index.js' +import UserModel from '../../../db/models/user/index.js' /* --------------------------------- PRIVATE FUNCTIONS --------------------------------------- */ function userApiWrapper(fn, req, res) { const email = req.params.email - dbapi.loadUser(email).then(function(user) { + UserModel.loadUser(email).then(function(user) { if (!user) { apiutil.respond(res, 404, 'Not Found (user)') } @@ -39,24 +41,24 @@ async function removeUser(email, req, res) { const groupOwnerState = req.query.groupOwner const anyGroupOwnerState = typeof groupOwnerState === 'undefined' const lock = {} - const user = await dbapi.loadUser(email) + const user = await UserModel.loadUser(email) if (!user) { return 'not found' } async function removeGroupUser(owner, id) { - const userGroup = await dbapi.getUserGroup(owner, id) + const userGroup = await GroupModel.getUserGroup(owner, id) if (!userGroup) { return 'not found' } return owner === email ? - dbapi.deleteUserGroup(id) : - dbapi.removeGroupUser(id, email) + GroupModel.deleteUserGroup(id) : + GroupModel.removeGroupUser(id, email) } function deleteUserInDatabase(channel) { - return dbapi.removeUserAccessTokens(email).then(function() { - return dbapi.deleteUser(email).then(function() { + return AllModel.removeUserAccessTokens(email).then(function() { + return UserModel.deleteUser(email).then(function() { req.options.pushdev.send([ channel, wireutil.envelope(new wire.DeleteUserMessage(email)) @@ -90,12 +92,12 @@ async function removeUser(email, req, res) { if (req.user.email === email) { return Promise.resolve('forbidden') } - return dbapi.lockUser(email).then(function(stats) { + return AllModel.lockUser(email).then(function(stats) { if (stats.modifiedCount === 0) { return apiutil.lightComputeStats(res, stats) } const user = lock.user = stats.changes[0].new_val - return dbapi.getGroupsByUser(user.email).then(function(groups) { + return GroupModel.getGroupsByUser(user.email).then(function(groups) { return computeUserGroupOwnership(groups).then(function(doContinue) { if (!doContinue) { return 'unchanged' @@ -117,7 +119,7 @@ function grantAdmin(req, res) { if (req.user.privilege !== apiutil.ADMIN) { return apiutil.respond(res, 403, 'Forbidden (user doesnt have admin privilege)') } - dbapi.grantAdmin(req.params.email).then((user) => { + UserModel.grantAdmin(req.params.email).then((user) => { if (user) { // @ts-ignore return apiutil.respond(res, 200, 'Grant admin for user', {user: user}) @@ -131,7 +133,7 @@ function revokeAdmin(req, res) { if (req.user.privilege !== apiutil.ADMIN) { return apiutil.respond(res, 403, 'Forbidden (user doesnt have admin privilege)') } - dbapi.revokeAdmin(req.params.email).then((user) => { + UserModel.revokeAdmin(req.params.email).then((user) => { if (user) { // @ts-ignore return apiutil.respond(res, 200, 'Revoke admin for user', {user: user}) @@ -142,7 +144,7 @@ function revokeAdmin(req, res) { }) } function lockStfAdminUser(res) { - return dbapi.lockUser(apiutil.STF_ADMIN_EMAIL).then(function(stats) { + return AllModel.lockUser(apiutil.STF_ADMIN_EMAIL).then(function(stats) { if (stats.modifiedCount === 0) { return apiutil.lightComputeStats(res, stats) } @@ -154,12 +156,12 @@ function updateUsersAlertMessage(req, res) { return apiutil.respond(res, 403, 'Forbidden (user doesnt have admin privilege)') } const lock = lockStfAdminUser(res) - return dbapi.updateUsersAlertMessage(req.body).then(function(/** @type {any} */ stats) { + return UserModel.updateUsersAlertMessage(req.body).then(function(/** @type {any} */ stats) { if (stats.matchedCount > 0 && stats.modifiedCount === 0) { - apiutil.respond(res, 200, 'Unchanged (users alert message)', {alertMessage: stats.changes[0].new_val.settings.alertMessage}) + apiutil.respond(res, 200, 'Unchanged (users alert message)', {alertMessage: stats.newUser.settings.alertMessage}) } else { - apiutil.respond(res, 200, 'Updated (users alert message)', {alertMessage: stats.changes[0].new_val.settings.alertMessage}) + apiutil.respond(res, 200, 'Updated (users alert message)', {alertMessage: stats.newUser.settings.alertMessage}) } }) .catch(function(err) { @@ -178,9 +180,9 @@ function updateUsersAlertMessage(req, res) { /* --------------------------------- PUBLIC FUNCTIONS --------------------------------------- */ function getUserInfo(req, email) { const fields = req.query.fields - return dbapi.loadUser(email).then(function(user) { + return UserModel.loadUser(email).then(function(user) { if (user) { - return dbapi.getRootGroup().then(function(group) { + return GroupModel.getRootGroup().then(function(group) { return getPublishedUser(user, req.user.email, group?.owner?.email, fields) }) } @@ -189,7 +191,7 @@ function getUserInfo(req, email) { } function getUsersAlertMessage(req, res) { const fields = req.query.fields - return dbapi.loadUser(apiutil.STF_ADMIN_EMAIL).then(async function(user) { + return UserModel.loadUser(apiutil.STF_ADMIN_EMAIL).then(async function(user) { if (user?.settings?.alertMessage === undefined) { const lock = await lockStfAdminUser(res) const alertMessage = { @@ -197,9 +199,9 @@ function getUsersAlertMessage(req, res) { data: '*** this site is currently under maintenance, please wait ***', level: 'Critical' } - return dbapi.updateUsersAlertMessage(alertMessage).then(function(/** @type {any} */ stats) { - if (!stats.errors) { - return stats.changes[0].new_val.settings.alertMessage + return UserModel.updateUsersAlertMessage(alertMessage).then(function(/** @type {any} */ stats) { + if (stats.modifiedCount === 1) { + return stats.newUser.settings.alertMessage } throw new Error('Failed to initialize users alert message') }) @@ -239,15 +241,15 @@ function updateUserGroupsQuotas(req, res) { null const lock = {} - dbapi.loadUser(email).then(function(user) { + UserModel.loadUser(email).then(function(user) { if (user) { lockutil.lockUser(email, res, lock).then(function(lockingSuccessed) { if (lockingSuccessed) { - return dbapi.updateUserGroupsQuotas(email, duration, number, repetitions) + return UserModel.updateUserGroupsQuotas(email, duration, number, repetitions) .then(function(/** @type {any} */ stats) { if (stats.modifiedCount > 0) { return apiutil.respond(res, 200, 'Updated (user quotas)', { - user: apiutil.publishUser(stats.changes[0].new_val) + user: apiutil.publishUser(stats.newUser) }) } if ((duration === null || duration === lock.user.groups.quotas.allocated.duration) && @@ -285,11 +287,11 @@ function updateDefaultUserGroupsQuotas(req, res) { const lock = {} lockutil.lockUser(req.user.email, res, lock).then(function(lockingSuccessed) { if (lockingSuccessed) { - return dbapi.updateDefaultUserGroupsQuotas(req.user.email, duration, number, repetitions) + return UserModel.updateDefaultUserGroupsQuotas(req.user.email, duration, number, repetitions) .then(function(/** @type {any} */ stats) { if (stats.modifiedCount > 0) { return apiutil.respond(res, 200, 'Updated (user default quotas)', { - user: apiutil.publishUser(stats) + user: apiutil.publishUser(stats.newUser) }) } return apiutil.respond(res, 200, 'Unchanged (user default quotas)', {user: {}}) @@ -320,8 +322,8 @@ function getUserByEmail(req, res) { } function getUsers(req, res) { const fields = req.query.fields - dbapi.getUsers().then(function(users) { - return dbapi.getRootGroup().then(function(group) { + UserModel.getUsers().then(function(users) { + return GroupModel.getRootGroup().then(function(group) { apiutil.respond(res, 200, 'Users Information', { users: users.map(function(user) { return getPublishedUser(user, req.user.email, group?.owner?.email, fields) @@ -336,7 +338,7 @@ function getUsers(req, res) { function createUser(req, res) { const email = req.params.email const name = req.query.name - dbapi.createUser(email, name, req.user.ip).then(function(/** @type {any} */ stats) { + UserModel.createUser(email, name, req.user.ip).then(function(/** @type {any} */ stats) { apiutil.respond(res, 201, 'Created (user)', { user: apiutil.publishUser(stats.changes[0].new_val) }) @@ -405,7 +407,7 @@ function deleteUsers(req, res) { } (function() { if (typeof emails === 'undefined') { - return dbapi.getEmails().then(function(emails) { + return UserModel.getEmails().then(function(emails) { return removeUsers(emails) }) } diff --git a/lib/units/groups-engine/index.js b/lib/units/groups-engine/index.js index ee3d1f877c..7ccb596dd6 100644 --- a/lib/units/groups-engine/index.js +++ b/lib/units/groups-engine/index.js @@ -1,6 +1,5 @@ import devicesWatcher from './watchers/devices.js' import lifecycle from '../../util/lifecycle.js' -import usersWatcher from './watchers/users.js' import logger from '../../util/logger.js' import db from '../../db/index.js' @@ -15,7 +14,6 @@ export default (async function(options) { await db.connect() devicesWatcher(push, pushdev, channelRouter) - usersWatcher(pushdev) lifecycle.observe(() => [push, pushdev].forEach((sock) => sock.close()) diff --git a/lib/units/groups-engine/watchers/users.js b/lib/units/groups-engine/watchers/users.js deleted file mode 100644 index 6ae21ffc59..0000000000 --- a/lib/units/groups-engine/watchers/users.js +++ /dev/null @@ -1,105 +0,0 @@ -import timeutil from '../../../util/timeutil.js' -import _ from 'lodash' -import logger from '../../../util/logger.js' -import wireutil from '../../../wire/util.js' -import wire from '../../../wire/index.js' -import db from '../../../db/index.js' -export default (function(pushdev) { - const log = logger.createLogger('watcher-users') - function sendUserChange(user, isAddedGroup, groups, action, targets) { - pushdev.send([ - wireutil.global, - wireutil.envelope(new wire.UserChangeMessage(user, isAddedGroup, groups, action, targets, timeutil.now('nano'))) - ]) - } - let changeStream - db.connect().then(client => { - const users = client.collection('users') - changeStream = users.watch([ - { - $project: { - 'fullDocument.email': 1, - 'fullDocument.name': 1, - 'fullDocument.privilege': 1, - 'fullDocument.groups.quotas': 1, - 'fullDocument.groups.subscribed': 1, - 'fullDocument.settings.alertMessage': 1, - 'fullDocumentBeforeChange.email': 1, - 'fullDocumentBeforeChange.name': 1, - 'fullDocumentBeforeChange.privilege': 1, - 'fullDocumentBeforeChange.groups.quotas': 1, - 'fullDocumentBeforeChange.groups.subscribed': 1, - 'fullDocumentBeforeChange.settings.alertMessage': 1, - operationType: 1 - } - } - ], {fullDocument: 'whenAvailable', fullDocumentBeforeChange: 'whenAvailable'}) - changeStream.on('change', next => { - log.info('Users watcher next: ' + JSON.stringify(next)) - try { - let newDoc, oldDoc - let operationType = next.operationType - // @ts-ignore - if (next.fullDocument) { - // @ts-ignore - newDoc = next.fullDocument - } - else { - newDoc = null - } - // @ts-ignore - if (next.fullDocumentBeforeChange) { - // @ts-ignore - oldDoc = next.fullDocumentBeforeChange - } - else { - oldDoc = null - } - if (newDoc === null && oldDoc === null) { - log.info('New user doc and old user doc is NULL') - return false - } - if (operationType === 'insert') { - sendUserChange(newDoc, false, [], 'created', ['settings']) - } - else if (operationType === 'delete') { - sendUserChange(oldDoc, false, [], 'deleted', ['settings']) - } - else { - const targets = [] - if (newDoc.groups && oldDoc.groups) { - if (newDoc.groups.quotas && oldDoc.groups.quotas) { - if (!_.isEqual(newDoc.groups.quotas.allocated, oldDoc.groups.quotas.allocated)) { - targets.push('settings') - targets.push('view') - } - else if (!_.isEqual(newDoc.groups.quotas.consumed, oldDoc.groups.quotas.consumed)) { - targets.push('view') - } - else if (newDoc.groups.quotas.defaultGroupsNumber !== - oldDoc.groups.quotas.defaultGroupsNumber || - newDoc.groups.defaultGroupsDuration !== - oldDoc.groups.quotas.defaultGroupsDuration || - newDoc.groups.defaultGroupsRepetitions !== - oldDoc.groups.quotas.defaultGroupsRepetitions || - newDoc.groups.repetitions !== - oldDoc.groups.quotas.repetitions || - !_.isEqual(newDoc.groups.subscribed, oldDoc.groups.subscribed)) { - targets.push('settings') - } - } - } - else if (!_.isEqual(newDoc.settings.alertMessage, oldDoc.settings.alertMessage)) { - targets.push('menu') - } - if (targets.length) { - sendUserChange(newDoc, newDoc.groups.subscribed.length > oldDoc.groups.subscribed.length, _.xor(newDoc.groups.subscribed, oldDoc.groups.subscribed), 'updated', targets) - } - } - } - catch (e) { - log.error(e) - } - }) - }) -}) diff --git a/lib/units/processor/index.ts b/lib/units/processor/index.ts index 266594b347..0490196b0d 100644 --- a/lib/units/processor/index.ts +++ b/lib/units/processor/index.ts @@ -8,6 +8,7 @@ import dbapi from '../../db/models/all/index.js' import lifecycle from '../../util/lifecycle.js' import srv from '../../util/srv.js' import * as zmqutil from '../../util/zmqutil.js' +import UserModel from '../../db/models/user/index.js' import { UserChangeMessage, GroupChangeMessage, @@ -162,7 +163,7 @@ export default db.ensureConnectivity(async(options: Options) => { }) .on(JoinGroupByAdbFingerprintMessage, async (channel, message) => { try { - const user = await dbapi.lookupUserByAdbFingerprint(message.fingerprint) + const user = await UserModel.lookupUserByAdbFingerprint(message.fingerprint) if (user) { devDealer.send([ channel, diff --git a/lib/units/websocket/index.js b/lib/units/websocket/index.js index 07e08e8c22..6f59f52e4c 100644 --- a/lib/units/websocket/index.js +++ b/lib/units/websocket/index.js @@ -13,7 +13,6 @@ import logger from '../../util/logger.js' import wire from '../../wire/index.js' import wireutil from '../../wire/util.js' import {WireRouter} from '../../wire/router.js' -import dbapi from '../../db/api.js' import datautil from '../../util/datautil.js' import lifecycle from '../../util/lifecycle.js' import cookieSession from './middleware/cookie-session.js' @@ -26,6 +25,8 @@ import db from '../../db/index.js' import EventEmitter from 'events' import generateToken from '../api/helpers/generateToken.js' import {UpdateAccessTokenMessage, DeleteUserMessage, DeviceChangeMessage, UserChangeMessage, GroupChangeMessage, DeviceGroupChangeMessage, GroupUserChangeMessage, DeviceLogMessage, DeviceIntroductionMessage, DeviceReadyMessage, DevicePresentMessage, DeviceAbsentMessage, InstalledApplications, JoinGroupMessage, JoinGroupByAdbFingerprintMessage, LeaveGroupMessage, DeviceStatusMessage, DeviceIdentityMessage, TransactionProgressMessage, TransactionDoneMessage, TransactionTreeMessage, DeviceLogcatEntryMessage, AirplaneModeEvent, BatteryEvent, GetServicesAvailabilityMessage, DeviceBrowserMessage, ConnectivityEvent, PhoneStateEvent, RotationEvent, CapabilitiesMessage, ReverseForwardsEvent, TemporarilyUnavailableMessage, UpdateRemoteConnectUrl} from '../../wire/wire.js' +import AllModel from '../../db/models/all/index.js' +import UserModel from '../../db/models/user/index.js' const request = Promise.promisifyAll(postmanRequest) export default (async function(options) { const log = logger.createLogger('websocket') @@ -245,7 +246,7 @@ export default (async function(options) { }) // @TODO refactore JoimGroupMessage route .on(JoinGroupMessage, function(channel, message) { - dbapi.getInstalledApplications({serial: message.serial}) + AllModel.getInstalledApplications({serial: message.serial}) .then(applications => { if (!user?.ownedChannels) { user.ownedChannels = new Set() @@ -448,10 +449,10 @@ export default (async function(options) { // // Device note .on('device.note', function(data) { - return dbapi + return AllModel .setDeviceNote(data.serial, data.note) .then(function() { - return dbapi.loadDevice(user.groups.subscribed, data.serial) + return AllModel.loadDevice(user.groups.subscribed, data.serial) }) .then(function(device) { if (device) { @@ -470,19 +471,19 @@ export default (async function(options) { // Settings .on('user.settings.update', function(data) { if (data.alertMessage === undefined) { - dbapi.updateUserSettings(user.email, data) + UserModel.updateUserSettings(user.email, data) } else { - dbapi.updateUserSettings(apiutil.STF_ADMIN_EMAIL, data) + UserModel.updateUserSettings(apiutil.STF_ADMIN_EMAIL, data) } }) .on('user.settings.reset', function() { - dbapi.resetUserSettings(user.email) + UserModel.resetUserSettings(user.email) }) .on('user.keys.accessToken.generate', async(data) => { const {title} = data const token = generateToken(user, options.secret) - await dbapi + await AllModel .saveUserAccessToken(user.email, { title: title, id: token.id, @@ -496,7 +497,7 @@ export default (async function(options) { .on('user.keys.accessToken.remove', function(data) { const isAdmin = user.privilege === apiutil.ADMIN const email = (isAdmin ? data.email : null) || user.email - return dbapi + return AllModel .removeUserAccessToken(email, data.title) .then(function() { socket.emit('user.keys.accessToken.updated') @@ -506,16 +507,16 @@ export default (async function(options) { // @ts-ignore return Adb.util.parsePublicKey(data.key) .then(function(key) { - return dbapi.lookupUsersByAdbKey(key.fingerprint) + return UserModel.lookupUsersByAdbKey(key.fingerprint) .then(function(keys) { return keys }) .then(function(users) { if (users.length) { - throw new dbapi.DuplicateSecondaryIndexError() + throw new AllModel.DuplicateSecondaryIndexError() } else { - return dbapi.insertUserAdbKey(user.email, { + return UserModel.insertUserAdbKey(user.email, { title: data.title, fingerprint: key.fingerprint }) @@ -541,16 +542,16 @@ export default (async function(options) { }) }) .on('user.keys.adb.accept', function(data) { - return dbapi.lookupUsersByAdbKey(data.fingerprint) + return UserModel.lookupUsersByAdbKey(data.fingerprint) .then(function(keys) { return keys }) .then(function(users) { if (users.length) { - throw new dbapi.DuplicateSecondaryIndexError() + throw new AllModel.DuplicateSecondaryIndexError() } else { - return dbapi.insertUserAdbKey(user.email, { + return UserModel.insertUserAdbKey(user.email, { title: data.title, fingerprint: data.fingerprint }) @@ -569,12 +570,12 @@ export default (async function(options) { ]) }) // @ts-ignore - .catch(dbapi.DuplicateSecondaryIndexError, function() { + .catch(AllModel.DuplicateSecondaryIndexError, function() { // No-op }) }) .on('user.keys.adb.remove', function(data) { - return dbapi + return UserModel .deleteUserAdbKey(user.email, data.fingerprint) .then(function() { socket.emit('user.keys.adb.removed', data) @@ -582,7 +583,7 @@ export default (async function(options) { }) .on('shell.settings.execute', function(data) { let command = data.command - dbapi.loadDevices().then(devices => { + AllModel.loadDevices().then(devices => { devices.forEach(device => { push.send([ device.channel, @@ -901,7 +902,7 @@ export default (async function(options) { }) .on('group.invite', async(channel, responseChannel, data) => { joinChannel(responseChannel) - const keys = await dbapi.getUserAdbKeys(user.email) + const keys = await UserModel.getUserAdbKeys(user.email) push.send([ channel, wireutil.transaction(responseChannel, new wire.GroupMessage( @@ -1342,7 +1343,7 @@ export default (async function(options) { ]) }) .on('policy.accept', function(data) { - dbapi.acceptPolicy(user.email) + UserModel.acceptPolicy(user.email) }) }) .finally(function() { From c94a61923b36f6e1809abcd34020d5d962ee4f4a Mon Sep 17 00:00:00 2001 From: Elmir Khalilov <52529096+e-khalilov@users.noreply.github.com> Date: Thu, 2 Oct 2025 11:53:48 +0300 Subject: [PATCH 07/13] fix heartbeat (#377) Co-authored-by: e.khalilov --- lib/units/processor/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/units/processor/index.ts b/lib/units/processor/index.ts index 0490196b0d..e98df9ab83 100644 --- a/lib/units/processor/index.ts +++ b/lib/units/processor/index.ts @@ -123,7 +123,6 @@ export default db.ensureConnectivity(async(options: Options) => { .on(GroupChangeMessage, defaultWireHandler) .on(DeviceGroupChangeMessage, defaultWireHandler) .on(GroupUserChangeMessage, defaultWireHandler) - .on(DeviceHeartbeatMessage, defaultWireHandler) .on(DeviceLogMessage, defaultWireHandler) .on(TransactionProgressMessage, defaultWireHandler) .on(TransactionDoneMessage, defaultWireHandler) @@ -297,6 +296,9 @@ export default db.ensureConnectivity(async(options: Options) => { reply.okay('success', {devices}) ]) }) + .on(DeviceHeartbeatMessage, (channel, message, data) => { + devDealer.send([ channel, data ]) + }) .handler(); devDealer.on('message', router) From 649b907e877d3c96606e9fa04db06e363a03fb01 Mon Sep 17 00:00:00 2001 From: Elmir Khalilov <52529096+e-khalilov@users.noreply.github.com> Date: Fri, 3 Oct 2025 12:38:36 +0300 Subject: [PATCH 08/13] overrides dependencies (#378) Co-authored-by: e.khalilov --- package-lock.json | 54 ++++++++++++++++++++++++++++++-------------- package.json | 5 ++-- ui/package-lock.json | 24 +++++--------------- ui/package.json | 3 +++ 4 files changed, 49 insertions(+), 37 deletions(-) diff --git a/package-lock.json b/package-lock.json index 95d72eab76..6139152d62 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5492,12 +5492,43 @@ "yauzl": "^2.7.0" } }, + "node_modules/appium-support/node_modules/axios": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.0.tgz", + "integrity": "sha512-oXTDccv8PcfjZmPGlWsPSwtOJCZ/b6W5jAMCNcfwJbCzDckwG0jrYJFaWH1yvivfCXjVzV/SPDEhMB3Q+DSurg==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/appium-support/node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "license": "MIT" }, + "node_modules/appium-support/node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/appium-support/node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -5734,17 +5765,6 @@ "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", "license": "MIT" }, - "node_modules/axios": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.30.0.tgz", - "integrity": "sha512-Z4F3LjCgfjZz8BMYalWdMgAQUnEtKDmpwNHjh/C8pQZWde32TF64cqnSeyL3xD/aTIASRU30RHTNzRiV/NpGMg==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.4", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "node_modules/backoff": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", @@ -6565,9 +6585,9 @@ } }, "node_modules/cmake-js/node_modules/axios": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", - "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.0.tgz", + "integrity": "sha512-oXTDccv8PcfjZmPGlWsPSwtOJCZ/b6W5jAMCNcfwJbCzDckwG0jrYJFaWH1yvivfCXjVzV/SPDEhMB3Q+DSurg==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -6576,9 +6596,9 @@ } }, "node_modules/cmake-js/node_modules/follow-redirects": { - "version": "1.15.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.10.tgz", - "integrity": "sha512-V7O/fFKM539IC2bweloFWuoiJ9OtI3W2uIqJPWM8IT5xxNyt73QtvVqmSpcDmk07ivmmlKB+rRY0vpQjIYNtKw==", + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", diff --git a/package.json b/package.json index 257e9e1c0f..f31f526540 100644 --- a/package.json +++ b/package.json @@ -171,7 +171,8 @@ "socket.io-parser": "4.2.4", "request": "$request", "validator": "13.9.0", - "node-forge": "1.3.1" + "node-forge": "1.3.1", + "axios": "1.12.0" }, "engines": { "node": ">= 12", @@ -190,4 +191,4 @@ "pre-commit": "true" } } -} \ No newline at end of file +} diff --git a/ui/package-lock.json b/ui/package-lock.json index ab8c37f585..162c7aefc3 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -7379,17 +7379,6 @@ "react": "^15.x || ^16.x || ^17.x || ^18.x || ^19.x" } }, - "node_modules/console-feed/node_modules/linkifyjs": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-2.1.9.tgz", - "integrity": "sha512-74ivurkK6WHvHFozVaGtQWV38FzBwSTGNmJolEgFp7QgR2bl6ArUWlvT4GcHKbPe1z3nWYi+VUdDZk16zDOVug==", - "license": "MIT", - "peerDependencies": { - "jquery": ">= 1.11.0", - "react": ">= 0.14.0", - "react-dom": ">= 0.14.0" - } - }, "node_modules/console-feed/node_modules/react-inspector": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-5.1.1.tgz", @@ -11276,13 +11265,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jquery": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", - "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", - "license": "MIT", - "peer": true - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -11640,6 +11622,12 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "license": "MIT" }, + "node_modules/linkifyjs": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.3.2.tgz", + "integrity": "sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==", + "license": "MIT" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", diff --git a/ui/package.json b/ui/package.json index 4989f9d0da..fa9dabfd55 100644 --- a/ui/package.json +++ b/ui/package.json @@ -106,6 +106,9 @@ "vite-tsconfig-paths": "^5.0.1", "vitest": "^3.0.9" }, + "overrides": { + "linkifyjs": "4.3.2" + }, "msw": { "workerDirectory": [ "public" From 920ee10fccb66c66fe8487bfba7d96c23711e9de Mon Sep 17 00:00:00 2001 From: Elmir Khalilov <52529096+e-khalilov@users.noreply.github.com> Date: Mon, 6 Oct 2025 15:17:57 +0300 Subject: [PATCH 09/13] Automatic removal of disabled devices (#379) * clear dead devices * minor fix * revert api edits * revert ui (types) edits --------- Co-authored-by: e.khalilov --- lib/cli/local/index.js | 14 ++++- lib/cli/reaper/index.js | 12 ++++ lib/db/models/all/model.js | 14 +---- lib/db/models/device/model.js | 15 ++++- lib/db/models/group/model.js | 2 +- lib/units/processor/index.ts | 20 +++++-- lib/units/reaper/index.ts | 104 ++++++++++++++++++++++++++-------- lib/wire/wire.proto | 4 ++ lib/wire/wire.ts | 56 ++++++++++++++++++ 9 files changed, 196 insertions(+), 45 deletions(-) diff --git a/lib/cli/local/index.js b/lib/cli/local/index.js index 5acc202e36..83e57c0b94 100644 --- a/lib/cli/local/index.js +++ b/lib/cli/local/index.js @@ -302,6 +302,16 @@ export const builder = function(yargs) { type: 'boolean', default: true }) + .option('time-to-device-cleanup', { + describe: 'Time in seconds after which connected devices should be deleted. 0 - do not delete', + type: 'number', + default: 0 + }) + .option('device-cleanup-interval', { + describe: 'Interval for checking devices for cleanup in minutes', + type: 'number', + default: 120_000 + }) .epilog('Each option can be be overwritten with an environment variable ' + 'by converting the option to uppercase, replacing dashes with ' + 'underscores and prefixing it with `STF_LOCAL_` (e.g. ' + @@ -343,7 +353,9 @@ export const handler = function(argv) { [ // reaper one 'reaper', 'reaper001', '--connect-push', argv.bindDevPull, - '--connect-sub', argv.bindDevPub + '--connect-sub', argv.bindDevPub, + '--time-to-device-cleanup', argv.timeToDeviceCleanup, + '--device-cleanup-interval', argv.deviceCleanupInterval ], [ // provider 'provider', diff --git a/lib/cli/reaper/index.js b/lib/cli/reaper/index.js index 651889b528..b741bc2214 100644 --- a/lib/cli/reaper/index.js +++ b/lib/cli/reaper/index.js @@ -30,6 +30,16 @@ export const builder = function(yargs) { type: 'string', default: os.hostname() }) + .option('time-to-device-cleanup', { + describe: 'Time in minutes after which connected devices should be deleted. 0 - do not delete', + type: 'number', + default: 0 + }) + .option('device-cleanup-interval', { + describe: 'Interval for checking devices for cleanup in minutes', + type: 'number', + default: 2 + }) .epilog('Each option can be be overwritten with an environment variable ' + 'by converting the option to uppercase, replacing dashes with ' + 'underscores and prefixing it with `STF_REAPER_` (e.g. ' + @@ -39,6 +49,8 @@ export const handler = function(argv) { return reaper({ name: argv.name, heartbeatTimeout: argv.heartbeatTimeout, + timeToDeviceCleanup: argv.timeToDeviceCleanup, + deviceCleanupInterval: argv.deviceCleanupInterval, endpoints: { push: argv.connectPush, sub: argv.connectSub diff --git a/lib/db/models/all/model.js b/lib/db/models/all/model.js index 1082680ac9..0dd60610b3 100644 --- a/lib/db/models/all/model.js +++ b/lib/db/models/all/model.js @@ -9,7 +9,7 @@ import {v4 as uuidv4} from 'uuid' import * as apiutil from '../../../util/apiutil.js' import GroupModel from '../group/index.js' import UserModel from '../user/index.js' - +import DeviceModel from '../device/index.js' import logger from '../../../util/logger.js' import {getRootGroup, getGroup} from '../group/model.js' @@ -887,16 +887,6 @@ export const loadStandardDevices = function(groups, fields) { }, fields) } -// dbapi.loadPresentDevices = function() { -export const loadPresentDevices = function() { - return db.devices.find({present: true}).toArray() -} - -// dbapi.loadDeviceBySerial = function(serial) { -export const loadDeviceBySerial = function(serial) { - return findDevice({serial: serial}) -} - // dbapi.loadDevice = function(groups, serial) { export const loadDevice = function(groups, serial) { return findDevice({ @@ -1186,7 +1176,7 @@ export const setAbsentDisconnectedDevices = function() { // dbapi.getInstalledApplications = function(message) { export const getInstalledApplications = function(message) { - return loadDeviceBySerial(message.serial) + return DeviceModel.loadDeviceBySerial(message.serial) } // dbapi.setDeviceType = function(serial, type) { diff --git a/lib/db/models/device/model.js b/lib/db/models/device/model.js index ef29f27e49..b00c715014 100644 --- a/lib/db/models/device/model.js +++ b/lib/db/models/device/model.js @@ -32,6 +32,10 @@ export const loadPresentDevices = function() { return db.devices.find({present: true}).toArray() } +export const loadDeviceBySerial = function(serial) { + return db.devices.findOne({serial}) +} + // dbapi.loadDevicesBySerials = function(serials) { export const loadDevicesBySerials = function(serials) { return db.devices.find({serial: {$in: serials}}).toArray() @@ -97,6 +101,15 @@ export const getDeviceType = function(serial) { }) } +export const getDeadDevice = function(time = 60_000) { + return db.devices.find( + { + present: false, + presenceChangedAt: {$lt: new Date(Date.now() - time)} + } + ).project({serial: 1, present: 1, presenceChangedAt: 1}).toArray() +} + // dbapi.generateIndexes = function() { export const generateIndexes = function() { db.devices.createIndex({serial: -1}).then((result) => { @@ -111,8 +124,6 @@ export const generateIndexes = function() { */ - - // dbapi.deleteDevice = function(serial) { export const deleteDevice = function(serial) { return db.devices.deleteOne({serial: serial}) diff --git a/lib/db/models/group/model.js b/lib/db/models/group/model.js index a68fd84eb8..045093bc58 100644 --- a/lib/db/models/group/model.js +++ b/lib/db/models/group/model.js @@ -568,7 +568,7 @@ export const deleteUserGroup = async(id) => { await db.groups.deleteOne({id}) await Promise.all( - group?.users.map(email => db.groups.updateOne( + group?.users.map(email => db.users.updateOne( {email} , { $pull: {'groups.subscribed': id} diff --git a/lib/units/processor/index.ts b/lib/units/processor/index.ts index e98df9ab83..0e4578293b 100644 --- a/lib/units/processor/index.ts +++ b/lib/units/processor/index.ts @@ -9,6 +9,7 @@ import lifecycle from '../../util/lifecycle.js' import srv from '../../util/srv.js' import * as zmqutil from '../../util/zmqutil.js' import UserModel from '../../db/models/user/index.js' +import DeviceModel from '../../db/models/device/index.js' import { UserChangeMessage, GroupChangeMessage, @@ -53,8 +54,9 @@ import { DeleteDevice, SetAbsentDisconnectedDevices, GetServicesAvailabilityMessage, - DeviceRegisteredMessage, GetPresentDevices, DeviceGetIsInOrigin + DeviceRegisteredMessage, GetPresentDevices, DeviceGetIsInOrigin, GetDeadDevices } from '../../wire/wire.js' +import {getDeadDevice} from "../../db/models/device/model.js"; interface Options { name: string @@ -228,8 +230,8 @@ export default db.ensureConnectivity(async(options: Options) => { appDealer.send([channel, data]) }) .on(DeviceGetIsInOrigin, async (channel, message) => { - const device = await dbapi.loadDeviceBySerial(message.serial) - const isInOrigin = device.group.id === device.group.origin + const device = await DeviceModel.loadDeviceBySerial(message.serial) + const isInOrigin = device ? device.group.id === device.group.origin : false devDealer.send([ channel, reply.okay('success', {isInOrigin}) @@ -289,7 +291,7 @@ export default db.ensureConnectivity(async(options: Options) => { appDealer.send([channel, data]) }) .on(GetPresentDevices, async (channel, message, data) => { - const devices = await dbapi.loadPresentDevices() + const devices = await DeviceModel.loadPresentDevices() .then(devices => devices.map(d => d.serial)) devDealer.send([ channel, @@ -299,6 +301,16 @@ export default db.ensureConnectivity(async(options: Options) => { .on(DeviceHeartbeatMessage, (channel, message, data) => { devDealer.send([ channel, data ]) }) + .on(GetDeadDevices, async(channel, message, data) => { + const deadDevices = await DeviceModel.getDeadDevice(message.time) + devDealer.send([ + channel, + reply.okay('success', {deadDevices}) + ]) + }) + .on(DeleteDevice, async(channel, message, data) => { + DeviceModel.deleteDevice(message.serial) + }) .handler(); devDealer.on('message', router) diff --git a/lib/units/reaper/index.ts b/lib/units/reaper/index.ts index 0db7898f36..2fde098619 100644 --- a/lib/units/reaper/index.ts +++ b/lib/units/reaper/index.ts @@ -1,8 +1,9 @@ import logger from '../../util/logger.js' import { + DeleteDevice, DeviceAbsentMessage, DeviceHeartbeatMessage, - DeviceIntroductionMessage, DevicePresentMessage, + DeviceIntroductionMessage, DevicePresentMessage, GetDeadDevices, GetPresentDevices } from '../../wire/wire.js' import wireutil from '../../wire/util.js' @@ -17,6 +18,8 @@ const log = logger.createLogger('reaper') interface Options { heartbeatTimeout: number + timeToDeviceCleanup: number // in minutes + deviceCleanupInterval: number // in minutes endpoints: { sub: string[] push: string[] @@ -87,34 +90,85 @@ export default (async(options: Options) => { ttlset.stop() }) - try { - log.info('Reaping devices with no heartbeat') + const router = new WireRouter() + .on(DeviceIntroductionMessage, (channel, message) => { + ttlset.drop(message.serial, TTLSet.SILENT) + ttlset.bump(message.serial, Date.now()) + }) + .on(DeviceHeartbeatMessage, (channel, message) => { + ttlset.bump(message.serial, Date.now()) + }) + .on(DeviceAbsentMessage, (channel, message) => { + ttlset.drop(message.serial, TTLSet.SILENT) + }) - const router = new WireRouter() - .on(DeviceIntroductionMessage, (channel, message) => { - ttlset.drop(message.serial, TTLSet.SILENT) - ttlset.bump(message.serial, Date.now()) - }) - .on(DeviceHeartbeatMessage, (channel, message) => { - ttlset.bump(message.serial, Date.now()) - }) - .on(DeviceAbsentMessage, (channel, message) => { - ttlset.drop(message.serial, TTLSet.SILENT) - }) + if (options.timeToDeviceCleanup) { + log.info('deviceCleanerLoop enabled') - // Listen to changes - sub.on('message', router.handler()) + // This functionality is implemented in the Reaper unit because this unit cannot be replicated + const deviceCleanerLoop = () => setTimeout(async() => { + log.info('Checking dead devices [interval: %s]', options.deviceCleanupInterval) + try { + const absenceDuration = options.timeToDeviceCleanup + const {deadDevices} = await runTransactionDev(wireutil.global, GetDeadDevices, { + time: options.timeToDeviceCleanup * 60 * 1000 + }, {sub, push, router}) - // Load initial state - const {devices} = await runTransactionDev(wireutil.global, GetPresentDevices, {}, {sub, push, router}) + for (const {serial, present} of deadDevices) { + if (present) { + continue + } - const now = Date.now() - devices.forEach((serial: string) => { - ttlset.bump(serial, now, TTLSet.SILENT) - }) + log.info( // @ts-ignore + 'Removing a dead device [serial: %s, absence_duration: %.1f %s]', + serial, + ... ( + absenceDuration >= 60 // if more 1 hour + ? [absenceDuration / 60, 'hrs'] + : [absenceDuration, 'min'] + ) + ) + + push.send([ + wireutil.global, + wireutil.pack(DeleteDevice, {serial}) + ]) + } + } catch (err: any) { + log.error('Dead device check failed with error: %s', err?.message) + } finally { + deviceCleanerLoop() + } + }, options.deviceCleanupInterval * 60 * 1000) + + deviceCleanerLoop() } - catch (err: any) { - log.fatal('Unable to load initial state: %s', err?.message) - lifecycle.fatal() + + const init = async() => { + try { + log.info('Reaping devices with no heartbeat') + + // Listen to changes + sub.on('message', router.handler()) + + // Load initial state + const {devices} = await runTransactionDev(wireutil.global, GetPresentDevices, {}, {sub, push, router}) + + const now = Date.now() + devices?.forEach((serial: string) => { + ttlset.bump(serial, now, TTLSet.SILENT) + }) + } + catch (err: any) { + if (err?.message === 'Timeout when running transaction') { + log.error('Load initial state error: Timeout when running transaction, retry') + setTimeout(init, 2000) + return + } + log.fatal('Unable to load initial state: %s', err?.message) + lifecycle.fatal() + } } + + init() }) diff --git a/lib/wire/wire.proto b/lib/wire/wire.proto index 53be0505e9..655b7138a8 100644 --- a/lib/wire/wire.proto +++ b/lib/wire/wire.proto @@ -909,3 +909,7 @@ message DeviceGetIsInOrigin { message GetPresentDevices { } + +message GetDeadDevices { + required uint32 time = 1; +} diff --git a/lib/wire/wire.ts b/lib/wire/wire.ts index 85edad04eb..438ab51313 100644 --- a/lib/wire/wire.ts +++ b/lib/wire/wire.ts @@ -2397,6 +2397,15 @@ export interface DeviceGetIsInOrigin { */ export interface GetPresentDevices { } +/** + * @generated from protobuf message GetDeadDevices + */ +export interface GetDeadDevices { + /** + * @generated from protobuf field: required uint32 time = 1 + */ + time: number; +} /** * @generated from protobuf enum DeviceStatus */ @@ -11744,3 +11753,50 @@ class GetPresentDevices$Type extends MessageType { * @generated MessageType for protobuf message GetPresentDevices */ export const GetPresentDevices = new GetPresentDevices$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GetDeadDevices$Type extends MessageType { + constructor() { + super("GetDeadDevices", [ + { no: 1, name: "time", kind: "scalar", T: 13 /*ScalarType.UINT32*/ } + ]); + } + create(value?: PartialMessage): GetDeadDevices { + const message = globalThis.Object.create((this.messagePrototype!)); + message.time = 0; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GetDeadDevices): GetDeadDevices { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* required uint32 time */ 1: + message.time = reader.uint32(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GetDeadDevices, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* required uint32 time = 1; */ + if (message.time !== 0) + writer.tag(1, WireType.Varint).uint32(message.time); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message GetDeadDevices + */ +export const GetDeadDevices = new GetDeadDevices$Type(); From 91c8a0b1a2a97133619155f30dc80323d18e678b Mon Sep 17 00:00:00 2001 From: Elmir Khalilov <52529096+e-khalilov@users.noreply.github.com> Date: Mon, 13 Oct 2025 15:53:50 +0300 Subject: [PATCH 10/13] fix linkifyjs issue (#380) Co-authored-by: e.khalilov --- ui/package-lock.json | 21 +++++++++++++++++++++ ui/package.json | 2 ++ ui/vite.config.ts | 8 +++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/ui/package-lock.json b/ui/package-lock.json index 162c7aefc3..05631b6170 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -25,6 +25,8 @@ "i18next-http-backend": "^2.6.2", "inversify": "^6.2.1", "inversify-react": "^1.2.0", + "linkify-html": "^4.3.2", + "linkify-react": "^4.3.2", "lodash": "^4.17.21", "mobx": "^6.13.5", "mobx-persist-store": "^1.1.5", @@ -11622,6 +11624,25 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "license": "MIT" }, + "node_modules/linkify-html": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/linkify-html/-/linkify-html-4.3.2.tgz", + "integrity": "sha512-RozNgrfSFrNQlprJSZIN7lF+ZVPj5Pz8POQcu1PYGAUhL9tKtvtWcOXOmlXjuGGEWHtC6gt6Q2U4+VUq9ELmng==", + "license": "MIT", + "peerDependencies": { + "linkifyjs": "^4.0.0" + } + }, + "node_modules/linkify-react": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/linkify-react/-/linkify-react-4.3.2.tgz", + "integrity": "sha512-mi744h1hf+WDsr+paJgSBBgYNLMWNSHyM9V9LVUo03RidNGdw1VpI7Twnt+K3pEh3nIzB4xiiAgZxpd61ItKpQ==", + "license": "MIT", + "peerDependencies": { + "linkifyjs": "^4.0.0", + "react": ">= 15.0.0" + } + }, "node_modules/linkifyjs": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.3.2.tgz", diff --git a/ui/package.json b/ui/package.json index fa9dabfd55..de59eb82dc 100644 --- a/ui/package.json +++ b/ui/package.json @@ -45,6 +45,8 @@ "i18next-http-backend": "^2.6.2", "inversify": "^6.2.1", "inversify-react": "^1.2.0", + "linkify-html": "^4.3.2", + "linkify-react": "^4.3.2", "lodash": "^4.17.21", "mobx": "^6.13.5", "mobx-persist-store": "^1.1.5", diff --git a/ui/vite.config.ts b/ui/vite.config.ts index f0da2be776..91d36f544f 100644 --- a/ui/vite.config.ts +++ b/ui/vite.config.ts @@ -9,7 +9,13 @@ import tsconfigPaths from 'vite-tsconfig-paths' export default defineConfig({ plugins: [react({ tsDecorators: true }), tsconfigPaths(), svgr()], resolve: { - alias: [{ find: /^@vkontakte\/vkui$/, replacement: '@vkontakte/vkui/dist/cssm' }], + alias: [ + { find: /^@vkontakte\/vkui$/, replacement: '@vkontakte/vkui/dist/cssm' }, + + // TODO: REMOVE AFTER REPLACING `console-feed` WITH `chii` + { find: /^linkifyjs\/html$/, replacement: 'linkify-html' }, + { find: /^linkifyjs\/react$/, replacement: 'linkify-react' } + ], }, preview: { port: 5173, From fea328e743444a30caf4d3916ea8fc46fa1a73d8 Mon Sep 17 00:00:00 2001 From: Elmir Khalilov <52529096+e-khalilov@users.noreply.github.com> Date: Mon, 13 Oct 2025 20:58:47 +0300 Subject: [PATCH 11/13] Resolve conflicts (#381) * Hotfix: device imei issue (#371) * hotfix * minor fix * fix types * minor fix --------- Co-authored-by: e.khalilov * increase ram for v8 (#372) * hotfix (#373) Co-authored-by: e.khalilov * hotfix ADBObserver (#375) Co-authored-by: e.khalilov --------- Co-authored-by: e.khalilov Co-authored-by: Daniil <8039921+DaniilSmirnov@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index eac6f90dca..f345e49bad 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,7 +32,7 @@ LABEL org.opencontainers.image.description="Control and manage Android and iOS d LABEL org.opencontainers.image.licenses=Apache-2.0 ENV PATH=/app/bin:$PATH -ENV NODE_OPTIONS="--max-old-space-size=8192" +ENV NODE_OPTIONS="--max-old-space-size=32768" EXPOSE 3000 WORKDIR /app From 2f10409f8c47c346fd28b6600d044a852c4f9621 Mon Sep 17 00:00:00 2001 From: Elmir Khalilov <52529096+e-khalilov@users.noreply.github.com> Date: Tue, 14 Oct 2025 18:53:41 +0300 Subject: [PATCH 12/13] Fixed transactions & minor optimizations (#382) * minor edits * fix transactions * minor fix * fix ts types --------- Co-authored-by: e.khalilov --- lib/db/models/all/model.js | 2 +- lib/db/proxiedModel.js | 56 ------------------------- lib/db/proxiedModel.ts | 38 +++++++++++++++++ lib/units/api/controllers/devices.js | 22 +++++----- lib/units/api/controllers/user.js | 33 ++++++++------- lib/units/api/helpers/useDevice.js | 35 +++++++++++----- lib/units/poorxy/index.js | 2 +- lib/util/zmqutil.js | 62 ++++++++++++++++++++++++---- 8 files changed, 147 insertions(+), 103 deletions(-) delete mode 100644 lib/db/proxiedModel.js create mode 100644 lib/db/proxiedModel.ts diff --git a/lib/db/models/all/model.js b/lib/db/models/all/model.js index 0dd60610b3..327a2427a9 100644 --- a/lib/db/models/all/model.js +++ b/lib/db/models/all/model.js @@ -1374,7 +1374,7 @@ export const updateDevicesOriginGroup = async(serial, group) => { db.devices.updateOne({serial}, update) ) - if (stats.modifiedCount) { + if (stats.modifiedCount || stats.matchedCount) { log.info( '[updateDevicesOriginGroup] Successfully updated origin group in device [serial: "%s", group: "%s", name: "%s"]', serial, diff --git a/lib/db/proxiedModel.js b/lib/db/proxiedModel.js deleted file mode 100644 index c78417cea6..0000000000 --- a/lib/db/proxiedModel.js +++ /dev/null @@ -1,56 +0,0 @@ -import * as Sentry from '@sentry/node' - -// ----------------------------------Proxy all methods for Sentry error tracing---------------------------------------// - -const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg -const ARGUMENT_NAMES = /([^\s,]+)/g - -// TODO: argument names can be simplified after build -function getArgumentsNames(fn) { - const fnStr = fn.toString().replace(STRIP_COMMENTS, '') - let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES) - return result || [] -} - -const getAddedAttributes = (fn, args) => Object.fromEntries( - getArgumentsNames(fn).map((argument, i) => [ - `dbapi.${argument}`, - args[i] - ]) -) - -/** - * @template ModelType - * @param {ModelType} model - * @return {ModelType} - */ -// @ts-ignore -export default (model) => new Proxy(model, { - - /** @param {string} prop */ - get(target, prop) { - return (...args) => Sentry.startSpan( - { - op: 'dbapi', - name: prop, - attributes: args?.length ? getAddedAttributes(target[prop], args) : {} - } - , () => target[prop](...args) - ) - } -}) - -// export default (model) => model ? Object.keys(model).reduce((proxiedModel, method) => { -// db.connect() -// // console.log('\n\n', method, '\n\n') -// proxiedModel[method] = (...args) => Sentry.startSpan( -// { -// op: 'dbapi' -// , name: method -// , attributes: getAddedAttributes(model[method], args) -// } -// , () => model[method](...args) -// ) -// return proxiedModel -// }, Object.create({})) : model - diff --git a/lib/db/proxiedModel.ts b/lib/db/proxiedModel.ts new file mode 100644 index 0000000000..a1c80dd255 --- /dev/null +++ b/lib/db/proxiedModel.ts @@ -0,0 +1,38 @@ +import * as Sentry from '@sentry/node' + +// ----------------------------------Proxy all methods for Sentry error tracing---------------------------------------// + +const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg +const ARGUMENT_NAMES = /([^\s,]+)/g + +// TODO: argument names can be simplified after build +function getArgumentsNames(fn: Function) { + const fnStr = fn.toString().replace(STRIP_COMMENTS, '') + let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES) + return result || [] +} + +const getAddedAttributes = (fn: Function, args: any[]) => Object.fromEntries( + getArgumentsNames(fn).map((argument, i) => [ + `dbapi.${argument}`, + args[i] + ]) +) + +export default >(model: T) => Object.keys(model).reduce((proxiedModel, method) => { + if (typeof model[method] !== 'function') { + proxiedModel[method] = model[method] + return proxiedModel + } + + proxiedModel[method] = (...args: any[]) => Sentry.startSpan( + { + op: 'dbapi', + name: method, + attributes: getAddedAttributes(model[method], args) + } + , () => model[method](...args) + ) + return proxiedModel +}, {} as any) as T + diff --git a/lib/units/api/controllers/devices.js b/lib/units/api/controllers/devices.js index 7d9f916420..58a037c5b0 100644 --- a/lib/units/api/controllers/devices.js +++ b/lib/units/api/controllers/devices.js @@ -16,7 +16,7 @@ import useDevice, {UseDeviceError} from '../helpers/useDevice.js' import * as Sentry from '@sentry/node' import {accessTokenAuth} from '../helpers/securityHandlers.js' import {DeviceOriginGroupMessage} from '../../../wire/wire.js' -var log = logger.createLogger('api:controllers:devices') +const log = logger.createLogger('api:controllers:devices') /* ------------------------------------ PRIVATE FUNCTIONS ------------------------------- */ function filterGenericDevices(req, res, devices) { @@ -237,8 +237,8 @@ function getDevices(req, res) { } } function getDeviceBySerial(req, res) { - var serial = req.params.serial - var fields = req.query.fields + const serial = req.params.serial + const fields = req.query.fields dbapi.loadDevice(req.user.groups.subscribed, serial) .then(device => { if (!device) { @@ -263,8 +263,8 @@ function getDeviceBySerial(req, res) { }) } function getDeviceSize(req, res) { - var serial = req.params.serial - dbapi.getDeviceDisplaySize(serial) + const serial = req.params.serial + return dbapi.getDeviceDisplaySize(serial) .then(response => { return res.status(200).json(response.display) }) @@ -295,8 +295,8 @@ function getDeviceGroups(req, res) { }) } function getDeviceOwner(req, res) { - var serial = req.params.serial - dbapi.getDeviceGroupOwner(serial) + const serial = req.params.serial + return dbapi.getDeviceGroupOwner(serial) .then(response => { if (!response) { return res.status(404).json({ @@ -312,8 +312,8 @@ function getDeviceOwner(req, res) { }) } function getDeviceType(req, res) { - var serial = req.params.serial - dbapi.getDeviceType(serial) + const serial = req.params.serial + return dbapi.getDeviceType(serial) .then(response => { return res.status(200).json(response) }) @@ -481,12 +481,12 @@ function removeOriginGroupDevice(req, res) { function putDeviceInfoBySerial(req, res) { const serial = req.params.serial const body = req.body - dbapi.loadDeviceBySerial(serial) + return dbapi.loadDeviceBySerial(serial) .then((data) => { if (!data) { return apiutil.respond(res, 404, `Not Found (${serial})`) } - var updates = [] + const updates = [] // Update fields based on given body if (_.has(body, 'note')) { updates.push(dbapi.setDeviceNote(serial, body.note)) diff --git a/lib/units/api/controllers/user.js b/lib/units/api/controllers/user.js index 8aef72fb95..390d7c7c5d 100644 --- a/lib/units/api/controllers/user.js +++ b/lib/units/api/controllers/user.js @@ -48,7 +48,7 @@ function getUser(req, res) { } function getUserDevices(req, res) { - var fields = req.query.fields + const fields = req.query.fields log.info('Loading user devices') dbapi.loadUserDevices(req.user.email) .then(list => { @@ -78,9 +78,9 @@ function getUserDevices(req, res) { } function getUserDeviceBySerial(req, res) { - var serial = req.params.serial - var fields = req.query.fields - dbapi.loadDevice(req.user.groups.subscribed, serial) + const serial = req.params.serial + const fields = req.query.fields + return dbapi.loadDevice(req.user.groups.subscribed, serial) .then(function(device) { if (!device) { return res.status(404).json({ @@ -95,7 +95,7 @@ function getUserDeviceBySerial(req, res) { description: 'Device is not owned by you' }) } - var responseDevice = device + let responseDevice = device if (fields) { responseDevice = _.pick(device, fields.split(',')) } @@ -116,7 +116,7 @@ function addUserDevice(req, res) { let timeout = Object.prototype.hasOwnProperty.call(req, 'body') ? req.body.timeout || null : req.query.timeout || null const lock = {} - lockutil.lockGenericDevice(req, res, lock, dbapi.lockDeviceByCurrent) + return lockutil.lockGenericDevice(req, res, lock, dbapi.lockDeviceByCurrent) .then(function(lockingSuccessed) { if (lockingSuccessed) { const device = lock.device @@ -183,7 +183,7 @@ function deleteUserDeviceBySerial(req, res) { else { serial = req.params.serial } - dbapi.loadDevice(req.user.groups.subscribed, serial) + return dbapi.loadDevice(req.user.groups.subscribed, serial) .then(async function(device) { if (!device) { if (isInternal) { @@ -216,13 +216,18 @@ function deleteUserDeviceBySerial(req, res) { } } - await runTransaction(device.channel, UngroupMessage.create({ + await runTransaction(device.channel, UngroupMessage, { requirements: wireutil.toDeviceRequirements({ serial: { value: serial, match: 'exact' } - })})) + }) + }, { + sub: req.options.sub, + push: req.options.push, + channelRouter: req.options.channelRouter + }) }) .catch(function(err) { let errSerial @@ -244,7 +249,7 @@ function deleteUserDeviceBySerial(req, res) { function remoteConnectUserDeviceBySerial(req, res) { let serial = req.params.serial - dbapi.loadDevice(req.user.groups.subscribed, serial) + return dbapi.loadDevice(req.user.groups.subscribed, serial) .then(function(device) { if (!device) { return res.status(404).json({ @@ -302,7 +307,7 @@ function remoteDisconnectUserDeviceBySerial(req, res) { else { serial = req.params.serial } - dbapi.loadDevice(req.user.groups.subscribed, serial) + return dbapi.loadDevice(req.user.groups.subscribed, serial) .then(function(device) { if (!device) { if (isInternal) { @@ -327,10 +332,10 @@ function remoteDisconnectUserDeviceBySerial(req, res) { }) } } - var responseChannel = 'txn_' + uuidv4() + const responseChannel = 'txn_' + uuidv4() req.options.sub.subscribe(responseChannel) // Timer will be called if no JoinGroupMessage is received till 5 seconds - var timer = setTimeoutS(function() { + const timer = setTimeoutS(function() { req.options.channelRouter.removeListener(responseChannel, messageListener) req.options.sub.unsubscribe(responseChannel) if (isInternal) { @@ -340,7 +345,7 @@ function remoteDisconnectUserDeviceBySerial(req, res) { return apiutil.respond(res, 504, 'Device is not responding') } }, apiutil.GRPC_WAIT_TIMEOUT) - var messageListener = new WireRouter() + const messageListener = new WireRouter() .on(ConnectStoppedMessage, function(channel, message) { if (message.serial === serial) { clearTimeout(timer) diff --git a/lib/units/api/helpers/useDevice.js b/lib/units/api/helpers/useDevice.js index 93c3a267a7..01b3ffba78 100644 --- a/lib/units/api/helpers/useDevice.js +++ b/lib/units/api/helpers/useDevice.js @@ -9,7 +9,7 @@ import wire from '../../../wire/index.js' import {v4 as uuidv4} from 'uuid' import {Log} from '../../../util/logger.js' import {runTransaction} from '../../../wire/transmanager.js' -import {ConnectStartedMessage, JoinGroupMessage} from '../../../wire/wire.js' +import {ConnectStartedMessage, GroupMessage, JoinGroupMessage, OwnerMessage, UngroupMessage} from '../../../wire/wire.js' export const UseDeviceError = Object.freeze({ NOT_FOUND: 0, @@ -50,10 +50,12 @@ const useDevice = ({user, device, channelRouter, push, sub, usage = null, log}) }) try { - await runTransaction(device.channel, new wire.UngroupMessage(deviceRequirements), {sub, push, channelRouter}) + await runTransaction(device.channel, UngroupMessage, { + requirements: deviceRequirements + }, {sub, push, channelRouter}) } catch (/** @type {any} */e) { - log?.info('Transaction failed: $s', e?.message) + log?.info('Transaction failed: %s', e?.message) } const responseTimeout = setTimeout(function() { @@ -73,7 +75,7 @@ const useDevice = ({user, device, channelRouter, push, sub, usage = null, log}) sub.subscribe(responseChannel) const connectTimeout = setTimeout(function() { - channelRouter.removeListener(responseChannel, useDeviceMessageListener) + channelRouter.removeListener(responseChannel, messageListener) sub.unsubscribe(responseChannel) reject(UseDeviceError.FAILED_CONNECT) @@ -102,13 +104,24 @@ const useDevice = ({user, device, channelRouter, push, sub, usage = null, log}) channelRouter.on(wireutil.global, useDeviceMessageListener) - await runTransaction(device.channel, new wire.GroupMessage( - new wire.OwnerMessage(user.email, user.name, user.group) - , timeout - , deviceRequirements - , usage - , user.adbKeys.map((/** @type {{ fingerprint: string }} */ k) => k.fingerprint) - ), {sub, push, channelRouter}) + try { + await runTransaction(device.channel, GroupMessage, { + owner: OwnerMessage.create({ + email: user.email, + name: user.name, + group: user.group + }), + requirements: deviceRequirements, + usage: usage || undefined, + keys: user.adbKeys?.map((/** @type {{ fingerprint: string }} */ k) => k.fingerprint) || [] + }, {sub, push, channelRouter}) + } + catch (/** @type {any} */e) { + log?.info('Transaction failed: %s', e?.message) + clearTimeout(responseTimeout) + channelRouter.removeListener(wireutil.global, useDeviceMessageListener) + return reject(UseDeviceError.FAILED_JOIN) + } }) export default useDevice diff --git a/lib/units/poorxy/index.js b/lib/units/poorxy/index.js index 6a6efc00d9..3b8320dd83 100644 --- a/lib/units/poorxy/index.js +++ b/lib/units/poorxy/index.js @@ -8,7 +8,7 @@ export default (function(options) { let server = http.createServer(app) let proxy = httpProxy.createProxyServer() proxy.on('error', function(err) { - log.error('Proxy had an error', err.stack) + log.error('Proxy had an error %s', err?.message) }) app.use(function(req, res, next) { res.setHeader('X-devicehub-unit', 'poorxy') diff --git a/lib/util/zmqutil.js b/lib/util/zmqutil.js index 6098ff06d7..3a4d67b438 100644 --- a/lib/util/zmqutil.js +++ b/lib/util/zmqutil.js @@ -20,9 +20,32 @@ const socketTypeMap = { reply: zmq.Reply } +// Shared ZMQ context to avoid creating multiple contexts with thread pools +// Each context creates ioThreads (4 by default), so sharing saves resources +/** @type {zmq.Context | null} */ +let sharedContext = null +const getSharedContext = () => { + if (!sharedContext) { + sharedContext = new zmq.Context({ + blocky: true, + ioThreads: 4, + ipv6: true, + maxSockets: 8192, + }) + } + return sharedContext +} + export class SocketWrapper extends EventEmitter { #sendQueue = Promise.resolve() + /** @type {AsyncIterator | null} */ + #iterator = null + + /** + * @param {string} type + * @param {number} keepAliveInterval + */ constructor(type, keepAliveInterval = 30) { super() @@ -34,18 +57,14 @@ export class SocketWrapper extends EventEmitter { this.isActive = true this.endpoints = new Set() + // @ts-ignore const SocketClass = socketTypeMap[type] this.socket = new SocketClass({ tcpKeepalive: 1, tcpKeepaliveIdle: keepAliveInterval, tcpKeepaliveInterval: keepAliveInterval, tcpKeepaliveCount: 100 - }, new zmq.Context({ - blocky: true, - ioThreads: 4, - ipv6: true, - maxSockets: 8192, - })) + }, getSharedContext()) } bindSync = (address) => this.socket.bindSync(address) @@ -86,17 +105,42 @@ export class SocketWrapper extends EventEmitter { } catch (/** @type {any} */ err) { log.error('Error on send: %s', err?.message || err?.toString() || JSON.stringify(err)) + throw err // Re-throw to properly handle in the promise chain } } + /** + * @param {any} args + */ send(args) { this.#sendQueue = this.#sendQueue.then(() => this.sendAsync(args)) return this } - close() { + async close() { this.isActive = false + + // Close async iterator if it exists + if (this.#iterator && typeof this.#iterator.return === 'function') { + try { + await this.#iterator.return() + } + catch { + // Ignore errors during cleanup + } + this.#iterator = null + } + + // Wait for send queue to drain before closing socket + try { + await this.#sendQueue.catch(() => {}) + } + catch { + // Ignore errors during cleanup + } + this.socket.close() + this.removeAllListeners() return this } @@ -118,10 +162,10 @@ export class SocketWrapper extends EventEmitter { } try { - const iterator = this.socket[Symbol.asyncIterator]() + this.#iterator = this.socket[Symbol.asyncIterator]() let result - while (this.isActive && !(result = await iterator.next()).done) { + while (this.isActive && this.#iterator && !(result = await this.#iterator.next()).done) { const message = result.value if (Array.isArray(message) && !!message[0]?.toString) { From 34ccd1ddff85af967a47ca3770d28415a3b94055 Mon Sep 17 00:00:00 2001 From: Maksim Alzhanov Date: Tue, 14 Oct 2025 21:25:45 +0300 Subject: [PATCH 13/13] Fix lint issues --- lib/units/base-device/plugins/group.js | 0 lib/units/device/plugins/group.js | 0 lib/units/tizen-device/plugins/webinspector/Replicator.ts | 2 -- lib/util/lifecycle.js | 0 4 files changed, 2 deletions(-) delete mode 100755 lib/units/base-device/plugins/group.js delete mode 100644 lib/units/device/plugins/group.js delete mode 100644 lib/util/lifecycle.js diff --git a/lib/units/base-device/plugins/group.js b/lib/units/base-device/plugins/group.js deleted file mode 100755 index e69de29bb2..0000000000 diff --git a/lib/units/device/plugins/group.js b/lib/units/device/plugins/group.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/lib/units/tizen-device/plugins/webinspector/Replicator.ts b/lib/units/tizen-device/plugins/webinspector/Replicator.ts index 4cb8800f01..4bd30fabd8 100644 --- a/lib/units/tizen-device/plugins/webinspector/Replicator.ts +++ b/lib/units/tizen-device/plugins/webinspector/Replicator.ts @@ -7,7 +7,6 @@ const KEY_REQUIRE_ESCAPING_RE = /^#*@(t|r)$/ const REMAINING_KEY = '__console_feed_remaining__' const GLOBAL = (function getGlobal() { // NOTE: see http://www.ecma-international.org/ecma-262/6.0/index.html#sec-performeval step 10 - // eslint-disable-next-line no-eval const savedEval = eval return savedEval('this') })() @@ -128,7 +127,6 @@ class EncodingTransformer { } const remaining = total - counter - // eslint-disable-next-line no-proto const name = obj?.__proto__?.constructor?.name if (name && name !== 'Object') { diff --git a/lib/util/lifecycle.js b/lib/util/lifecycle.js deleted file mode 100644 index e69de29bb2..0000000000