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
@@ -6,48 +6,64 @@ Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
8
  exports["default"] = void 0;
9
- var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
10
- var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
11
- var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
12
- var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
13
- var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
14
- var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
15
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
16
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
17
11
  var _react = _interopRequireWildcard(require("react"));
18
- var _simple_png_view = _interopRequireDefault(require("./views/simple_png_view.js"));
19
- var _webrtc_view = _interopRequireDefault(require("./views/webrtc_view.js"));
12
+ var _webrtc_view = _interopRequireDefault(require("./views/webrtc_view"));
20
13
  var _event_handler = _interopRequireDefault(require("./views/event_handler"));
21
- var _jsep_protocol_driver = _interopRequireDefault(require("./net/jsep_protocol_driver.js"));
22
- var Proto = _interopRequireWildcard(require("../../proto/emulator_controller_pb"));
23
- var _emulator_web_client = require("../../proto/emulator_web_client");
14
+ var _ws_jsep_protocol_driver = _interopRequireDefault(require("./net/ws_jsep_protocol_driver"));
15
+ var _logger = _interopRequireDefault(require("./net/logger"));
16
+ var _emulator_controller_pb = _interopRequireDefault(require("../../proto/emulator_controller_pb"));
24
17
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
25
18
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
26
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
27
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } /*
28
- * Copyright 2019 The Android Open Source Project
29
- *
30
- * Licensed under the Apache License, Version 2.0 (the "License")
31
- * you may not use this file except in compliance with the License.
32
- * You may obtain a copy of the License at
33
- *
34
- * http://www.apache.org/licenses/LICENSE-2.0
35
- *
36
- * Unless required by applicable law or agreed to in writing, software
37
- * distributed under the License is distributed on an "AS IS" BASIS,
38
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39
- * See the License for the specific language governing permissions and
40
- * limitations under the License.
41
- */
42
- var PngView = (0, _event_handler["default"])(_simple_png_view["default"]);
19
+ /*
20
+ * Copyright 2019 The Android Open Source Project
21
+ *
22
+ * Licensed under the Apache License, Version 2.0 (the "License")
23
+ * you may not use this file except in compliance with the License.
24
+ * You may obtain a copy of the License at
25
+ *
26
+ * http://www.apache.org/licenses/LICENSE-2.0
27
+ *
28
+ * Unless required by applicable law or agreed to in writing, software
29
+ * distributed under the License is distributed on an "AS IS" BASIS,
30
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31
+ * See the License for the specific language governing permissions and
32
+ * limitations under the License.
33
+ */
34
+
43
35
  var RtcView = (0, _event_handler["default"])(_webrtc_view["default"]);
44
36
 
