android-emulator-webrtc 1.0.18 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +93 -204
  2. package/dist/components/emulator/emulator.d.ts +64 -0
  3. package/dist/components/emulator/emulator.js +161 -173
  4. package/dist/components/emulator/net/emulator_status.d.ts +45 -0
  5. package/dist/components/emulator/net/emulator_status.js +35 -42
  6. package/dist/components/emulator/net/logcat.js +37 -54
  7. package/dist/components/emulator/net/logger.d.ts +7 -0
  8. package/dist/components/emulator/net/logger.js +20 -0
  9. package/dist/components/emulator/net/ws_jsep_protocol_driver.d.ts +213 -0
  10. package/dist/components/emulator/net/ws_jsep_protocol_driver.js +640 -0
  11. package/dist/components/emulator/views/event_handler.d.ts +37 -0
  12. package/dist/components/emulator/views/event_handler.js +274 -260
  13. package/dist/components/emulator/views/webrtc_view.d.ts +27 -0
  14. package/dist/components/emulator/views/webrtc_view.js +42 -20
  15. package/dist/index.d.ts +8 -0
  16. package/dist/index.js +0 -7
  17. package/dist/proto/emulator_controller_pb.d.ts +1 -0
  18. package/dist/proto/emulator_controller_pb.js +146 -287
  19. package/dist/src/components/emulator/emulator.d.ts +64 -0
  20. package/dist/src/components/emulator/net/emulator_status.d.ts +45 -0
  21. package/dist/src/components/emulator/net/logger.d.ts +7 -0
  22. package/dist/src/components/emulator/net/ws_jsep_protocol_driver.d.ts +213 -0
  23. package/dist/src/components/emulator/views/event_handler.d.ts +37 -0
  24. package/dist/src/components/emulator/views/webrtc_view.d.ts +27 -0
  25. package/dist/src/index.d.ts +8 -0
  26. package/dist/src/proto/emulator_controller_pb.d.ts +1 -0
  27. package/package.json +17 -17
  28. package/proto/emulator_controller.proto +746 -181
  29. package/.vscode/launch.json +0 -21
  30. package/.vscode/settings.json +0 -3
  31. package/CONTRIBUTING.md +0 -28
  32. package/Makefile +0 -123
  33. package/android-emulator-webrtc.code-workspace +0 -7
  34. package/api_descriptor.pb +0 -0
  35. package/babel.config.js +0 -16
  36. package/cloudbuild.yaml +0 -41
  37. package/cloudbuilders/.gcloudignore +0 -1
  38. package/cloudbuilders/Dockerfile +0 -20
  39. package/cloudbuilders/README.md +0 -29
  40. package/cloudbuilders/cloudbuild.yaml +0 -19
  41. package/dist/components/emulator/net/jsep_protocol_driver.js +0 -365
  42. package/dist/components/emulator/views/simple_png_view.js +0 -110
  43. package/dist/proto/emulator_controller_grpc_web_pb.js +0 -1601
  44. package/dist/proto/emulator_web_client.js +0 -176
  45. package/dist/proto/rtc_service_grpc_web_pb.js +0 -231
  46. package/dist/proto/rtc_service_pb.js +0 -338
  47. package/emulator/index.js +0 -1
  48. package/eslint_prefix.py +0 -37
  49. package/gen_md_doc.js +0 -40
  50. package/npmrc.enc +0 -0
  51. package/proto/rtc_service.proto +0 -117
  52. package/protoc-plugin/Makefile +0 -31
  53. package/protoc-plugin/grpc_generator.cc +0 -1755
  54. package/src/components/emulator/emulator.js +0 -217
  55. package/src/components/emulator/net/emulator_status.js +0 -94
  56. package/src/components/emulator/net/jsep_protocol_driver.js +0 -364
  57. package/src/components/emulator/net/logcat.js +0 -155
  58. package/src/components/emulator/views/event_handler.js +0 -268
  59. package/src/components/emulator/views/simple_png_view.js +0 -105
  60. package/src/components/emulator/views/webrtc_view.js +0 -142
  61. package/src/index.js +0 -20
  62. package/src/proto/emulator_web_client.js +0 -140
  63. package/test/cloudbuild.yaml +0 -41
  64. package/test/emulator.test.js +0 -125
  65. package/test/event_handler.test.js +0 -91
  66. package/test/fake_events.js +0 -50
  67. package/test/jsep_protocol_driver.test.js +0 -228
  68. package/test/simple_png_view.test.js +0 -145
  69. package/test/touch_event_handler.test.js +0 -118
