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,140 +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 { EmulatorControllerClient } from "../proto/emulator_controller_grpc_web_pb";
17
- import { RtcClient } from "../proto/rtc_service_grpc_web_pb";
18
- import { GrpcWebClientBase } from "grpc-web";
19
- import { EventEmitter } from "events";
20
-
21
- export class NopAuthenticator {
22
- authHeader = () => {
23
- return {};
24
- };
25
-
26
- unauthorized = () => { };
27
- }
28
-
29
- /**
30
- * A GrcpWebClientBase that inject authentication headers and intercepts
31
- * errors. If the errors are 401, the unauthorized method of the authenticator will be invoked.
32
- *
33
- * @export
34
- * @class EmulatorWebClient
35
- * @extends {GrpcWebClientBase}
36
- */
37
- class EmulatorWebClient extends GrpcWebClientBase {
38
- constructor(options, auth) {
39
- super(options);
40
- this.auth = auth;
41
- this.events = new EventEmitter();
42
- this.events.on("error", e => {console.log("low level gRPC error: " + JSON.stringify(e));})
43
- }
44
-
45
- on = (name, fn) => {
46
- this.events.on(name, fn);
47
- };
48
-
49
- rpcCall = (method, request, metadata, methodinfo, callback) => {
50
- const authHeader = this.auth.authHeader();
51
- const meta = { ...metadata, ...authHeader };
52
- const self = this;
53
- return super.rpcCall(method, request, meta, methodinfo, (err, res) => {
54
- if (err) {
55
- if (err.code === 401) self.auth.unauthorized();
56
- if (self.events)
57
- self.events.emit("error", err);
58
- }
59
- if (callback) callback(err, res);
60
- });
61
- };
62
-
63
- serverStreaming = (method, request, metadata, methodInfo) => {
64
- const authHeader = this.auth.authHeader();
65
- const meta = { ...metadata, ...authHeader };
66
- const stream = super.serverStreaming(method, request, meta, methodInfo);
67
- const self = this;
68
-
69
- // Intercept errors.
70
- stream.on("error", e => {
71
- if (e.code === 401) {
72
- self.auth.unauthorized();
73
- }
74
- self.events.emit("error", e);
75
- });
76
- return stream;
77
- };
78
- }
79
-
80
- /**
81
- * An EmulatorControllerService is an EmulatorControllerClient that inject authentication headers.
82
- * You can provide your own authenticator service that must implement the following mehtods:
83
- *
84
- * - `authHeader()` which must return a set of headers that should be send along with a request.
85
- * - `unauthorized()` a function that gets called when a 401 was received.
86
- *
87
- * You can use this to simplify handling authentication failures.
88
- *
89
- * TODO(jansene): Maybe expose error handling? That way it does
90
- * not have to be repeated at every function call.
91
- *
92
- * @export
93
- * @class EmulatorControllerService
94
- * @extends {EmulatorControllerClient}
95
- */
96
- export class EmulatorControllerService extends EmulatorControllerClient {
97
- /**
98
- *Creates an instance of EmulatorControllerService.
99
- * @param {string} uri of the emulator controller endpoint.
100
- * @param {Authenticator} authenticator used to authenticate with the emulator endpoint.
101
- * @param onError callback that will be invoked when a low level gRPC error arises.
102
- * @memberof EmulatorControllerService
103
- */
104
- constructor(uri, authenticator, onError) {
105
- super(uri);
106
- if (!authenticator) authenticator = new NopAuthenticator();
107
- this.client_ = new EmulatorWebClient({}, authenticator);
108
- if (onError) this.client_.on('error', e => { onError(e); });
109
- }
110
- }
111
-
112
-
113
- /**
114
- * An RtcService is an RtcClient that inject authentication headers.
115
- * You can provide your own authenticator service that must implement the following mehtods:
116
- *
117
- * - `authHeader()` which must return a set of headers that should be send along with a request.
118
- * - `unauthorized()` a function that gets called when a 401 was received.
119
- *
120
- * You can use this to simplify handling authentication failures.
121
- *
122
- * @export
123
- * @class EmulatorControllerService
124
- * @extends {RtcClient}
125
- */
126
- export class RtcService extends RtcClient {
127
- /**
128
- *Creates an instance of RtcService.
129
- * @param {string} uri of the emulator controller endpoint.
130
- * @param {Authenticator} authenticator used to authenticate with the emulator endpoint.
131
- * @param onError callback that will be invoked when a low level gRPC error arises.
132
- * @memberof RtcService
133
- */
134
- constructor(uri, authenticator, onError) {
135
- super(uri);
136
- if (!authenticator) authenticator = new NopAuthenticator();
137
- this.client_ = new EmulatorWebClient({}, authenticator);
138
- if (onError) this.client_.on('error', e => { onError(e); });
139
- }
140
- }
@@ -1,41 +0,0 @@
1
- steps:
2
- - name: "gcr.io/cloud-builders/gcloud"
3
- args:
4
- - kms
5
- - decrypt
6
- - --ciphertext-file=npmrc.enc
7
- - --plaintext-file=/root/.npmrc
8
- - --location=global
9
- - --keyring=my-keyring
10
- - --key=npm-key
11
- volumes:
12
- - name: "home"
13
- path: /root/
14
- - name: gcr.io/emu-dev-cts/protoc
15
- args:
16
- [
17
- "--include_imports",
18
- "--include_source_info",
19
- "--proto_path",
20
- "./proto",
21
- "--descriptor_set_out",
22
- "api_descriptor.pb",
23
- "--plugin=protoc-gen-grpc-web=/protoc/bin/protoc-gen-grpc-web",
24
- "--js_out=import_style=commonjs:src/proto",
25
- "--grpc-web_out=import_style=commonjs,mode=grpcwebtext:src/proto",
26
- "./proto/emulator_controller.proto",
27
- "./proto/rtc_service.proto",
28
- ]
29
- - name: "gcr.io/cloud-builders/npm"
30
- args: ["install"]
31
- - name: "gcr.io/cloud-builders/npm"
32
- args: ["run", "build"]
33
- - name: "gcr.io/cloud-builders/npm"
34
- args: ["test"]
35
- - name: "gcr.io/cloud-builders/npm"
36
- args: ["publish", "/workspace", "--dry-run"]
37
- env:
38
- - HOME=/root/
39
- volumes:
40
- - name: "home"
41
- path: /root/
@@ -1,125 +0,0 @@
1
-
2
- /**
3
- * @jest-environment jsdom
4
- */
5
- /*
6
- * Copyright 2020 The Android Open Source Project
7
- *
8
- * Licensed under the Apache License, Version 2.0 (the "License")
9
- * you may not use this file except in compliance with the License.
10
- * You may obtain a copy of the License at
11
- *
12
- * http://www.apache.org/licenses/LICENSE-2.0
13
- *
14
- * Unless required by applicable law or agreed to in writing, software
15
- * distributed under the License is distributed on an "AS IS" BASIS,
16
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
- * See the License for the specific language governing permissions and
18
- * limitations under the License.
19
- */
20
- import "@testing-library/jest-dom";
21
- import "babel-polyfill";
22
- import { EventEmitter } from "events";
23
- import React from "react";
24
- import { render, fireEvent, screen, waitFor } from "@testing-library/react";
25
- import Emulator from "../src/components/emulator/emulator";
26
- import * as Proto from "../src/proto/emulator_controller_pb";
27
- import * as Rtc from "../src/proto/rtc_service_pb";
28
- import {
29
- RtcService,
30
- EmulatorControllerService,
31
- } from "../src/proto/emulator_web_client";
32
-
33
- jest.mock("../src/proto/emulator_web_client");
34
-
35
- // See https://github.com/testing-library/react-testing-library/issues/470
36
- // As well as https://github.com/facebook/react/issues/10389
37
- // All because of the "muted" tag on our video element inside webrtc_view
38
- const renderIgnoringUnstableFlushDiscreteUpdates = (component) => {
39
- // tslint:disable: no-console
40
- const originalError = console.error;
41
- const error = jest.fn();
42
- console.error = error;
43
- const result = render(component);
44
- expect(error).toHaveBeenCalledTimes(1);
45
- expect(error).toHaveBeenCalledWith(
46
- "Warning: unstable_flushDiscreteUpdates: Cannot flush updates when React is already rendering.%s",
47
- expect.any(String)
48
- );
49
- console.error = originalError;
50
- // tslint:enable: no-console
51
- return result;
52
- };
53
-
54
- describe("The emulator", () => {
55
- beforeEach(() => {
56
- // Clear all instances and calls to constructor and all methods:
57
- RtcService.mockClear();
58
- EmulatorControllerService.mockClear();
59
- });
60
-
61
- test("Creates gRPC services", async () => {
62
- render(
63
- <Emulator uri="/test" width={300} height={300} />
64
- );
65
-
66
- expect(EmulatorControllerService).toHaveBeenCalled();
67
- expect(RtcService).toHaveBeenCalled();
68
- // Shipped out a gps call
69
- });
70
- test("Tries to establish a webrtc connection", async () => {
71
- let state;
72
- render(
73
- <Emulator
74
- uri="/test"
75
- width={300}
76
- height={300}
77
- onStateChange={(e) => {
78
- state = e;
79
- }}
80
- />
81
- );
82
-
83
- await waitFor(() => state === "connecting");
84
- expect(RtcService).toHaveBeenCalled();
85
- });
86
-
87
- test("Sends a gps location to the emulator", async () => {
88
- // Let's go to Seattle!
89
- render(
90
- <Emulator
91
- uri="/test"
92
- width={300}
93
- height={300}
94
- gps={{ latitude: 47.6062, longitude: 122.3321 }}
95
- />
96
- );
97
-
98
- const setGps = EmulatorControllerService.mock.instances[0].setGps;
99
- expect(setGps).toHaveBeenCalled();
100
-
101
- const location = new Proto.GpsState();
102
- location.setLatitude(47.6062);
103
- location.setLongitude(122.3321);
104
- location.setAltitude(undefined);
105
- location.setBearing(undefined);
106
- location.setSpeed(undefined);
107
- expect(setGps).toHaveBeenCalledWith(location);
108
- });
109
-
110
- test("The png view requests images", async () => {
111
- let pngCall = false
112
- EmulatorControllerService.mockImplementation(() => {
113
- return {
114
- streamScreenshot: jest.fn((request) => {
115
- pngCall = true
116
- return { on: jest.fn(), cancel: jest.fn() };
117
- }),
118
- getStatus: jest.fn(() => {}),
119
- };
120
- });
121
-
122
- render(<Emulator uri="/test" width={300} height={300} view="png" />);
123
- expect(pngCall).toBeTruthy()
124
- });
125
- });
@@ -1,91 +0,0 @@
1
- /**
2
- * @jest-environment jsdom
3
- */
4
- /*
5
- * Copyright 2020 The Android Open Source Project
6
- *
7
- * Licensed under the Apache License, Version 2.0 (the "License")
8
- * you may not use this file except in compliance with the License.
9
- * You may obtain a copy of the License at
10
- *
11
- * http://www.apache.org/licenses/LICENSE-2.0
12
- *
13
- * Unless required by applicable law or agreed to in writing, software
14
- * distributed under the License is distributed on an "AS IS" BASIS,
15
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- * See the License for the specific language governing permissions and
17
- * limitations under the License.
18
- */
19
- import "@testing-library/jest-dom";
20
-
21
- import React from "react";
22
- import { render, fireEvent, screen } from "@testing-library/react";
23
- import { fakeMouseEvent, fakeTouchEvent} from "./fake_events";
24
- import withMouseKeyHandler from "../src/components/emulator/views/event_handler";
25
-
26
- import JsepProtocol from "../src/components/emulator/net/jsep_protocol_driver";
27
- import {
28
- RtcService,
29
- EmulatorControllerService,
30
- } from "../src/proto/emulator_web_client";
31
-
32
- jest.mock("../src/proto/emulator_web_client");
33
- jest.mock("../src/proto/rtc_service_pb");
34
- jest.mock("../src/proto/emulator_controller_pb");
35
-
36
-
37
- class FakeEmulator extends React.Component {
38
- render() {
39
- return (
40
- <div
41
- data-testid="fake"
42
- style={{ height: "200px", width: "200px", backgroundColor: "#555" }}
43
- ></div>
44
- );
45
- }
46
- }
47
-
48
- const TestView = withMouseKeyHandler(FakeEmulator);
49
- describe("The event handler using a real jsep serializer", () => {
50
-
51
- const rtcServiceInstance = new RtcService("http://foo");
52
- const emulatorServiceInstance = new EmulatorControllerService("http://foo");
53
- let jsep, fakeScreen;
54
-
55
- beforeEach(() => {
56
- jest.clearAllMocks();
57
- jsep = new JsepProtocol(emulatorServiceInstance, rtcServiceInstance, true);
58
-
59
- render(<TestView emulator={emulatorServiceInstance} jsep={jsep} />);
60
- fakeScreen = screen.getByTestId("fake").parentElement;
61
- Object.defineProperty(fakeScreen, "clientWidth", { get: () => 200 });
62
- Object.defineProperty(fakeScreen, "clientHeight", { get: () => 200 });
63
-
64
- expect(fakeScreen).toBeInTheDocument();
65
- });
66
-
67
- test("Forwards mouse events", () => {
68
- fireEvent(fakeScreen, fakeMouseEvent("mousedown", 10, 10));
69
- fireEvent(fakeScreen, fakeMouseEvent("mouseup", 20, 20));
70
-
71
- // Shipped out a mouse event
72
- expect(emulatorServiceInstance.sendMouse).toHaveBeenCalledTimes(2);
73
- });
74
-
75
- test("Forwards keyboard events", () => {
76
- fireEvent.keyDown(fakeScreen, { key: "Enter", code: "Enter" });
77
- fireEvent.keyUp(fakeScreen, { key: "Enter", code: "Enter" });
78
-
79
- // Shipped out a keyboard event
80
- expect(emulatorServiceInstance.sendKey).toHaveBeenCalledTimes(2);
81
- });
82
-
83
- test("Forwards touch events", () => {
84
- fireEvent(fakeScreen, fakeTouchEvent("touchstart", 10, 10, 1));
85
- fireEvent(fakeScreen, fakeTouchEvent("touchmove", 20, 20, 2));
86
- fireEvent(fakeScreen, fakeTouchEvent("touchend", 30, 30, 0));
87
-
88
- // Shipped out a touch event
89
- expect(emulatorServiceInstance.sendTouch).toHaveBeenCalledTimes(3);
90
- });
91
- });
@@ -1,50 +0,0 @@
1
- /*
2
- * Copyright 2021 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
- export function fakeMouseEvent(tp, x, y, props = {}) {
17
- const event = new MouseEvent(tp, {
18
- bubbles: true,
19
- cancelable: true,
20
- ...props,
21
- });
22
-
23
- Object.defineProperty(event, "offsetX", { get: () => x });
24
- Object.defineProperty(event, "offsetY", { get: () => y });
25
- return event;
26
- }
27
-
28
- export function fakeTouchEvent(tp, x, y, force, props = {}) {
29
- const event = new TouchEvent(tp, {
30
- bubbles: true,
31
- cancelable: true,
32
- ...props,
33
- });
34
-
35
- Object.defineProperty(event, "changedTouches", {
36
- get: () => [
37
- { clientX: x, clientY: y, radiusX: 4, radiusY: 4, force: force },
38
- ],
39
- });
40
- return event;
41
- }
42
-
43
- export function resize(width, height) {
44
- const resizeEvent = document.createEvent("Event");
45
- resizeEvent.initEvent("resize", true, true);
46
-
47
- global.window.innerWidth = width || global.window.innerWidth;
48
- global.window.innerHeight = height || global.window.innerHeight;
49
- global.window.dispatchEvent(resizeEvent);
50
- }
@@ -1,228 +0,0 @@
1
- /**
2
- * @jest-environment jsdom
3
- */
4
- /*
5
- * Copyright 2020 The Android Open Source Project
6
- *
7
- * Licensed under the Apache License, Version 2.0 (the "License")
8
- * you may not use this file except in compliance with the License.
9
- * You may obtain a copy of the License at
10
- *
11
- * http://www.apache.org/licenses/LICENSE-2.0
12
- *
13
- * Unless required by applicable law or agreed to in writing, software
14
- * distributed under the License is distributed on an "AS IS" BASIS,
15
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- * See the License for the specific language governing permissions and
17
- * limitations under the License.
18
- */
19
- import { jest } from "@jest/globals";
20
- import "regenerator-runtime/runtime"; // Somehow needed for jest to be happy with ES6
21
-
22
- import * as Proto from "../src/proto/emulator_controller_pb";
23
- import * as Rtc from "../src/proto/rtc_service_pb";
24
- import JsepProtocol from "../src/components/emulator/net/jsep_protocol_driver.js";
25
- import {
26
- RtcService,
27
- EmulatorControllerService,
28
- } from "../src/proto/emulator_web_client";
29
-
30
- jest.mock("../src/proto/emulator_web_client");
31
-
32
- const jsepMessage = (object, uid) => {
33
- const guid = new Rtc.RtcId();
34
- guid.setGuid(uid);
35
-
36
- const jsepMsg = new Rtc.JsepMsg();
37
- jsepMsg.setId(guid);
38
- jsepMsg.setMessage(JSON.stringify(object));
39
- return jsepMsg;
40
- };
41
-
42
- const requestRtcStream = jest.fn((request, metadata, callback) => {
43
- const guid = new Rtc.RtcId();
44
- guid.setGuid("abcde");
45
-
46
- callback(null, guid);
47
- });
48
-
49
- const receiveJsepMessage = (message) => {
50
- const jsepMsg = jsepMessage(message);
51
- return jest.fn((request, metadata, callback) => {
52
- callback(null, jsepMsg);
53
- });
54
- };
55
-
56
- const RTCPeerConnectionMock = jest.fn().mockImplementation((cfg) => ({
57
- ondatachannel: jest.fn(),
58
- createAnswer: jest.fn(),
59
- addEventListener: jest.fn(),
60
- addIceCandidate: jest.fn(),
61
- dispatchEvent: jest.fn(),
62
- setRemoteDescription: jest.fn(),
63
- setLocalDescription: jest.fn(),
64
- close: jest.fn(),
65
- }));
66
-
67
- Object.defineProperty(window, "RTCPeerConnection", {
68
- writable: true,
69
- value: jest.fn().mockImplementation((cfg) => {
70
- let sdp = null;
71
- let signal = null;
72
- let state = null;
73
- return {
74
- ondatachannel: jest.fn(),
75
- createAnswer: jest.fn(() => {
76
- return new Promise((resolve) => {
77
- return { answer: "fake-answer" };
78
- });
79
- }),
80
- addEventListener: jest.fn(),
81
- addIceCandidate: jest.fn(),
82
- dispatchEvent: jest.fn(),
83
- setRemoteDescription: (desc) => {
84
- sdp = desc;
85
- state = "have-remote-offer";
86
- if (signal) signal();
87
- },
88
- setLocalDescription: jest.fn(),
89
- get currentRemoteDescription() {
90
- return sdp;
91
- },
92
- set onsignalingstatechange(fn) {
93
- signal = fn;
94
- },
95
- get signalingState() {
96
- return state;
97
- },
98
- close: jest.fn(),
99
- };
100
- }),
101
- });
102
-
103
- Object.defineProperty(window, "RTCIceCandidate", {
104
- writable: true,
105
- value: jest.fn().mockImplementation((cfg) => ({})),
106
- });
107
-
108
- Object.defineProperty(window, "RTCSessionDescription", {
109
- writable: true,
110
- value: jest.fn().mockImplementation((desc) => {
111
- return { sdp: desc };
112
- }),
113
- });
114
-
115
- const sdp = {
116
- sdp: "fakesdp1",
117
- type: "offer",
118
- };
119
-
120
- const sdp2 = {
121
- sdp: "fakesdp2",
122
- type: "offer",
123
- };
124
- const candidates_and_sdp = [
125
- {
126
- candidate:
127
- "candidate:4205781435 1 udp 2122260223 10.146.0.6 37608 typ host generation 0 ufrag Er9W network-id 1 network-cost 50",
128
- sdpMLineIndex: 1,
129
- sdpMid: "1",
130
- },
131
- {
132
- candidate:
133
- "candidate:3022839115 1 tcp 1518280447 10.146.0.6 36959 typ host tcptype passive generation 0 ufrag Er9W network-id 1 network-cost 50",
134
- sdpMLineIndex: 0,
135
- sdpMid: "0",
136
- },
137
- sdp,
138
- ];
139
-
140
- const jsepProtocol = (messages) => {
141
- RtcService.mockClear();
142
- EmulatorControllerService.mockClear();
143
-
144
- let receive = jest.fn();
145
- for (var i = 0; i < messages.length; i++) {
146
- receive.mockImplementationOnce(receiveJsepMessage(messages[i]));
147
- }
148
- RtcService.mockImplementation(() => {
149
- return {
150
- requestRtcStream: requestRtcStream,
151
- receiveJsepMessage: receive,
152
- sendJsepMessage: jest.fn((msg) => {
153
- console.log("Sending " + msg);
154
- }),
155
- };
156
- });
157
- const rtcServiceInstance = new RtcService("http://foo");
158
- const emulatorServiceInstance = new EmulatorControllerService("http://foo");
159
- return {
160
- rtc: rtcServiceInstance,
161
- jsep: new JsepProtocol(emulatorServiceInstance, rtcServiceInstance, true),
162
- };
163
- };
164
-
165
- describe("Basic jsep protocol with polling.", () => {
166
- it("calls request rtc stream", () => {
167
- const { rtc, jsep } = jsepProtocol([{ bye: "we're done" }]);
168
- jsep.startStream();
169
- expect(rtc.requestRtcStream.mock.calls.length).toBe(1);
170
- expect(rtc.receiveJsepMessage.mock.calls.length).toBe(1);
171
- });
172
-
173
- it("Notifies listeners of a disconnect", () => {
174
- const { jsep } = jsepProtocol([{ bye: "we're done" }]);
175
-
176
- const disconnect = jest.fn();
177
- jsep.on("disconnected", disconnect);
178
- jsep.startStream();
179
- expect(disconnect).toHaveBeenCalledTimes(1);
180
- });
181
-
182
- it("Does not process messages before start", () => {
183
- const { jsep } = jsepProtocol(candidates_and_sdp);
184
-
185
- jsep.startStream();
186
- // All candidates are queued.
187
- expect(jsep.old_emu_patch.candidates.length).toBe(2);
188
- expect(jsep.old_emu_patch.sdp).not.toBeNull();
189
- });
190
-
191
- it("Flush message queue after bye", () => {
192
- let msg = Array.from(candidates_and_sdp);
193
- msg.push({ bye: "we're done" });
194
- const { jsep } = jsepProtocol(msg);
195
-
196
- jsep.startStream();
197
- expect(jsep.old_emu_patch.candidates.length).toBe(0);
198
- expect(jsep.old_emu_patch.sdp).toBe(null);
199
- expect(jsep.peerConnection).toBe(null);
200
- });
201
-
202
- it("Out of order messages handled after start", () => {
203
- let msg = Array.from(candidates_and_sdp);
204
- msg.push({ start: { foo: "bar" } });
205
- const { jsep } = jsepProtocol(msg);
206
-
207
- jsep.startStream();
208
- expect(jsep.old_emu_patch.candidates.length).toBe(0);
209
- expect(jsep.peerConnection).not.toBeNull();
210
- expect(jsep.peerConnection.currentRemoteDescription).not.toBeNull();
211
- // Peer connection was initialized with rtc config
212
- expect(RTCPeerConnection.mock.calls[0][0]).toStrictEqual({ foo: "bar" });
213
- });
214
-
215
- it.skip("Never handles sdp twice / (async problem)", async () => {
216
- // 2nd jsep gets dropped.
217
- let { rtc, jsep } = jsepProtocol([sdp, sdp2, { start: { foo: "bar" } }]);
218
- jsep.startStream();
219
- expect(jsep.old_emu_patch.candidates.length).toBe(0);
220
- expect(jsep.old_emu_patch.sdp).toBeNull();
221
- expect(jsep.old_emu_patch.answer).toBe(true);
222
- expect(jsep.peerConnection).not.toBeNull();
223
- expect(jsep.peerConnection.currentRemoteDescription.sdp.sdp).toBe(sdp.sdp);
224
- // Peer connection was initialized with rtc config
225
- expect(RTCPeerConnection.mock.calls[0][0]).toStrictEqual({ foo: "bar" });
226
- expect(rtc.sendJsepMessage.mock.calls[0]).toBe(1);
227
- });
228
- });