37
+ /**
38
+ * Resolves the given URI into the required REST and WebSocket endpoints for the emulator.
39
+ *
40
+ * @param {string} uri The base URI of the emulator gateway.
41
+ * @returns {Object} An object containing the resolved URLs:
42
+ * - status: The REST endpoint for retrieving emulator status.
43
+ * - gps: The REST endpoint for setting GPS coordinates.
44
+ * - jsep: The WebSocket endpoint for WebRTC JSEP signaling.
45
+ */
46
+ var getUrls = function getUrls(uri) {
47
+ var restBase = uri;
48
+ if (!/^https?:\/\//i.test(uri)) {
49
+ restBase = "http://" + uri;
50
+ }
51
+ var wsUrl = restBase.replace(/^http/i, "ws");
52
+ restBase = restBase.replace(/\/$/, "");
53
+ wsUrl = wsUrl.replace(/\/$/, "");
54
+ return {
55
+ status: "".concat(restBase, "/api/v1/emulator/status"),
56
+ gps: "".concat(restBase, "/api/v1/emulator/gps"),
57
+ jsep: "".concat(wsUrl, "/api/v1/emulator/ws-jsep")
58
+ };
59
+ };
60
+
45
61
  /**
46
62
  * A React component that displays a remote android emulator.
47
63
  *
48
- * The emulator will mount a png or webrtc view component to display the current state
49
- * of the emulator. It will translate mouse events on this component and send them
50
- * to the actual emulator.
64
+ * The emulator will mount a webrtc view component to display the current state
65
+ * of the emulator. It will translate mouse and touch events on this component and send them
66
+ * to the actual emulator over WebRTC Data Channels.
51
67
  *
52
68
  * #### Authentication Service
53
69
  *
@@ -56,12 +72,6 @@ var RtcView = (0, _event_handler["default"])(_webrtc_view["default"]);
56
72
  * - `authHeader()` which must return a set of headers that should be send along with a request.
57
73
  * - `unauthorized()` a function that gets called when a 401 was received.
58
74
  *
59
- * #### Type of view
60
- *
61
- * You usually want this to be webrtc as this will make use of the efficient
62
- * webrtc implementation. The png view will request screenshots, which are
63
- * very slow, and require the envoy proxy. You should not use this for remote emulators.
64
- *
65
75
  * Note that chrome will not autoplay the video if it is not muted and no interaction
66
76
  * with the page has taken place. See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes.
67
77
  *
@@ -77,126 +87,125 @@ var RtcView = (0, _event_handler["default"])(_webrtc_view["default"]);
77
87
  * "GoHome" - Go to the home screen.
78
88
  * "GoBack" - Open the previous screen you were looking at.
79
89
  *
90
+ * **Note**: The user must have interacted with the page before you can set the volume to "unmuted" (muted = false). Otherwise the video
91
+ * will not play and will throw an error, which is currently not handled.
92
+ *
93
+ * **Note**: The volume is the volume of the video element that is displayed, this is not the actual volume used inside the emulator. You can change the audio inside the emulator by sending the proper keys as documented
94
+ * above, or follow the steps in the [support](https://support.google.com/android/answer/9082609?hl=en) document
95
+ * on how to change the audio volume.
96
+ *
80
97
  */
