aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/frontend/webrtc_operator/assets/js/cf_webrtc.js168
1 files changed, 95 insertions, 73 deletions
diff --git a/host/frontend/webrtc_operator/assets/js/cf_webrtc.js b/host/frontend/webrtc_operator/assets/js/cf_webrtc.js
index 8c831a750..358aa497f 100644
--- a/host/frontend/webrtc_operator/assets/js/cf_webrtc.js
+++ b/host/frontend/webrtc_operator/assets/js/cf_webrtc.js
@@ -93,105 +93,127 @@ async function ajaxPostJson(url, data) {
}
class DeviceConnection {
+ #pc;
+ #control;
+ #description;
+
+ #cameraDataChannel;
+ #cameraInputQueue;
+ #controlChannel;
+ #inputChannel;
+ #adbChannel;
+ #bluetoothChannel;
+
+ #streams;
+ #streamPromiseResolvers;
+ #micSenders;
+ #cameraSenders;
+ #camera_res_x;
+ #camera_res_y;
+
+ #onAdbMessage;
+ #onControlMessage;
+ #onBluetoothMessage;
+
constructor(pc, control) {
- this._pc = pc;
- this._control = control;
- this._cameraDataChannel = pc.createDataChannel('camera-data-channel');
- this._cameraDataChannel.binaryType = 'arraybuffer';
- this._cameraInputQueue = new Array();
+ this.#pc = pc;
+ this.#control = control;
+ this.#cameraDataChannel = pc.createDataChannel('camera-data-channel');
+ this.#cameraDataChannel.binaryType = 'arraybuffer';
+ this.#cameraInputQueue = new Array();
var self = this;
- this._cameraDataChannel.onbufferedamountlow = () => {
- if (self._cameraInputQueue.length > 0) {
- self.sendCameraData(self._cameraInputQueue.shift());
+ this.#cameraDataChannel.onbufferedamountlow = () => {
+ if (self.#cameraInputQueue.length > 0) {
+ self.sendCameraData(self.#cameraInputQueue.shift());
}
};
- this._inputChannel = createDataChannel(pc, 'input-channel');
- this._adbChannel = createDataChannel(pc, 'adb-channel', (msg) => {
- if (this._onAdbMessage) {
- this._onAdbMessage(msg.data);
+ this.#inputChannel = createDataChannel(pc, 'input-channel');
+ this.#adbChannel = createDataChannel(pc, 'adb-channel', (msg) => {
+ if (this.#onAdbMessage) {
+ this.#onAdbMessage(msg.data);
} else {
console.error('Received unexpected ADB message');
}
});
- this._controlChannel = awaitDataChannel(pc, 'device-control', (msg) => {
- if (this._onControlMessage) {
- this._onControlMessage(msg);
+ this.#controlChannel = awaitDataChannel(pc, 'device-control', (msg) => {
+ if (this.#onControlMessage) {
+ this.#onControlMessage(msg);
} else {
console.error('Received unexpected Control message');
}
});
- this._bluetoothChannel =
+ this.#bluetoothChannel =
createDataChannel(pc, 'bluetooth-channel', (msg) => {
- if (this._onBluetoothMessage) {
- this._onBluetoothMessage(msg.data);
+ if (this.#onBluetoothMessage) {
+ this.#onBluetoothMessage(msg.data);
} else {
console.error('Received unexpected Bluetooth message');
}
});
- this._streams = {};
- this._streamPromiseResolvers = {};
+ this.#streams = {};
+ this.#streamPromiseResolvers = {};
pc.addEventListener('track', e => {
console.debug('Got remote stream: ', e);
for (const stream of e.streams) {
- this._streams[stream.id] = stream;
- if (this._streamPromiseResolvers[stream.id]) {
- for (let resolver of this._streamPromiseResolvers[stream.id]) {
+ this.#streams[stream.id] = stream;
+ if (this.#streamPromiseResolvers[stream.id]) {
+ for (let resolver of this.#streamPromiseResolvers[stream.id]) {
resolver();
}
- delete this._streamPromiseResolvers[stream.id];
+ delete this.#streamPromiseResolvers[stream.id];
}
}
});
}
set description(desc) {
- this._description = desc;
+ this.#description = desc;
}
get description() {
- return this._description;
+ return this.#description;
}
get imageCapture() {
- if (this._cameraSenders && this._cameraSenders.length > 0) {
- let track = this._cameraSenders[0].track;
+ if (this.#cameraSenders && this.#cameraSenders.length > 0) {
+ let track = this.#cameraSenders[0].track;
return new ImageCapture(track);
}
return undefined;
}
get cameraWidth() {
- return this._x_res;
+ return this.#camera_res_x;
}
get cameraHeight() {
- return this._y_res;
+ return this.#camera_res_y;
}
get cameraEnabled() {
- return this._cameraSenders && this._cameraSenders.length > 0;
+ return this.#cameraSenders && this.#cameraSenders.length > 0;
}
getStream(stream_id) {
return new Promise((resolve, reject) => {
- if (this._streams[stream_id]) {
- resolve(this._streams[stream_id]);
+ if (this.#streams[stream_id]) {
+ resolve(this.#streams[stream_id]);
} else {
- if (!this._streamPromiseResolvers[stream_id]) {
- this._streamPromiseResolvers[stream_id] = [];
+ if (!this.#streamPromiseResolvers[stream_id]) {
+ this.#streamPromiseResolvers[stream_id] = [];
}
- this._streamPromiseResolvers[stream_id].push(resolve);
+ this.#streamPromiseResolvers[stream_id].push(resolve);
}
});
}
- _sendJsonInput(evt) {
- this._inputChannel.send(JSON.stringify(evt));
+ #sendJsonInput(evt) {
+ this.#inputChannel.send(JSON.stringify(evt));
}
sendMousePosition({x, y, down, display_label}) {
- this._sendJsonInput({
+ this.#sendJsonInput({
type: 'mouse',
down: down ? 1 : 0,
x,
@@ -203,7 +225,7 @@ class DeviceConnection {
// TODO (b/124121375): This should probably be an array of pointer events and
// have different properties.
sendMultiTouch({idArr, xArr, yArr, down, slotArr, display_label}) {
- this._sendJsonInput({
+ this.#sendJsonInput({
type: 'multi-touch',
id: idArr,
x: xArr,
@@ -215,101 +237,101 @@ class DeviceConnection {
}
sendKeyEvent(code, type) {
- this._sendJsonInput({type: 'keyboard', keycode: code, event_type: type});
+ this.#sendJsonInput({type: 'keyboard', keycode: code, event_type: type});
}
disconnect() {
- this._pc.close();
+ this.#pc.close();
}
// Sends binary data directly to the in-device adb daemon (skipping the host)
sendAdbMessage(msg) {
- this._adbChannel.send(msg);
+ this.#adbChannel.send(msg);
}
// Provide a callback to receive data from the in-device adb daemon
onAdbMessage(cb) {
- this._onAdbMessage = cb;
+ this.#onAdbMessage = cb;
}
// Send control commands to the device
sendControlMessage(msg) {
- this._controlChannel.send(msg);
+ this.#controlChannel.send(msg);
}
async useMic(in_use) {
if (in_use) {
- if (this._micSenders) {
+ if (this.#micSenders) {
console.warn('Microphone is already in use');
return;
}
- this._micSenders = [];
+ this.#micSenders = [];
try {
let audioStream = await navigator.mediaDevices.getUserMedia(
{video: false, audio: true});
audioStream.getTracks().forEach(track => {
console.info(`Using ${track.kind} device: ${track.label}`);
- this._micSenders.push(this._pc.addTrack(track));
+ this.#micSenders.push(this.#pc.addTrack(track));
});
} catch (e) {
console.error('Failed to add audio stream to peer connection: ', e);
}
} else {
- if (!this._micSenders) {
+ if (!this.#micSenders) {
return;
}
- for (const sender of this._micSenders) {
+ for (const sender of this.#micSenders) {
console.info(
`Removing ${sender.track.kind} device: ${sender.track.label}`);
let track = sender.track;
track.stop();
- this._pc.removeTrack(sender);
+ this.#pc.removeTrack(sender);
}
- delete this._micSenders;
+ this.#micSenders = undefined;
}
- this._control.renegotiateConnection();
+ this.#control.renegotiateConnection();
}
async useVideo(in_use) {
if (in_use) {
- if (this._cameraSenders) {
+ if (this.#cameraSenders) {
console.warn('Video is already in use');
return;
}
- this._cameraSenders = [];
+ this.#cameraSenders = [];
try {
let videoStream = await navigator.mediaDevices.getUserMedia(
{video: true, audio: false});
this.sendCameraResolution(videoStream);
videoStream.getTracks().forEach(track => {
console.info(`Using ${track.kind} device: ${track.label}`);
- this._cameraSenders.push(this._pc.addTrack(track));
+ this.#cameraSenders.push(this.#pc.addTrack(track));
});
} catch (e) {
console.error('Failed to add video stream to peer connection: ', e);
}
} else {
- if (!this._cameraSenders) {
+ if (!this.#cameraSenders) {
return;
}
- for (const sender of this._cameraSenders) {
+ for (const sender of this.#cameraSenders) {
console.info(
`Removing ${sender.track.kind} device: ${sender.track.label}`);
let track = sender.track;
track.stop();
- this._pc.removeTrack(sender);
+ this.#pc.removeTrack(sender);
}
- delete this._cameraSenders;
+ this.#cameraSenders = undefined;
}
- this._control.renegotiateConnection();
+ this.#control.renegotiateConnection();
}
sendCameraResolution(stream) {
const cameraTracks = stream.getVideoTracks();
if (cameraTracks.length > 0) {
const settings = cameraTracks[0].getSettings();
- this._x_res = settings.width;
- this._y_res = settings.height;
+ this.#camera_res_x = settings.width;
+ this.#camera_res_y = settings.height;
this.sendControlMessage(JSON.stringify({
command: 'camera_settings',
width: settings.width,
@@ -321,9 +343,9 @@ class DeviceConnection {
}
sendOrQueueCameraData(data) {
- if (this._cameraDataChannel.bufferedAmount > 0 ||
- this._cameraInputQueue.length > 0) {
- this._cameraInputQueue.push(data);
+ if (this.#cameraDataChannel.bufferedAmount > 0 ||
+ this.#cameraInputQueue.length > 0) {
+ this.#cameraInputQueue.push(data);
} else {
this.sendCameraData(data);
}
@@ -334,28 +356,28 @@ class DeviceConnection {
const END_MARKER = 'EOF';
for (let i = 0; i < data.byteLength; i += MAX_SIZE) {
// range is clamped to the valid index range
- this._cameraDataChannel.send(data.slice(i, i + MAX_SIZE));
+ this.#cameraDataChannel.send(data.slice(i, i + MAX_SIZE));
}
- this._cameraDataChannel.send(END_MARKER);
+ this.#cameraDataChannel.send(END_MARKER);
}
// Provide a callback to receive control-related comms from the device
onControlMessage(cb) {
- this._onControlMessage = cb;
+ this.#onControlMessage = cb;
}
sendBluetoothMessage(msg) {
- this._bluetoothChannel.send(msg);
+ this.#bluetoothChannel.send(msg);
}
onBluetoothMessage(cb) {
- this._onBluetoothMessage = cb;
+ this.#onBluetoothMessage = cb;
}
// Provide a callback to receive connectionstatechange states.
onConnectionStateChange(cb) {
- this._pc.addEventListener(
- 'connectionstatechange', evt => cb(this._pc.connectionState));
+ this.#pc.addEventListener(
+ 'connectionstatechange', evt => cb(this.#pc.connectionState));
}
}