android-emulator-webrtc 1.0.17 → 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.
- package/README.md +93 -204
- package/dist/components/emulator/emulator.d.ts +64 -0
- package/dist/components/emulator/emulator.js +161 -173
- package/dist/components/emulator/net/emulator_status.d.ts +45 -0
- package/dist/components/emulator/net/emulator_status.js +35 -42
- package/dist/components/emulator/net/logcat.js +37 -54
- package/dist/components/emulator/net/logger.d.ts +7 -0
- package/dist/components/emulator/net/logger.js +20 -0
- package/dist/components/emulator/net/ws_jsep_protocol_driver.d.ts +213 -0
- package/dist/components/emulator/net/ws_jsep_protocol_driver.js +640 -0
- package/dist/components/emulator/views/event_handler.d.ts +37 -0
- package/dist/components/emulator/views/event_handler.js +274 -260
- package/dist/components/emulator/views/webrtc_view.d.ts +27 -0
- package/dist/components/emulator/views/webrtc_view.js +42 -25
- package/dist/index.d.ts +8 -0
- package/dist/index.js +0 -7
- package/dist/proto/emulator_controller_pb.d.ts +1 -0
- package/dist/proto/emulator_controller_pb.js +146 -287
- package/dist/src/components/emulator/emulator.d.ts +64 -0
- package/dist/src/components/emulator/net/emulator_status.d.ts +45 -0
- package/dist/src/components/emulator/net/logger.d.ts +7 -0
- package/dist/src/components/emulator/net/ws_jsep_protocol_driver.d.ts +213 -0
- package/dist/src/components/emulator/views/event_handler.d.ts +37 -0
- package/dist/src/components/emulator/views/webrtc_view.d.ts +27 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/proto/emulator_controller_pb.d.ts +1 -0
- package/package.json +17 -18
- package/proto/emulator_controller.proto +746 -181
- package/.vscode/launch.json +0 -21
- package/.vscode/settings.json +0 -3
- package/CONTRIBUTING.md +0 -28
- package/Makefile +0 -123
- package/android-emulator-webrtc.code-workspace +0 -7
- package/api_descriptor.pb +0 -0
- package/babel.config.js +0 -16
- package/cloudbuild.yaml +0 -41
- package/cloudbuilders/.gcloudignore +0 -1
- package/cloudbuilders/Dockerfile +0 -20
- package/cloudbuilders/README.md +0 -29
- package/cloudbuilders/cloudbuild.yaml +0 -19
- package/dist/components/emulator/net/jsep_protocol_driver.js +0 -365
- package/dist/components/emulator/views/resizing_component.js +0 -86
- package/dist/components/emulator/views/simple_png_view.js +0 -111
- package/dist/proto/emulator_controller_grpc_web_pb.js +0 -1601
- package/dist/proto/emulator_web_client.js +0 -176
- package/dist/proto/rtc_service_grpc_web_pb.js +0 -231
- package/dist/proto/rtc_service_pb.js +0 -338
- package/emulator/index.js +0 -1
- package/eslint_prefix.py +0 -37
- package/gen_md_doc.js +0 -40
- package/npmrc.enc +0 -0
- package/proto/rtc_service.proto +0 -117
- package/protoc-plugin/Makefile +0 -31
- package/protoc-plugin/grpc_generator.cc +0 -1755
- package/src/components/emulator/emulator.js +0 -217
- package/src/components/emulator/net/emulator_status.js +0 -94
- package/src/components/emulator/net/jsep_protocol_driver.js +0 -364
- package/src/components/emulator/net/logcat.js +0 -155
- package/src/components/emulator/views/event_handler.js +0 -268
- package/src/components/emulator/views/resizing_component.js +0 -65
- package/src/components/emulator/views/simple_png_view.js +0 -106
- package/src/components/emulator/views/webrtc_view.js +0 -146
- package/src/index.js +0 -20
- package/src/proto/emulator_web_client.js +0 -140
- package/test/cloudbuild.yaml +0 -41
- package/test/emulator.test.js +0 -125
- package/test/event_handler.test.js +0 -91
- package/test/fake_events.js +0 -50
- package/test/jsep_protocol_driver.test.js +0 -228
- package/test/resizing_component.test.js +0 -37
- package/test/simple_png_view.test.js +0 -145
- package/test/touch_event_handler.test.js +0 -118
|
@@ -6,35 +6,20 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
8
|
exports["default"] = withMouseKeyHandler;
|
|
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
9
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
10
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
16
11
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
17
|
-
var _react =
|
|
18
|
-
var
|
|
12
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
13
|
+
var _emulator_controller_pb = _interopRequireDefault(require("../../../proto/emulator_controller_pb"));
|
|
19
14
|
var _emulator_status = _interopRequireDefault(require("../net/emulator_status"));
|
|
15
|
+
var _logger = _interopRequireDefault(require("../net/logger"));
|
|
20
16
|
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); }
|
|
21
17
|
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; }
|
|
22
|
-
function
|
|
23
|
-
function
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
* you may not use this file except in compliance with the License.
|
|
28
|
-
* You may obtain a copy of the License at
|
|
29
|
-
*
|
|
30
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
31
|
-
*
|
|
32
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
33
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
34
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
35
|
-
* See the License for the specific language governing permissions and
|
|
36
|
-
* limitations under the License.
|
|
37
|
-
*/
|
|
18
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
19
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
20
|
+
var DEFAULT_WIDTH = 1080;
|
|
21
|
+
var DEFAULT_HEIGHT = 2424;
|
|
22
|
+
|
|
38
23
|
/**
|
|
39
24
|
* A handler that extends a view to send key/mouse events to the emulator.
|
|
40
25
|
* It wraps the inner component in a div, and will use the jsep handler
|
|
@@ -46,253 +31,282 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
|
|
|
46
31
|
* You usually want to wrap a EmulatorRtcview, or EmulatorPngView in it.
|
|
47
32
|
*/
|
|
48
33
|
function withMouseKeyHandler(WrappedComponent) {
|
|
49
|
-
var
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
34
|
+
var MouseKeyHandler = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
|
|
35
|
+
var statusUrl = props.statusUrl,
|
|
36
|
+
auth = props.auth,
|
|
37
|
+
jsep = props.jsep,
|
|
38
|
+
width = props.width,
|
|
39
|
+
height = props.height;
|
|
40
|
+
var _useState = (0, _react.useState)(DEFAULT_WIDTH),
|
|
41
|
+
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
|
|
42
|
+
deviceWidth = _useState2[0],
|
|
43
|
+
setDeviceWidth = _useState2[1];
|
|
44
|
+
var _useState3 = (0, _react.useState)(DEFAULT_HEIGHT),
|
|
45
|
+
_useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
|
|
46
|
+
deviceHeight = _useState4[0],
|
|
47
|
+
setDeviceHeight = _useState4[1];
|
|
48
|
+
var _useState5 = (0, _react.useState)({
|
|
49
|
+
xp: 0,
|
|
50
|
+
yp: 0,
|
|
51
|
+
mouseDown: false,
|
|
52
|
+
mouseButton: 0
|
|
53
|
+
}),
|
|
54
|
+
_useState6 = (0, _slicedToArray2["default"])(_useState5, 2),
|
|
55
|
+
mouse = _useState6[0],
|
|
56
|
+
setMouse = _useState6[1];
|
|
57
|
+
var handlerRef = (0, _react.useRef)(null);
|
|
58
|
+
var statusRef = (0, _react.useRef)(null);
|
|
59
|
+
if (!statusRef.current) {
|
|
60
|
+
statusRef.current = new _emulator_status["default"](statusUrl, auth);
|
|
61
|
+
}
|
|
62
|
+
(0, _react.useImperativeHandle)(ref, function () {
|
|
63
|
+
return {
|
|
64
|
+
scaleCoordinates: scaleCoordinates,
|
|
65
|
+
setDeviceWidth: setDeviceWidth,
|
|
66
|
+
setDeviceHeight: setDeviceHeight,
|
|
67
|
+
handlerRef: handlerRef
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
(0, _react.useEffect)(function () {
|
|
71
|
+
statusRef.current.updateStatus(function (state) {
|
|
72
|
+
setDeviceWidth(parseInt(state.hardwareConfig["hw.lcd.width"]) || DEFAULT_WIDTH);
|
|
73
|
+
setDeviceHeight(parseInt(state.hardwareConfig["hw.lcd.height"]) || DEFAULT_HEIGHT);
|
|
59
74
|
});
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
}, [statusUrl, auth]);
|
|
76
|
+
var onContextMenu = function onContextMenu(e) {
|
|
77
|
+
e.preventDefault();
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Translates and scales HTML coordinates (xp, yp) from the event handler's
|
|
82
|
+
* container element to the emulator's internal device coordinate system.
|
|
83
|
+
*
|
|
84
|
+
* This method accounts for letterboxing or pillarboxing that occurs when
|
|
85
|
+
* the container's aspect ratio differs from the emulator's native screen aspect ratio,
|
|
86
|
+
* ensuring that clicks on black borders are ignored and clicks on the active area
|
|
87
|
+
* are correctly mapped.
|
|
88
|
+
*/
|
|
89
|
+
var scaleCoordinates = function scaleCoordinates(xp, yp) {
|
|
90
|
+
var _handlerRef$current = handlerRef.current,
|
|
91
|
+
clientHeight = _handlerRef$current.clientHeight,
|
|
92
|
+
clientWidth = _handlerRef$current.clientWidth;
|
|
93
|
+
var deviceRatio = deviceWidth / deviceHeight;
|
|
94
|
+
var containerRatio = clientWidth / clientHeight;
|
|
95
|
+
var renderedWidth = clientWidth;
|
|
96
|
+
var renderedHeight = clientHeight;
|
|
97
|
+
var offsetX = 0;
|
|
98
|
+
var offsetY = 0;
|
|
99
|
+
if (containerRatio > deviceRatio) {
|
|
100
|
+
// Pillarboxed (bars on left and right)
|
|
101
|
+
renderedWidth = clientHeight * deviceRatio;
|
|
102
|
+
offsetX = (clientWidth - renderedWidth) / 2;
|
|
103
|
+
} else {
|
|
104
|
+
// Letterboxed (bars on top and bottom)
|
|
105
|
+
renderedHeight = clientWidth / deviceRatio;
|
|
106
|
+
offsetY = (clientHeight - renderedHeight) / 2;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Adjust coordinate relative to the actual rendered video area
|
|
110
|
+
var adjustedXp = xp - offsetX;
|
|
111
|
+
var adjustedYp = yp - offsetY;
|
|
112
|
+
var scaleX = deviceWidth / renderedWidth;
|
|
113
|
+
var scaleY = deviceHeight / renderedHeight;
|
|
114
|
+
var x = Math.round(adjustedXp * scaleX);
|
|
115
|
+
var y = Math.round(adjustedYp * scaleY);
|
|
116
|
+
_logger["default"].debug("scaleCoordinates: input(".concat(xp, ", ").concat(yp, "), container(").concat(clientWidth, "x").concat(clientHeight, "), ") + "device(".concat(deviceWidth, "x").concat(deviceHeight, "), offset(").concat(Math.round(offsetX), ", ").concat(Math.round(offsetY), "), ") + "adjusted(".concat(Math.round(adjustedXp), ", ").concat(Math.round(adjustedYp), "), scale(").concat(scaleX.toFixed(3), ", ").concat(scaleY.toFixed(3), "), output(").concat(x, ", ").concat(y, ")"));
|
|
117
|
+
|
|
118
|
+
// Guard against out of bounds or division by zero
|
|
119
|
+
if (isNaN(x) || isNaN(y) || adjustedXp < 0 || adjustedXp > renderedWidth || adjustedYp < 0 || adjustedYp > renderedHeight) {
|
|
120
|
+
_logger["default"].debug("Ignoring out of bounds or invalid click: x: " + x + ", y:" + y);
|
|
79
121
|
return {
|
|
80
|
-
x:
|
|
81
|
-
y:
|
|
122
|
+
x: -1,
|
|
123
|
+
y: -1,
|
|
82
124
|
scaleX: scaleX,
|
|
83
125
|
scaleY: scaleY
|
|
84
126
|
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
});
|
|
116
|
-
// Properly handle the mouse events.
|
|
117
|
-
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "handleMouseDown", function (e) {
|
|
118
|
-
var _e$nativeEvent = e.nativeEvent,
|
|
119
|
-
offsetX = _e$nativeEvent.offsetX,
|
|
120
|
-
offsetY = _e$nativeEvent.offsetY;
|
|
121
|
-
_this.setState({
|
|
122
|
-
mouse: {
|
|
123
|
-
xp: offsetX,
|
|
124
|
-
yp: offsetY,
|
|
125
|
-
mouseDown: true,
|
|
126
|
-
// In browser's MouseEvent.button property,
|
|
127
|
-
// 0 stands for left button and 2 stands for right button.
|
|
128
|
-
mouseButton: e.button === 0 ? 1 : e.button === 2 ? 2 : 0
|
|
129
|
-
}
|
|
130
|
-
}, _this.setMouseCoordinates);
|
|
131
|
-
});
|
|
132
|
-
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "handleMouseUp", function (e) {
|
|
133
|
-
var _e$nativeEvent2 = e.nativeEvent,
|
|
134
|
-
offsetX = _e$nativeEvent2.offsetX,
|
|
135
|
-
offsetY = _e$nativeEvent2.offsetY;
|
|
136
|
-
_this.setState({
|
|
137
|
-
mouse: {
|
|
138
|
-
xp: offsetX,
|
|
139
|
-
yp: offsetY,
|
|
140
|
-
mouseDown: false,
|
|
141
|
-
mouseButton: 0
|
|
142
|
-
}
|
|
143
|
-
}, _this.setMouseCoordinates);
|
|
144
|
-
});
|
|
145
|
-
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "handleMouseMove", function (e) {
|
|
146
|
-
// Let's not overload the endpoint with useless events.
|
|
147
|
-
if (!_this.state.mouse.mouseDown) return;
|
|
148
|
-
var _e$nativeEvent3 = e.nativeEvent,
|
|
149
|
-
offsetX = _e$nativeEvent3.offsetX,
|
|
150
|
-
offsetY = _e$nativeEvent3.offsetY;
|
|
151
|
-
var mouse = _this.state.mouse;
|
|
152
|
-
mouse.xp = offsetX;
|
|
153
|
-
mouse.yp = offsetY;
|
|
154
|
-
_this.setState({
|
|
155
|
-
mouse: mouse
|
|
156
|
-
}, _this.setMouseCoordinates);
|
|
157
|
-
});
|
|
158
|
-
/**
|
|
159
|
-
* Scales an axis to linux input codes that the emulator understands.
|
|
160
|
-
*
|
|
161
|
-
* @param {*} value The value to transform.
|
|
162
|
-
* @param {*} minIn The minimum value, the lower bound of the value param.
|
|
163
|
-
* @param {*} maxIn The maximum value, the upper bound of the value param.
|
|
164
|
-
*/
|
|
165
|
-
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "scaleAxis", function (value, minIn, maxIn) {
|
|
166
|
-
var minOut = 0x0; // EV_ABS_MIN
|
|
167
|
-
var maxOut = 0x7fff; // EV_ABS_MAX
|
|
168
|
-
var rangeOut = maxOut - minOut;
|
|
169
|
-
var rangeIn = maxIn - minIn;
|
|
170
|
-
if (rangeIn < 1) {
|
|
171
|
-
return minOut + rangeOut / 2;
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
x: x,
|
|
130
|
+
y: y,
|
|
131
|
+
scaleX: scaleX,
|
|
132
|
+
scaleY: scaleY
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
var sendMouseCoordinates = function sendMouseCoordinates(currentMouse) {
|
|
136
|
+
var mouseDown = currentMouse.mouseDown,
|
|
137
|
+
mouseButton = currentMouse.mouseButton,
|
|
138
|
+
xp = currentMouse.xp,
|
|
139
|
+
yp = currentMouse.yp;
|
|
140
|
+
var _scaleCoordinates = scaleCoordinates(xp, yp),
|
|
141
|
+
x = _scaleCoordinates.x,
|
|
142
|
+
y = _scaleCoordinates.y;
|
|
143
|
+
if (x < 0 || y < 0) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
var request = new _emulator_controller_pb["default"].MouseEvent();
|
|
147
|
+
request.setX(x);
|
|
148
|
+
request.setY(y);
|
|
149
|
+
request.setButtons(mouseDown ? mouseButton : 0);
|
|
150
|
+
jsep.send("mouse", request);
|
|
151
|
+
};
|
|
152
|
+
var handleKey = function handleKey(eventType) {
|
|
153
|
+
return function (e) {
|
|
154
|
+
// Disable jumping to next control when pressing the space bar.
|
|
155
|
+
if (e.keyCode === 32) {
|
|
156
|
+
e.preventDefault();
|
|
172
157
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
var touchesToSend = Object.keys(touches).map(function (index) {
|
|
180
|
-
var touch = touches[index];
|
|
181
|
-
var clientX = touch.clientX,
|
|
182
|
-
clientY = touch.clientY,
|
|
183
|
-
identifier = touch.identifier,
|
|
184
|
-
force = touch.force,
|
|
185
|
-
radiusX = touch.radiusX,
|
|
186
|
-
radiusY = touch.radiusY;
|
|
187
|
-
var offsetX = clientX - rect.left;
|
|
188
|
-
var offsetY = clientY - rect.top;
|
|
189
|
-
var _scaleCoordinates = scaleCoordinates(offsetX, offsetY),
|
|
190
|
-
x = _scaleCoordinates.x,
|
|
191
|
-
y = _scaleCoordinates.y,
|
|
192
|
-
scaleX = _scaleCoordinates.scaleX,
|
|
193
|
-
scaleY = _scaleCoordinates.scaleY;
|
|
194
|
-
var scaledRadiusX = 2 * radiusX * scaleX;
|
|
195
|
-
var scaledRadiusY = 2 * radiusY * scaleY;
|
|
196
|
-
var protoTouch = new Proto.Touch();
|
|
197
|
-
protoTouch.setX(x | 0);
|
|
198
|
-
protoTouch.setY(y | 0);
|
|
199
|
-
protoTouch.setIdentifier(identifier);
|
|
200
|
-
|
|
201
|
-
// Normalize the force
|
|
202
|
-
var MT_PRESSURE = _this.scaleAxis(Math.max(minForce, Math.min(maxForce, force)), 0, 1);
|
|
203
|
-
protoTouch.setPressure(MT_PRESSURE);
|
|
204
|
-
protoTouch.setTouchMajor(Math.max(scaledRadiusX, scaledRadiusY) | 0);
|
|
205
|
-
protoTouch.setTouchMinor(Math.min(scaledRadiusX, scaledRadiusY) | 0);
|
|
206
|
-
return protoTouch;
|
|
207
|
-
});
|
|
158
|
+
var request = new _emulator_controller_pb["default"].KeyboardEvent();
|
|
159
|
+
request.setEventtype(eventType === "KEYDOWN" ? _emulator_controller_pb["default"].KeyboardEvent.KeyEventType.KEYDOWN : eventType === "KEYUP" ? _emulator_controller_pb["default"].KeyboardEvent.KeyEventType.KEYUP : _emulator_controller_pb["default"].KeyboardEvent.KeyEventType.KEYPRESS);
|
|
160
|
+
request.setKey(e.key);
|
|
161
|
+
jsep.send("keyboard", request);
|
|
162
|
+
};
|
|
163
|
+
};
|
|
208
164
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
165
|
+
// Properly handle the mouse events.
|
|
166
|
+
var handleMouseDown = function handleMouseDown(e) {
|
|
167
|
+
var rect = handlerRef.current ? handlerRef.current.getBoundingClientRect() : null;
|
|
168
|
+
var xp = rect && rect.width > 0 ? e.clientX - rect.left : e.nativeEvent.offsetX || 0;
|
|
169
|
+
var yp = rect && rect.height > 0 ? e.clientY - rect.top : e.nativeEvent.offsetY || 0;
|
|
170
|
+
var newMouse = {
|
|
171
|
+
xp: xp,
|
|
172
|
+
yp: yp,
|
|
173
|
+
mouseDown: true,
|
|
174
|
+
// In browser's MouseEvent.button property,
|
|
175
|
+
// 0 stands for left button and 2 stands for right button.
|
|
176
|
+
mouseButton: e.button === 0 ? 1 : e.button === 2 ? 2 : 0
|
|
177
|
+
};
|
|
178
|
+
setMouse(newMouse);
|
|
179
|
+
sendMouseCoordinates(newMouse);
|
|
180
|
+
};
|
|
181
|
+
var handleMouseUp = function handleMouseUp(e) {
|
|
182
|
+
var rect = handlerRef.current ? handlerRef.current.getBoundingClientRect() : null;
|
|
183
|
+
var xp = rect && rect.width > 0 ? e.clientX - rect.left : e.nativeEvent.offsetX || 0;
|
|
184
|
+
var yp = rect && rect.height > 0 ? e.clientY - rect.top : e.nativeEvent.offsetY || 0;
|
|
185
|
+
var newMouse = {
|
|
186
|
+
xp: xp,
|
|
187
|
+
yp: yp,
|
|
188
|
+
mouseDown: false,
|
|
189
|
+
mouseButton: 0
|
|
190
|
+
};
|
|
191
|
+
setMouse(newMouse);
|
|
192
|
+
sendMouseCoordinates(newMouse);
|
|
193
|
+
};
|
|
194
|
+
var handleMouseMove = function handleMouseMove(e) {
|
|
195
|
+
// Let's not overload the endpoint with useless events.
|
|
196
|
+
if (!mouse.mouseDown) return;
|
|
197
|
+
var rect = handlerRef.current ? handlerRef.current.getBoundingClientRect() : null;
|
|
198
|
+
var xp = rect && rect.width > 0 ? e.clientX - rect.left : e.nativeEvent.offsetX || 0;
|
|
199
|
+
var yp = rect && rect.height > 0 ? e.clientY - rect.top : e.nativeEvent.offsetY || 0;
|
|
200
|
+
var newMouse = _objectSpread(_objectSpread({}, mouse), {}, {
|
|
201
|
+
xp: xp,
|
|
202
|
+
yp: yp
|
|
226
203
|
});
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
204
|
+
setMouse(newMouse);
|
|
205
|
+
sendMouseCoordinates(newMouse);
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Scales an axis to linux input codes that the emulator understands.
|
|
210
|
+
*/
|
|
211
|
+
var scaleAxis = function scaleAxis(value, minIn, maxIn) {
|
|
212
|
+
var minOut = 0x0; // EV_ABS_MIN
|
|
213
|
+
var maxOut = 0x7fff; // EV_ABS_MAX
|
|
214
|
+
var rangeOut = maxOut - minOut;
|
|
215
|
+
var rangeIn = maxIn - minIn;
|
|
216
|
+
if (rangeIn < 1) {
|
|
217
|
+
return minOut + rangeOut / 2;
|
|
218
|
+
}
|
|
219
|
+
return (value - minIn) * rangeOut / rangeIn + minOut | 0;
|
|
220
|
+
};
|
|
221
|
+
var setTouchCoordinates = function setTouchCoordinates(type, touches, minForce, maxForce) {
|
|
222
|
+
// We need to calculate the offset of the touch events.
|
|
223
|
+
var rect = handlerRef.current.getBoundingClientRect();
|
|
224
|
+
var touchesToSend = [];
|
|
225
|
+
for (var i = 0; i < touches.length; i++) {
|
|
226
|
+
var touch = touches[i];
|
|
227
|
+
var clientX = touch.clientX,
|
|
228
|
+
clientY = touch.clientY,
|
|
229
|
+
identifier = touch.identifier,
|
|
230
|
+
force = touch.force,
|
|
231
|
+
radiusX = touch.radiusX,
|
|
232
|
+
radiusY = touch.radiusY;
|
|
233
|
+
var offsetX = clientX - rect.left;
|
|
234
|
+
var offsetY = clientY - rect.top;
|
|
235
|
+
var _scaleCoordinates2 = scaleCoordinates(offsetX, offsetY),
|
|
236
|
+
x = _scaleCoordinates2.x,
|
|
237
|
+
y = _scaleCoordinates2.y,
|
|
238
|
+
scaleX = _scaleCoordinates2.scaleX,
|
|
239
|
+
scaleY = _scaleCoordinates2.scaleY;
|
|
240
|
+
if (x < 0 || y < 0) {
|
|
241
|
+
continue;
|
|
238
242
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
243
|
+
var scaledRadiusX = 2 * radiusX * scaleX;
|
|
244
|
+
var scaledRadiusY = 2 * radiusY * scaleY;
|
|
245
|
+
var protoTouch = new _emulator_controller_pb["default"].Touch();
|
|
246
|
+
protoTouch.setX(x | 0);
|
|
247
|
+
protoTouch.setY(y | 0);
|
|
248
|
+
protoTouch.setIdentifier(identifier);
|
|
249
|
+
|
|
250
|
+
// Normalize the force
|
|
251
|
+
var MT_PRESSURE = scaleAxis(Math.max(minForce, Math.min(maxForce, force)), 0, 1);
|
|
252
|
+
protoTouch.setPressure(MT_PRESSURE);
|
|
253
|
+
protoTouch.setTouchMajor(Math.max(scaledRadiusX, scaledRadiusY) | 0);
|
|
254
|
+
protoTouch.setTouchMinor(Math.min(scaledRadiusX, scaledRadiusY) | 0);
|
|
255
|
+
touchesToSend.push(protoTouch);
|
|
249
256
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
value: function getScreenSize() {
|
|
253
|
-
var _this2 = this;
|
|
254
|
-
this.status.updateStatus(function (state) {
|
|
255
|
-
_this2.setState({
|
|
256
|
-
deviceWidth: parseInt(state.hardwareConfig["hw.lcd.width"]) || 1080,
|
|
257
|
-
deviceHeight: parseInt(state.hardwareConfig["hw.lcd.height"]) || 1920
|
|
258
|
-
});
|
|
259
|
-
});
|
|
257
|
+
if (touchesToSend.length === 0) {
|
|
258
|
+
return;
|
|
260
259
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
260
|
+
|
|
261
|
+
// Make the grpc call.
|
|
262
|
+
var requestTouchEvent = new _emulator_controller_pb["default"].TouchEvent();
|
|
263
|
+
requestTouchEvent.setTouchesList(touchesToSend);
|
|
264
|
+
jsep.send("touch", requestTouchEvent);
|
|
265
|
+
};
|
|
266
|
+
var handleTouch = function handleTouch(minForce, maxForce) {
|
|
267
|
+
return function (e) {
|
|
268
|
+
// Make sure they are not processed as mouse events later on.
|
|
269
|
+
if (e.cancelable) {
|
|
270
|
+
e.preventDefault();
|
|
271
|
+
}
|
|
272
|
+
setTouchCoordinates(e.nativeEvent.type, e.nativeEvent.changedTouches, minForce, maxForce);
|
|
273
|
+
};
|
|
274
|
+
};
|
|
275
|
+
return /*#__PURE__*/_react["default"].createElement("div", {
|
|
276
|
+
onTouchStart: handleTouch(0.01, 1.0),
|
|
277
|
+
onTouchMove: handleTouch(0.01, 1.0),
|
|
278
|
+
onTouchEnd: handleTouch(0.0, 0.0),
|
|
279
|
+
onTouchCancel: handleTouch(0.0, 0.0),
|
|
280
|
+
onMouseDown: handleMouseDown,
|
|
281
|
+
onMouseMove: handleMouseMove,
|
|
282
|
+
onMouseUp: handleMouseUp,
|
|
283
|
+
onMouseOut: handleMouseUp,
|
|
284
|
+
onKeyDown: handleKey("KEYDOWN"),
|
|
285
|
+
onKeyUp: handleKey("KEYUP"),
|
|
286
|
+
onContextMenu: onContextMenu,
|
|
287
|
+
tabIndex: "0",
|
|
288
|
+
ref: handlerRef,
|
|
289
|
+
style: {
|
|
290
|
+
pointerEvents: "all",
|
|
291
|
+
outline: "none",
|
|
292
|
+
margin: "0",
|
|
293
|
+
padding: "0",
|
|
294
|
+
border: "0",
|
|
295
|
+
display: "inline-block",
|
|
296
|
+
width: width ? "".concat(width, "px") : "100%",
|
|
297
|
+
height: height ? "".concat(height, "px") : "auto"
|
|
289
298
|
}
|
|
290
|
-
}]);
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
/** The
|
|
294
|
-
|
|
299
|
+
}, /*#__PURE__*/_react["default"].createElement(WrappedComponent, props));
|
|
300
|
+
});
|
|
301
|
+
MouseKeyHandler.propTypes = {
|
|
302
|
+
/** The REST endpoint to retrieve status */
|
|
303
|
+
statusUrl: _propTypes["default"].string,
|
|
295
304
|
/** Jsep protocol driver, used to send mouse & touch events. */
|
|
296
|
-
jsep: _propTypes["default"].object.isRequired
|
|
297
|
-
|
|
305
|
+
jsep: _propTypes["default"].object.isRequired,
|
|
306
|
+
/** The authentication service to use */
|
|
307
|
+
auth: _propTypes["default"].object,
|
|
308
|
+
width: _propTypes["default"].number,
|
|
309
|
+
height: _propTypes["default"].number
|
|
310
|
+
};
|
|
311
|
+
return MouseKeyHandler;
|
|
298
312
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import WsJsepProtocol from "../net/ws_jsep_protocol_driver";
|
|
3
|
+
export interface EmulatorWebrtcViewProps {
|
|
4
|
+
/** The JSEP protocol driver instance. */
|
|
5
|
+
jsep: WsJsepProtocol;
|
|
6
|
+
/** Callback for connection state changes ("connecting", "connected", "disconnected"). */
|
|
7
|
+
onStateChange?: (state: string) => void;
|
|
8
|
+
/** Callback when audio track status changes. */
|
|
9
|
+
onAudioStateChange?: (audio: boolean) => void;
|
|
10
|
+
/** Whether the audio should be muted. */
|
|
11
|
+
muted?: boolean;
|
|
12
|
+
/** Audio volume (between 0.0 and 1.0). */
|
|
13
|
+
volume?: number;
|
|
14
|
+
/** Callback invoked on signaling or playback errors. */
|
|
15
|
+
onError?: (error: Error) => void;
|
|
16
|
+
/** Component width. */
|
|
17
|
+
width?: number;
|
|
18
|
+
/** Component height. */
|
|
19
|
+
height?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A React component that renders the WebRTC video stream of the emulator.
|
|
23
|
+
* Handles establishing the stream via the JSEP protocol driver and managing
|
|
24
|
+
* local playback (including handling autoplay constraints).
|
|
25
|
+
*/
|
|
26
|
+
declare const EmulatorWebrtcView: React.FC<EmulatorWebrtcViewProps>;
|
|
27
|
+
export default EmulatorWebrtcView;
|