81
- var Emulator = /*#__PURE__*/function (_Component) {
82
- (0, _inherits2["default"])(Emulator, _Component);
83
- var _super = _createSuper(Emulator);
84
- function Emulator(props) {
85
- var _this;
86
- (0, _classCallCheck2["default"])(this, Emulator);
87
- _this = _super.call(this, props);
88
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "components", {
89
- webrtc: RtcView,
90
- png: PngView
91
- });
92
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", {
93
- audio: false
94
- });
95
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "componentDidMount", function () {
96
- _this.updateLocation();
97
- });
98
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "componentDidUpdate", function (prevProps) {
99
- if (prevProps.gps !== _this.props.gps) {
100
- _this.updateLocation();
101
- }
102
- });
103
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "updateLocation", function () {
104
- var gps = _this.props.gps;
105
- if (typeof gps === "undefined") {
106
- return;
98
+ var Emulator = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) {
99
+ var uri = _ref.uri,
100
+ _ref$auth = _ref.auth,
101
+ auth = _ref$auth === void 0 ? null : _ref$auth,
102
+ _ref$muted = _ref.muted,
103
+ muted = _ref$muted === void 0 ? true : _ref$muted,
104
+ _ref$volume = _ref.volume,
105
+ volume = _ref$volume === void 0 ? 1.0 : _ref$volume,
106
+ _ref$onStateChange = _ref.onStateChange,
107
+ onStateChange = _ref$onStateChange === void 0 ? function (s) {
108
+ _logger["default"].debug("emulator state: " + s);
109
+ } : _ref$onStateChange,
110
+ _ref$onAudioStateChan = _ref.onAudioStateChange,
111
+ onAudioStateChange = _ref$onAudioStateChan === void 0 ? function (s) {
112
+ _logger["default"].debug("emulator audio: " + s);
113
+ } : _ref$onAudioStateChan,
114
+ width = _ref.width,
115
+ height = _ref.height,
116
+ gps = _ref.gps,
117
+ _ref$onError = _ref.onError,
118
+ onError = _ref$onError === void 0 ? function (e) {
119
+ _logger["default"].error(e);
120
+ } : _ref$onError;
121
+ var _useState = (0, _react.useState)(false),
122
+ _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
123
+ audio = _useState2[0],
124
+ setAudio = _useState2[1];
125
+ var jsep = (0, _react.useRef)(null);
126
+ var viewRef = (0, _react.useRef)(null);
127
+ var onErrorRef = (0, _react.useRef)(onError);
128
+ (0, _react.useEffect)(function () {
129
+ onErrorRef.current = onError;
130
+ }, [onError]);
131
+ var urls = getUrls(uri);
132
+ if (!jsep.current) {
133
+ jsep.current = new _ws_jsep_protocol_driver["default"](urls.jsep, null, {
134
+ onError: function onError(err) {
135
+ if (onErrorRef.current) {
136
+ onErrorRef.current(err);
137
+ }
107
138
  }
108
- var state = new Proto.GpsState();
109
- state.setLatitude(gps.latitude);
110
- state.setLongitude(gps.longitude);
111
- state.setAltitude(gps.altitude);
112
- state.setBearing(gps.heading);
113
- state.setSpeed(gps.speed);
114
- _this.emulator.setGps(state);
115
139
  });
116
- /**
117
- * Sends the given key to the emulator.
118
- *
119
- * You can use this to send physical hardware events to the emulator for example:
120
- *
121
- * "AudioVolumeDown" - Decreases the audio volume.
122
- * "AudioVolumeUp" - Increases the audio volume.
123
- * "Power" - The Power button or key, turn off the device.
124
- * "AppSwitch" - Should bring up the application switcher dialog.
125
- * "GoHome" - Go to the home screen.
126
- * "GoBack" - Open the previous screen you were looking at.
127
- *
128
- * See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values for
129
- * a list of valid values you can send as well.
130
- */
131
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "sendKey", function (key) {
132
- var request = new Proto.KeyboardEvent();
133
- request.setEventtype(Proto.KeyboardEvent.KeyEventType.KEYPRESS);
134
- request.setKey(key);
135
- _this.jsep.send("keyboard", request);
136
- });
137
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onAudioStateChange", function (s) {
138
- var onAudioStateChange = _this.props.onAudioStateChange;
139
- _this.setState({
140
- audio: s
141
- }, function () {
142
- onAudioStateChange(s);
143
- });
144
- });
145
- var uri = props.uri,
146
- auth = props.auth,
147
- poll = props.poll,
148
- onError = props.onError;
149
- _this.emulator = new _emulator_web_client.EmulatorControllerService(uri, auth, onError);
150
- _this.rtc = new _emulator_web_client.RtcService(uri, auth, onError);
151
- _this.jsep = new _jsep_protocol_driver["default"](_this.emulator, _this.rtc, poll);
152
- _this.view = /*#__PURE__*/_react["default"].createRef();
153
- return _this;
140
+ _logger["default"].info("Created JSEP:", jsep.current);
154
141
  }