@@ -1,217 +0,0 @@
1
- /*
2
- * Copyright 2019 The Android Open Source Project
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License")
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- import PropTypes from "prop-types";
17
- import React, { Component } from "react";
18
- import EmulatorPngView from "./views/simple_png_view.js";
19
- import EmulatorWebrtcView from "./views/webrtc_view.js";
20
- import withMouseKeyHandler from "./views/event_handler";
21
- import JsepProtocol from "./net/jsep_protocol_driver.js";
22
- import * as Proto from "../../proto/emulator_controller_pb";
23
- import {
24
- RtcService,
25
- EmulatorControllerService,
26
- } from "../../proto/emulator_web_client";
27
-
28
- const PngView = withMouseKeyHandler(EmulatorPngView);
29
- const RtcView = withMouseKeyHandler(EmulatorWebrtcView);
30
-
31
- /**
32
- * A React component that displays a remote android emulator.
33
- *
34
- * The emulator will mount a png or webrtc view component to display the current state
35
- * of the emulator. It will translate mouse events on this component and send them
36
- * to the actual emulator.
37
- *
38
- * #### Authentication Service
39
- *
40
- * The authentication service should implement the following methods:
41
- *
42
- * - `authHeader()` which must return a set of headers that should be send along with a request.
43
- * - `unauthorized()` a function that gets called when a 401 was received.
44
- *
45
- * #### Type of view
46
- *
47
- * You usually want this to be webrtc as this will make use of the efficient
48
- * webrtc implementation. The png view will request screenshots, which are
49
- * very slow, and require the envoy proxy. You should not use this for remote emulators.
50
- *
51
- * Note that chrome will not autoplay the video if it is not muted and no interaction
52
- * with the page has taken place. See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes.
53
- *
54
- * #### Pressing hardware buttons
55
- *
56
- * This component has a method `sendKey` that sends a key to the emulator.
57
- * You can use this to send physical button events to the emulator for example:
58
- *
59
- * "AudioVolumeDown" - Decreases the audio volume.
60
- * "AudioVolumeUp" - Increases the audio volume.
61
- * "Power" - The Power button or key, turn off the device.
62
- * "AppSwitch" - Should bring up the application switcher dialog.
63
- * "GoHome" - Go to the home screen.
64
- * "GoBack" - Open the previous screen you were looking at.
65
- *
66
- */
67
- class Emulator extends Component {
68
- static propTypes = {
69
- /** gRPC Endpoint where we can reach the emulator. */
70
- uri: PropTypes.string.isRequired,
71
- /** The authentication service to use, or null for no authentication. */
72
- auth: PropTypes.object,
73
- /** True if the audio should be disabled. This is only relevant when using the webrtc engine. */
74
- muted: PropTypes.bool,
75
- /** Volume between [0, 1] when audio is enabled. 0 is muted, 1.0 is 100% */
76
- volume: PropTypes.number,
77
- /** Called upon state change, one of ["connecting", "connected", "disconnected"] */
78
- onStateChange: PropTypes.func,
79
- /** Called when the audio becomes (un)available. True if audio is available, false otherwise. */
80
- onAudioStateChange: PropTypes.func,
81
- /** The width of the component */
82
- width: PropTypes.number,
83
- /** The height of the component */
84
- height: PropTypes.number,
85
- /** The underlying view used to display the emulator, one of ["webrtc", "png"] */
86
- view: PropTypes.oneOf(["webrtc", "png"]).isRequired,
87
- /** A [GeolocationCoordinates](https://developer.mozilla.org/en-US/docs/Web/API/GeolocationCoordinates) like object indicating where the device is. */
88
- gps: PropTypes.object,
89
- /** True if polling should be used, only set this to true if you are using the go webgrpc proxy. */
90
- poll: PropTypes.bool,
91
- /** Callback that will be invoked in case of gRPC errors. */
92
- onError: PropTypes.func,
93
- };
94
-
95
- static defaultProps = {
96
- view: "webrtc",
97
- auth: null,
98
- poll: false,
99
- muted: true,
100
- volume: 1.0,
101
- onError: (e) => {
102
- console.error(e);
103
- },
104
- onAudioStateChange: (s) => {
105
- console.debug("emulator audio: " + s);
106
- },
107
- onStateChange: (s) => {
108
- console.debug("emulator state: " + s);
109
- },
110
- };
111
-
112
- components = {
113
- webrtc: RtcView,
114
- png: PngView,
115
- };
116
-
117
- state = {
118
- audio: false,
119
- };
120
-
121
- constructor(props) {
122
- super(props);
123
- const { uri, auth, poll, onError } = props;
124
- this.emulator = new EmulatorControllerService(uri, auth, onError);
125
- this.rtc = new RtcService(uri, auth, onError);
126
- this.jsep = new JsepProtocol(this.emulator, this.rtc, poll);
127
- this.view = React.createRef();
128
- }
129
-
130
- static getDerivedStateFromProps(nextProps, prevState) {
131
- if (nextProps.view === "png")
132
- return {
133
- audio: false,
134
- };
135
-
136
- return prevState;
137
- }
138
-
139
- componentDidMount = () => {
140
- this.updateLocation();
141
- };
142
-
143
- componentDidUpdate = (prevProps) => {
144
- if (prevProps.gps !== this.props.gps) {
145
- this.updateLocation();
146
- }
147
- };
148
-
149
- updateLocation = () => {
150
- const { gps } = this.props;
151
- if (typeof gps === "undefined") {
152
- return;
153
- }
154
-
155
- const state = new Proto.GpsState();
156
- state.setLatitude(gps.latitude);
157
- state.setLongitude(gps.longitude);
158
- state.setAltitude(gps.altitude);
159
- state.setBearing(gps.heading);
160
- state.setSpeed(gps.speed);
161
- this.emulator.setGps(state);
162
- };
163
-
164
- /**
165
- * Sends the given key to the emulator.
166
- *
167
- * You can use this to send physical hardware events to the emulator for example:
168
- *
169
- * "AudioVolumeDown" - Decreases the audio volume.
170
- * "AudioVolumeUp" - Increases the audio volume.
171
- * "Power" - The Power button or key, turn off the device.
172
- * "AppSwitch" - Should bring up the application switcher dialog.
173
- * "GoHome" - Go to the home screen.
174
- * "GoBack" - Open the previous screen you were looking at.
175
- *
176
- * See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values for
177
- * a list of valid values you can send as well.
178
- */
179
- sendKey = (key) => {
180
- var request = new Proto.KeyboardEvent();
181
- request.setEventtype(Proto.KeyboardEvent.KeyEventType.KEYPRESS);
182
- request.setKey(key);
183
- this.jsep.send("keyboard", request);
184
- };
185
-
186
- _onAudioStateChange = (s) => {
187
- const { onAudioStateChange } = this.props;
188
- this.setState({ audio: s }, () => {
189
- onAudioStateChange(s);
190
- });
191
- };
192
-
193
- render() {
194
- const { width, height, view, poll, muted, onStateChange, onError, volume } =
195
- this.props;
196
- const SpecificView = this.components[view] || RtcView;
197
-
198
- console.log(`render ${width}x${height}`);
199
- return (
200
- <SpecificView
201
- ref={this.view}
202
- width={width}
203
- height={height}
204
- emulator={this.emulator}
205
- jsep={this.jsep}
206
- onStateChange={onStateChange}
207
- poll={poll}
208
- muted={muted}
209
- volume={volume}
210
- onError={onError}
211
- onAudioStateChange={this._onAudioStateChange}
212
- />
213
- );
214
- }
215
- }
216
-
217
- export default Emulator;
@@ -1,94 +0,0 @@
1
- /*
2
- * Copyright 2020 The Android Open Source Project
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License")
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- import { Empty } from "google-protobuf/google/protobuf/empty_pb";
17
- import { EmulatorControllerService } from "../../../proto/emulator_web_client";
18
-
19
- /**
20
- * Gets the status of the emulator, parsing the hardware config into something
21
- * easy to digest.
22
- *
23
- * @export
24
- * @class EmulatorStatus
25
- */
26
- class EmulatorStatus {
27
- /**
28
- * Creates an EmulatorStatus object that can retrieve the status of the running emulator.
29
- *
30
- * @param {object} uriOrEmulator An emulator controller service, or a URI to a gRPC endpoint.
31
- * @param {object} auth The authentication service to use, or null for no authentication.
32
- *
33
- * The authentication service should implement the following methods:
34
- * - `authHeader()` which must return a set of headers that should be send along with a request.
35
- * - `unauthorized()` a function that gets called when a 401 was received.
36
- */
37
- constructor(uriOrEmulator, auth) {
38
- if (uriOrEmulator instanceof EmulatorControllerService) {
39
- this.emulator = uriOrEmulator;
40
- } else {
41
- this.emulator = new EmulatorControllerService(uriOrEmulator, auth);
42
- }
43
- this.status = null;
44
- }
45
-
46
- /**
47
- * Gets the cached status.
48
- *
49
- * @memberof EmulatorStatus
50
- */
51
- getStatus = () => {
52
- return this.status;
53
- };
54
-
55
- /**
56
- * Retrieves the current status from the emulator.
57
- *
58
- * @param {Callback} fnNotify when the status is available, returns the retrieved status.
59
- * @param {boolean} cache True if the cache can be used.
60
- * @memberof EmulatorStatus
61
- */
62
- updateStatus = (fnNotify, cache) => {
63
- const request = new Empty();
64
- if (cache && this.status) {
65
- fnNotify(this.status);
66
- return this.status;
67
- }
68
- this.emulator.getStatus(request, {}, (err, response) => {
69
- var hwConfig = {};
70
- const entryList = response.getHardwareconfig().getEntryList();
71
- for (var i = 0; i < entryList.length; i++) {
72
- const key = entryList[i].getKey();
73
- const val = entryList[i].getValue();
74
- hwConfig[key] = val;
75
- }
76
-
77
- const vmConfig = response.getVmconfig();
78
- this.status = {
79
- version: response.getVersion(),
80
- uptime: response.getUptime(),
81
- booted: response.getBooted(),
82
- hardwareConfig: hwConfig,
83
- vmConfig: {
84
- hypervisorType: vmConfig.getHypervisortype(),
85
- numberOfCpuCores: vmConfig.getNumberofcpucores(),
86
- ramSizeBytes: vmConfig.getRamsizebytes()
87
- }
88
- };
89
- fnNotify(this.status);
90
- });
91
- };
92
- }
93
-
94
- export default EmulatorStatus;
@@ -1,364 +0,0 @@
1
- /*
2
- * Copyright 2019 The Android Open Source Project
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License")
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- import { EventEmitter } from "events";
17
- import { Empty } from "google-protobuf/google/protobuf/empty_pb";
18
- /**
19
- * This drives the jsep protocol with the emulator, and can be used to
20
- * send key/mouse/touch events to the emulator. Events will be send
21
- * over the data channel if open, otherwise they will be send via the
22
- * grpc endpoint.
23
- *
24
- * The jsep protocol is described here:
25
- * https://rtcweb-wg.github.io/jsep/.
26
- *
27
- * This class can fire two events:
28
- *
29
- * - `connected` when the stream has become available.
30
- * - `disconnected` when the stream broke down, or when we failed to establish a connection
31
- *
32
- * You usually want to start the stream after instantiating this object. Do not forget to
33
- * disconnect once you are finished to terminate the message pump.
34
- *
35
- *
36
- * @example
37
- * jsep = new JsepProtocolDriver(emulator, s => { video.srcObject = s; video.play() });
38
- * jsep.startStream();
39
- *
40
- * @export
41
- * @class JsepProtocol
42
- */
43
- export default class JsepProtocol {
44
- /**
45
- * Creates an instance of JsepProtocol.
46
- * @param {EmulatorService} emulator Service used to make the gRPC calls
47
- * @param {RtcService} rtc Service used to open up the rtc calls.
48
- * @param {boolean} poll True if we should use polling
49
- * @param {callback} onConnect optional callback that is invoked when a stream is available
50
- * @param {callback} onDisconnect optional callback that is invoked when the stream is closed.
51
- * @memberof JsepProtocol
52
- */
53
- constructor(emulator, rtc, poll, onConnect, onDisconnect) {
54
- this.emulator = emulator;
55
- this.rtc = rtc;
56
- this.events = new EventEmitter();
57
-
58
- // Workaround for older emulators that send messages out of order
59
- // and do not handle all answers properly.
60
- this.old_emu_patch = {
61
- candidates: [],
62
- sdp: null,
63
- haveOffer: false,
64
- answer: false,
65
- };
66
-
67
- this.poll = poll;
68
- this.guid = null;
69
- this.stream = null;
70
- this.event_forwarders = {};
71
- if (onConnect) this.events.on("connected", onConnect);
72
- if (onDisconnect) this.events.on("disconnected", onDisconnect);
73
- }
74
-
75
- on = (name, fn) => {
76
- this.events.on(name, fn);
77
- };
78
-
79
- /**
80
- * Disconnects the stream. This will stop the message pump as well.
81
- *
82
- * @memberof JsepProtocol
83
- */
84
- disconnect = () => {
85
- this.connected = false;
86
- if (this.peerConnection) this.peerConnection.close();
87
- if (this.stream) {
88
- this.stream.cancel();
89
- this.stream = null;
90
- }
91
- this.active = false;
92
- this.old_emu_patch = {
93
- candidates: [],
94
- sdp: null,
95
- haveOffer: false,
96
- answer: false,
97
- };
98
- this.events.emit("disconnected", this);
99
- };
100
-
101
- /**
102
- * Initiates the JSEP protocol.
103
- *
104
- * @memberof JsepProtocol
105
- */
106
- startStream = () => {
107
- const self = this;
108
- this.connected = false;
109
- this.peerConnection = null;
110
- this.active = true;
111
- this.old_emu_patch = {
112
- candidates: [],
113
- sdp: null,
114
- haveOffer: false,
115
- answer: false,
116
- };
117
- var request = new Empty();
118
- this.rtc.requestRtcStream(request, {}, (err, response) => {
119
- if (err) {
120
- console.error("Failed to configure rtc stream: " + JSON.stringify(err));
121
- this.disconnect();
122
- return;
123
- }
124
-
125
- // Configure
126
- self.guid = response;
127
- self.connected = true;
128
-
129
- if (!this.poll) {
130
- // Streaming envoy based.
131
- self._streamJsepMessage();
132
- } else {
133
- // Poll pump messages, go/envoy based proxy.
134
- console.debug("Polling jsep messages.");
135
- self._receiveJsepMessage();
136
- }
137
- });
138
- };
139
-
140
- cleanup = () => {
141
- this.disconnect();
142
- if (this.peerConnection) {
143
- this.peerConnection.removeEventListener(
144
- "track",
145
- this._handlePeerConnectionTrack
146
- );
147
- this.peerConnection.removeEventListener(
148
- "icecandidate",
149
- this._handlePeerIceCandidate
150
- );
151
- this.peerConnection = null;
152
- }
153
- this.event_forwarders = {};
154
- };
155
-
156
- _handlePeerConnectionTrack = (e) => {
157
- this.events.emit("connected", e.track);
158
- };
159
-
160
- _handlePeerConnectionStateChange = (e) => {
161
- switch (this.peerConnection.connectionState) {
162
- case "disconnected":
163
- // At least one of the ICE transports for the connection is in the "disconnected" state
164
- // and none of the other transports are in the state "failed", "connecting",
165
- // or "checking".
166
- case "failed":
167
- // One or more of the ICE transports on the connection is in the "failed" state.
168
- case "closed":
169
- //The RTCPeerConnection is closed.
170
- this.disconnect();
171
- }
172
- };
173
-
174
- send(label, msg) {
175
- let bytes = msg.serializeBinary();
176
- let forwarder = this.event_forwarders[label];
177
- console.log("Send " + label + " " + JSON.stringify(msg.toObject()));
178
- // Send via data channel/gRPC bridge.
179
- if (this.connected && forwarder && forwarder.readyState == "open") {
180
- this.event_forwarders[label].send(bytes);
181
- } else {
182
- // Fallback to using the gRPC protocol
183
- switch (label) {
184
- case "mouse":
185
- this.emulator.sendMouse(msg);
186
- break;
187
- case "keyboard":
188
- this.emulator.sendKey(msg);
189
- break;
190
- case "touch":
191
- this.emulator.sendTouch(msg);
192
- break;
193
- }
194
- }
195
- }
196
-
197
- _handlePeerIceCandidate = (e) => {
198
- if (e.candidate === null) return;
199
- this._sendJsep({ candidate: e.candidate });
200
- };
201
-
202
- _handleDataChannel = (e) => {
203
- let channel = e.channel;
204
- this.event_forwarders[channel.label] = channel;
205
- };
206
-
207
- _handleStart = (signal) => {
208
- this.peerConnection = new RTCPeerConnection(signal.start);
209
- this.peerConnection.ontrack = this._handlePeerConnectionTrack;
210
- this.peerConnection.onicecandidate = this._handlePeerIceCandidate;
211
- this.peerConnection.onconnectionstatechange = this._handlePeerConnectionStateChange;
212
- this.peerConnection.ondatachannel = this._handleDataChannel;
213
- this.peerConnection.onsignalingstatechange = this._handlePeerState;
214
- };
215
-
216
- _handlePeerState = (event) => {
217
- if (!this.peerConnection) {
218
- console.log("Peerconnection no longer available, ignoring signal state.");
219
- }
220
- switch (this.peerConnection.signalingState) {
221
- case "have-remote-offer":
222
- this.old_emu_patch.haveOffer = true;
223
- while (this.old_emu_patch.candidates.length > 0) {
224
- this._handleCandidate(this.old_emu_patch.candidates.shift());
225
- }
226
- break;
227
- }
228
- };
229
-
230
- _handleSDP = async (signal) => {
231
- // We should not call this more than once..
232
- this.old_emu_patch.sdp = null;
233
- this.peerConnection.setRemoteDescription(new RTCSessionDescription(signal));
234
- const answer = await this.peerConnection.createAnswer();
235
- if (answer) {
236
- // Older emulators cannot handle multiple answers, so make sure we do not send one
237
- // again.
238
- if (!this.old_emu_patch.answer) {
239
- this.old_emu_patch.answer = true;
240
- this.peerConnection.setLocalDescription(answer);
241
- this._sendJsep({ sdp: answer });
242
- }
243
- } else {
244
- this.disconnect();
245
- }
246
- };
247
-
248
- _handleCandidate = (signal) => {
249
- this.peerConnection.addIceCandidate(new RTCIceCandidate(signal));
250
- };
251
-
252
- _handleSignal = (signal) => {
253
- if (signal.start) {
254
- this._handleStart(signal);
255
- }
256
- if (signal.bye) {
257
- this._handleBye();
258
- }
259
- if (signal.sdp && !this.old_emu_patch.sdp) {
260
- this.old_emu_patch.sdp = signal;
261
- }
262
- if (signal.candidate) {
263
- this.old_emu_patch.candidates.push(signal);
264
- }
265
-
266
- if (!!this.peerConnection) {
267
- // We have created a peer connection..
268
- if (this.old_emu_patch.sdp) {
269
- this._handleSDP(this.old_emu_patch.sdp);
270
- }
271
-
272
- if (this.old_emu_patch.haveOffer) {
273
- // We have a remote peer, add the candidates in.
274
- while (this.old_emu_patch.candidates.length > 0) {
275
- this._handleCandidate(this.old_emu_patch.candidates.shift());
276
- }
277
- }
278
- }
279
- };
280
-
281
- _handleJsepMessage = (message) => {
282
- try {
283
- const signal = JSON.parse(message);
284
- this._handleSignal(signal);
285
- } catch (e) {
286
- console.error(
287
- "Failed to handle message: [" +
288
- message +
289
- "], due to: " +
290
- JSON.stringify(e)
291
- );
292
- }
293
- };
294
-
295
- _handleBye = () => {
296
- if (this.connected) {
297
- this.disconnect();
298
- }
299
- };
300
-
301
- _sendJsep = (jsonObject) => {
302
- /* eslint-disable */
303
- var request = new proto.android.emulation.control.JsepMsg();
304
- request.setId(this.guid);
305
- request.setMessage(JSON.stringify(jsonObject));
306
- this.rtc.sendJsepMessage(request);
307
- };
308
-
309
- _streamJsepMessage = () => {
310
- if (!this.connected) return;
311
- var self = this;
312
-
313
- this.stream = this.rtc.receiveJsepMessages(this.guid, {});
314
- this.stream.on("data", (response) => {
315
- const msg = response.getMessage();
316
- self._handleJsepMessage(msg);
317
- });
318
- this.stream.on("error", (e) => {
319
- console.log("Jsep message stream error:", e);
320
- if (self.connected) {
321
- console.log("Attempting to reconnect to jsep message stream.");
322
- self._streamJsepMessage();
323
- }
324
- });
325
- this.stream.on("end", (e) => {
326
- if (self.connected) {
327
- console.log("Stream end while still connected.. Reconnecting");
328
- self._streamJsepMessage();
329
- }
330
- });
331
- };
332
-
333
- // This function is a fallback for v1 (go based proxy), that does not support streaming.
334
- _receiveJsepMessage = () => {
335
- if (!this.connected) return;
336
-
337
- var self = this;
338
-
339
- // This is a blocking call, that will return as soon as a series
340
- // of messages have been made available, or if we reach a timeout
341
- this.rtc.receiveJsepMessage(this.guid, {}, (err, response) => {
342
- if (err) {
343
- console.error(
344
- "Failed to receive jsep message, disconnecting: " +
345
- JSON.stringify(err)
346
- );
347
- this.disconnect();
348
- }
349
- const msg = response.getMessage();
350
- // Handle only if we received a useful message.
351
- // it is possible to get nothing if the server decides
352
- // to kick us out.
353
- if (msg) {
354
- self._handleJsepMessage(response.getMessage());
355
- }
356
-
357
- // And pump messages. Note we must continue the message pump as we
358
- // can receive new ICE candidates at any point in time.
359
- if (self.active) {
360
- self._receiveJsepMessage();
361
- }
362
- });
363
- };
364
- }