155
- (0, _createClass2["default"])(Emulator, [{
156
- key: "render",
157
- value: function render() {
158
- var _this$props = this.props,
159
- width = _this$props.width,
160
- height = _this$props.height,
161
- view = _this$props.view,
162
- poll = _this$props.poll,
163
- muted = _this$props.muted,
164
- onStateChange = _this$props.onStateChange,
165
- onError = _this$props.onError,
166
- volume = _this$props.volume;
167
- var SpecificView = this.components[view] || RtcView;
168
- console.log("render ".concat(width, "x").concat(height));
169
- return /*#__PURE__*/_react["default"].createElement(SpecificView, {
170
- ref: this.view,
171
- width: width,
172
- height: height,
173
- emulator: this.emulator,
174
- jsep: this.jsep,
175
- onStateChange: onStateChange,
176
- poll: poll,
177
- muted: muted,
178
- volume: volume,
179
- onError: onError,
180
- onAudioStateChange: this._onAudioStateChange
181
- });
142
+ (0, _react.useEffect)(function () {
143
+ if (typeof gps === "undefined") {
144
+ return;
182
145
  }
183
- }], [{
184
- key: "getDerivedStateFromProps",
185
- value: function getDerivedStateFromProps(nextProps, prevState) {
186
- if (nextProps.view === "png") return {
187
- audio: false
188
- };
189
- return prevState;
146
+ var headers = {
147
+ 'Content-Type': 'application/json'
148
+ };
149
+ if (auth && auth.authHeader) {
150
+ Object.assign(headers, auth.authHeader());
190
151
  }
191
- }]);
192
- return Emulator;
193
- }(_react.Component);
194
- (0, _defineProperty2["default"])(Emulator, "propTypes", {
195
- /** gRPC Endpoint where we can reach the emulator. */
152
+ var body = JSON.stringify({
153
+ latitude: gps.latitude,
154
+ longitude: gps.longitude,
155
+ altitude: gps.altitude,
156
+ heading: gps.heading,
157
+ speed: gps.speed
158
+ });
159
+ fetch(urls.gps, {
160
+ method: 'POST',
161
+ headers: headers,
162
+ body: body
163
+ })["catch"](function (err) {
164
+ if (onError) onError(err);
165
+ });
166
+ }, [gps, uri, auth]);
167
+ (0, _react.useEffect)(function () {
168
+ return function () {
169
+ if (jsep.current) {
170
+ jsep.current.cleanup();
171
+ }
172
+ };
173
+ }, []);
174
+ (0, _react.useImperativeHandle)(ref, function () {
175
+ return {
176
+ sendKey: function sendKey(key) {
177
+ var request = new _emulator_controller_pb["default"].KeyboardEvent();
178
+ request.setEventtype(_emulator_controller_pb["default"].KeyboardEvent.KeyEventType.KEYPRESS);
179
+ request.setKey(key);
180
+ jsep.current.send("keyboard", request);
181
+ }
182
+ };
183
+ });
184
+ var _onAudioStateChange = function _onAudioStateChange(s) {
185
+ setAudio(s);
186
+ onAudioStateChange(s);
187
+ };
188
+ _logger["default"].debug("render ".concat(width, "x").concat(height));
189
+ return /*#__PURE__*/_react["default"].createElement(RtcView, {
190
+ ref: viewRef,
191
+ width: width,
192
+ height: height,
193
+ statusUrl: urls.status,
194
+ jsep: jsep.current,
195
+ onStateChange: onStateChange,
196
+ muted: muted,
197
+ volume: volume,
198
+ onError: onError,
199
+ onAudioStateChange: _onAudioStateChange,
200
+ auth: auth
201
+ });
202
+ });
203
+ Emulator.propTypes = {
204
+ /** Endpoint where we can reach the emulator gateway (host:port or http(s)://host:port). */
196
205
  uri: _propTypes["default"].string.isRequired,
197
206
  /** The authentication service to use, or null for no authentication. */
198
207
  auth: _propTypes["default"].object,
199
- /** True if the audio should be disabled. This is only relevant when using the webrtc engine. */
208
+ /** True if the audio should be disabled. */
200
209
  muted: _propTypes["default"].bool,
201
210
  /** Volume between [0, 1] when audio is enabled. 0 is muted, 1.0 is 100% */
202
211
  volume: _propTypes["default"].number,
@@ -208,30 +217,9 @@ var Emulator = /*#__PURE__*/function (_Component) {
208
217
  width: _propTypes["default"].number,
209
218
  /** The height of the component */
210
219
  height: _propTypes["default"].number,
211
- /** The underlying view used to display the emulator, one of ["webrtc", "png"] */
212
- view: _propTypes["default"].oneOf(["webrtc", "png"]).isRequired,
213
220
  /** A [GeolocationCoordinates](https://developer.mozilla.org/en-US/docs/Web/API/GeolocationCoordinates) like object indicating where the device is. */
214
221
  gps: _propTypes["default"].object,
215
- /** True if polling should be used, only set this to true if you are using the go webgrpc proxy. */
216
- poll: _propTypes["default"].bool,
217
- /** Callback that will be invoked in case of gRPC errors. */
222
+ /** Callback that will be invoked in case of errors. */
218
223
  onError: _propTypes["default"].func
219
- });
220
- (0, _defineProperty2["default"])(Emulator, "defaultProps", {
221
- view: "webrtc",
222
- auth: null,
223
- poll: false,
224
- muted: true,
225
- volume: 1.0,
226
- onError: function onError(e) {
227
- console.error(e);
228
- },
229
- onAudioStateChange: function onAudioStateChange(s) {
230
- console.debug("emulator audio: " + s);
231
- },
232
- onStateChange: function onStateChange(s) {
233
- console.debug("emulator state: " + s);
234
- }
235
- });
236
- var _default = Emulator;
237
- exports["default"] = _default;
224
+ };
225
+ var _default = exports["default"] = Emulator;
@@ -0,0 +1,45 @@
1
+ export interface AuthService {
2
+ authHeader?(): Record<string, string>;
3
+ unauthorized?(): void;
4
+ }
5
+ export interface EmulatorStatusData {
6
+ status?: string;
7
+ hardwareConfig?: Record<string, string>;
8
+ [key: string]: any;
9
+ }
10
+ /**
11
+ * Utility class to query and manage the emulator's status by communicating
12
+ * with its REST configuration endpoint. It parses the hardware configuration
13
+ * and caches the status.
14
+ *
15
+ * @export
16
+ * @class EmulatorStatus
17
+ */
18
+ declare class EmulatorStatus {
19
+ statusUrl: string;
20
+ auth: AuthService | null;
21
+ status: EmulatorStatusData | null;
22
+ /**
23
+ * Creates an EmulatorStatus object that can retrieve the status of the running emulator.
24
+ *
25
+ * @param statusUrl The REST endpoint to retrieve status.
26
+ * @param auth The authentication service to use, or null for no authentication.
27
+ */
28
+ constructor(statusUrl: string, auth?: AuthService | null);
29
+ /**
30
+ * Gets the cached status object.
31
+ *
32
+ * @returns The cached emulator status or null if not yet loaded.
33
+ * @memberof EmulatorStatus
34
+ */
35
+ getStatus: () => EmulatorStatusData | null;
36
+ /**
37
+ * Retrieves the current status from the emulator REST endpoint.
38
+ *
39
+ * @param fnNotify Callback invoked when the status is retrieved. Receives the status object.
40
+ * @param cache If true, uses the cached status if available instead of fetching.
41
+ * @memberof EmulatorStatus
42
+ */
43
+ updateStatus: (fnNotify: (status: EmulatorStatusData) => void, cache?: boolean) => EmulatorStatusData;
44
+ }
45
+ export default EmulatorStatus;
@@ -8,8 +8,7 @@ exports["default"] = void 0;
8
8
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
9
9
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
10
10
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
- var _empty_pb = require("google-protobuf/google/protobuf/empty_pb");
12
- var _emulator_web_client = require("../../../proto/emulator_web_client");
11
+ var _logger = _interopRequireDefault(require("./logger"));
13
12
  /*
14
13
  * Copyright 2020 The Android Open Source Project
15
14
  *
@@ -26,8 +25,9 @@ var _emulator_web_client = require("../../../proto/emulator_web_client");
26
25
  * limitations under the License.
27
26
  */
28
27
  /**
29
- * Gets the status of the emulator, parsing the hardware config into something
30
- * easy to digest.
28
+ * Utility class to query and manage the emulator's status by communicating
29
+ * with its REST configuration endpoint. It parses the hardware configuration
30
+ * and caches the status.
31
31
  *
32
32
  * @export
33
33
  * @class EmulatorStatus
@@ -36,66 +36,59 @@ var EmulatorStatus = /*#__PURE__*/(0, _createClass2["default"])(
36
36
  /**
37
37
  * Creates an EmulatorStatus object that can retrieve the status of the running emulator.
38
38
  *
39
- * @param {object} uriOrEmulator An emulator controller service, or a URI to a gRPC endpoint.
40
- * @param {object} auth The authentication service to use, or null for no authentication.
41
- *
42
- * The authentication service should implement the following methods:
43
- * - `authHeader()` which must return a set of headers that should be send along with a request.
44
- * - `unauthorized()` a function that gets called when a 401 was received.
39
+ * @param {string} statusUrl The REST endpoint to retrieve status.
40
+ * @param {Object} [auth] The authentication service to use, or null for no authentication.
41
+ * @param {function} [auth.authHeader] Function returning authorization headers.
45
42
  */
46
- function EmulatorStatus(uriOrEmulator, auth) {
43
+ function EmulatorStatus(statusUrl, auth) {
47
44
  var _this = this;
48
45
  (0, _classCallCheck2["default"])(this, EmulatorStatus);
49
46
  /**
50
- * Gets the cached status.
47
+ * Gets the cached status object.
51
48
  *
49
+ * @returns {Object|null} The cached emulator status or null if not yet loaded.
52
50
  * @memberof EmulatorStatus
53
51
  */
54
52
  (0, _defineProperty2["default"])(this, "getStatus", function () {
55
53
  return _this.status;
56
54
  });
57
55
  /**
58
- * Retrieves the current status from the emulator.
56
+ * Retrieves the current status from the emulator REST endpoint.
59
57
  *
60
- * @param {Callback} fnNotify when the status is available, returns the retrieved status.
61
- * @param {boolean} cache True if the cache can be used.
58
+ * @param {function(Object): void} fnNotify Callback invoked when the status is retrieved. Receives the status object.
59
+ * @param {boolean} [cache=false] If true, uses the cached status if available instead of fetching.
62
60
  * @memberof EmulatorStatus
63
61
  */
64
62
  (0, _defineProperty2["default"])(this, "updateStatus", function (fnNotify, cache) {
65
- var request = new _empty_pb.Empty();
63
+ if (!_this.statusUrl) {
64
+ return;
65
+ }
66
66
  if (cache && _this.status) {
67
67
  fnNotify(_this.status);
68
68
  return _this.status;
69
69
  }
70
- _this.emulator.getStatus(request, {}, function (err, response) {
71
- var hwConfig = {};
72
- var entryList = response.getHardwareconfig().getEntryList();
73
- for (var i = 0; i < entryList.length; i++) {
74
- var key = entryList[i].getKey();
75
- var val = entryList[i].getValue();
76
- hwConfig[key] = val;
70
+ var headers = {
71
+ Accept: "application/json"
72
+ };
73
+ if (_this.auth && _this.auth.authHeader) {
74
+ Object.assign(headers, _this.auth.authHeader());
75
+ }
76
+ fetch(_this.statusUrl, {
77
+ headers: headers
78
+ }).then(function (response) {
79
+ if (!response.ok) {
80
+ throw new Error("HTTP error! status: ".concat(response.status));
77
81
  }
78
- var vmConfig = response.getVmconfig();
79
- _this.status = {
80
- version: response.getVersion(),
81
- uptime: response.getUptime(),
82
- booted: response.getBooted(),
83
- hardwareConfig: hwConfig,
84
- vmConfig: {
85
- hypervisorType: vmConfig.getHypervisortype(),
86
- numberOfCpuCores: vmConfig.getNumberofcpucores(),
87
- ramSizeBytes: vmConfig.getRamsizebytes()
88
- }
89
- };
82
+ return response.json();
83
+ }).then(function (data) {
84
+ _this.status = data;
90
85
  fnNotify(_this.status);
86
+ })["catch"](function (err) {
87
+ _logger["default"].error("Failed to get emulator status:", err);
91
88
  });
92
89
  });
93
- if (uriOrEmulator instanceof _emulator_web_client.EmulatorControllerService) {
94
- this.emulator = uriOrEmulator;
95
- } else {
96
- this.emulator = new _emulator_web_client.EmulatorControllerService(uriOrEmulator, auth);
97
- }
90
+ this.statusUrl = statusUrl;
91
+ this.auth = auth;
98
92
  this.status = null;
99
93
  });
100
- var _default = EmulatorStatus;
101
- exports["default"] = _default;
94
+ var _default = exports["default"] = EmulatorStatus;