appium-android-driver 5.7.2 → 5.8.0
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/CHANGELOG.md +9 -0
- package/build/index.js +1 -2
- package/build/lib/android-helpers.js +2 -26
- package/build/lib/android-helpers.js.map +1 -1
- package/build/lib/bootstrap.js +1 -8
- package/build/lib/bootstrap.js.map +1 -1
- package/build/lib/commands/actions.js +1 -2
- package/build/lib/commands/actions.js.map +1 -1
- package/build/lib/commands/alert.js +1 -2
- package/build/lib/commands/alert.js.map +1 -1
- package/build/lib/commands/app-management.js +2 -16
- package/build/lib/commands/app-management.js.map +1 -1
- package/build/lib/commands/context.js +1 -15
- package/build/lib/commands/context.js.map +1 -1
- package/build/lib/commands/element.js +1 -4
- package/build/lib/commands/element.js.map +1 -1
- package/build/lib/commands/emu-console.js +1 -3
- package/build/lib/commands/emu-console.js.map +1 -1
- package/build/lib/commands/file-actions.js +1 -13
- package/build/lib/commands/file-actions.js.map +1 -1
- package/build/lib/commands/find.js +1 -5
- package/build/lib/commands/find.js.map +1 -1
- package/build/lib/commands/general.js +1 -83
- package/build/lib/commands/general.js.map +1 -1
- package/build/lib/commands/index.js +3 -3
- package/build/lib/commands/index.js.map +1 -1
- package/build/lib/commands/intent.js +1 -5
- package/build/lib/commands/intent.js.map +1 -1
- package/build/lib/commands/log.js +1 -4
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/media-projection.js +1 -5
- package/build/lib/commands/media-projection.js.map +1 -1
- package/build/lib/commands/network.js +1 -7
- package/build/lib/commands/network.js.map +1 -1
- package/build/lib/commands/performance.js +1 -8
- package/build/lib/commands/performance.js.map +1 -1
- package/build/lib/commands/permissions.js +116 -0
- package/build/lib/commands/permissions.js.map +1 -0
- package/build/lib/commands/recordscreen.js +1 -3
- package/build/lib/commands/recordscreen.js.map +1 -1
- package/build/lib/commands/shell.js +4 -4
- package/build/lib/commands/shell.js.map +1 -1
- package/build/lib/commands/streamscreen.js +4 -9
- package/build/lib/commands/streamscreen.js.map +1 -1
- package/build/lib/commands/system-bars.js +1 -4
- package/build/lib/commands/system-bars.js.map +1 -1
- package/build/lib/commands/touch.js +1 -9
- package/build/lib/commands/touch.js.map +1 -1
- package/build/lib/desired-caps.js +2 -4
- package/build/lib/desired-caps.js.map +1 -1
- package/build/lib/driver.js +1 -20
- package/build/lib/driver.js.map +1 -1
- package/build/lib/uiautomator.js +1 -3
- package/build/lib/uiautomator.js.map +1 -1
- package/build/lib/unlock-helpers.js +1 -3
- package/build/lib/unlock-helpers.js.map +1 -1
- package/build/lib/utils.js +4 -1
- package/build/lib/utils.js.map +1 -1
- package/build/lib/webview-helpers.js +1 -13
- package/build/lib/webview-helpers.js.map +1 -1
- package/lib/commands/general.js +0 -112
- package/lib/commands/index.js +2 -0
- package/lib/commands/permissions.js +169 -0
- package/lib/commands/shell.js +2 -3
- package/lib/utils.js +2 -1
- package/package.json +2 -2
|
@@ -46,7 +46,6 @@ exports.helpers = helpers;
|
|
|
46
46
|
function toDetailsCacheKey(adb, webview) {
|
|
47
47
|
return `${adb === null || adb === void 0 ? void 0 : adb.curDeviceId}:${webview}`;
|
|
48
48
|
}
|
|
49
|
-
|
|
50
49
|
async function getPotentialWebviewProcs(adb) {
|
|
51
50
|
const out = await adb.shell(['cat', '/proc/net/unix']);
|
|
52
51
|
const names = [];
|
|
@@ -77,7 +76,6 @@ async function getPotentialWebviewProcs(adb) {
|
|
|
77
76
|
}
|
|
78
77
|
return _lodash.default.uniq(names);
|
|
79
78
|
}
|
|
80
|
-
|
|
81
79
|
async function webviewsFromProcs(adb, deviceSocket = null) {
|
|
82
80
|
const socketNames = await getPotentialWebviewProcs(adb);
|
|
83
81
|
const webviews = [];
|
|
@@ -106,7 +104,6 @@ async function webviewsFromProcs(adb, deviceSocket = null) {
|
|
|
106
104
|
}
|
|
107
105
|
return webviews;
|
|
108
106
|
}
|
|
109
|
-
|
|
110
107
|
async function allocateDevtoolsPort(adb, socketName, webviewDevtoolsPort = null) {
|
|
111
108
|
const remotePort = socketName.replace(/^@/, '');
|
|
112
109
|
let [startPort, endPort] = DEVTOOLS_PORTS_RANGE;
|
|
@@ -129,7 +126,6 @@ async function allocateDevtoolsPort(adb, socketName, webviewDevtoolsPort = null)
|
|
|
129
126
|
return localPort;
|
|
130
127
|
});
|
|
131
128
|
}
|
|
132
|
-
|
|
133
129
|
async function collectWebviewsDetails(adb, webviewsMapping, opts = {}) {
|
|
134
130
|
if (_lodash.default.isEmpty(webviewsMapping)) {
|
|
135
131
|
return;
|
|
@@ -148,7 +144,6 @@ async function collectWebviewsDetails(adb, webviewsMapping, opts = {}) {
|
|
|
148
144
|
if (!ensureWebviewsHavePages && !enableWebviewDetailsCollection) {
|
|
149
145
|
return;
|
|
150
146
|
}
|
|
151
|
-
|
|
152
147
|
_logger.default.debug(`Collecting CDP data of ${_support.util.pluralize('webview', webviewsMapping.length, true)}`);
|
|
153
148
|
const detailCollectors = [];
|
|
154
149
|
for (const item of webviewsMapping) {
|
|
@@ -174,21 +169,18 @@ async function collectWebviewsDetails(adb, webviewsMapping, opts = {}) {
|
|
|
174
169
|
await _bluebird.default.all(detailCollectors);
|
|
175
170
|
_logger.default.debug(`CDP data collection completed`);
|
|
176
171
|
}
|
|
177
|
-
|
|
178
172
|
async function cdpList(localPort) {
|
|
179
173
|
return (await (0, _axios.default)({
|
|
180
174
|
url: `http://127.0.0.1:${localPort}/json/list`,
|
|
181
175
|
timeout: CDP_REQ_TIMEOUT
|
|
182
176
|
})).data;
|
|
183
177
|
}
|
|
184
|
-
|
|
185
178
|
async function cdpInfo(localPort) {
|
|
186
179
|
return (await (0, _axios.default)({
|
|
187
180
|
url: `http://127.0.0.1:${localPort}/json/version`,
|
|
188
181
|
timeout: CDP_REQ_TIMEOUT
|
|
189
182
|
})).data;
|
|
190
183
|
}
|
|
191
|
-
|
|
192
184
|
helpers.procFromWebview = async function procFromWebview(adb, webview) {
|
|
193
185
|
const pidMatch = WEBVIEW_PID_PATTERN.exec(webview);
|
|
194
186
|
if (!pidMatch) {
|
|
@@ -201,7 +193,6 @@ helpers.procFromWebview = async function procFromWebview(adb, webview) {
|
|
|
201
193
|
_logger.default.debug(`Got process name: '${pkg}'`);
|
|
202
194
|
return pkg;
|
|
203
195
|
};
|
|
204
|
-
|
|
205
196
|
helpers.parseWebviewNames = function parseWebviewNames(webviewsMapping, {
|
|
206
197
|
ensureWebviewsHavePages = true,
|
|
207
198
|
isChromeSession = false
|
|
@@ -227,7 +218,6 @@ helpers.parseWebviewNames = function parseWebviewNames(webviewsMapping, {
|
|
|
227
218
|
_logger.default.debug(`Found ${_support.util.pluralize('webview', result.length, true)}: ${JSON.stringify(result)}`);
|
|
228
219
|
return result;
|
|
229
220
|
};
|
|
230
|
-
|
|
231
221
|
helpers.getWebViewsMapping = async function getWebViewsMapping(adb, {
|
|
232
222
|
androidDeviceSocket = null,
|
|
233
223
|
ensureWebviewsHavePages = true,
|
|
@@ -277,12 +267,10 @@ helpers.getWebViewsMapping = async function getWebViewsMapping(adb, {
|
|
|
277
267
|
}
|
|
278
268
|
return webviewsMapping;
|
|
279
269
|
};
|
|
280
|
-
|
|
281
270
|
helpers.getWebviewDetails = function getWebviewDetails(adb, webview) {
|
|
282
271
|
const key = toDetailsCacheKey(adb, webview);
|
|
283
272
|
return WEBVIEWS_DETAILS_CACHE.get(key);
|
|
284
273
|
};
|
|
285
|
-
|
|
286
274
|
helpers.createChromedriverCaps = function createChromedriverCaps(opts, deviceId, webViewDetails) {
|
|
287
275
|
var _opts$chromeOptions, _webViewDetails$info, _webViewDetails$proce, _webViewDetails$proce2, _opts$chromeOptions2;
|
|
288
276
|
const caps = {
|
|
@@ -357,4 +345,4 @@ helpers.createChromedriverCaps = function createChromedriverCaps(opts, deviceId,
|
|
|
357
345
|
};
|
|
358
346
|
var _default = helpers;
|
|
359
347
|
exports.default = _default;
|
|
360
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJOQVRJVkVfV0lOIiwiV0VCVklFV19XSU4iLCJDSFJPTUlVTV9XSU4iLCJXRUJWSUVXX0JBU0UiLCJXRUJWSUVXX1BJRF9QQVRURVJOIiwiUmVnRXhwIiwiV0VCVklFV19QS0dfUEFUVEVSTiIsIkRFVlRPT0xTX1NPQ0tFVF9QQVRURVJOIiwiQ1JPU1NXQUxLX1NPQ0tFVF9QQVRURVJOIiwiQ0hST01JVU1fREVWVE9PTFNfU09DS0VUIiwiQ0hST01FX1BBQ0tBR0VfTkFNRSIsIktOT1dOX0NIUk9NRV9QQUNLQUdFX05BTUVTIiwiREVWVE9PTFNfUE9SVFNfUkFOR0UiLCJXRUJWSUVXU19ERVRBSUxTX0NBQ0hFIiwiTFJVIiwibWF4IiwidXBkYXRlQWdlT25HZXQiLCJDRFBfUkVRX1RJTUVPVVQiLCJERVZUT09MU19QT1JUX0FMTE9DQVRJT05fR1VBUkQiLCJ1dGlsIiwiZ2V0TG9ja0ZpbGVHdWFyZCIsInBhdGgiLCJyZXNvbHZlIiwib3MiLCJ0bXBkaXIiLCJ0aW1lb3V0IiwidHJ5UmVjb3ZlcnkiLCJoZWxwZXJzIiwidG9EZXRhaWxzQ2FjaGVLZXkiLCJhZGIiLCJ3ZWJ2aWV3IiwiY3VyRGV2aWNlSWQiLCJnZXRQb3RlbnRpYWxXZWJ2aWV3UHJvY3MiLCJvdXQiLCJzaGVsbCIsIm5hbWVzIiwiYWxsTWF0Y2hlcyIsImxpbmUiLCJzcGxpdCIsImZsYWdzIiwic3QiLCJzb2NrUGF0aCIsInRyaW0iLCJzdGFydHNXaXRoIiwicHVzaCIsInRlc3QiLCJfIiwiaXNFbXB0eSIsImxvZ2dlciIsImRlYnVnIiwiSlNPTiIsInN0cmluZ2lmeSIsImxlbmd0aCIsInBsdXJhbGl6ZSIsInVuaXEiLCJ3ZWJ2aWV3c0Zyb21Qcm9jcyIsImRldmljZVNvY2tldCIsInNvY2tldE5hbWVzIiwid2Vidmlld3MiLCJzb2NrZXROYW1lIiwicHJvYyIsInNvY2tldE5hbWVNYXRjaCIsImV4ZWMiLCJjcm9zc3dhbGtNYXRjaCIsImFsbG9jYXRlRGV2dG9vbHNQb3J0Iiwid2Vidmlld0RldnRvb2xzUG9ydCIsInJlbW90ZVBvcnQiLCJyZXBsYWNlIiwic3RhcnRQb3J0IiwiZW5kUG9ydCIsImxvY2FsUG9ydCIsImZpbmRBUG9ydE5vdEluVXNlIiwiZSIsIkVycm9yIiwiYWRiRXhlYyIsImNvbGxlY3RXZWJ2aWV3c0RldGFpbHMiLCJ3ZWJ2aWV3c01hcHBpbmciLCJvcHRzIiwiZW5zdXJlV2Vidmlld3NIYXZlUGFnZXMiLCJlbmFibGVXZWJ2aWV3RGV0YWlsc0NvbGxlY3Rpb24iLCJpbmZvIiwiZGV0YWlsQ29sbGVjdG9ycyIsIml0ZW0iLCJjZHBJbmZvIiwicGFnZXMiLCJjZHBMaXN0IiwicmVtb3ZlUG9ydEZvcndhcmQiLCJCIiwiYWxsIiwiYXhpb3MiLCJ1cmwiLCJkYXRhIiwicHJvY0Zyb21XZWJ2aWV3IiwicGlkTWF0Y2giLCJwaWQiLCJwa2ciLCJnZXROYW1lQnlQaWQiLCJwYXJzZVdlYnZpZXdOYW1lcyIsImlzQ2hyb21lU2Vzc2lvbiIsInJlc3VsdCIsIndlYnZpZXdOYW1lIiwiZ2V0V2ViVmlld3NNYXBwaW5nIiwiYW5kcm9pZERldmljZVNvY2tldCIsIndlYnZpZXdNYXBwaW5nIiwid3ZOYW1lIiwicHJvY2VzcyIsInVuZGVmaW5lZCIsInBrZ01hdGNoIiwibmFtZSIsImlkIiwid2FybiIsIm1lc3NhZ2UiLCJrZXkiLCJzZXQiLCJoYXMiLCJkZWxldGUiLCJnZXRXZWJ2aWV3RGV0YWlscyIsImdldCIsImNyZWF0ZUNocm9tZWRyaXZlckNhcHMiLCJkZXZpY2VJZCIsIndlYlZpZXdEZXRhaWxzIiwiY2FwcyIsImNocm9tZU9wdGlvbnMiLCJhbmRyb2lkUGFja2FnZSIsImFwcFBhY2thZ2UiLCJpc0Jvb2xlYW4iLCJjaHJvbWVVc2VSdW5uaW5nQXBwIiwiYW5kcm9pZFVzZVJ1bm5pbmdBcHAiLCJjaHJvbWVBbmRyb2lkUGFja2FnZSIsImNocm9tZUFuZHJvaWRBY3Rpdml0eSIsImFuZHJvaWRBY3Rpdml0eSIsImNocm9tZUFuZHJvaWRQcm9jZXNzIiwiYW5kcm9pZFByb2Nlc3MiLCJ0b0xvd2VyIiwiYnJvd3Nlck5hbWUiLCJhcHBBY3Rpdml0eSIsInBhZ2VMb2FkU3RyYXRlZ3kiLCJpc0Nocm9tZSIsImluY2x1ZGVzIiwiYW5kcm9pZERldmljZVNlcmlhbCIsImlzUGxhaW5PYmplY3QiLCJsb2dnaW5nUHJlZnMiLCJjaHJvbWVMb2dnaW5nUHJlZnMiLCJlbmFibGVQZXJmb3JtYW5jZUxvZ2dpbmciLCJuZXdQcmVmIiwicGVyZm9ybWFuY2UiLCJPYmplY3QiLCJhc3NpZ24iLCJBcmd1bWVudHMiLCJhcmdzIiwicHJvdGVjdGVkQ2FwTmFtZXMiLCJvcHQiLCJ2YWwiLCJ0b1BhaXJzIiwiaXNVbmRlZmluZWQiLCJvcHROYW1lIl0sInNvdXJjZXMiOlsiLi4vLi4vbGliL3dlYnZpZXctaGVscGVycy5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IGxvZ2dlciBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IHsgdXRpbCB9IGZyb20gJ0BhcHBpdW0vc3VwcG9ydCc7XG5pbXBvcnQgeyBmaW5kQVBvcnROb3RJblVzZSB9IGZyb20gJ3BvcnRzY2FubmVyJztcbmltcG9ydCBMUlUgZnJvbSAnbHJ1LWNhY2hlJztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IG9zIGZyb20gJ29zJztcblxuY29uc3QgTkFUSVZFX1dJTiA9ICdOQVRJVkVfQVBQJztcbmNvbnN0IFdFQlZJRVdfV0lOID0gJ1dFQlZJRVcnO1xuY29uc3QgQ0hST01JVU1fV0lOID0gJ0NIUk9NSVVNJztcbmNvbnN0IFdFQlZJRVdfQkFTRSA9IGAke1dFQlZJRVdfV0lOfV9gO1xuY29uc3QgV0VCVklFV19QSURfUEFUVEVSTiA9IG5ldyBSZWdFeHAoYF4ke1dFQlZJRVdfQkFTRX0oXFxcXGQrKWApO1xuY29uc3QgV0VCVklFV19QS0dfUEFUVEVSTiA9IG5ldyBSZWdFeHAoYF4ke1dFQlZJRVdfQkFTRX0oW15cXFxcZFxcXFxzXVtcXFxcdy5dKilgKTtcbmNvbnN0IERFVlRPT0xTX1NPQ0tFVF9QQVRURVJOID0gL0BbXFx3Ll0rX2RldnRvb2xzX3JlbW90ZV8/KFxcZCspP1xcYi87XG5jb25zdCBDUk9TU1dBTEtfU09DS0VUX1BBVFRFUk4gPSAvQChbXFx3Ll0rKV9kZXZ0b29sc19yZW1vdGVcXGIvO1xuY29uc3QgQ0hST01JVU1fREVWVE9PTFNfU09DS0VUID0gJ2Nocm9tZV9kZXZ0b29sc19yZW1vdGUnO1xuY29uc3QgQ0hST01FX1BBQ0tBR0VfTkFNRSA9ICdjb20uYW5kcm9pZC5jaHJvbWUnO1xuY29uc3QgS05PV05fQ0hST01FX1BBQ0tBR0VfTkFNRVMgPSBbXG4gIENIUk9NRV9QQUNLQUdFX05BTUUsXG4gICdjb20uY2hyb21lLmJldGEnLFxuICAnY29tLmNocm9tZS5kZXYnLFxuICAnY29tLmNocm9tZS5jYW5hcnknLFxuXTtcbmNvbnN0IERFVlRPT0xTX1BPUlRTX1JBTkdFID0gWzEwOTAwLCAxMTAwMF07XG5jb25zdCBXRUJWSUVXU19ERVRBSUxTX0NBQ0hFID0gbmV3IExSVSh7XG4gIG1heDogMTAwLFxuICB1cGRhdGVBZ2VPbkdldDogdHJ1ZSxcbn0pO1xuY29uc3QgQ0RQX1JFUV9USU1FT1VUID0gMjAwMDsgLy8gbXNcbmNvbnN0IERFVlRPT0xTX1BPUlRfQUxMT0NBVElPTl9HVUFSRCA9IHV0aWwuZ2V0TG9ja0ZpbGVHdWFyZChcbiAgcGF0aC5yZXNvbHZlKG9zLnRtcGRpcigpLCAnYW5kcm9pZF9kZXZ0b29sc19wb3J0X2d1YXJkJyksXG4gIHt0aW1lb3V0OiA3LCB0cnlSZWNvdmVyeTogdHJ1ZX1cbik7XG5cbmNvbnN0IGhlbHBlcnMgPSB7fTtcblxuZnVuY3Rpb24gdG9EZXRhaWxzQ2FjaGVLZXkgKGFkYiwgd2Vidmlldykge1xuICByZXR1cm4gYCR7YWRiPy5jdXJEZXZpY2VJZH06JHt3ZWJ2aWV3fWA7XG59XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBnZXRzIGEgbGlzdCBvZiBhbmRyb2lkIHN5c3RlbSBwcm9jZXNzZXMgYW5kIHJldHVybnMgb25lc1xuICogdGhhdCBsb29rIGxpa2Ugd2Vidmlld3NcbiAqIFNlZSBodHRwczovL2NzLmNocm9taXVtLm9yZy9jaHJvbWl1bS9zcmMvY2hyb21lL2Jyb3dzZXIvZGV2dG9vbHMvZGV2aWNlL2FuZHJvaWRfZGV2aWNlX2luZm9fcXVlcnkuY2NcbiAqIGZvciBtb3JlIGRldGFpbHNcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gYWRiIC0gYW4gQURCIGluc3RhbmNlXG4gKlxuICogQHJldHVybiB7QXJyYXkuPHN0cmluZz59IC0gYSBsaXN0IG9mIG1hdGNoaW5nIHdlYnZpZXcgc29ja2V0IG5hbWVzIChpbmNsdWRpbmcgdGhlIGxlYWRpbmcgJ0AnKVxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRQb3RlbnRpYWxXZWJ2aWV3UHJvY3MgKGFkYikge1xuICBjb25zdCBvdXQgPSBhd2FpdCBhZGIuc2hlbGwoWydjYXQnLCAnL3Byb2MvbmV0L3VuaXgnXSk7XG4gIGNvbnN0IG5hbWVzID0gW107XG4gIGNvbnN0IGFsbE1hdGNoZXMgPSBbXTtcbiAgZm9yIChjb25zdCBsaW5lIG9mIG91dC5zcGxpdCgnXFxuJykpIHtcbiAgICAvLyBOdW0gUmVmQ291bnQgUHJvdG9jb2wgRmxhZ3MgVHlwZSBTdCBJbm9kZSBQYXRoXG4gICAgY29uc3QgWywsLCBmbGFncywsIHN0LCwgc29ja1BhdGhdID0gbGluZS50cmltKCkuc3BsaXQoL1xccysvKTtcbiAgICBpZiAoIXNvY2tQYXRoKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKHNvY2tQYXRoLnN0YXJ0c1dpdGgoJ0AnKSkge1xuICAgICAgYWxsTWF0Y2hlcy5wdXNoKGxpbmUudHJpbSgpKTtcbiAgICB9XG4gICAgaWYgKGZsYWdzICE9PSAnMDAwMTAwMDAnIHx8IHN0ICE9PSAnMDEnKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKCFERVZUT09MU19TT0NLRVRfUEFUVEVSTi50ZXN0KHNvY2tQYXRoKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgbmFtZXMucHVzaChzb2NrUGF0aCk7XG4gIH1cbiAgaWYgKF8uaXNFbXB0eShuYW1lcykpIHtcbiAgICBsb2dnZXIuZGVidWcoJ0ZvdW5kIG5vIGFjdGl2ZSBkZXZ0b29scyBzb2NrZXRzJyk7XG4gICAgaWYgKCFfLmlzRW1wdHkoYWxsTWF0Y2hlcykpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgT3RoZXIgc29ja2V0cyBhcmU6ICR7SlNPTi5zdHJpbmdpZnkoYWxsTWF0Y2hlcywgbnVsbCwgMil9YCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGxvZ2dlci5kZWJ1ZyhgUGFyc2VkICR7bmFtZXMubGVuZ3RofSBhY3RpdmUgZGV2dG9vbHMgJHt1dGlsLnBsdXJhbGl6ZSgnc29ja2V0JywgbmFtZXMubGVuZ3RoLCBmYWxzZSl9OiBgICtcbiAgICAgIEpTT04uc3RyaW5naWZ5KG5hbWVzKSk7XG4gIH1cbiAgLy8gc29tZXRpbWVzIHRoZSB3ZWJ2aWV3IHByb2Nlc3Mgc2hvd3MgdXAgbXVsdGlwbGUgdGltZXMgcGVyIGFwcFxuICByZXR1cm4gXy51bmlxKG5hbWVzKTtcbn1cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBXZWJ2aWV3UHJvY1xuICogQHByb3BlcnR5IHtzdHJpbmd9IHByb2MgLSBUaGUgd2VidmlldyBwcm9jZXNzIG5hbWUgKGFzIHJldHVybmVkIGJ5XG4gKiBnZXRQb3RlbnRpYWxXZWJ2aWV3UHJvY3NcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB3ZWJ2aWV3IC0gVGhlIGFjdHVhbCB3ZWJ2aWV3IGNvbnRleHQgbmFtZVxuICovXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gcmV0cmlldmVzIGEgbGlzdCBvZiBzeXN0ZW0gcHJvY2Vzc2VzIHRoYXQgbG9vayBsaWtlIHdlYnZpZXdzLFxuICogYW5kIHJldHVybnMgdGhlbSBhbG9uZyB3aXRoIHRoZSB3ZWJ2aWV3IGNvbnRleHQgbmFtZSBhcHByb3ByaWF0ZSBmb3IgaXQuXG4gKiBJZiB3ZSBwYXNzIGluIGEgZGV2aWNlU29ja2V0LCB3ZSBvbmx5IGF0dGVtcHQgdG8gZmluZCB3ZWJ2aWV3cyB3aGljaCBtYXRjaFxuICogdGhhdCBzb2NrZXQgbmFtZSAodGhpcyBpcyBmb3IgYXBwcyB3aGljaCBlbWJlZCBDaHJvbWl1bSwgd2hpY2ggaXNuJ3QgdGhlXG4gKiBzYW1lIGFzIGNocm9tZS1iYWNrZWQgd2Vidmlld3MpLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBhZGIgLSBhbiBBREIgaW5zdGFuY2VcbiAqIEBwYXJhbSB7P3N0cmluZ30gZGV2aWNlU29ja2V0IC0gdGhlIGV4cGxpY3RseS1uYW1lZCBkZXZpY2Ugc29ja2V0IHRvIHVzZVxuICpcbiAqIEByZXR1cm4ge0FycmF5LjxXZWJ2aWV3UHJvYz59XG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHdlYnZpZXdzRnJvbVByb2NzIChhZGIsIGRldmljZVNvY2tldCA9IG51bGwpIHtcbiAgY29uc3Qgc29ja2V0TmFtZXMgPSBhd2FpdCBnZXRQb3RlbnRpYWxXZWJ2aWV3UHJvY3MoYWRiKTtcbiAgY29uc3Qgd2Vidmlld3MgPSBbXTtcbiAgZm9yIChjb25zdCBzb2NrZXROYW1lIG9mIHNvY2tldE5hbWVzKSB7XG4gICAgaWYgKGRldmljZVNvY2tldCA9PT0gQ0hST01JVU1fREVWVE9PTFNfU09DS0VUICYmIHNvY2tldE5hbWUgPT09IGBAJHtkZXZpY2VTb2NrZXR9YCkge1xuICAgICAgd2Vidmlld3MucHVzaCh7XG4gICAgICAgIHByb2M6IHNvY2tldE5hbWUsXG4gICAgICAgIHdlYnZpZXc6IENIUk9NSVVNX1dJTixcbiAgICAgIH0pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3Qgc29ja2V0TmFtZU1hdGNoID0gREVWVE9PTFNfU09DS0VUX1BBVFRFUk4uZXhlYyhzb2NrZXROYW1lKTtcbiAgICBpZiAoIXNvY2tldE5hbWVNYXRjaCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IGNyb3Nzd2Fsa01hdGNoID0gQ1JPU1NXQUxLX1NPQ0tFVF9QQVRURVJOLmV4ZWMoc29ja2V0TmFtZSk7XG4gICAgaWYgKCFzb2NrZXROYW1lTWF0Y2hbMV0gJiYgIWNyb3Nzd2Fsa01hdGNoKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoZGV2aWNlU29ja2V0ICYmIHNvY2tldE5hbWUgPT09IGBAJHtkZXZpY2VTb2NrZXR9YCB8fCAhZGV2aWNlU29ja2V0KSB7XG4gICAgICB3ZWJ2aWV3cy5wdXNoKHtcbiAgICAgICAgcHJvYzogc29ja2V0TmFtZSxcbiAgICAgICAgd2Vidmlldzogc29ja2V0TmFtZU1hdGNoWzFdXG4gICAgICAgICAgPyBgJHtXRUJWSUVXX0JBU0V9JHtzb2NrZXROYW1lTWF0Y2hbMV19YFxuICAgICAgICAgIDogYCR7V0VCVklFV19CQVNFfSR7Y3Jvc3N3YWxrTWF0Y2hbMV19YCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gd2Vidmlld3M7XG59XG5cbi8qKlxuICogQWxsb2NhdGVzIGEgbG9jYWwgcG9ydCBmb3IgZGV2dG9vbHMgY29tbXVuaWNhdGlvblxuICpcbiAqIEBwYXJhbSB7QURCfSBhZGIgQURCIGluc3RhbmNlXG4gKiBAcGFyYW0ge3N0cmluZ30gc29ja2V0TmFtZSBUaGUgcmVtb3RlIFVuaXggc29ja2V0IG5hbWVcbiAqIEBwYXJhbSB7P251bWJlcn0gd2Vidmlld0RldnRvb2xzUG9ydCBUaGUgbG9jYWwgcG9ydCBudW1iZXIgb3IgbnVsbCB0byBhcHBseVxuICogYXV0b2RldGVjdGlvblxuICogQHJldHVybnMge251bWJlcn0gVGhlIGxvY2FsIHBvcnQgbnVtYmVyIGlmIHRoZSByZW1vdGUgc29ja2V0IGhhcyBiZWVuIGZvcndhcmRlZFxuICogc3VjY2Vzc2Z1bGx5IG9yIGBudWxsYCBvdGhlcndpc2VcbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGVyZSB3YXMgYW4gZXJyb3Igd2hpbGUgYWxsb2NhdGluZyB0aGUgbG9jYWwgcG9ydFxuICovXG5hc3luYyBmdW5jdGlvbiBhbGxvY2F0ZURldnRvb2xzUG9ydCAoYWRiLCBzb2NrZXROYW1lLCB3ZWJ2aWV3RGV2dG9vbHNQb3J0ID0gbnVsbCkge1xuICAvLyBzb2NrZXQgbmFtZXMgY29tZSB3aXRoICdAJywgYnV0IHRoaXMgc2hvdWxkIG5vdCBiZSBhIHBhcnQgb2YgdGhlIGFic3RyYWN0XG4gIC8vIHJlbW90ZSBwb3J0LCBzbyByZW1vdmUgaXRcbiAgY29uc3QgcmVtb3RlUG9ydCA9IHNvY2tldE5hbWUucmVwbGFjZSgvXkAvLCAnJyk7XG4gIGxldCBbc3RhcnRQb3J0LCBlbmRQb3J0XSA9IERFVlRPT0xTX1BPUlRTX1JBTkdFO1xuICBpZiAod2Vidmlld0RldnRvb2xzUG9ydCkge1xuICAgIGVuZFBvcnQgPSB3ZWJ2aWV3RGV2dG9vbHNQb3J0ICsgKGVuZFBvcnQgLSBzdGFydFBvcnQpO1xuICAgIHN0YXJ0UG9ydCA9IHdlYnZpZXdEZXZ0b29sc1BvcnQ7XG4gIH1cbiAgbG9nZ2VyLmRlYnVnKGBGb3J3YXJkaW5nIHJlbW90ZSBwb3J0ICR7cmVtb3RlUG9ydH0gdG8gYSBsb2NhbCBgICtcbiAgICBgcG9ydCBpbiByYW5nZSAke3N0YXJ0UG9ydH0uLiR7ZW5kUG9ydH1gKTtcbiAgaWYgKCF3ZWJ2aWV3RGV2dG9vbHNQb3J0KSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBZb3UgY291bGQgdXNlIHRoZSAnd2Vidmlld0RldnRvb2xzUG9ydCcgY2FwYWJpbGl0eSB0byBjdXN0b21pemUgYCArXG4gICAgICBgdGhlIHN0YXJ0aW5nIHBvcnQgbnVtYmVyYCk7XG4gIH1cbiAgcmV0dXJuIGF3YWl0IERFVlRPT0xTX1BPUlRfQUxMT0NBVElPTl9HVUFSRChhc3luYyAoKSA9PiB7XG4gICAgbGV0IGxvY2FsUG9ydDtcbiAgICB0cnkge1xuICAgICAgbG9jYWxQb3J0ID0gYXdhaXQgZmluZEFQb3J0Tm90SW5Vc2Uoc3RhcnRQb3J0LCBlbmRQb3J0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBmaW5kIGFueSBmcmVlIHBvcnQgdG8gZm9yd2FyZCB0aGUgRGV2dG9vbHMgc29ja2V0IGAgK1xuICAgICAgICBgaW4gcmFuZ2UgJHtzdGFydFBvcnR9Li4ke2VuZFBvcnR9LiBZb3UgY291bGQgc2V0IHRoZSBzdGFydGluZyBwb3J0IG51bWJlciBgICtcbiAgICAgICAgYG1hbnVhbGx5IGJ5IHByb3ZpZGluZyB0aGUgJ3dlYnZpZXdEZXZ0b29sc1BvcnQnIGNhcGFiaWxpdHlgKTtcbiAgICB9XG4gICAgYXdhaXQgYWRiLmFkYkV4ZWMoWydmb3J3YXJkJywgYHRjcDoke2xvY2FsUG9ydH1gLCBgbG9jYWxhYnN0cmFjdDoke3JlbW90ZVBvcnR9YF0pO1xuICAgIHJldHVybiBsb2NhbFBvcnQ7XG4gIH0pO1xufVxuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFdlYnZpZXdQcm9wc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IHByb2MgVGhlIG5hbWUgb2YgdGhlIERldnRvb2xzIFVuaXggc29ja2V0XG4gKiBAcHJvcGVydHkge3N0cmluZ30gd2VidmlldyBUaGUgd2ViIHZpZXcgYWxpYXMuIExvb2tzIGxpa2UgYFdFQlZJRVdfYFxuICogcHJlZml4IHBsdXMgUElEIG9yIHBhY2thZ2UgbmFtZVxuICogQHByb3BlcnR5IHs/T2JqZWN0fSBpbmZvIFdlYnZpZXcgaW5mb3JtYXRpb24gYXMgaXQgaXMgcmV0cmlldmVkIGJ5XG4gKiAvanNvbi92ZXJzaW9uIENEUCBlbmRwb2ludFxuICogQHByb3BlcnR5IHs/QXJyYXk8T2JqZWN0Pn0gcGFnZXMgV2VidmlldyBwYWdlcyBsaXN0IGFzIGl0IGlzIHJldHJpZXZlZCBieVxuICogL2pzb24vbGlzdCBDRFAgZW5kcG9pbnRcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IERldGFpbENvbGxlY3Rpb25PcHRpb25zXG4gKiBAcHJvcGVydHkgez9zdHJpbmd8bnVtYmVyfSB3ZWJ2aWV3RGV2dG9vbHNQb3J0IFRoZSBzdGFydGluZyBwb3J0IHRvIHVzZSBmb3Igd2VidmlldyBwYWdlXG4gKiBwcmVzZW5jZSBjaGVjayAoaWYgbm90IHRoZSBkZWZhdWx0IG9mIDkyMjIpLlxuICogQHByb3BlcnR5IHs/Ym9vbGVhbn0gZW5zdXJlV2Vidmlld3NIYXZlUGFnZXMgV2hldGhlciB0byBjaGVjayBmb3Igd2Vidmlld1xuICogcGFnZXMgcHJlc2VuY2VcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gZW5hYmxlV2Vidmlld0RldGFpbHNDb2xsZWN0aW9uIFdoZXRoZXIgdG8gY29sbGVjdFxuICogd2ViIHZpZXcgZGV0YWlscyBhbmQgc2VuZCB0aGVtIHRvIENocm9tZWRyaXZlciBjb25zdHJ1Y3Rvciwgc28gaXQgY291bGRcbiAqIHNlbGVjdCBhIGJpbmFyeSBtb3JlIHByZWNpc2VseSBiYXNlZCBvbiB0aGlzIGluZm8uXG4gKi9cblxuLyoqXG4gKiBUaGlzIGlzIGEgd3JhcHBlciBmb3IgQ2hyb21lIERlYnVnZ2VyIFByb3RvY29sIGRhdGEgY29sbGVjdGlvbi5cbiAqIE5vIGVycm9yIGlzIHRocm93biBpZiBDRFAgcmVxdWVzdCBmYWlscyAtIGluIHN1Y2ggY2FzZSBubyBkYXRhIHdpbGwgYmVcbiAqIHJlY29yZGVkIGludG8gdGhlIGNvcnJlc3BvbmRpbmcgYHdlYnZpZXdzTWFwcGluZ2AgaXRlbS5cbiAqXG4gKiBAcGFyYW0ge0FEQn0gYWRiIFRoZSBBREIgaW5zdGFuY2VcbiAqIEBwYXJhbSB7QXJyYXk8V2Vidmlld1Byb3BzPn0gd2Vidmlld3NNYXBwaW5nIFRoZSBjdXJyZW50IHdlYnZpZXdzIG1hcHBpbmdcbiAqICEhISBFYWNoIGl0ZW0gb2YgdGhpcyBhcnJheSBnZXRzIG11dGF0ZWQgKGBpbmZvYC9gcGFnZXNgIHByb3BlcnRpZXMgZ2V0IGFkZGVkXG4gKiBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgYG9wdHNgKSBpZiB0aGUgcmVxdWVzdGVkIGRldGFpbHMgaGF2ZSBiZWVuXG4gKiBzdWNjZXNzZnVsbHkgcmV0cmlldmVkIGZvciBpdCAhISFcbiAqIEBwYXJhbSB7RGV0YWlsQ29sbGVjdGlvbk9wdGlvbnN9IG9wdHMgSWYgYm90aCBgZW5zdXJlV2Vidmlld3NIYXZlUGFnZXNgIGFuZFxuICogYGVuYWJsZVdlYnZpZXdEZXRhaWxzQ29sbGVjdGlvbmAgcHJvcGVydGllcyBhcmUgZmFsc3kgdGhlbiBubyBkZXRhaWxzIGNvbGxlY3Rpb25cbiAqIGlzIHBlcmZvcm1lZFxuICovXG5hc3luYyBmdW5jdGlvbiBjb2xsZWN0V2Vidmlld3NEZXRhaWxzIChhZGIsIHdlYnZpZXdzTWFwcGluZywgb3B0cyA9IHt9KSB7XG4gIGlmIChfLmlzRW1wdHkod2Vidmlld3NNYXBwaW5nKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHtcbiAgICB3ZWJ2aWV3RGV2dG9vbHNQb3J0ID0gbnVsbCxcbiAgICBlbnN1cmVXZWJ2aWV3c0hhdmVQYWdlcyA9IG51bGwsXG4gICAgZW5hYmxlV2Vidmlld0RldGFpbHNDb2xsZWN0aW9uID0gbnVsbCxcbiAgfSA9IG9wdHM7XG5cbiAgaWYgKCFlbnN1cmVXZWJ2aWV3c0hhdmVQYWdlcykge1xuICAgIGxvZ2dlci5pbmZvKGBOb3QgY2hlY2tpbmcgd2hldGhlciB3ZWJ2aWV3cyBoYXZlIGFjdGl2ZSBwYWdlczsgdXNlIHRoZSBgICtcbiAgICAgIGAnZW5zdXJlV2Vidmlld3NIYXZlUGFnZXMnIGNhcCB0byB0dXJuIHRoaXMgY2hlY2sgb25gKTtcbiAgfVxuXG4gIGlmICghZW5hYmxlV2Vidmlld0RldGFpbHNDb2xsZWN0aW9uKSB7XG4gICAgbG9nZ2VyLmluZm8oYE5vdCBjb2xsZWN0aW5nIHdlYiB2aWV3IGRldGFpbHMuIERldGFpbHMgY29sbGVjdGlvbiBtaWdodCBoZWxwIGAgK1xuICAgICAgYHRvIG1ha2UgQ2hyb21lZHJpdmVyIGluaXRpYWxpemF0aW9uIG1vcmUgcHJlY2lzZS4gVXNlIHRoZSAnZW5hYmxlV2Vidmlld0RldGFpbHNDb2xsZWN0aW9uJyBgICtcbiAgICAgIGBjYXAgdG8gdHVybiBpdCBvbmApO1xuICB9XG5cbiAgaWYgKCFlbnN1cmVXZWJ2aWV3c0hhdmVQYWdlcyAmJiAhZW5hYmxlV2Vidmlld0RldGFpbHNDb2xsZWN0aW9uKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gQ29ubmVjdCB0byBlYWNoIGRldnRvb2xzIHNvY2tldCBhbmQgcmV0cmlldmUgd2ViIHZpZXcgZGV0YWlsc1xuICBsb2dnZXIuZGVidWcoYENvbGxlY3RpbmcgQ0RQIGRhdGEgb2YgJHt1dGlsLnBsdXJhbGl6ZSgnd2VidmlldycsIHdlYnZpZXdzTWFwcGluZy5sZW5ndGgsIHRydWUpfWApO1xuICBjb25zdCBkZXRhaWxDb2xsZWN0b3JzID0gW107XG4gIGZvciAoY29uc3QgaXRlbSBvZiB3ZWJ2aWV3c01hcHBpbmcpIHtcbiAgICBkZXRhaWxDb2xsZWN0b3JzLnB1c2goKGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBsb2NhbFBvcnQ7XG4gICAgICB0cnkge1xuICAgICAgICBsb2NhbFBvcnQgPSBhd2FpdCBhbGxvY2F0ZURldnRvb2xzUG9ydChhZGIsIGl0ZW0ucHJvYywgd2Vidmlld0RldnRvb2xzUG9ydCk7XG4gICAgICAgIGlmIChlbmFibGVXZWJ2aWV3RGV0YWlsc0NvbGxlY3Rpb24pIHtcbiAgICAgICAgICBpdGVtLmluZm8gPSBhd2FpdCBjZHBJbmZvKGxvY2FsUG9ydCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVuc3VyZVdlYnZpZXdzSGF2ZVBhZ2VzKSB7XG4gICAgICAgICAgaXRlbS5wYWdlcyA9IGF3YWl0IGNkcExpc3QobG9jYWxQb3J0KTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsb2dnZXIuZGVidWcoZSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBpZiAobG9jYWxQb3J0KSB7XG4gICAgICAgICAgYXdhaXQgYWRiLnJlbW92ZVBvcnRGb3J3YXJkKGxvY2FsUG9ydCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KSgpKTtcbiAgfVxuICBhd2FpdCBCLmFsbChkZXRhaWxDb2xsZWN0b3JzKTtcbiAgbG9nZ2VyLmRlYnVnKGBDRFAgZGF0YSBjb2xsZWN0aW9uIGNvbXBsZXRlZGApO1xufVxuXG4vLyBodHRwczovL2Nocm9tZWRldnRvb2xzLmdpdGh1Yi5pby9kZXZ0b29scy1wcm90b2NvbC9cbmFzeW5jIGZ1bmN0aW9uIGNkcExpc3QgKGxvY2FsUG9ydCkge1xuICByZXR1cm4gKGF3YWl0IGF4aW9zKHtcbiAgICB1cmw6IGBodHRwOi8vMTI3LjAuMC4xOiR7bG9jYWxQb3J0fS9qc29uL2xpc3RgLFxuICAgIHRpbWVvdXQ6IENEUF9SRVFfVElNRU9VVCxcbiAgfSkpLmRhdGE7XG59XG5cbi8vIGh0dHBzOi8vY2hyb21lZGV2dG9vbHMuZ2l0aHViLmlvL2RldnRvb2xzLXByb3RvY29sL1xuYXN5bmMgZnVuY3Rpb24gY2RwSW5mbyAobG9jYWxQb3J0KSB7XG4gIHJldHVybiAoYXdhaXQgYXhpb3Moe1xuICAgIHVybDogYGh0dHA6Ly8xMjcuMC4wLjE6JHtsb2NhbFBvcnR9L2pzb24vdmVyc2lvbmAsXG4gICAgdGltZW91dDogQ0RQX1JFUV9USU1FT1VULFxuICB9KSkuZGF0YTtcbn1cblxuLyoqXG4gKiBUYWtlIGEgd2VidmlldyBuYW1lIGxpa2UgV0VCVklFV180Mjk2IGFuZCB1c2UgJ2FkYiBzaGVsbCBwcycgdG8gZmlndXJlIG91dFxuICogd2hpY2ggYXBwIHBhY2thZ2UgaXMgYXNzb2NpYXRlZCB3aXRoIHRoYXQgd2Vidmlldy4gT25lIG9mIHRoZSByZWFzb25zIHdlXG4gKiB3YW50IHRvIGRvIHRoaXMgaXMgdG8gbWFrZSBzdXJlIHdlJ3JlIGxpc3Rpbmcgd2Vidmlld3MgZm9yIHRoZSBhY3R1YWwgQVVULFxuICogbm90IHNvbWUgb3RoZXIgcnVubmluZyBhcHBcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gYWRiIC0gYW4gQURCIGluc3RhbmNlXG4gKiBAcGFyYW0ge3N0cmluZ30gd2VidmlldyAtIGEgd2VidmlldyBwcm9jZXNzIG5hbWVcbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSAtIHRoZSBwYWNrYWdlIG5hbWUgb2YgdGhlIGFwcCBydW5uaW5nIHRoZSB3ZWJ2aWV3XG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlcmUgd2FzIGEgZmFpbHVyZSB3aGlsZSByZXRyaWV2aW5nIHRoZSBwcm9jZXNzIG5hbWVcbiAqL1xuaGVscGVycy5wcm9jRnJvbVdlYnZpZXcgPSBhc3luYyBmdW5jdGlvbiBwcm9jRnJvbVdlYnZpZXcgKGFkYiwgd2Vidmlldykge1xuICBjb25zdCBwaWRNYXRjaCA9IFdFQlZJRVdfUElEX1BBVFRFUk4uZXhlYyh3ZWJ2aWV3KTtcbiAgaWYgKCFwaWRNYXRjaCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgQ291bGQgbm90IGZpbmQgUElEIGZvciB3ZWJ2aWV3ICcke3dlYnZpZXd9J2ApO1xuICB9XG5cbiAgY29uc3QgcGlkID0gcGlkTWF0Y2hbMV07XG4gIGxvZ2dlci5kZWJ1ZyhgJHt3ZWJ2aWV3fSBtYXBwZWQgdG8gcGlkICR7cGlkfWApO1xuICBsb2dnZXIuZGVidWcoYEdldHRpbmcgcHJvY2VzcyBuYW1lIGZvciB3ZWJ2aWV3ICcke3dlYnZpZXd9J2ApO1xuICBjb25zdCBwa2cgPSBhd2FpdCBhZGIuZ2V0TmFtZUJ5UGlkKHBpZCk7XG4gIGxvZ2dlci5kZWJ1ZyhgR290IHByb2Nlc3MgbmFtZTogJyR7cGtnfSdgKTtcbiAgcmV0dXJuIHBrZztcbn07XG5cbi8qKlxuICogUGFyc2Ugd2VidmlldyBuYW1lcyBmb3IgZ2V0Q29udGV4dHNcbiAqXG4gKiBAcGFyYW0ge0FycmF5PFdlYnZpZXdzTWFwcGluZz59IHdlYnZpZXdzTWFwcGluZyBTZWUgbm90ZSBvbiBnZXRXZWJWaWV3c01hcHBpbmdcbiAqIEBwYXJhbSB7R2V0V2Vidmlld3NPcHRzfSBvcHRzIFNlZSBub3RlIG9uIGdldFdlYlZpZXdzTWFwcGluZ1xuICogQHJldHVybiB7QXJyYXkuPHN0cmluZz59IC0gYSBsaXN0IG9mIHdlYnZpZXcgbmFtZXNcbiAqL1xuaGVscGVycy5wYXJzZVdlYnZpZXdOYW1lcyA9IGZ1bmN0aW9uIHBhcnNlV2Vidmlld05hbWVzICh3ZWJ2aWV3c01hcHBpbmcsIHtcbiAgZW5zdXJlV2Vidmlld3NIYXZlUGFnZXMgPSB0cnVlLFxuICBpc0Nocm9tZVNlc3Npb24gPSBmYWxzZVxufSA9IHt9KSB7XG4gIGlmIChpc0Nocm9tZVNlc3Npb24pIHtcbiAgICByZXR1cm4gW0NIUk9NSVVNX1dJTl07XG4gIH1cblxuICBjb25zdCByZXN1bHQgPSBbXTtcbiAgZm9yIChjb25zdCB7d2VidmlldywgcGFnZXMsIHByb2MsIHdlYnZpZXdOYW1lfSBvZiB3ZWJ2aWV3c01hcHBpbmcpIHtcbiAgICBpZiAoZW5zdXJlV2Vidmlld3NIYXZlUGFnZXMgJiYgcGFnZXM/Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgbG9nZ2VyLmluZm8oYFNraXBwaW5nIHRoZSB3ZWJ2aWV3ICcke3dlYnZpZXd9JyBhdCAnJHtwcm9jfScgYCArXG4gICAgICAgIGBzaW5jZSBpdCBoYXMgcmVwb3J0ZWQgaGF2aW5nIHplcm8gcGFnZXNgKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAod2Vidmlld05hbWUpIHtcbiAgICAgIHJlc3VsdC5wdXNoKHdlYnZpZXdOYW1lKTtcbiAgICB9XG4gIH1cbiAgbG9nZ2VyLmRlYnVnKGBGb3VuZCAke3V0aWwucGx1cmFsaXplKCd3ZWJ2aWV3JywgcmVzdWx0Lmxlbmd0aCwgdHJ1ZSl9OiAke0pTT04uc3RyaW5naWZ5KHJlc3VsdCl9YCk7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEdldFdlYnZpZXdzT3B0c1xuICogQHByb3BlcnR5IHtzdHJpbmd9IGFuZHJvaWREZXZpY2VTb2NrZXQgW251bGxdIC0gZGV2aWNlIHNvY2tldCBuYW1lXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGVuc3VyZVdlYnZpZXdzSGF2ZVBhZ2VzIFt0cnVlXSAtIHdoZXRoZXIgdG8gY2hlY2sgZm9yIHdlYnZpZXdcbiAqIHBhZ2UgcHJlc2VuY2VcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB3ZWJ2aWV3RGV2dG9vbHNQb3J0IFs5MjIyXSAtIHBvcnQgdG8gdXNlIGZvciB3ZWJ2aWV3IHBhZ2VcbiAqIHByZXNlbmNlIGNoZWNrLlxuICogQHByb3BlcnR5IHtib29sZWFufSBlbmFibGVXZWJ2aWV3RGV0YWlsc0NvbGxlY3Rpb24gW3RydWVdIC0gd2hldGhlciB0byBjb2xsZWN0XG4gKiB3ZWIgdmlldyBkZXRhaWxzIGFuZCBzZW5kIHRoZW0gdG8gQ2hyb21lZHJpdmVyIGNvbnN0cnVjdG9yLCBzbyBpdCBjb3VsZFxuICogc2VsZWN0IGEgYmluYXJ5IG1vcmUgcHJlY2lzZWx5IGJhc2VkIG9uIHRoaXMgaW5mby5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFdlYnZpZXdzTWFwcGluZ1xuICogQHByb3BlcnR5IHtzdHJpbmd9IHByb2MgU2VlIG5vdGUgb24gV2Vidmlld1Byb3BzXG4gKiBAcHJvcGVydHkge3N0cmluZ30gd2VidmlldyBTZWUgbm90ZSBvbiBXZWJ2aWV3UHJvcHNcbiAqIEBwcm9wZXJ0eSB7P09iamVjdH0gaW5mbyBTZWUgbm90ZSBvbiBXZWJ2aWV3UHJvcHNcbiAqIEBwcm9wZXJ0eSB7P0FycmF5PE9iamVjdD59IHBhZ2VzIFNlZSBub3RlIG9uIFdlYnZpZXdQcm9wc1xuICogQHByb3Blcnkgez9zdHJpbmd9IHdlYnZpZXdOYW1lIEFuIGFjdHVhbCB3ZWJ2aWV3IG5hbWUgZm9yIHN3aXRjaGluZyBjb250ZXh0XG4gKi9cblxuLyoqXG4gKiBHZXQgYSBsaXN0IG9mIGF2YWlsYWJsZSB3ZWJ2aWV3cyBtYXBwaW5nIGJ5IGludHJvc3BlY3RpbmcgcHJvY2Vzc2VzIHdpdGggYWRiLFxuICogd2hlcmUgd2Vidmlld3MgYXJlIGxpc3RlZC4gSXQncyBwb3NzaWJsZSB0byBwYXNzIGluIGEgJ2RldmljZVNvY2tldCcgYXJnLCB3aGljaFxuICogbGltaXRzIHRoZSB3ZWJ2aWV3IHBvc3NpYmlsaXRpZXMgdG8gdGhlIG9uZSBydW5uaW5nIG9uIHRoZSBDaHJvbWl1bSBkZXZ0b29sc1xuICogc29ja2V0IHdlJ3JlIGludGVyZXN0ZWQgaW4gKHNlZSBub3RlIG9uIHdlYnZpZXdzRnJvbVByb2NzKS4gV2UgY2FuIGFsc29cbiAqIGRpcmVjdCB0aGlzIG1ldGhvZCB0byB2ZXJpZnkgd2hldGhlciBhIHBhcnRpY3VsYXIgd2VidmlldyBwcm9jZXNzIGFjdHVhbGx5XG4gKiBoYXMgYW55IHBhZ2VzIChpZiBhIHByb2Nlc3MgZXhpc3RzIGJ1dCBubyBwYWdlcyBhcmUgZm91bmQsIENocm9tZWRyaXZlciB3aWxsXG4gKiBub3QgYWN0dWFsbHkgYmUgYWJsZSB0byBjb25uZWN0IHRvIGl0LCBzbyB0aGlzIHNlcnZlcyBhcyBhIGd1YXJkIGZvciB0aGF0XG4gKiBzdHJhbmdlIGZhaWx1cmUgbW9kZSkuIFRoZSBzdHJhdGVneSBmb3IgY2hlY2tpbmcgd2hldGhlciBhbnkgcGFnZXMgYXJlXG4gKiBhY3RpdmUgaW52b2x2ZXMgc2VuZGluZyBhIHJlcXVlc3QgdG8gdGhlIHJlbW90ZSBkZWJ1ZyBzZXJ2ZXIgb24gdGhlIGRldmljZSxcbiAqIGhlbmNlIGl0IGlzIGFsc28gcG9zc2libGUgdG8gc3BlY2lmeSB0aGUgcG9ydCBvbiB0aGUgaG9zdCBtYWNoaW5lIHdoaWNoXG4gKiBzaG91bGQgYmUgdXNlZCBmb3IgdGhpcyBjb21tdW5pY2F0aW9uLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBhZGIgLSBhbiBBREIgaW5zdGFuY2VcbiAqIEBwYXJhbSB7R2V0V2Vidmlld3NPcHRzfSBvcHRzXG4gKlxuICogQHJldHVybiB7QXJyYXk8V2Vidmlld3NNYXBwaW5nPn0gd2Vidmlld3NNYXBwaW5nXG4gKi9cbmhlbHBlcnMuZ2V0V2ViVmlld3NNYXBwaW5nID0gYXN5bmMgZnVuY3Rpb24gZ2V0V2ViVmlld3NNYXBwaW5nIChhZGIsIHtcbiAgYW5kcm9pZERldmljZVNvY2tldCA9IG51bGwsXG4gIGVuc3VyZVdlYnZpZXdzSGF2ZVBhZ2VzID0gdHJ1ZSxcbiAgd2Vidmlld0RldnRvb2xzUG9ydCA9IG51bGwsXG4gIGVuYWJsZVdlYnZpZXdEZXRhaWxzQ29sbGVjdGlvbiA9IHRydWVcbn0gPSB7fSkge1xuICBsb2dnZXIuZGVidWcoJ0dldHRpbmcgYSBsaXN0IG9mIGF2YWlsYWJsZSB3ZWJ2aWV3cycpO1xuICBjb25zdCB3ZWJ2aWV3c01hcHBpbmcgPSBhd2FpdCB3ZWJ2aWV3c0Zyb21Qcm9jcyhhZGIsIGFuZHJvaWREZXZpY2VTb2NrZXQpO1xuXG4gIGF3YWl0IGNvbGxlY3RXZWJ2aWV3c0RldGFpbHMoYWRiLCB3ZWJ2aWV3c01hcHBpbmcsIHtcbiAgICBlbnN1cmVXZWJ2aWV3c0hhdmVQYWdlcyxcbiAgICBlbmFibGVXZWJ2aWV3RGV0YWlsc0NvbGxlY3Rpb24sXG4gICAgd2Vidmlld0RldnRvb2xzUG9ydCxcbiAgfSk7XG5cbiAgZm9yIChjb25zdCB3ZWJ2aWV3TWFwcGluZyBvZiB3ZWJ2aWV3c01hcHBpbmcpIHtcbiAgICBjb25zdCB7d2VidmlldywgaW5mb30gPSB3ZWJ2aWV3TWFwcGluZztcbiAgICB3ZWJ2aWV3TWFwcGluZy53ZWJ2aWV3TmFtZSA9IG51bGw7XG5cbiAgICBsZXQgd3ZOYW1lID0gd2VidmlldztcbiAgICBsZXQgcHJvY2VzcyA9IHVuZGVmaW5lZDtcbiAgICBpZiAoIWFuZHJvaWREZXZpY2VTb2NrZXQpIHtcbiAgICAgIGNvbnN0IHBrZ01hdGNoID0gV0VCVklFV19QS0dfUEFUVEVSTi5leGVjKHdlYnZpZXcpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gd2ViIHZpZXcgbmFtZSBjb3VsZCBlaXRoZXIgYmUgc3VmZml4ZWQgd2l0aCBQSUQgb3IgdGhlIHBhY2thZ2UgbmFtZVxuICAgICAgICAvLyBwYWNrYWdlIG5hbWVzIGNvdWxkIG5vdCBzdGFydCB3aXRoIGEgZGlnaXRcbiAgICAgICAgY29uc3QgcGtnID0gcGtnTWF0Y2ggPyBwa2dNYXRjaFsxXSA6IGF3YWl0IGhlbHBlcnMucHJvY0Zyb21XZWJ2aWV3KGFkYiwgd2Vidmlldyk7XG4gICAgICAgIHd2TmFtZSA9IGAke1dFQlZJRVdfQkFTRX0ke3BrZ31gO1xuICAgICAgICBjb25zdCBwaWRNYXRjaCA9IFdFQlZJRVdfUElEX1BBVFRFUk4uZXhlYyh3ZWJ2aWV3KTtcbiAgICAgICAgcHJvY2VzcyA9IHtcbiAgICAgICAgICBuYW1lOiBwa2csXG4gICAgICAgICAgaWQ6IHBpZE1hdGNoID8gcGlkTWF0Y2hbMV0gOiBudWxsLFxuICAgICAgICB9O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsb2dnZXIud2FybihlLm1lc3NhZ2UpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB3ZWJ2aWV3TWFwcGluZy53ZWJ2aWV3TmFtZSA9IHd2TmFtZTtcbiAgICBjb25zdCBrZXkgPSB0b0RldGFpbHNDYWNoZUtleShhZGIsIHd2TmFtZSk7XG4gICAgaWYgKGluZm8gfHwgcHJvY2Vzcykge1xuICAgICAgV0VCVklFV1NfREVUQUlMU19DQUNIRS5zZXQoa2V5LCB7IGluZm8sIHByb2Nlc3MgfSk7XG4gICAgfSBlbHNlIGlmIChXRUJWSUVXU19ERVRBSUxTX0NBQ0hFLmhhcyhrZXkpKSB7XG4gICAgICBXRUJWSUVXU19ERVRBSUxTX0NBQ0hFLmRlbGV0ZShrZXkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gd2Vidmlld3NNYXBwaW5nO1xufTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBQcm9jZXNzSW5mb1xuICogQHByb3BlcnR5IHtzdHJpbmd9IG5hbWUgVGhlIHByb2Nlc3MgbmFtZVxuICogQHByb3BlcnR5IHs/c3RyaW5nfSBpZCBUaGUgcHJvY2VzcyBpZCAoaWYgY291bGQgYmUgcmV0cmlldmVkKVxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gV2ViVmlld0RldGFpbHNcbiAqIEBwcm9wZXJ0eSB7P1Byb2Nlc3NJbmZvfSBwcm9jZXNzIC0gV2ViIHZpZXcgcHJvY2VzcyBkZXRhaWxzXG4gKiBAcHJvcGVydHkge09iamVjdH0gaW5mbyAtIFdlYiB2aWV3IGRldGFpbHMgYXMgcmV0dXJuZWQgYnkgL2pzb24vdmVyc2lvbiBDRFAgZW5kcG9pbnQsIGZvciBleGFtcGxlOlxuICoge1xuICogIFwiQnJvd3NlclwiOiBcIkNocm9tZS83Mi4wLjM2MDEuMFwiLFxuICogIFwiUHJvdG9jb2wtVmVyc2lvblwiOiBcIjEuM1wiLFxuICogIFwiVXNlci1BZ2VudFwiOiBcIk1vemlsbGEvNS4wIChNYWNpbnRvc2g7IEludGVsIE1hYyBPUyBYIDEwXzEzXzYpIEFwcGxlV2ViS2l0LzUzNy4zNiAoS0hUTUwsIGxpa2UgR2Vja28pIENocm9tZS83Mi4wLjM2MDEuMCBTYWZhcmkvNTM3LjM2XCIsXG4gKiAgXCJWOC1WZXJzaW9uXCI6IFwiNy4yLjIzM1wiLFxuICogIFwiV2ViS2l0LVZlcnNpb25cIjogXCI1MzcuMzYgKEBjZmVkZTlkYjFkMTU0ZGUwNDY4Y2IwNTM4NDc5ZjM0YzA3NTVhMGY0KVwiLFxuICogIFwid2ViU29ja2V0RGVidWdnZXJVcmxcIjogXCJ3czovL2xvY2FsaG9zdDo5MjIyL2RldnRvb2xzL2Jyb3dzZXIvYjBiOGE0ZmItYmIxNy00MzU5LTk1MzMtYThkOWYzOTA4YmQ4XCJcbiAqIH1cbiAqL1xuXG4vKipcbiAqIFJldHJpZXZlcyB3ZWIgdmlldyBkZXRhaWxzIHByZXZpb3VzbHkgY2FjaGVkIGJ5IGBnZXRXZWJ2aWV3c2AgY2FsbFxuICpcbiAqIEBwYXJhbSB7QURCfSBhZGIgQURCIGluc3RhbmNlXG4gKiBAcGFyYW0ge3N0cmluZ30gd2VidmlldyBUaGUgbmFtZSBvZiB0aGUgd2ViIHZpZXdcbiAqIEByZXR1cm5zIHs/V2ViVmlld0RldGFpbHN9IEVpdGhlciBgdW5kZWZpbmVkYCBvciB0aGUgcmVjZW50IHdlYiB2aWV3IGRldGFpbHNcbiAqL1xuaGVscGVycy5nZXRXZWJ2aWV3RGV0YWlscyA9IGZ1bmN0aW9uIGdldFdlYnZpZXdEZXRhaWxzIChhZGIsIHdlYnZpZXcpIHtcbiAgY29uc3Qga2V5ID0gdG9EZXRhaWxzQ2FjaGVLZXkoYWRiLCB3ZWJ2aWV3KTtcbiAgcmV0dXJuIFdFQlZJRVdTX0RFVEFJTFNfQ0FDSEUuZ2V0KGtleSk7XG59O1xuXG4vKipcbiAqIENyZWF0ZSBDaHJvbWUgZHJpdmVyIGNhcGFiaWxpdGllcyBiYXNlZCBvbiB0aGUgcHJvdmlkZWRcbiAqIEFwcGl1bSBjYXBhYmlsaXRpZXNcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0cyBVc2VyLXByb3ZpZGVkIGNhcGFiaWxpdGllcyBvYmplY3RcbiAqIEBwYXJhbSB7c3RyaW5nfSBkZXZpY2VJZCBUaGUgaWRlbnRpZmllciBvZiB0aGUgQW5kcm9pZCBkZXZpY2UgdW5kZXIgdGVzdFxuICogQHBhcmFtIHs/V2ViVmlld0RldGFpbHN9IHdlYlZpZXdEZXRhaWxzXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBUaGUgY2FwYWJpbGl0aWVzIG9iamVjdC5cbiAqIFNlZSBodHRwczovL2Nocm9tZWRyaXZlci5jaHJvbWl1bS5vcmcvY2FwYWJpbGl0aWVzIGZvciBtb3JlIGRldGFpbHMuXG4gKi9cbmhlbHBlcnMuY3JlYXRlQ2hyb21lZHJpdmVyQ2FwcyA9IGZ1bmN0aW9uIGNyZWF0ZUNocm9tZWRyaXZlckNhcHMgKG9wdHMsIGRldmljZUlkLCB3ZWJWaWV3RGV0YWlscykge1xuICBjb25zdCBjYXBzID0geyBjaHJvbWVPcHRpb25zOiB7fSB9O1xuXG4gIGNvbnN0IGFuZHJvaWRQYWNrYWdlID0gb3B0cy5jaHJvbWVPcHRpb25zPy5hbmRyb2lkUGFja2FnZVxuICAgIHx8IG9wdHMuYXBwUGFja2FnZVxuICAgIHx8IHdlYlZpZXdEZXRhaWxzPy5pbmZvPy5bJ0FuZHJvaWQtUGFja2FnZSddO1xuICBpZiAoYW5kcm9pZFBhY2thZ2UpIHtcbiAgICAvLyBjaHJvbWVkcml2ZXIgcmFpc2VzIGFuIGludmFsaWQgYXJndW1lbnQgZXJyb3Igd2hlbiBhbmRyb2lkUGFja2FnZSBpcyAnbnVsbCdcbiAgICBjYXBzLmNocm9tZU9wdGlvbnMuYW5kcm9pZFBhY2thZ2UgPSBhbmRyb2lkUGFja2FnZTtcbiAgfVxuICBpZiAoXy5pc0Jvb2xlYW4ob3B0cy5jaHJvbWVVc2VSdW5uaW5nQXBwKSkge1xuICAgIGNhcHMuY2hyb21lT3B0aW9ucy5hbmRyb2lkVXNlUnVubmluZ0FwcCA9IG9wdHMuY2hyb21lVXNlUnVubmluZ0FwcDtcbiAgfVxuICBpZiAob3B0cy5jaHJvbWVBbmRyb2lkUGFja2FnZSkge1xuICAgIGNhcHMuY2hyb21lT3B0aW9ucy5hbmRyb2lkUGFja2FnZSA9IG9wdHMuY2hyb21lQW5kcm9pZFBhY2thZ2U7XG4gIH1cbiAgaWYgKG9wdHMuY2hyb21lQW5kcm9pZEFjdGl2aXR5KSB7XG4gICAgY2Fwcy5jaHJvbWVPcHRpb25zLmFuZHJvaWRBY3Rpdml0eSA9IG9wdHMuY2hyb21lQW5kcm9pZEFjdGl2aXR5O1xuICB9XG4gIGlmIChvcHRzLmNocm9tZUFuZHJvaWRQcm9jZXNzKSB7XG4gICAgY2Fwcy5jaHJvbWVPcHRpb25zLmFuZHJvaWRQcm9jZXNzID0gb3B0cy5jaHJvbWVBbmRyb2lkUHJvY2VzcztcbiAgfSBlbHNlIGlmICh3ZWJWaWV3RGV0YWlscz8ucHJvY2Vzcz8ubmFtZSAmJiB3ZWJWaWV3RGV0YWlscz8ucHJvY2Vzcz8uaWQpIHtcbiAgICBjYXBzLmNocm9tZU9wdGlvbnMuYW5kcm9pZFByb2Nlc3MgPSB3ZWJWaWV3RGV0YWlscy5wcm9jZXNzLm5hbWU7XG4gIH1cbiAgaWYgKF8udG9Mb3dlcihvcHRzLmJyb3dzZXJOYW1lKSA9PT0gJ2Nocm9taXVtLXdlYnZpZXcnKSB7XG4gICAgY2Fwcy5jaHJvbWVPcHRpb25zLmFuZHJvaWRBY3Rpdml0eSA9IG9wdHMuYXBwQWN0aXZpdHk7XG4gIH1cbiAgaWYgKG9wdHMucGFnZUxvYWRTdHJhdGVneSkge1xuICAgIGNhcHMucGFnZUxvYWRTdHJhdGVneSA9IG9wdHMucGFnZUxvYWRTdHJhdGVneTtcbiAgfVxuICBjb25zdCBpc0Nocm9tZSA9IF8udG9Mb3dlcihjYXBzLmNocm9tZU9wdGlvbnMuYW5kcm9pZFBhY2thZ2UpID09PSAnY2hyb21lJztcbiAgaWYgKF8uaW5jbHVkZXMoS05PV05fQ0hST01FX1BBQ0tBR0VfTkFNRVMsIGNhcHMuY2hyb21lT3B0aW9ucy5hbmRyb2lkUGFja2FnZSkgfHwgaXNDaHJvbWUpIHtcbiAgICAvLyBpZiB3ZSBoYXZlIGV4dHJhY3RlZCBwYWNrYWdlIGZyb20gY29udGV4dCBuYW1lLCBpdCBjb3VsZCBjb21lIGluIGFzIGJhcmVcbiAgICAvLyBcImNocm9tZVwiLCBhbmQgc28gd2Ugc2hvdWxkIG1ha2Ugc3VyZSB0aGUgZGV0YWlscyBhcmUgY29ycmVjdCwgaW5jbHVkaW5nXG4gICAgLy8gbm90IHVzaW5nIGFuIGFjdGl2aXR5IG9yIHByb2Nlc3MgaWRcbiAgICBpZiAoaXNDaHJvbWUpIHtcbiAgICAgIGNhcHMuY2hyb21lT3B0aW9ucy5hbmRyb2lkUGFja2FnZSA9IENIUk9NRV9QQUNLQUdFX05BTUU7XG4gICAgfVxuICAgIGRlbGV0ZSBjYXBzLmNocm9tZU9wdGlvbnMuYW5kcm9pZEFjdGl2aXR5O1xuICAgIGRlbGV0ZSBjYXBzLmNocm9tZU9wdGlvbnMuYW5kcm9pZFByb2Nlc3M7XG4gIH1cbiAgLy8gYWRkIGRldmljZSBpZCBmcm9tIGFkYlxuICBjYXBzLmNocm9tZU9wdGlvbnMuYW5kcm9pZERldmljZVNlcmlhbCA9IGRldmljZUlkO1xuXG4gIGlmIChfLmlzUGxhaW5PYmplY3Qob3B0cy5sb2dnaW5nUHJlZnMpIHx8IF8uaXNQbGFpbk9iamVjdChvcHRzLmNocm9tZUxvZ2dpbmdQcmVmcykpIHtcbiAgICBpZiAob3B0cy5sb2dnaW5nUHJlZnMpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBUaGUgJ2xvZ2dpbmdQcmVmcycgY2FwIGlzIGRlcHJlY2F0ZWQ7IHVzZSB0aGUgJ2Nocm9tZUxvZ2dpbmdQcmVmcycgY2FwIGluc3RlYWRgKTtcbiAgICB9XG4gICAgY2Fwcy5sb2dnaW5nUHJlZnMgPSBvcHRzLmNocm9tZUxvZ2dpbmdQcmVmcyB8fCBvcHRzLmxvZ2dpbmdQcmVmcztcbiAgfVxuICBpZiAob3B0cy5lbmFibGVQZXJmb3JtYW5jZUxvZ2dpbmcpIHtcbiAgICBsb2dnZXIud2FybihgVGhlICdlbmFibGVQZXJmb3JtYW5jZUxvZ2dpbmcnIGNhcCBpcyBkZXByZWNhdGVkOyBzaW1wbHkgdXNlIGAgK1xuICAgICAgYHRoZSAnY2hyb21lTG9nZ2luZ1ByZWZzJyBjYXAgaW5zdGVhZCwgd2l0aCBhICdwZXJmb3JtYW5jZScga2V5IHNldCB0byAnQUxMJ2ApO1xuICAgIGNvbnN0IG5ld1ByZWYgPSB7cGVyZm9ybWFuY2U6ICdBTEwnfTtcbiAgICAvLyBkb24ndCBvdmVyd3JpdGUgb3RoZXIgbG9nZ2luZyBwcmVmcyB0aGF0IGhhdmUgYmVlbiBzZW50IGluIGlmIHRoZXkgZXhpc3RcbiAgICBjYXBzLmxvZ2dpbmdQcmVmcyA9IGNhcHMubG9nZ2luZ1ByZWZzXG4gICAgICA/IE9iamVjdC5hc3NpZ24oe30sIGNhcHMubG9nZ2luZ1ByZWZzLCBuZXdQcmVmKVxuICAgICAgOiBuZXdQcmVmO1xuICB9XG5cbiAgaWYgKG9wdHMuY2hyb21lT3B0aW9ucz8uQXJndW1lbnRzKSB7XG4gICAgLy8gbWVyZ2UgYEFyZ3VtZW50c2AgYW5kIGBhcmdzYFxuICAgIG9wdHMuY2hyb21lT3B0aW9ucy5hcmdzID0gWy4uLihvcHRzLmNocm9tZU9wdGlvbnMuYXJncyB8fCBbXSksIC4uLm9wdHMuY2hyb21lT3B0aW9ucy5Bcmd1bWVudHNdO1xuICAgIGRlbGV0ZSBvcHRzLmNocm9tZU9wdGlvbnMuQXJndW1lbnRzO1xuICB9XG5cbiAgbG9nZ2VyLmRlYnVnKCdQcmVjYWxjdWxhdGVkIENocm9tZWRyaXZlciBjYXBhYmlsaXRpZXM6ICcgK1xuICAgIEpTT04uc3RyaW5naWZ5KGNhcHMuY2hyb21lT3B0aW9ucywgbnVsbCwgMikpO1xuXG4gIGNvbnN0IHByb3RlY3RlZENhcE5hbWVzID0gW107XG4gIGZvciAoY29uc3QgW29wdCwgdmFsXSBvZiBfLnRvUGFpcnMob3B0cy5jaHJvbWVPcHRpb25zKSkge1xuICAgIGlmIChfLmlzVW5kZWZpbmVkKGNhcHMuY2hyb21lT3B0aW9uc1tvcHRdKSkge1xuICAgICAgY2Fwcy5jaHJvbWVPcHRpb25zW29wdF0gPSB2YWw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb3RlY3RlZENhcE5hbWVzLnB1c2gob3B0KTtcbiAgICB9XG4gIH1cbiAgaWYgKCFfLmlzRW1wdHkocHJvdGVjdGVkQ2FwTmFtZXMpKSB7XG4gICAgbG9nZ2VyLmluZm8oJ1RoZSBmb2xsb3dpbmcgQ2hyb21lZHJpdmVyIGNhcGFiaWxpdGllcyBjYW5ub3QgYmUgb3ZlcnJpZGRlbiAnICtcbiAgICAgICdieSB0aGUgcHJvdmlkZWQgY2hyb21lT3B0aW9uczonKTtcbiAgICBmb3IgKGNvbnN0IG9wdE5hbWUgb2YgcHJvdGVjdGVkQ2FwTmFtZXMpIHtcbiAgICAgIGxvZ2dlci5pbmZvKGAgICR7b3B0TmFtZX0gKCR7SlNPTi5zdHJpbmdpZnkob3B0cy5jaHJvbWVPcHRpb25zW29wdE5hbWVdKX0pYCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNhcHM7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBoZWxwZXJzO1xuZXhwb3J0IHsgaGVscGVycywgTkFUSVZFX1dJTiwgV0VCVklFV19XSU4sIFdFQlZJRVdfQkFTRSwgQ0hST01JVU1fV0lOLCBLTk9XTl9DSFJPTUVfUEFDS0FHRV9OQU1FUyB9O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBLE1BQU1BLFVBQVUsR0FBRyxZQUFZO0FBQUM7QUFDaEMsTUFBTUMsV0FBVyxHQUFHLFNBQVM7QUFBQztBQUM5QixNQUFNQyxZQUFZLEdBQUcsVUFBVTtBQUFDO0FBQ2hDLE1BQU1DLFlBQVksR0FBSSxHQUFFRixXQUFZLEdBQUU7QUFBQztBQUN2QyxNQUFNRyxtQkFBbUIsR0FB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
|
|
348
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJOQVRJVkVfV0lOIiwiV0VCVklFV19XSU4iLCJDSFJPTUlVTV9XSU4iLCJXRUJWSUVXX0JBU0UiLCJXRUJWSUVXX1BJRF9QQVRURVJOIiwiUmVnRXhwIiwiV0VCVklFV19QS0dfUEFUVEVSTiIsIkRFVlRPT0xTX1NPQ0tFVF9QQVRURVJOIiwiQ1JPU1NXQUxLX1NPQ0tFVF9QQVRURVJOIiwiQ0hST01JVU1fREVWVE9PTFNfU09DS0VUIiwiQ0hST01FX1BBQ0tBR0VfTkFNRSIsIktOT1dOX0NIUk9NRV9QQUNLQUdFX05BTUVTIiwiREVWVE9PTFNfUE9SVFNfUkFOR0UiLCJXRUJWSUVXU19ERVRBSUxTX0NBQ0hFIiwiTFJVIiwibWF4IiwidXBkYXRlQWdlT25HZXQiLCJDRFBfUkVRX1RJTUVPVVQiLCJERVZUT09MU19QT1JUX0FMTE9DQVRJT05fR1VBUkQiLCJ1dGlsIiwiZ2V0TG9ja0ZpbGVHdWFyZCIsInBhdGgiLCJyZXNvbHZlIiwib3MiLCJ0bXBkaXIiLCJ0aW1lb3V0IiwidHJ5UmVjb3ZlcnkiLCJoZWxwZXJzIiwidG9EZXRhaWxzQ2FjaGVLZXkiLCJhZGIiLCJ3ZWJ2aWV3IiwiY3VyRGV2aWNlSWQiLCJnZXRQb3RlbnRpYWxXZWJ2aWV3UHJvY3MiLCJvdXQiLCJzaGVsbCIsIm5hbWVzIiwiYWxsTWF0Y2hlcyIsImxpbmUiLCJzcGxpdCIsImZsYWdzIiwic3QiLCJzb2NrUGF0aCIsInRyaW0iLCJzdGFydHNXaXRoIiwicHVzaCIsInRlc3QiLCJfIiwiaXNFbXB0eSIsImxvZ2dlciIsImRlYnVnIiwiSlNPTiIsInN0cmluZ2lmeSIsImxlbmd0aCIsInBsdXJhbGl6ZSIsInVuaXEiLCJ3ZWJ2aWV3c0Zyb21Qcm9jcyIsImRldmljZVNvY2tldCIsInNvY2tldE5hbWVzIiwid2Vidmlld3MiLCJzb2NrZXROYW1lIiwicHJvYyIsInNvY2tldE5hbWVNYXRjaCIsImV4ZWMiLCJjcm9zc3dhbGtNYXRjaCIsImFsbG9jYXRlRGV2dG9vbHNQb3J0Iiwid2Vidmlld0RldnRvb2xzUG9ydCIsInJlbW90ZVBvcnQiLCJyZXBsYWNlIiwic3RhcnRQb3J0IiwiZW5kUG9ydCIsImxvY2FsUG9ydCIsImZpbmRBUG9ydE5vdEluVXNlIiwiZSIsIkVycm9yIiwiYWRiRXhlYyIsImNvbGxlY3RXZWJ2aWV3c0RldGFpbHMiLCJ3ZWJ2aWV3c01hcHBpbmciLCJvcHRzIiwiZW5zdXJlV2Vidmlld3NIYXZlUGFnZXMiLCJlbmFibGVXZWJ2aWV3RGV0YWlsc0NvbGxlY3Rpb24iLCJpbmZvIiwiZGV0YWlsQ29sbGVjdG9ycyIsIml0ZW0iLCJjZHBJbmZvIiwicGFnZXMiLCJjZHBMaXN0IiwicmVtb3ZlUG9ydEZvcndhcmQiLCJCIiwiYWxsIiwiYXhpb3MiLCJ1cmwiLCJkYXRhIiwicHJvY0Zyb21XZWJ2aWV3IiwicGlkTWF0Y2giLCJwaWQiLCJwa2ciLCJnZXROYW1lQnlQaWQiLCJwYXJzZVdlYnZpZXdOYW1lcyIsImlzQ2hyb21lU2Vzc2lvbiIsInJlc3VsdCIsIndlYnZpZXdOYW1lIiwiZ2V0V2ViVmlld3NNYXBwaW5nIiwiYW5kcm9pZERldmljZVNvY2tldCIsIndlYnZpZXdNYXBwaW5nIiwid3ZOYW1lIiwicHJvY2VzcyIsInVuZGVmaW5lZCIsInBrZ01hdGNoIiwibmFtZSIsImlkIiwid2FybiIsIm1lc3NhZ2UiLCJrZXkiLCJzZXQiLCJoYXMiLCJkZWxldGUiLCJnZXRXZWJ2aWV3RGV0YWlscyIsImdldCIsImNyZWF0ZUNocm9tZWRyaXZlckNhcHMiLCJkZXZpY2VJZCIsIndlYlZpZXdEZXRhaWxzIiwiY2FwcyIsImNocm9tZU9wdGlvbnMiLCJhbmRyb2lkUGFja2FnZSIsImFwcFBhY2thZ2UiLCJpc0Jvb2xlYW4iLCJjaHJvbWVVc2VSdW5uaW5nQXBwIiwiYW5kcm9pZFVzZVJ1bm5pbmdBcHAiLCJjaHJvbWVBbmRyb2lkUGFja2FnZSIsImNocm9tZUFuZHJvaWRBY3Rpdml0eSIsImFuZHJvaWRBY3Rpdml0eSIsImNocm9tZUFuZHJvaWRQcm9jZXNzIiwiYW5kcm9pZFByb2Nlc3MiLCJ0b0xvd2VyIiwiYnJvd3Nlck5hbWUiLCJhcHBBY3Rpdml0eSIsInBhZ2VMb2FkU3RyYXRlZ3kiLCJpc0Nocm9tZSIsImluY2x1ZGVzIiwiYW5kcm9pZERldmljZVNlcmlhbCIsImlzUGxhaW5PYmplY3QiLCJsb2dnaW5nUHJlZnMiLCJjaHJvbWVMb2dnaW5nUHJlZnMiLCJlbmFibGVQZXJmb3JtYW5jZUxvZ2dpbmciLCJuZXdQcmVmIiwicGVyZm9ybWFuY2UiLCJPYmplY3QiLCJhc3NpZ24iLCJBcmd1bWVudHMiLCJhcmdzIiwicHJvdGVjdGVkQ2FwTmFtZXMiLCJvcHQiLCJ2YWwiLCJ0b1BhaXJzIiwiaXNVbmRlZmluZWQiLCJvcHROYW1lIl0sInNvdXJjZXMiOlsiLi4vLi4vbGliL3dlYnZpZXctaGVscGVycy5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IGxvZ2dlciBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IHsgdXRpbCB9IGZyb20gJ0BhcHBpdW0vc3VwcG9ydCc7XG5pbXBvcnQgeyBmaW5kQVBvcnROb3RJblVzZSB9IGZyb20gJ3BvcnRzY2FubmVyJztcbmltcG9ydCBMUlUgZnJvbSAnbHJ1LWNhY2hlJztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IG9zIGZyb20gJ29zJztcblxuY29uc3QgTkFUSVZFX1dJTiA9ICdOQVRJVkVfQVBQJztcbmNvbnN0IFdFQlZJRVdfV0lOID0gJ1dFQlZJRVcnO1xuY29uc3QgQ0hST01JVU1fV0lOID0gJ0NIUk9NSVVNJztcbmNvbnN0IFdFQlZJRVdfQkFTRSA9IGAke1dFQlZJRVdfV0lOfV9gO1xuY29uc3QgV0VCVklFV19QSURfUEFUVEVSTiA9IG5ldyBSZWdFeHAoYF4ke1dFQlZJRVdfQkFTRX0oXFxcXGQrKWApO1xuY29uc3QgV0VCVklFV19QS0dfUEFUVEVSTiA9IG5ldyBSZWdFeHAoYF4ke1dFQlZJRVdfQkFTRX0oW15cXFxcZFxcXFxzXVtcXFxcdy5dKilgKTtcbmNvbnN0IERFVlRPT0xTX1NPQ0tFVF9QQVRURVJOID0gL0BbXFx3Ll0rX2RldnRvb2xzX3JlbW90ZV8/KFxcZCspP1xcYi87XG5jb25zdCBDUk9TU1dBTEtfU09DS0VUX1BBVFRFUk4gPSAvQChbXFx3Ll0rKV9kZXZ0b29sc19yZW1vdGVcXGIvO1xuY29uc3QgQ0hST01JVU1fREVWVE9PTFNfU09DS0VUID0gJ2Nocm9tZV9kZXZ0b29sc19yZW1vdGUnO1xuY29uc3QgQ0hST01FX1BBQ0tBR0VfTkFNRSA9ICdjb20uYW5kcm9pZC5jaHJvbWUnO1xuY29uc3QgS05PV05fQ0hST01FX1BBQ0tBR0VfTkFNRVMgPSBbXG4gIENIUk9NRV9QQUNLQUdFX05BTUUsXG4gICdjb20uY2hyb21lLmJldGEnLFxuICAnY29tLmNocm9tZS5kZXYnLFxuICAnY29tLmNocm9tZS5jYW5hcnknLFxuXTtcbmNvbnN0IERFVlRPT0xTX1BPUlRTX1JBTkdFID0gWzEwOTAwLCAxMTAwMF07XG5jb25zdCBXRUJWSUVXU19ERVRBSUxTX0NBQ0hFID0gbmV3IExSVSh7XG4gIG1heDogMTAwLFxuICB1cGRhdGVBZ2VPbkdldDogdHJ1ZSxcbn0pO1xuY29uc3QgQ0RQX1JFUV9USU1FT1VUID0gMjAwMDsgLy8gbXNcbmNvbnN0IERFVlRPT0xTX1BPUlRfQUxMT0NBVElPTl9HVUFSRCA9IHV0aWwuZ2V0TG9ja0ZpbGVHdWFyZChcbiAgcGF0aC5yZXNvbHZlKG9zLnRtcGRpcigpLCAnYW5kcm9pZF9kZXZ0b29sc19wb3J0X2d1YXJkJyksXG4gIHt0aW1lb3V0OiA3LCB0cnlSZWNvdmVyeTogdHJ1ZX1cbik7XG5cbmNvbnN0IGhlbHBlcnMgPSB7fTtcblxuZnVuY3Rpb24gdG9EZXRhaWxzQ2FjaGVLZXkgKGFkYiwgd2Vidmlldykge1xuICByZXR1cm4gYCR7YWRiPy5jdXJEZXZpY2VJZH06JHt3ZWJ2aWV3fWA7XG59XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBnZXRzIGEgbGlzdCBvZiBhbmRyb2lkIHN5c3RlbSBwcm9jZXNzZXMgYW5kIHJldHVybnMgb25lc1xuICogdGhhdCBsb29rIGxpa2Ugd2Vidmlld3NcbiAqIFNlZSBodHRwczovL2NzLmNocm9taXVtLm9yZy9jaHJvbWl1bS9zcmMvY2hyb21lL2Jyb3dzZXIvZGV2dG9vbHMvZGV2aWNlL2FuZHJvaWRfZGV2aWNlX2luZm9fcXVlcnkuY2NcbiAqIGZvciBtb3JlIGRldGFpbHNcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gYWRiIC0gYW4gQURCIGluc3RhbmNlXG4gKlxuICogQHJldHVybiB7QXJyYXkuPHN0cmluZz59IC0gYSBsaXN0IG9mIG1hdGNoaW5nIHdlYnZpZXcgc29ja2V0IG5hbWVzIChpbmNsdWRpbmcgdGhlIGxlYWRpbmcgJ0AnKVxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRQb3RlbnRpYWxXZWJ2aWV3UHJvY3MgKGFkYikge1xuICBjb25zdCBvdXQgPSBhd2FpdCBhZGIuc2hlbGwoWydjYXQnLCAnL3Byb2MvbmV0L3VuaXgnXSk7XG4gIGNvbnN0IG5hbWVzID0gW107XG4gIGNvbnN0IGFsbE1hdGNoZXMgPSBbXTtcbiAgZm9yIChjb25zdCBsaW5lIG9mIG91dC5zcGxpdCgnXFxuJykpIHtcbiAgICAvLyBOdW0gUmVmQ291bnQgUHJvdG9jb2wgRmxhZ3MgVHlwZSBTdCBJbm9kZSBQYXRoXG4gICAgY29uc3QgWywsLCBmbGFncywsIHN0LCwgc29ja1BhdGhdID0gbGluZS50cmltKCkuc3BsaXQoL1xccysvKTtcbiAgICBpZiAoIXNvY2tQYXRoKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKHNvY2tQYXRoLnN0YXJ0c1dpdGgoJ0AnKSkge1xuICAgICAgYWxsTWF0Y2hlcy5wdXNoKGxpbmUudHJpbSgpKTtcbiAgICB9XG4gICAgaWYgKGZsYWdzICE9PSAnMDAwMTAwMDAnIHx8IHN0ICE9PSAnMDEnKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKCFERVZUT09MU19TT0NLRVRfUEFUVEVSTi50ZXN0KHNvY2tQYXRoKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgbmFtZXMucHVzaChzb2NrUGF0aCk7XG4gIH1cbiAgaWYgKF8uaXNFbXB0eShuYW1lcykpIHtcbiAgICBsb2dnZXIuZGVidWcoJ0ZvdW5kIG5vIGFjdGl2ZSBkZXZ0b29scyBzb2NrZXRzJyk7XG4gICAgaWYgKCFfLmlzRW1wdHkoYWxsTWF0Y2hlcykpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgT3RoZXIgc29ja2V0cyBhcmU6ICR7SlNPTi5zdHJpbmdpZnkoYWxsTWF0Y2hlcywgbnVsbCwgMil9YCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGxvZ2dlci5kZWJ1ZyhgUGFyc2VkICR7bmFtZXMubGVuZ3RofSBhY3RpdmUgZGV2dG9vbHMgJHt1dGlsLnBsdXJhbGl6ZSgnc29ja2V0JywgbmFtZXMubGVuZ3RoLCBmYWxzZSl9OiBgICtcbiAgICAgIEpTT04uc3RyaW5naWZ5KG5hbWVzKSk7XG4gIH1cbiAgLy8gc29tZXRpbWVzIHRoZSB3ZWJ2aWV3IHByb2Nlc3Mgc2hvd3MgdXAgbXVsdGlwbGUgdGltZXMgcGVyIGFwcFxuICByZXR1cm4gXy51bmlxKG5hbWVzKTtcbn1cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBXZWJ2aWV3UHJvY1xuICogQHByb3BlcnR5IHtzdHJpbmd9IHByb2MgLSBUaGUgd2VidmlldyBwcm9jZXNzIG5hbWUgKGFzIHJldHVybmVkIGJ5XG4gKiBnZXRQb3RlbnRpYWxXZWJ2aWV3UHJvY3NcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB3ZWJ2aWV3IC0gVGhlIGFjdHVhbCB3ZWJ2aWV3IGNvbnRleHQgbmFtZVxuICovXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gcmV0cmlldmVzIGEgbGlzdCBvZiBzeXN0ZW0gcHJvY2Vzc2VzIHRoYXQgbG9vayBsaWtlIHdlYnZpZXdzLFxuICogYW5kIHJldHVybnMgdGhlbSBhbG9uZyB3aXRoIHRoZSB3ZWJ2aWV3IGNvbnRleHQgbmFtZSBhcHByb3ByaWF0ZSBmb3IgaXQuXG4gKiBJZiB3ZSBwYXNzIGluIGEgZGV2aWNlU29ja2V0LCB3ZSBvbmx5IGF0dGVtcHQgdG8gZmluZCB3ZWJ2aWV3cyB3aGljaCBtYXRjaFxuICogdGhhdCBzb2NrZXQgbmFtZSAodGhpcyBpcyBmb3IgYXBwcyB3aGljaCBlbWJlZCBDaHJvbWl1bSwgd2hpY2ggaXNuJ3QgdGhlXG4gKiBzYW1lIGFzIGNocm9tZS1iYWNrZWQgd2Vidmlld3MpLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBhZGIgLSBhbiBBREIgaW5zdGFuY2VcbiAqIEBwYXJhbSB7P3N0cmluZ30gZGV2aWNlU29ja2V0IC0gdGhlIGV4cGxpY3RseS1uYW1lZCBkZXZpY2Ugc29ja2V0IHRvIHVzZVxuICpcbiAqIEByZXR1cm4ge0FycmF5LjxXZWJ2aWV3UHJvYz59XG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHdlYnZpZXdzRnJvbVByb2NzIChhZGIsIGRldmljZVNvY2tldCA9IG51bGwpIHtcbiAgY29uc3Qgc29ja2V0TmFtZXMgPSBhd2FpdCBnZXRQb3RlbnRpYWxXZWJ2aWV3UHJvY3MoYWRiKTtcbiAgY29uc3Qgd2Vidmlld3MgPSBbXTtcbiAgZm9yIChjb25zdCBzb2NrZXROYW1lIG9mIHNvY2tldE5hbWVzKSB7XG4gICAgaWYgKGRldmljZVNvY2tldCA9PT0gQ0hST01JVU1fREVWVE9PTFNfU09DS0VUICYmIHNvY2tldE5hbWUgPT09IGBAJHtkZXZpY2VTb2NrZXR9YCkge1xuICAgICAgd2Vidmlld3MucHVzaCh7XG4gICAgICAgIHByb2M6IHNvY2tldE5hbWUsXG4gICAgICAgIHdlYnZpZXc6IENIUk9NSVVNX1dJTixcbiAgICAgIH0pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3Qgc29ja2V0TmFtZU1hdGNoID0gREVWVE9PTFNfU09DS0VUX1BBVFRFUk4uZXhlYyhzb2NrZXROYW1lKTtcbiAgICBpZiAoIXNvY2tldE5hbWVNYXRjaCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IGNyb3Nzd2Fsa01hdGNoID0gQ1JPU1NXQUxLX1NPQ0tFVF9QQVRURVJOLmV4ZWMoc29ja2V0TmFtZSk7XG4gICAgaWYgKCFzb2NrZXROYW1lTWF0Y2hbMV0gJiYgIWNyb3Nzd2Fsa01hdGNoKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoZGV2aWNlU29ja2V0ICYmIHNvY2tldE5hbWUgPT09IGBAJHtkZXZpY2VTb2NrZXR9YCB8fCAhZGV2aWNlU29ja2V0KSB7XG4gICAgICB3ZWJ2aWV3cy5wdXNoKHtcbiAgICAgICAgcHJvYzogc29ja2V0TmFtZSxcbiAgICAgICAgd2Vidmlldzogc29ja2V0TmFtZU1hdGNoWzFdXG4gICAgICAgICAgPyBgJHtXRUJWSUVXX0JBU0V9JHtzb2NrZXROYW1lTWF0Y2hbMV19YFxuICAgICAgICAgIDogYCR7V0VCVklFV19CQVNFfSR7Y3Jvc3N3YWxrTWF0Y2hbMV19YCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gd2Vidmlld3M7XG59XG5cbi8qKlxuICogQWxsb2NhdGVzIGEgbG9jYWwgcG9ydCBmb3IgZGV2dG9vbHMgY29tbXVuaWNhdGlvblxuICpcbiAqIEBwYXJhbSB7QURCfSBhZGIgQURCIGluc3RhbmNlXG4gKiBAcGFyYW0ge3N0cmluZ30gc29ja2V0TmFtZSBUaGUgcmVtb3RlIFVuaXggc29ja2V0IG5hbWVcbiAqIEBwYXJhbSB7P251bWJlcn0gd2Vidmlld0RldnRvb2xzUG9ydCBUaGUgbG9jYWwgcG9ydCBudW1iZXIgb3IgbnVsbCB0byBhcHBseVxuICogYXV0b2RldGVjdGlvblxuICogQHJldHVybnMge251bWJlcn0gVGhlIGxvY2FsIHBvcnQgbnVtYmVyIGlmIHRoZSByZW1vdGUgc29ja2V0IGhhcyBiZWVuIGZvcndhcmRlZFxuICogc3VjY2Vzc2Z1bGx5IG9yIGBudWxsYCBvdGhlcndpc2VcbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGVyZSB3YXMgYW4gZXJyb3Igd2hpbGUgYWxsb2NhdGluZyB0aGUgbG9jYWwgcG9ydFxuICovXG5hc3luYyBmdW5jdGlvbiBhbGxvY2F0ZURldnRvb2xzUG9ydCAoYWRiLCBzb2NrZXROYW1lLCB3ZWJ2aWV3RGV2dG9vbHNQb3J0ID0gbnVsbCkge1xuICAvLyBzb2NrZXQgbmFtZXMgY29tZSB3aXRoICdAJywgYnV0IHRoaXMgc2hvdWxkIG5vdCBiZSBhIHBhcnQgb2YgdGhlIGFic3RyYWN0XG4gIC8vIHJlbW90ZSBwb3J0LCBzbyByZW1vdmUgaXRcbiAgY29uc3QgcmVtb3RlUG9ydCA9IHNvY2tldE5hbWUucmVwbGFjZSgvXkAvLCAnJyk7XG4gIGxldCBbc3RhcnRQb3J0LCBlbmRQb3J0XSA9IERFVlRPT0xTX1BPUlRTX1JBTkdFO1xuICBpZiAod2Vidmlld0RldnRvb2xzUG9ydCkge1xuICAgIGVuZFBvcnQgPSB3ZWJ2aWV3RGV2dG9vbHNQb3J0ICsgKGVuZFBvcnQgLSBzdGFydFBvcnQpO1xuICAgIHN0YXJ0UG9ydCA9IHdlYnZpZXdEZXZ0b29sc1BvcnQ7XG4gIH1cbiAgbG9nZ2VyLmRlYnVnKGBGb3J3YXJkaW5nIHJlbW90ZSBwb3J0ICR7cmVtb3RlUG9ydH0gdG8gYSBsb2NhbCBgICtcbiAgICBgcG9ydCBpbiByYW5nZSAke3N0YXJ0UG9ydH0uLiR7ZW5kUG9ydH1gKTtcbiAgaWYgKCF3ZWJ2aWV3RGV2dG9vbHNQb3J0KSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBZb3UgY291bGQgdXNlIHRoZSAnd2Vidmlld0RldnRvb2xzUG9ydCcgY2FwYWJpbGl0eSB0byBjdXN0b21pemUgYCArXG4gICAgICBgdGhlIHN0YXJ0aW5nIHBvcnQgbnVtYmVyYCk7XG4gIH1cbiAgcmV0dXJuIGF3YWl0IERFVlRPT0xTX1BPUlRfQUxMT0NBVElPTl9HVUFSRChhc3luYyAoKSA9PiB7XG4gICAgbGV0IGxvY2FsUG9ydDtcbiAgICB0cnkge1xuICAgICAgbG9jYWxQb3J0ID0gYXdhaXQgZmluZEFQb3J0Tm90SW5Vc2Uoc3RhcnRQb3J0LCBlbmRQb3J0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBmaW5kIGFueSBmcmVlIHBvcnQgdG8gZm9yd2FyZCB0aGUgRGV2dG9vbHMgc29ja2V0IGAgK1xuICAgICAgICBgaW4gcmFuZ2UgJHtzdGFydFBvcnR9Li4ke2VuZFBvcnR9LiBZb3UgY291bGQgc2V0IHRoZSBzdGFydGluZyBwb3J0IG51bWJlciBgICtcbiAgICAgICAgYG1hbnVhbGx5IGJ5IHByb3ZpZGluZyB0aGUgJ3dlYnZpZXdEZXZ0b29sc1BvcnQnIGNhcGFiaWxpdHlgKTtcbiAgICB9XG4gICAgYXdhaXQgYWRiLmFkYkV4ZWMoWydmb3J3YXJkJywgYHRjcDoke2xvY2FsUG9ydH1gLCBgbG9jYWxhYnN0cmFjdDoke3JlbW90ZVBvcnR9YF0pO1xuICAgIHJldHVybiBsb2NhbFBvcnQ7XG4gIH0pO1xufVxuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFdlYnZpZXdQcm9wc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IHByb2MgVGhlIG5hbWUgb2YgdGhlIERldnRvb2xzIFVuaXggc29ja2V0XG4gKiBAcHJvcGVydHkge3N0cmluZ30gd2VidmlldyBUaGUgd2ViIHZpZXcgYWxpYXMuIExvb2tzIGxpa2UgYFdFQlZJRVdfYFxuICogcHJlZml4IHBsdXMgUElEIG9yIHBhY2thZ2UgbmFtZVxuICogQHByb3BlcnR5IHs/T2JqZWN0fSBpbmZvIFdlYnZpZXcgaW5mb3JtYXRpb24gYXMgaXQgaXMgcmV0cmlldmVkIGJ5XG4gKiAvanNvbi92ZXJzaW9uIENEUCBlbmRwb2ludFxuICogQHByb3BlcnR5IHs/QXJyYXk8T2JqZWN0Pn0gcGFnZXMgV2VidmlldyBwYWdlcyBsaXN0IGFzIGl0IGlzIHJldHJpZXZlZCBieVxuICogL2pzb24vbGlzdCBDRFAgZW5kcG9pbnRcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IERldGFpbENvbGxlY3Rpb25PcHRpb25zXG4gKiBAcHJvcGVydHkgez9zdHJpbmd8bnVtYmVyfSB3ZWJ2aWV3RGV2dG9vbHNQb3J0IFRoZSBzdGFydGluZyBwb3J0IHRvIHVzZSBmb3Igd2VidmlldyBwYWdlXG4gKiBwcmVzZW5jZSBjaGVjayAoaWYgbm90IHRoZSBkZWZhdWx0IG9mIDkyMjIpLlxuICogQHByb3BlcnR5IHs/Ym9vbGVhbn0gZW5zdXJlV2Vidmlld3NIYXZlUGFnZXMgV2hldGhlciB0byBjaGVjayBmb3Igd2Vidmlld1xuICogcGFnZXMgcHJlc2VuY2VcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gZW5hYmxlV2Vidmlld0RldGFpbHNDb2xsZWN0aW9uIFdoZXRoZXIgdG8gY29sbGVjdFxuICogd2ViIHZpZXcgZGV0YWlscyBhbmQgc2VuZCB0aGVtIHRvIENocm9tZWRyaXZlciBjb25zdHJ1Y3Rvciwgc28gaXQgY291bGRcbiAqIHNlbGVjdCBhIGJpbmFyeSBtb3JlIHByZWNpc2VseSBiYXNlZCBvbiB0aGlzIGluZm8uXG4gKi9cblxuLyoqXG4gKiBUaGlzIGlzIGEgd3JhcHBlciBmb3IgQ2hyb21lIERlYnVnZ2VyIFByb3RvY29sIGRhdGEgY29sbGVjdGlvbi5cbiAqIE5vIGVycm9yIGlzIHRocm93biBpZiBDRFAgcmVxdWVzdCBmYWlscyAtIGluIHN1Y2ggY2FzZSBubyBkYXRhIHdpbGwgYmVcbiAqIHJlY29yZGVkIGludG8gdGhlIGNvcnJlc3BvbmRpbmcgYHdlYnZpZXdzTWFwcGluZ2AgaXRlbS5cbiAqXG4gKiBAcGFyYW0ge0FEQn0gYWRiIFRoZSBBREIgaW5zdGFuY2VcbiAqIEBwYXJhbSB7QXJyYXk8V2Vidmlld1Byb3BzPn0gd2Vidmlld3NNYXBwaW5nIFRoZSBjdXJyZW50IHdlYnZpZXdzIG1hcHBpbmdcbiAqICEhISBFYWNoIGl0ZW0gb2YgdGhpcyBhcnJheSBnZXRzIG11dGF0ZWQgKGBpbmZvYC9gcGFnZXNgIHByb3BlcnRpZXMgZ2V0IGFkZGVkXG4gKiBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgYG9wdHNgKSBpZiB0aGUgcmVxdWVzdGVkIGRldGFpbHMgaGF2ZSBiZWVuXG4gKiBzdWNjZXNzZnVsbHkgcmV0cmlldmVkIGZvciBpdCAhISFcbiAqIEBwYXJhbSB7RGV0YWlsQ29sbGVjdGlvbk9wdGlvbnN9IG9wdHMgSWYgYm90aCBgZW5zdXJlV2Vidmlld3NIYXZlUGFnZXNgIGFuZFxuICogYGVuYWJsZVdlYnZpZXdEZXRhaWxzQ29sbGVjdGlvbmAgcHJvcGVydGllcyBhcmUgZmFsc3kgdGhlbiBubyBkZXRhaWxzIGNvbGxlY3Rpb25cbiAqIGlzIHBlcmZvcm1lZFxuICovXG5hc3luYyBmdW5jdGlvbiBjb2xsZWN0V2Vidmlld3NEZXRhaWxzIChhZGIsIHdlYnZpZXdzTWFwcGluZywgb3B0cyA9IHt9KSB7XG4gIGlmIChfLmlzRW1wdHkod2Vidmlld3NNYXBwaW5nKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHtcbiAgICB3ZWJ2aWV3RGV2dG9vbHNQb3J0ID0gbnVsbCxcbiAgICBlbnN1cmVXZWJ2aWV3c0hhdmVQYWdlcyA9IG51bGwsXG4gICAgZW5hYmxlV2Vidmlld0RldGFpbHNDb2xsZWN0aW9uID0gbnVsbCxcbiAgfSA9IG9wdHM7XG5cbiAgaWYgKCFlbnN1cmVXZWJ2aWV3c0hhdmVQYWdlcykge1xuICAgIGxvZ2dlci5pbmZvKGBOb3QgY2hlY2tpbmcgd2hldGhlciB3ZWJ2aWV3cyBoYXZlIGFjdGl2ZSBwYWdlczsgdXNlIHRoZSBgICtcbiAgICAgIGAnZW5zdXJlV2Vidmlld3NIYXZlUGFnZXMnIGNhcCB0byB0dXJuIHRoaXMgY2hlY2sgb25gKTtcbiAgfVxuXG4gIGlmICghZW5hYmxlV2Vidmlld0RldGFpbHNDb2xsZWN0aW9uKSB7XG4gICAgbG9nZ2VyLmluZm8oYE5vdCBjb2xsZWN0aW5nIHdlYiB2aWV3IGRldGFpbHMuIERldGFpbHMgY29sbGVjdGlvbiBtaWdodCBoZWxwIGAgK1xuICAgICAgYHRvIG1ha2UgQ2hyb21lZHJpdmVyIGluaXRpYWxpemF0aW9uIG1vcmUgcHJlY2lzZS4gVXNlIHRoZSAnZW5hYmxlV2Vidmlld0RldGFpbHNDb2xsZWN0aW9uJyBgICtcbiAgICAgIGBjYXAgdG8gdHVybiBpdCBvbmApO1xuICB9XG5cbiAgaWYgKCFlbnN1cmVXZWJ2aWV3c0hhdmVQYWdlcyAmJiAhZW5hYmxlV2Vidmlld0RldGFpbHNDb2xsZWN0aW9uKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gQ29ubmVjdCB0byBlYWNoIGRldnRvb2xzIHNvY2tldCBhbmQgcmV0cmlldmUgd2ViIHZpZXcgZGV0YWlsc1xuICBsb2dnZXIuZGVidWcoYENvbGxlY3RpbmcgQ0RQIGRhdGEgb2YgJHt1dGlsLnBsdXJhbGl6ZSgnd2VidmlldycsIHdlYnZpZXdzTWFwcGluZy5sZW5ndGgsIHRydWUpfWApO1xuICBjb25zdCBkZXRhaWxDb2xsZWN0b3JzID0gW107XG4gIGZvciAoY29uc3QgaXRlbSBvZiB3ZWJ2aWV3c01hcHBpbmcpIHtcbiAgICBkZXRhaWxDb2xsZWN0b3JzLnB1c2goKGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBsb2NhbFBvcnQ7XG4gICAgICB0cnkge1xuICAgICAgICBsb2NhbFBvcnQgPSBhd2FpdCBhbGxvY2F0ZURldnRvb2xzUG9ydChhZGIsIGl0ZW0ucHJvYywgd2Vidmlld0RldnRvb2xzUG9ydCk7XG4gICAgICAgIGlmIChlbmFibGVXZWJ2aWV3RGV0YWlsc0NvbGxlY3Rpb24pIHtcbiAgICAgICAgICBpdGVtLmluZm8gPSBhd2FpdCBjZHBJbmZvKGxvY2FsUG9ydCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVuc3VyZVdlYnZpZXdzSGF2ZVBhZ2VzKSB7XG4gICAgICAgICAgaXRlbS5wYWdlcyA9IGF3YWl0IGNkcExpc3QobG9jYWxQb3J0KTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsb2dnZXIuZGVidWcoZSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBpZiAobG9jYWxQb3J0KSB7XG4gICAgICAgICAgYXdhaXQgYWRiLnJlbW92ZVBvcnRGb3J3YXJkKGxvY2FsUG9ydCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KSgpKTtcbiAgfVxuICBhd2FpdCBCLmFsbChkZXRhaWxDb2xsZWN0b3JzKTtcbiAgbG9nZ2VyLmRlYnVnKGBDRFAgZGF0YSBjb2xsZWN0aW9uIGNvbXBsZXRlZGApO1xufVxuXG4vLyBodHRwczovL2Nocm9tZWRldnRvb2xzLmdpdGh1Yi5pby9kZXZ0b29scy1wcm90b2NvbC9cbmFzeW5jIGZ1bmN0aW9uIGNkcExpc3QgKGxvY2FsUG9ydCkge1xuICByZXR1cm4gKGF3YWl0IGF4aW9zKHtcbiAgICB1cmw6IGBodHRwOi8vMTI3LjAuMC4xOiR7bG9jYWxQb3J0fS9qc29uL2xpc3RgLFxuICAgIHRpbWVvdXQ6IENEUF9SRVFfVElNRU9VVCxcbiAgfSkpLmRhdGE7XG59XG5cbi8vIGh0dHBzOi8vY2hyb21lZGV2dG9vbHMuZ2l0aHViLmlvL2RldnRvb2xzLXByb3RvY29sL1xuYXN5bmMgZnVuY3Rpb24gY2RwSW5mbyAobG9jYWxQb3J0KSB7XG4gIHJldHVybiAoYXdhaXQgYXhpb3Moe1xuICAgIHVybDogYGh0dHA6Ly8xMjcuMC4wLjE6JHtsb2NhbFBvcnR9L2pzb24vdmVyc2lvbmAsXG4gICAgdGltZW91dDogQ0RQX1JFUV9USU1FT1VULFxuICB9KSkuZGF0YTtcbn1cblxuLyoqXG4gKiBUYWtlIGEgd2VidmlldyBuYW1lIGxpa2UgV0VCVklFV180Mjk2IGFuZCB1c2UgJ2FkYiBzaGVsbCBwcycgdG8gZmlndXJlIG91dFxuICogd2hpY2ggYXBwIHBhY2thZ2UgaXMgYXNzb2NpYXRlZCB3aXRoIHRoYXQgd2Vidmlldy4gT25lIG9mIHRoZSByZWFzb25zIHdlXG4gKiB3YW50IHRvIGRvIHRoaXMgaXMgdG8gbWFrZSBzdXJlIHdlJ3JlIGxpc3Rpbmcgd2Vidmlld3MgZm9yIHRoZSBhY3R1YWwgQVVULFxuICogbm90IHNvbWUgb3RoZXIgcnVubmluZyBhcHBcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gYWRiIC0gYW4gQURCIGluc3RhbmNlXG4gKiBAcGFyYW0ge3N0cmluZ30gd2VidmlldyAtIGEgd2VidmlldyBwcm9jZXNzIG5hbWVcbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSAtIHRoZSBwYWNrYWdlIG5hbWUgb2YgdGhlIGFwcCBydW5uaW5nIHRoZSB3ZWJ2aWV3XG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlcmUgd2FzIGEgZmFpbHVyZSB3aGlsZSByZXRyaWV2aW5nIHRoZSBwcm9jZXNzIG5hbWVcbiAqL1xuaGVscGVycy5wcm9jRnJvbVdlYnZpZXcgPSBhc3luYyBmdW5jdGlvbiBwcm9jRnJvbVdlYnZpZXcgKGFkYiwgd2Vidmlldykge1xuICBjb25zdCBwaWRNYXRjaCA9IFdFQlZJRVdfUElEX1BBVFRFUk4uZXhlYyh3ZWJ2aWV3KTtcbiAgaWYgKCFwaWRNYXRjaCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgQ291bGQgbm90IGZpbmQgUElEIGZvciB3ZWJ2aWV3ICcke3dlYnZpZXd9J2ApO1xuICB9XG5cbiAgY29uc3QgcGlkID0gcGlkTWF0Y2hbMV07XG4gIGxvZ2dlci5kZWJ1ZyhgJHt3ZWJ2aWV3fSBtYXBwZWQgdG8gcGlkICR7cGlkfWApO1xuICBsb2dnZXIuZGVidWcoYEdldHRpbmcgcHJvY2VzcyBuYW1lIGZvciB3ZWJ2aWV3ICcke3dlYnZpZXd9J2ApO1xuICBjb25zdCBwa2cgPSBhd2FpdCBhZGIuZ2V0TmFtZUJ5UGlkKHBpZCk7XG4gIGxvZ2dlci5kZWJ1ZyhgR290IHByb2Nlc3MgbmFtZTogJyR7cGtnfSdgKTtcbiAgcmV0dXJuIHBrZztcbn07XG5cbi8qKlxuICogUGFyc2Ugd2VidmlldyBuYW1lcyBmb3IgZ2V0Q29udGV4dHNcbiAqXG4gKiBAcGFyYW0ge0FycmF5PFdlYnZpZXdzTWFwcGluZz59IHdlYnZpZXdzTWFwcGluZyBTZWUgbm90ZSBvbiBnZXRXZWJWaWV3c01hcHBpbmdcbiAqIEBwYXJhbSB7R2V0V2Vidmlld3NPcHRzfSBvcHRzIFNlZSBub3RlIG9uIGdldFdlYlZpZXdzTWFwcGluZ1xuICogQHJldHVybiB7QXJyYXkuPHN0cmluZz59IC0gYSBsaXN0IG9mIHdlYnZpZXcgbmFtZXNcbiAqL1xuaGVscGVycy5wYXJzZVdlYnZpZXdOYW1lcyA9IGZ1bmN0aW9uIHBhcnNlV2Vidmlld05hbWVzICh3ZWJ2aWV3c01hcHBpbmcsIHtcbiAgZW5zdXJlV2Vidmlld3NIYXZlUGFnZXMgPSB0cnVlLFxuICBpc0Nocm9tZVNlc3Npb24gPSBmYWxzZVxufSA9IHt9KSB7XG4gIGlmIChpc0Nocm9tZVNlc3Npb24pIHtcbiAgICByZXR1cm4gW0NIUk9NSVVNX1dJTl07XG4gIH1cblxuICBjb25zdCByZXN1bHQgPSBbXTtcbiAgZm9yIChjb25zdCB7d2VidmlldywgcGFnZXMsIHByb2MsIHdlYnZpZXdOYW1lfSBvZiB3ZWJ2aWV3c01hcHBpbmcpIHtcbiAgICBpZiAoZW5zdXJlV2Vidmlld3NIYXZlUGFnZXMgJiYgcGFnZXM/Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgbG9nZ2VyLmluZm8oYFNraXBwaW5nIHRoZSB3ZWJ2aWV3ICcke3dlYnZpZXd9JyBhdCAnJHtwcm9jfScgYCArXG4gICAgICAgIGBzaW5jZSBpdCBoYXMgcmVwb3J0ZWQgaGF2aW5nIHplcm8gcGFnZXNgKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAod2Vidmlld05hbWUpIHtcbiAgICAgIHJlc3VsdC5wdXNoKHdlYnZpZXdOYW1lKTtcbiAgICB9XG4gIH1cbiAgbG9nZ2VyLmRlYnVnKGBGb3VuZCAke3V0aWwucGx1cmFsaXplKCd3ZWJ2aWV3JywgcmVzdWx0Lmxlbmd0aCwgdHJ1ZSl9OiAke0pTT04uc3RyaW5naWZ5KHJlc3VsdCl9YCk7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEdldFdlYnZpZXdzT3B0c1xuICogQHByb3BlcnR5IHtzdHJpbmd9IGFuZHJvaWREZXZpY2VTb2NrZXQgW251bGxdIC0gZGV2aWNlIHNvY2tldCBuYW1lXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGVuc3VyZVdlYnZpZXdzSGF2ZVBhZ2VzIFt0cnVlXSAtIHdoZXRoZXIgdG8gY2hlY2sgZm9yIHdlYnZpZXdcbiAqIHBhZ2UgcHJlc2VuY2VcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB3ZWJ2aWV3RGV2dG9vbHNQb3J0IFs5MjIyXSAtIHBvcnQgdG8gdXNlIGZvciB3ZWJ2aWV3IHBhZ2VcbiAqIHByZXNlbmNlIGNoZWNrLlxuICogQHByb3BlcnR5IHtib29sZWFufSBlbmFibGVXZWJ2aWV3RGV0YWlsc0NvbGxlY3Rpb24gW3RydWVdIC0gd2hldGhlciB0byBjb2xsZWN0XG4gKiB3ZWIgdmlldyBkZXRhaWxzIGFuZCBzZW5kIHRoZW0gdG8gQ2hyb21lZHJpdmVyIGNvbnN0cnVjdG9yLCBzbyBpdCBjb3VsZFxuICogc2VsZWN0IGEgYmluYXJ5IG1vcmUgcHJlY2lzZWx5IGJhc2VkIG9uIHRoaXMgaW5mby5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFdlYnZpZXdzTWFwcGluZ1xuICogQHByb3BlcnR5IHtzdHJpbmd9IHByb2MgU2VlIG5vdGUgb24gV2Vidmlld1Byb3BzXG4gKiBAcHJvcGVydHkge3N0cmluZ30gd2VidmlldyBTZWUgbm90ZSBvbiBXZWJ2aWV3UHJvcHNcbiAqIEBwcm9wZXJ0eSB7P09iamVjdH0gaW5mbyBTZWUgbm90ZSBvbiBXZWJ2aWV3UHJvcHNcbiAqIEBwcm9wZXJ0eSB7P0FycmF5PE9iamVjdD59IHBhZ2VzIFNlZSBub3RlIG9uIFdlYnZpZXdQcm9wc1xuICogQHByb3Blcnkgez9zdHJpbmd9IHdlYnZpZXdOYW1lIEFuIGFjdHVhbCB3ZWJ2aWV3IG5hbWUgZm9yIHN3aXRjaGluZyBjb250ZXh0XG4gKi9cblxuLyoqXG4gKiBHZXQgYSBsaXN0IG9mIGF2YWlsYWJsZSB3ZWJ2aWV3cyBtYXBwaW5nIGJ5IGludHJvc3BlY3RpbmcgcHJvY2Vzc2VzIHdpdGggYWRiLFxuICogd2hlcmUgd2Vidmlld3MgYXJlIGxpc3RlZC4gSXQncyBwb3NzaWJsZSB0byBwYXNzIGluIGEgJ2RldmljZVNvY2tldCcgYXJnLCB3aGljaFxuICogbGltaXRzIHRoZSB3ZWJ2aWV3IHBvc3NpYmlsaXRpZXMgdG8gdGhlIG9uZSBydW5uaW5nIG9uIHRoZSBDaHJvbWl1bSBkZXZ0b29sc1xuICogc29ja2V0IHdlJ3JlIGludGVyZXN0ZWQgaW4gKHNlZSBub3RlIG9uIHdlYnZpZXdzRnJvbVByb2NzKS4gV2UgY2FuIGFsc29cbiAqIGRpcmVjdCB0aGlzIG1ldGhvZCB0byB2ZXJpZnkgd2hldGhlciBhIHBhcnRpY3VsYXIgd2VidmlldyBwcm9jZXNzIGFjdHVhbGx5XG4gKiBoYXMgYW55IHBhZ2VzIChpZiBhIHByb2Nlc3MgZXhpc3RzIGJ1dCBubyBwYWdlcyBhcmUgZm91bmQsIENocm9tZWRyaXZlciB3aWxsXG4gKiBub3QgYWN0dWFsbHkgYmUgYWJsZSB0byBjb25uZWN0IHRvIGl0LCBzbyB0aGlzIHNlcnZlcyBhcyBhIGd1YXJkIGZvciB0aGF0XG4gKiBzdHJhbmdlIGZhaWx1cmUgbW9kZSkuIFRoZSBzdHJhdGVneSBmb3IgY2hlY2tpbmcgd2hldGhlciBhbnkgcGFnZXMgYXJlXG4gKiBhY3RpdmUgaW52b2x2ZXMgc2VuZGluZyBhIHJlcXVlc3QgdG8gdGhlIHJlbW90ZSBkZWJ1ZyBzZXJ2ZXIgb24gdGhlIGRldmljZSxcbiAqIGhlbmNlIGl0IGlzIGFsc28gcG9zc2libGUgdG8gc3BlY2lmeSB0aGUgcG9ydCBvbiB0aGUgaG9zdCBtYWNoaW5lIHdoaWNoXG4gKiBzaG91bGQgYmUgdXNlZCBmb3IgdGhpcyBjb21tdW5pY2F0aW9uLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBhZGIgLSBhbiBBREIgaW5zdGFuY2VcbiAqIEBwYXJhbSB7R2V0V2Vidmlld3NPcHRzfSBvcHRzXG4gKlxuICogQHJldHVybiB7QXJyYXk8V2Vidmlld3NNYXBwaW5nPn0gd2Vidmlld3NNYXBwaW5nXG4gKi9cbmhlbHBlcnMuZ2V0V2ViVmlld3NNYXBwaW5nID0gYXN5bmMgZnVuY3Rpb24gZ2V0V2ViVmlld3NNYXBwaW5nIChhZGIsIHtcbiAgYW5kcm9pZERldmljZVNvY2tldCA9IG51bGwsXG4gIGVuc3VyZVdlYnZpZXdzSGF2ZVBhZ2VzID0gdHJ1ZSxcbiAgd2Vidmlld0RldnRvb2xzUG9ydCA9IG51bGwsXG4gIGVuYWJsZVdlYnZpZXdEZXRhaWxzQ29sbGVjdGlvbiA9IHRydWVcbn0gPSB7fSkge1xuICBsb2dnZXIuZGVidWcoJ0dldHRpbmcgYSBsaXN0IG9mIGF2YWlsYWJsZSB3ZWJ2aWV3cycpO1xuICBjb25zdCB3ZWJ2aWV3c01hcHBpbmcgPSBhd2FpdCB3ZWJ2aWV3c0Zyb21Qcm9jcyhhZGIsIGFuZHJvaWREZXZpY2VTb2NrZXQpO1xuXG4gIGF3YWl0IGNvbGxlY3RXZWJ2aWV3c0RldGFpbHMoYWRiLCB3ZWJ2aWV3c01hcHBpbmcsIHtcbiAgICBlbnN1cmVXZWJ2aWV3c0hhdmVQYWdlcyxcbiAgICBlbmFibGVXZWJ2aWV3RGV0YWlsc0NvbGxlY3Rpb24sXG4gICAgd2Vidmlld0RldnRvb2xzUG9ydCxcbiAgfSk7XG5cbiAgZm9yIChjb25zdCB3ZWJ2aWV3TWFwcGluZyBvZiB3ZWJ2aWV3c01hcHBpbmcpIHtcbiAgICBjb25zdCB7d2VidmlldywgaW5mb30gPSB3ZWJ2aWV3TWFwcGluZztcbiAgICB3ZWJ2aWV3TWFwcGluZy53ZWJ2aWV3TmFtZSA9IG51bGw7XG5cbiAgICBsZXQgd3ZOYW1lID0gd2VidmlldztcbiAgICBsZXQgcHJvY2VzcyA9IHVuZGVmaW5lZDtcbiAgICBpZiAoIWFuZHJvaWREZXZpY2VTb2NrZXQpIHtcbiAgICAgIGNvbnN0IHBrZ01hdGNoID0gV0VCVklFV19QS0dfUEFUVEVSTi5leGVjKHdlYnZpZXcpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gd2ViIHZpZXcgbmFtZSBjb3VsZCBlaXRoZXIgYmUgc3VmZml4ZWQgd2l0aCBQSUQgb3IgdGhlIHBhY2thZ2UgbmFtZVxuICAgICAgICAvLyBwYWNrYWdlIG5hbWVzIGNvdWxkIG5vdCBzdGFydCB3aXRoIGEgZGlnaXRcbiAgICAgICAgY29uc3QgcGtnID0gcGtnTWF0Y2ggPyBwa2dNYXRjaFsxXSA6IGF3YWl0IGhlbHBlcnMucHJvY0Zyb21XZWJ2aWV3KGFkYiwgd2Vidmlldyk7XG4gICAgICAgIHd2TmFtZSA9IGAke1dFQlZJRVdfQkFTRX0ke3BrZ31gO1xuICAgICAgICBjb25zdCBwaWRNYXRjaCA9IFdFQlZJRVdfUElEX1BBVFRFUk4uZXhlYyh3ZWJ2aWV3KTtcbiAgICAgICAgcHJvY2VzcyA9IHtcbiAgICAgICAgICBuYW1lOiBwa2csXG4gICAgICAgICAgaWQ6IHBpZE1hdGNoID8gcGlkTWF0Y2hbMV0gOiBudWxsLFxuICAgICAgICB9O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsb2dnZXIud2FybihlLm1lc3NhZ2UpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB3ZWJ2aWV3TWFwcGluZy53ZWJ2aWV3TmFtZSA9IHd2TmFtZTtcbiAgICBjb25zdCBrZXkgPSB0b0RldGFpbHNDYWNoZUtleShhZGIsIHd2TmFtZSk7XG4gICAgaWYgKGluZm8gfHwgcHJvY2Vzcykge1xuICAgICAgV0VCVklFV1NfREVUQUlMU19DQUNIRS5zZXQoa2V5LCB7IGluZm8sIHByb2Nlc3MgfSk7XG4gICAgfSBlbHNlIGlmIChXRUJWSUVXU19ERVRBSUxTX0NBQ0hFLmhhcyhrZXkpKSB7XG4gICAgICBXRUJWSUVXU19ERVRBSUxTX0NBQ0hFLmRlbGV0ZShrZXkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gd2Vidmlld3NNYXBwaW5nO1xufTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBQcm9jZXNzSW5mb1xuICogQHByb3BlcnR5IHtzdHJpbmd9IG5hbWUgVGhlIHByb2Nlc3MgbmFtZVxuICogQHByb3BlcnR5IHs/c3RyaW5nfSBpZCBUaGUgcHJvY2VzcyBpZCAoaWYgY291bGQgYmUgcmV0cmlldmVkKVxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gV2ViVmlld0RldGFpbHNcbiAqIEBwcm9wZXJ0eSB7P1Byb2Nlc3NJbmZvfSBwcm9jZXNzIC0gV2ViIHZpZXcgcHJvY2VzcyBkZXRhaWxzXG4gKiBAcHJvcGVydHkge09iamVjdH0gaW5mbyAtIFdlYiB2aWV3IGRldGFpbHMgYXMgcmV0dXJuZWQgYnkgL2pzb24vdmVyc2lvbiBDRFAgZW5kcG9pbnQsIGZvciBleGFtcGxlOlxuICoge1xuICogIFwiQnJvd3NlclwiOiBcIkNocm9tZS83Mi4wLjM2MDEuMFwiLFxuICogIFwiUHJvdG9jb2wtVmVyc2lvblwiOiBcIjEuM1wiLFxuICogIFwiVXNlci1BZ2VudFwiOiBcIk1vemlsbGEvNS4wIChNYWNpbnRvc2g7IEludGVsIE1hYyBPUyBYIDEwXzEzXzYpIEFwcGxlV2ViS2l0LzUzNy4zNiAoS0hUTUwsIGxpa2UgR2Vja28pIENocm9tZS83Mi4wLjM2MDEuMCBTYWZhcmkvNTM3LjM2XCIsXG4gKiAgXCJWOC1WZXJzaW9uXCI6IFwiNy4yLjIzM1wiLFxuICogIFwiV2ViS2l0LVZlcnNpb25cIjogXCI1MzcuMzYgKEBjZmVkZTlkYjFkMTU0ZGUwNDY4Y2IwNTM4NDc5ZjM0YzA3NTVhMGY0KVwiLFxuICogIFwid2ViU29ja2V0RGVidWdnZXJVcmxcIjogXCJ3czovL2xvY2FsaG9zdDo5MjIyL2RldnRvb2xzL2Jyb3dzZXIvYjBiOGE0ZmItYmIxNy00MzU5LTk1MzMtYThkOWYzOTA4YmQ4XCJcbiAqIH1cbiAqL1xuXG4vKipcbiAqIFJldHJpZXZlcyB3ZWIgdmlldyBkZXRhaWxzIHByZXZpb3VzbHkgY2FjaGVkIGJ5IGBnZXRXZWJ2aWV3c2AgY2FsbFxuICpcbiAqIEBwYXJhbSB7QURCfSBhZGIgQURCIGluc3RhbmNlXG4gKiBAcGFyYW0ge3N0cmluZ30gd2VidmlldyBUaGUgbmFtZSBvZiB0aGUgd2ViIHZpZXdcbiAqIEByZXR1cm5zIHs/V2ViVmlld0RldGFpbHN9IEVpdGhlciBgdW5kZWZpbmVkYCBvciB0aGUgcmVjZW50IHdlYiB2aWV3IGRldGFpbHNcbiAqL1xuaGVscGVycy5nZXRXZWJ2aWV3RGV0YWlscyA9IGZ1bmN0aW9uIGdldFdlYnZpZXdEZXRhaWxzIChhZGIsIHdlYnZpZXcpIHtcbiAgY29uc3Qga2V5ID0gdG9EZXRhaWxzQ2FjaGVLZXkoYWRiLCB3ZWJ2aWV3KTtcbiAgcmV0dXJuIFdFQlZJRVdTX0RFVEFJTFNfQ0FDSEUuZ2V0KGtleSk7XG59O1xuXG4vKipcbiAqIENyZWF0ZSBDaHJvbWUgZHJpdmVyIGNhcGFiaWxpdGllcyBiYXNlZCBvbiB0aGUgcHJvdmlkZWRcbiAqIEFwcGl1bSBjYXBhYmlsaXRpZXNcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0cyBVc2VyLXByb3ZpZGVkIGNhcGFiaWxpdGllcyBvYmplY3RcbiAqIEBwYXJhbSB7c3RyaW5nfSBkZXZpY2VJZCBUaGUgaWRlbnRpZmllciBvZiB0aGUgQW5kcm9pZCBkZXZpY2UgdW5kZXIgdGVzdFxuICogQHBhcmFtIHs/V2ViVmlld0RldGFpbHN9IHdlYlZpZXdEZXRhaWxzXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBUaGUgY2FwYWJpbGl0aWVzIG9iamVjdC5cbiAqIFNlZSBodHRwczovL2Nocm9tZWRyaXZlci5jaHJvbWl1bS5vcmcvY2FwYWJpbGl0aWVzIGZvciBtb3JlIGRldGFpbHMuXG4gKi9cbmhlbHBlcnMuY3JlYXRlQ2hyb21lZHJpdmVyQ2FwcyA9IGZ1bmN0aW9uIGNyZWF0ZUNocm9tZWRyaXZlckNhcHMgKG9wdHMsIGRldmljZUlkLCB3ZWJWaWV3RGV0YWlscykge1xuICBjb25zdCBjYXBzID0geyBjaHJvbWVPcHRpb25zOiB7fSB9O1xuXG4gIGNvbnN0IGFuZHJvaWRQYWNrYWdlID0gb3B0cy5jaHJvbWVPcHRpb25zPy5hbmRyb2lkUGFja2FnZVxuICAgIHx8IG9wdHMuYXBwUGFja2FnZVxuICAgIHx8IHdlYlZpZXdEZXRhaWxzPy5pbmZvPy5bJ0FuZHJvaWQtUGFja2FnZSddO1xuICBpZiAoYW5kcm9pZFBhY2thZ2UpIHtcbiAgICAvLyBjaHJvbWVkcml2ZXIgcmFpc2VzIGFuIGludmFsaWQgYXJndW1lbnQgZXJyb3Igd2hlbiBhbmRyb2lkUGFja2FnZSBpcyAnbnVsbCdcbiAgICBjYXBzLmNocm9tZU9wdGlvbnMuYW5kcm9pZFBhY2thZ2UgPSBhbmRyb2lkUGFja2FnZTtcbiAgfVxuICBpZiAoXy5pc0Jvb2xlYW4ob3B0cy5jaHJvbWVVc2VSdW5uaW5nQXBwKSkge1xuICAgIGNhcHMuY2hyb21lT3B0aW9ucy5hbmRyb2lkVXNlUnVubmluZ0FwcCA9IG9wdHMuY2hyb21lVXNlUnVubmluZ0FwcDtcbiAgfVxuICBpZiAob3B0cy5jaHJvbWVBbmRyb2lkUGFja2FnZSkge1xuICAgIGNhcHMuY2hyb21lT3B0aW9ucy5hbmRyb2lkUGFja2FnZSA9IG9wdHMuY2hyb21lQW5kcm9pZFBhY2thZ2U7XG4gIH1cbiAgaWYgKG9wdHMuY2hyb21lQW5kcm9pZEFjdGl2aXR5KSB7XG4gICAgY2Fwcy5jaHJvbWVPcHRpb25zLmFuZHJvaWRBY3Rpdml0eSA9IG9wdHMuY2hyb21lQW5kcm9pZEFjdGl2aXR5O1xuICB9XG4gIGlmIChvcHRzLmNocm9tZUFuZHJvaWRQcm9jZXNzKSB7XG4gICAgY2Fwcy5jaHJvbWVPcHRpb25zLmFuZHJvaWRQcm9jZXNzID0gb3B0cy5jaHJvbWVBbmRyb2lkUHJvY2VzcztcbiAgfSBlbHNlIGlmICh3ZWJWaWV3RGV0YWlscz8ucHJvY2Vzcz8ubmFtZSAmJiB3ZWJWaWV3RGV0YWlscz8ucHJvY2Vzcz8uaWQpIHtcbiAgICBjYXBzLmNocm9tZU9wdGlvbnMuYW5kcm9pZFByb2Nlc3MgPSB3ZWJWaWV3RGV0YWlscy5wcm9jZXNzLm5hbWU7XG4gIH1cbiAgaWYgKF8udG9Mb3dlcihvcHRzLmJyb3dzZXJOYW1lKSA9PT0gJ2Nocm9taXVtLXdlYnZpZXcnKSB7XG4gICAgY2Fwcy5jaHJvbWVPcHRpb25zLmFuZHJvaWRBY3Rpdml0eSA9IG9wdHMuYXBwQWN0aXZpdHk7XG4gIH1cbiAgaWYgKG9wdHMucGFnZUxvYWRTdHJhdGVneSkge1xuICAgIGNhcHMucGFnZUxvYWRTdHJhdGVneSA9IG9wdHMucGFnZUxvYWRTdHJhdGVneTtcbiAgfVxuICBjb25zdCBpc0Nocm9tZSA9IF8udG9Mb3dlcihjYXBzLmNocm9tZU9wdGlvbnMuYW5kcm9pZFBhY2thZ2UpID09PSAnY2hyb21lJztcbiAgaWYgKF8uaW5jbHVkZXMoS05PV05fQ0hST01FX1BBQ0tBR0VfTkFNRVMsIGNhcHMuY2hyb21lT3B0aW9ucy5hbmRyb2lkUGFja2FnZSkgfHwgaXNDaHJvbWUpIHtcbiAgICAvLyBpZiB3ZSBoYXZlIGV4dHJhY3RlZCBwYWNrYWdlIGZyb20gY29udGV4dCBuYW1lLCBpdCBjb3VsZCBjb21lIGluIGFzIGJhcmVcbiAgICAvLyBcImNocm9tZVwiLCBhbmQgc28gd2Ugc2hvdWxkIG1ha2Ugc3VyZSB0aGUgZGV0YWlscyBhcmUgY29ycmVjdCwgaW5jbHVkaW5nXG4gICAgLy8gbm90IHVzaW5nIGFuIGFjdGl2aXR5IG9yIHByb2Nlc3MgaWRcbiAgICBpZiAoaXNDaHJvbWUpIHtcbiAgICAgIGNhcHMuY2hyb21lT3B0aW9ucy5hbmRyb2lkUGFja2FnZSA9IENIUk9NRV9QQUNLQUdFX05BTUU7XG4gICAgfVxuICAgIGRlbGV0ZSBjYXBzLmNocm9tZU9wdGlvbnMuYW5kcm9pZEFjdGl2aXR5O1xuICAgIGRlbGV0ZSBjYXBzLmNocm9tZU9wdGlvbnMuYW5kcm9pZFByb2Nlc3M7XG4gIH1cbiAgLy8gYWRkIGRldmljZSBpZCBmcm9tIGFkYlxuICBjYXBzLmNocm9tZU9wdGlvbnMuYW5kcm9pZERldmljZVNlcmlhbCA9IGRldmljZUlkO1xuXG4gIGlmIChfLmlzUGxhaW5PYmplY3Qob3B0cy5sb2dnaW5nUHJlZnMpIHx8IF8uaXNQbGFpbk9iamVjdChvcHRzLmNocm9tZUxvZ2dpbmdQcmVmcykpIHtcbiAgICBpZiAob3B0cy5sb2dnaW5nUHJlZnMpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBUaGUgJ2xvZ2dpbmdQcmVmcycgY2FwIGlzIGRlcHJlY2F0ZWQ7IHVzZSB0aGUgJ2Nocm9tZUxvZ2dpbmdQcmVmcycgY2FwIGluc3RlYWRgKTtcbiAgICB9XG4gICAgY2Fwcy5sb2dnaW5nUHJlZnMgPSBvcHRzLmNocm9tZUxvZ2dpbmdQcmVmcyB8fCBvcHRzLmxvZ2dpbmdQcmVmcztcbiAgfVxuICBpZiAob3B0cy5lbmFibGVQZXJmb3JtYW5jZUxvZ2dpbmcpIHtcbiAgICBsb2dnZXIud2FybihgVGhlICdlbmFibGVQZXJmb3JtYW5jZUxvZ2dpbmcnIGNhcCBpcyBkZXByZWNhdGVkOyBzaW1wbHkgdXNlIGAgK1xuICAgICAgYHRoZSAnY2hyb21lTG9nZ2luZ1ByZWZzJyBjYXAgaW5zdGVhZCwgd2l0aCBhICdwZXJmb3JtYW5jZScga2V5IHNldCB0byAnQUxMJ2ApO1xuICAgIGNvbnN0IG5ld1ByZWYgPSB7cGVyZm9ybWFuY2U6ICdBTEwnfTtcbiAgICAvLyBkb24ndCBvdmVyd3JpdGUgb3RoZXIgbG9nZ2luZyBwcmVmcyB0aGF0IGhhdmUgYmVlbiBzZW50IGluIGlmIHRoZXkgZXhpc3RcbiAgICBjYXBzLmxvZ2dpbmdQcmVmcyA9IGNhcHMubG9nZ2luZ1ByZWZzXG4gICAgICA/IE9iamVjdC5hc3NpZ24oe30sIGNhcHMubG9nZ2luZ1ByZWZzLCBuZXdQcmVmKVxuICAgICAgOiBuZXdQcmVmO1xuICB9XG5cbiAgaWYgKG9wdHMuY2hyb21lT3B0aW9ucz8uQXJndW1lbnRzKSB7XG4gICAgLy8gbWVyZ2UgYEFyZ3VtZW50c2AgYW5kIGBhcmdzYFxuICAgIG9wdHMuY2hyb21lT3B0aW9ucy5hcmdzID0gWy4uLihvcHRzLmNocm9tZU9wdGlvbnMuYXJncyB8fCBbXSksIC4uLm9wdHMuY2hyb21lT3B0aW9ucy5Bcmd1bWVudHNdO1xuICAgIGRlbGV0ZSBvcHRzLmNocm9tZU9wdGlvbnMuQXJndW1lbnRzO1xuICB9XG5cbiAgbG9nZ2VyLmRlYnVnKCdQcmVjYWxjdWxhdGVkIENocm9tZWRyaXZlciBjYXBhYmlsaXRpZXM6ICcgK1xuICAgIEpTT04uc3RyaW5naWZ5KGNhcHMuY2hyb21lT3B0aW9ucywgbnVsbCwgMikpO1xuXG4gIGNvbnN0IHByb3RlY3RlZENhcE5hbWVzID0gW107XG4gIGZvciAoY29uc3QgW29wdCwgdmFsXSBvZiBfLnRvUGFpcnMob3B0cy5jaHJvbWVPcHRpb25zKSkge1xuICAgIGlmIChfLmlzVW5kZWZpbmVkKGNhcHMuY2hyb21lT3B0aW9uc1tvcHRdKSkge1xuICAgICAgY2Fwcy5jaHJvbWVPcHRpb25zW29wdF0gPSB2YWw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb3RlY3RlZENhcE5hbWVzLnB1c2gob3B0KTtcbiAgICB9XG4gIH1cbiAgaWYgKCFfLmlzRW1wdHkocHJvdGVjdGVkQ2FwTmFtZXMpKSB7XG4gICAgbG9nZ2VyLmluZm8oJ1RoZSBmb2xsb3dpbmcgQ2hyb21lZHJpdmVyIGNhcGFiaWxpdGllcyBjYW5ub3QgYmUgb3ZlcnJpZGRlbiAnICtcbiAgICAgICdieSB0aGUgcHJvdmlkZWQgY2hyb21lT3B0aW9uczonKTtcbiAgICBmb3IgKGNvbnN0IG9wdE5hbWUgb2YgcHJvdGVjdGVkQ2FwTmFtZXMpIHtcbiAgICAgIGxvZ2dlci5pbmZvKGAgICR7b3B0TmFtZX0gKCR7SlNPTi5zdHJpbmdpZnkob3B0cy5jaHJvbWVPcHRpb25zW29wdE5hbWVdKX0pYCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNhcHM7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBoZWxwZXJzO1xuZXhwb3J0IHsgaGVscGVycywgTkFUSVZFX1dJTiwgV0VCVklFV19XSU4sIFdFQlZJRVdfQkFTRSwgQ0hST01JVU1fV0lOLCBLTk9XTl9DSFJPTUVfUEFDS0FHRV9OQU1FUyB9O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBLE1BQU1BLFVBQVUsR0FBRyxZQUFZO0FBQUM7QUFDaEMsTUFBTUMsV0FBVyxHQUFHLFNBQVM7QUFBQztBQUM5QixNQUFNQyxZQUFZLEdBQUcsVUFBVTtBQUFDO0FBQ2hDLE1BQU1DLFlBQVksR0FBSSxHQUFFRixXQUFZLEdBQUU7QUFBQztBQUN2QyxNQUFNRyxtQkFBbUIsR0FB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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webview-helpers.js","names":["NATIVE_WIN","WEBVIEW_WIN","CHROMIUM_WIN","WEBVIEW_BASE","WEBVIEW_PID_PATTERN","RegExp","WEBVIEW_PKG_PATTERN","DEVTOOLS_SOCKET_PATTERN","CROSSWALK_SOCKET_PATTERN","CHROMIUM_DEVTOOLS_SOCKET","CHROME_PACKAGE_NAME","KNOWN_CHROME_PACKAGE_NAMES","DEVTOOLS_PORTS_RANGE","WEBVIEWS_DETAILS_CACHE","LRU","max","updateAgeOnGet","CDP_REQ_TIMEOUT","DEVTOOLS_PORT_ALLOCATION_GUARD","util","getLockFileGuard","path","resolve","os","tmpdir","timeout","tryRecovery","helpers","toDetailsCacheKey","adb","webview","curDeviceId","getPotentialWebviewProcs","out","shell","names","allMatches","line","split","flags","st","sockPath","trim","startsWith","push","test","_","isEmpty","logger","debug","JSON","stringify","length","pluralize","uniq","webviewsFromProcs","deviceSocket","socketNames","webviews","socketName","proc","socketNameMatch","exec","crosswalkMatch","allocateDevtoolsPort","webviewDevtoolsPort","remotePort","replace","startPort","endPort","localPort","findAPortNotInUse","e","Error","adbExec","collectWebviewsDetails","webviewsMapping","opts","ensureWebviewsHavePages","enableWebviewDetailsCollection","info","detailCollectors","item","cdpInfo","pages","cdpList","removePortForward","B","all","axios","url","data","procFromWebview","pidMatch","pid","pkg","getNameByPid","parseWebviewNames","isChromeSession","result","webviewName","getWebViewsMapping","androidDeviceSocket","webviewMapping","wvName","process","undefined","pkgMatch","name","id","warn","message","key","set","has","delete","getWebviewDetails","get","createChromedriverCaps","deviceId","webViewDetails","caps","chromeOptions","androidPackage","appPackage","isBoolean","chromeUseRunningApp","androidUseRunningApp","chromeAndroidPackage","chromeAndroidActivity","androidActivity","chromeAndroidProcess","androidProcess","toLower","browserName","appActivity","pageLoadStrategy","isChrome","includes","androidDeviceSerial","isPlainObject","loggingPrefs","chromeLoggingPrefs","enablePerformanceLogging","newPref","performance","Object","assign","Arguments","args","protectedCapNames","opt","val","toPairs","isUndefined","optName"],"sources":["../../lib/webview-helpers.js"],"sourcesContent":["import _ from 'lodash';\nimport logger from './logger';\nimport axios from 'axios';\nimport { util } from '@appium/support';\nimport { findAPortNotInUse } from 'portscanner';\nimport LRU from 'lru-cache';\nimport B from 'bluebird';\nimport path from 'path';\nimport os from 'os';\n\nconst NATIVE_WIN = 'NATIVE_APP';\nconst WEBVIEW_WIN = 'WEBVIEW';\nconst CHROMIUM_WIN = 'CHROMIUM';\nconst WEBVIEW_BASE = `${WEBVIEW_WIN}_`;\nconst WEBVIEW_PID_PATTERN = new RegExp(`^${WEBVIEW_BASE}(\\\\d+)`);\nconst WEBVIEW_PKG_PATTERN = new RegExp(`^${WEBVIEW_BASE}([^\\\\d\\\\s][\\\\w.]*)`);\nconst DEVTOOLS_SOCKET_PATTERN = /@[\\w.]+_devtools_remote_?(\\d+)?\\b/;\nconst CROSSWALK_SOCKET_PATTERN = /@([\\w.]+)_devtools_remote\\b/;\nconst CHROMIUM_DEVTOOLS_SOCKET = 'chrome_devtools_remote';\nconst CHROME_PACKAGE_NAME = 'com.android.chrome';\nconst KNOWN_CHROME_PACKAGE_NAMES = [\n CHROME_PACKAGE_NAME,\n 'com.chrome.beta',\n 'com.chrome.dev',\n 'com.chrome.canary',\n];\nconst DEVTOOLS_PORTS_RANGE = [10900, 11000];\nconst WEBVIEWS_DETAILS_CACHE = new LRU({\n max: 100,\n updateAgeOnGet: true,\n});\nconst CDP_REQ_TIMEOUT = 2000; // ms\nconst DEVTOOLS_PORT_ALLOCATION_GUARD = util.getLockFileGuard(\n path.resolve(os.tmpdir(), 'android_devtools_port_guard'),\n {timeout: 7, tryRecovery: true}\n);\n\nconst helpers = {};\n\nfunction toDetailsCacheKey (adb, webview) {\n return `${adb?.curDeviceId}:${webview}`;\n}\n\n/**\n * This function gets a list of android system processes and returns ones\n * that look like webviews\n * See https://cs.chromium.org/chromium/src/chrome/browser/devtools/device/android_device_info_query.cc\n * for more details\n *\n * @param {object} adb - an ADB instance\n *\n * @return {Array.<string>} - a list of matching webview socket names (including the leading '@')\n */\nasync function getPotentialWebviewProcs (adb) {\n const out = await adb.shell(['cat', '/proc/net/unix']);\n const names = [];\n const allMatches = [];\n for (const line of out.split('\\n')) {\n // Num RefCount Protocol Flags Type St Inode Path\n const [,,, flags,, st,, sockPath] = line.trim().split(/\\s+/);\n if (!sockPath) {\n continue;\n }\n if (sockPath.startsWith('@')) {\n allMatches.push(line.trim());\n }\n if (flags !== '00010000' || st !== '01') {\n continue;\n }\n if (!DEVTOOLS_SOCKET_PATTERN.test(sockPath)) {\n continue;\n }\n\n names.push(sockPath);\n }\n if (_.isEmpty(names)) {\n logger.debug('Found no active devtools sockets');\n if (!_.isEmpty(allMatches)) {\n logger.debug(`Other sockets are: ${JSON.stringify(allMatches, null, 2)}`);\n }\n } else {\n logger.debug(`Parsed ${names.length} active devtools ${util.pluralize('socket', names.length, false)}: ` +\n JSON.stringify(names));\n }\n // sometimes the webview process shows up multiple times per app\n return _.uniq(names);\n}\n\n/**\n * @typedef {Object} WebviewProc\n * @property {string} proc - The webview process name (as returned by\n * getPotentialWebviewProcs\n * @property {string} webview - The actual webview context name\n */\n/**\n * This function retrieves a list of system processes that look like webviews,\n * and returns them along with the webview context name appropriate for it.\n * If we pass in a deviceSocket, we only attempt to find webviews which match\n * that socket name (this is for apps which embed Chromium, which isn't the\n * same as chrome-backed webviews).\n *\n * @param {object} adb - an ADB instance\n * @param {?string} deviceSocket - the explictly-named device socket to use\n *\n * @return {Array.<WebviewProc>}\n */\nasync function webviewsFromProcs (adb, deviceSocket = null) {\n const socketNames = await getPotentialWebviewProcs(adb);\n const webviews = [];\n for (const socketName of socketNames) {\n if (deviceSocket === CHROMIUM_DEVTOOLS_SOCKET && socketName === `@${deviceSocket}`) {\n webviews.push({\n proc: socketName,\n webview: CHROMIUM_WIN,\n });\n continue;\n }\n\n const socketNameMatch = DEVTOOLS_SOCKET_PATTERN.exec(socketName);\n if (!socketNameMatch) {\n continue;\n }\n const crosswalkMatch = CROSSWALK_SOCKET_PATTERN.exec(socketName);\n if (!socketNameMatch[1] && !crosswalkMatch) {\n continue;\n }\n\n if (deviceSocket && socketName === `@${deviceSocket}` || !deviceSocket) {\n webviews.push({\n proc: socketName,\n webview: socketNameMatch[1]\n ? `${WEBVIEW_BASE}${socketNameMatch[1]}`\n : `${WEBVIEW_BASE}${crosswalkMatch[1]}`,\n });\n }\n }\n return webviews;\n}\n\n/**\n * Allocates a local port for devtools communication\n *\n * @param {ADB} adb ADB instance\n * @param {string} socketName The remote Unix socket name\n * @param {?number} webviewDevtoolsPort The local port number or null to apply\n * autodetection\n * @returns {number} The local port number if the remote socket has been forwarded\n * successfully or `null` otherwise\n * @throws {Error} If there was an error while allocating the local port\n */\nasync function allocateDevtoolsPort (adb, socketName, webviewDevtoolsPort = null) {\n // socket names come with '@', but this should not be a part of the abstract\n // remote port, so remove it\n const remotePort = socketName.replace(/^@/, '');\n let [startPort, endPort] = DEVTOOLS_PORTS_RANGE;\n if (webviewDevtoolsPort) {\n endPort = webviewDevtoolsPort + (endPort - startPort);\n startPort = webviewDevtoolsPort;\n }\n logger.debug(`Forwarding remote port ${remotePort} to a local ` +\n `port in range ${startPort}..${endPort}`);\n if (!webviewDevtoolsPort) {\n logger.debug(`You could use the 'webviewDevtoolsPort' capability to customize ` +\n `the starting port number`);\n }\n return await DEVTOOLS_PORT_ALLOCATION_GUARD(async () => {\n let localPort;\n try {\n localPort = await findAPortNotInUse(startPort, endPort);\n } catch (e) {\n throw new Error(`Cannot find any free port to forward the Devtools socket ` +\n `in range ${startPort}..${endPort}. You could set the starting port number ` +\n `manually by providing the 'webviewDevtoolsPort' capability`);\n }\n await adb.adbExec(['forward', `tcp:${localPort}`, `localabstract:${remotePort}`]);\n return localPort;\n });\n}\n\n/**\n * @typedef {Object} WebviewProps\n * @property {string} proc The name of the Devtools Unix socket\n * @property {string} webview The web view alias. Looks like `WEBVIEW_`\n * prefix plus PID or package name\n * @property {?Object} info Webview information as it is retrieved by\n * /json/version CDP endpoint\n * @property {?Array<Object>} pages Webview pages list as it is retrieved by\n * /json/list CDP endpoint\n */\n\n/**\n * @typedef {Object} DetailCollectionOptions\n * @property {?string|number} webviewDevtoolsPort The starting port to use for webview page\n * presence check (if not the default of 9222).\n * @property {?boolean} ensureWebviewsHavePages Whether to check for webview\n * pages presence\n * @property {boolean} enableWebviewDetailsCollection Whether to collect\n * web view details and send them to Chromedriver constructor, so it could\n * select a binary more precisely based on this info.\n */\n\n/**\n * This is a wrapper for Chrome Debugger Protocol data collection.\n * No error is thrown if CDP request fails - in such case no data will be\n * recorded into the corresponding `webviewsMapping` item.\n *\n * @param {ADB} adb The ADB instance\n * @param {Array<WebviewProps>} webviewsMapping The current webviews mapping\n * !!! Each item of this array gets mutated (`info`/`pages` properties get added\n * based on the provided `opts`) if the requested details have been\n * successfully retrieved for it !!!\n * @param {DetailCollectionOptions} opts If both `ensureWebviewsHavePages` and\n * `enableWebviewDetailsCollection` properties are falsy then no details collection\n * is performed\n */\nasync function collectWebviewsDetails (adb, webviewsMapping, opts = {}) {\n if (_.isEmpty(webviewsMapping)) {\n return;\n }\n\n const {\n webviewDevtoolsPort = null,\n ensureWebviewsHavePages = null,\n enableWebviewDetailsCollection = null,\n } = opts;\n\n if (!ensureWebviewsHavePages) {\n logger.info(`Not checking whether webviews have active pages; use the ` +\n `'ensureWebviewsHavePages' cap to turn this check on`);\n }\n\n if (!enableWebviewDetailsCollection) {\n logger.info(`Not collecting web view details. Details collection might help ` +\n `to make Chromedriver initialization more precise. Use the 'enableWebviewDetailsCollection' ` +\n `cap to turn it on`);\n }\n\n if (!ensureWebviewsHavePages && !enableWebviewDetailsCollection) {\n return;\n }\n\n // Connect to each devtools socket and retrieve web view details\n logger.debug(`Collecting CDP data of ${util.pluralize('webview', webviewsMapping.length, true)}`);\n const detailCollectors = [];\n for (const item of webviewsMapping) {\n detailCollectors.push((async () => {\n let localPort;\n try {\n localPort = await allocateDevtoolsPort(adb, item.proc, webviewDevtoolsPort);\n if (enableWebviewDetailsCollection) {\n item.info = await cdpInfo(localPort);\n }\n if (ensureWebviewsHavePages) {\n item.pages = await cdpList(localPort);\n }\n } catch (e) {\n logger.debug(e);\n } finally {\n if (localPort) {\n await adb.removePortForward(localPort);\n }\n }\n })());\n }\n await B.all(detailCollectors);\n logger.debug(`CDP data collection completed`);\n}\n\n// https://chromedevtools.github.io/devtools-protocol/\nasync function cdpList (localPort) {\n return (await axios({\n url: `http://127.0.0.1:${localPort}/json/list`,\n timeout: CDP_REQ_TIMEOUT,\n })).data;\n}\n\n// https://chromedevtools.github.io/devtools-protocol/\nasync function cdpInfo (localPort) {\n return (await axios({\n url: `http://127.0.0.1:${localPort}/json/version`,\n timeout: CDP_REQ_TIMEOUT,\n })).data;\n}\n\n/**\n * Take a webview name like WEBVIEW_4296 and use 'adb shell ps' to figure out\n * which app package is associated with that webview. One of the reasons we\n * want to do this is to make sure we're listing webviews for the actual AUT,\n * not some other running app\n *\n * @param {object} adb - an ADB instance\n * @param {string} webview - a webview process name\n *\n * @returns {string} - the package name of the app running the webview\n * @throws {Error} If there was a failure while retrieving the process name\n */\nhelpers.procFromWebview = async function procFromWebview (adb, webview) {\n const pidMatch = WEBVIEW_PID_PATTERN.exec(webview);\n if (!pidMatch) {\n throw new Error(`Could not find PID for webview '${webview}'`);\n }\n\n const pid = pidMatch[1];\n logger.debug(`${webview} mapped to pid ${pid}`);\n logger.debug(`Getting process name for webview '${webview}'`);\n const pkg = await adb.getNameByPid(pid);\n logger.debug(`Got process name: '${pkg}'`);\n return pkg;\n};\n\n/**\n * Parse webview names for getContexts\n *\n * @param {Array<WebviewsMapping>} webviewsMapping See note on getWebViewsMapping\n * @param {GetWebviewsOpts} opts See note on getWebViewsMapping\n * @return {Array.<string>} - a list of webview names\n */\nhelpers.parseWebviewNames = function parseWebviewNames (webviewsMapping, {\n ensureWebviewsHavePages = true,\n isChromeSession = false\n} = {}) {\n if (isChromeSession) {\n return [CHROMIUM_WIN];\n }\n\n const result = [];\n for (const {webview, pages, proc, webviewName} of webviewsMapping) {\n if (ensureWebviewsHavePages && pages?.length === 0) {\n logger.info(`Skipping the webview '${webview}' at '${proc}' ` +\n `since it has reported having zero pages`);\n continue;\n }\n if (webviewName) {\n result.push(webviewName);\n }\n }\n logger.debug(`Found ${util.pluralize('webview', result.length, true)}: ${JSON.stringify(result)}`);\n return result;\n};\n\n/**\n * @typedef {Object} GetWebviewsOpts\n * @property {string} androidDeviceSocket [null] - device socket name\n * @property {boolean} ensureWebviewsHavePages [true] - whether to check for webview\n * page presence\n * @property {number} webviewDevtoolsPort [9222] - port to use for webview page\n * presence check.\n * @property {boolean} enableWebviewDetailsCollection [true] - whether to collect\n * web view details and send them to Chromedriver constructor, so it could\n * select a binary more precisely based on this info.\n */\n\n/**\n * @typedef {Object} WebviewsMapping\n * @property {string} proc See note on WebviewProps\n * @property {string} webview See note on WebviewProps\n * @property {?Object} info See note on WebviewProps\n * @property {?Array<Object>} pages See note on WebviewProps\n * @propery {?string} webviewName An actual webview name for switching context\n */\n\n/**\n * Get a list of available webviews mapping by introspecting processes with adb,\n * where webviews are listed. It's possible to pass in a 'deviceSocket' arg, which\n * limits the webview possibilities to the one running on the Chromium devtools\n * socket we're interested in (see note on webviewsFromProcs). We can also\n * direct this method to verify whether a particular webview process actually\n * has any pages (if a process exists but no pages are found, Chromedriver will\n * not actually be able to connect to it, so this serves as a guard for that\n * strange failure mode). The strategy for checking whether any pages are\n * active involves sending a request to the remote debug server on the device,\n * hence it is also possible to specify the port on the host machine which\n * should be used for this communication.\n *\n * @param {object} adb - an ADB instance\n * @param {GetWebviewsOpts} opts\n *\n * @return {Array<WebviewsMapping>} webviewsMapping\n */\nhelpers.getWebViewsMapping = async function getWebViewsMapping (adb, {\n androidDeviceSocket = null,\n ensureWebviewsHavePages = true,\n webviewDevtoolsPort = null,\n enableWebviewDetailsCollection = true\n} = {}) {\n logger.debug('Getting a list of available webviews');\n const webviewsMapping = await webviewsFromProcs(adb, androidDeviceSocket);\n\n await collectWebviewsDetails(adb, webviewsMapping, {\n ensureWebviewsHavePages,\n enableWebviewDetailsCollection,\n webviewDevtoolsPort,\n });\n\n for (const webviewMapping of webviewsMapping) {\n const {webview, info} = webviewMapping;\n webviewMapping.webviewName = null;\n\n let wvName = webview;\n let process = undefined;\n if (!androidDeviceSocket) {\n const pkgMatch = WEBVIEW_PKG_PATTERN.exec(webview);\n try {\n // web view name could either be suffixed with PID or the package name\n // package names could not start with a digit\n const pkg = pkgMatch ? pkgMatch[1] : await helpers.procFromWebview(adb, webview);\n wvName = `${WEBVIEW_BASE}${pkg}`;\n const pidMatch = WEBVIEW_PID_PATTERN.exec(webview);\n process = {\n name: pkg,\n id: pidMatch ? pidMatch[1] : null,\n };\n } catch (e) {\n logger.warn(e.message);\n continue;\n }\n }\n\n webviewMapping.webviewName = wvName;\n const key = toDetailsCacheKey(adb, wvName);\n if (info || process) {\n WEBVIEWS_DETAILS_CACHE.set(key, { info, process });\n } else if (WEBVIEWS_DETAILS_CACHE.has(key)) {\n WEBVIEWS_DETAILS_CACHE.delete(key);\n }\n }\n return webviewsMapping;\n};\n\n/**\n * @typedef {Object} ProcessInfo\n * @property {string} name The process name\n * @property {?string} id The process id (if could be retrieved)\n */\n\n/**\n * @typedef {Object} WebViewDetails\n * @property {?ProcessInfo} process - Web view process details\n * @property {Object} info - Web view details as returned by /json/version CDP endpoint, for example:\n * {\n * \"Browser\": \"Chrome/72.0.3601.0\",\n * \"Protocol-Version\": \"1.3\",\n * \"User-Agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3601.0 Safari/537.36\",\n * \"V8-Version\": \"7.2.233\",\n * \"WebKit-Version\": \"537.36 (@cfede9db1d154de0468cb0538479f34c0755a0f4)\",\n * \"webSocketDebuggerUrl\": \"ws://localhost:9222/devtools/browser/b0b8a4fb-bb17-4359-9533-a8d9f3908bd8\"\n * }\n */\n\n/**\n * Retrieves web view details previously cached by `getWebviews` call\n *\n * @param {ADB} adb ADB instance\n * @param {string} webview The name of the web view\n * @returns {?WebViewDetails} Either `undefined` or the recent web view details\n */\nhelpers.getWebviewDetails = function getWebviewDetails (adb, webview) {\n const key = toDetailsCacheKey(adb, webview);\n return WEBVIEWS_DETAILS_CACHE.get(key);\n};\n\n/**\n * Create Chrome driver capabilities based on the provided\n * Appium capabilities\n *\n * @param {Object} opts User-provided capabilities object\n * @param {string} deviceId The identifier of the Android device under test\n * @param {?WebViewDetails} webViewDetails\n * @returns {Object} The capabilities object.\n * See https://chromedriver.chromium.org/capabilities for more details.\n */\nhelpers.createChromedriverCaps = function createChromedriverCaps (opts, deviceId, webViewDetails) {\n const caps = { chromeOptions: {} };\n\n const androidPackage = opts.chromeOptions?.androidPackage\n || opts.appPackage\n || webViewDetails?.info?.['Android-Package'];\n if (androidPackage) {\n // chromedriver raises an invalid argument error when androidPackage is 'null'\n caps.chromeOptions.androidPackage = androidPackage;\n }\n if (_.isBoolean(opts.chromeUseRunningApp)) {\n caps.chromeOptions.androidUseRunningApp = opts.chromeUseRunningApp;\n }\n if (opts.chromeAndroidPackage) {\n caps.chromeOptions.androidPackage = opts.chromeAndroidPackage;\n }\n if (opts.chromeAndroidActivity) {\n caps.chromeOptions.androidActivity = opts.chromeAndroidActivity;\n }\n if (opts.chromeAndroidProcess) {\n caps.chromeOptions.androidProcess = opts.chromeAndroidProcess;\n } else if (webViewDetails?.process?.name && webViewDetails?.process?.id) {\n caps.chromeOptions.androidProcess = webViewDetails.process.name;\n }\n if (_.toLower(opts.browserName) === 'chromium-webview') {\n caps.chromeOptions.androidActivity = opts.appActivity;\n }\n if (opts.pageLoadStrategy) {\n caps.pageLoadStrategy = opts.pageLoadStrategy;\n }\n const isChrome = _.toLower(caps.chromeOptions.androidPackage) === 'chrome';\n if (_.includes(KNOWN_CHROME_PACKAGE_NAMES, caps.chromeOptions.androidPackage) || isChrome) {\n // if we have extracted package from context name, it could come in as bare\n // \"chrome\", and so we should make sure the details are correct, including\n // not using an activity or process id\n if (isChrome) {\n caps.chromeOptions.androidPackage = CHROME_PACKAGE_NAME;\n }\n delete caps.chromeOptions.androidActivity;\n delete caps.chromeOptions.androidProcess;\n }\n // add device id from adb\n caps.chromeOptions.androidDeviceSerial = deviceId;\n\n if (_.isPlainObject(opts.loggingPrefs) || _.isPlainObject(opts.chromeLoggingPrefs)) {\n if (opts.loggingPrefs) {\n logger.warn(`The 'loggingPrefs' cap is deprecated; use the 'chromeLoggingPrefs' cap instead`);\n }\n caps.loggingPrefs = opts.chromeLoggingPrefs || opts.loggingPrefs;\n }\n if (opts.enablePerformanceLogging) {\n logger.warn(`The 'enablePerformanceLogging' cap is deprecated; simply use ` +\n `the 'chromeLoggingPrefs' cap instead, with a 'performance' key set to 'ALL'`);\n const newPref = {performance: 'ALL'};\n // don't overwrite other logging prefs that have been sent in if they exist\n caps.loggingPrefs = caps.loggingPrefs\n ? Object.assign({}, caps.loggingPrefs, newPref)\n : newPref;\n }\n\n if (opts.chromeOptions?.Arguments) {\n // merge `Arguments` and `args`\n opts.chromeOptions.args = [...(opts.chromeOptions.args || []), ...opts.chromeOptions.Arguments];\n delete opts.chromeOptions.Arguments;\n }\n\n logger.debug('Precalculated Chromedriver capabilities: ' +\n JSON.stringify(caps.chromeOptions, null, 2));\n\n const protectedCapNames = [];\n for (const [opt, val] of _.toPairs(opts.chromeOptions)) {\n if (_.isUndefined(caps.chromeOptions[opt])) {\n caps.chromeOptions[opt] = val;\n } else {\n protectedCapNames.push(opt);\n }\n }\n if (!_.isEmpty(protectedCapNames)) {\n logger.info('The following Chromedriver capabilities cannot be overridden ' +\n 'by the provided chromeOptions:');\n for (const optName of protectedCapNames) {\n logger.info(` ${optName} (${JSON.stringify(opts.chromeOptions[optName])})`);\n }\n }\n\n return caps;\n};\n\nexport default helpers;\nexport { helpers, NATIVE_WIN, WEBVIEW_WIN, WEBVIEW_BASE, CHROMIUM_WIN, KNOWN_CHROME_PACKAGE_NAMES };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"webview-helpers.js","names":["NATIVE_WIN","WEBVIEW_WIN","CHROMIUM_WIN","WEBVIEW_BASE","WEBVIEW_PID_PATTERN","RegExp","WEBVIEW_PKG_PATTERN","DEVTOOLS_SOCKET_PATTERN","CROSSWALK_SOCKET_PATTERN","CHROMIUM_DEVTOOLS_SOCKET","CHROME_PACKAGE_NAME","KNOWN_CHROME_PACKAGE_NAMES","DEVTOOLS_PORTS_RANGE","WEBVIEWS_DETAILS_CACHE","LRU","max","updateAgeOnGet","CDP_REQ_TIMEOUT","DEVTOOLS_PORT_ALLOCATION_GUARD","util","getLockFileGuard","path","resolve","os","tmpdir","timeout","tryRecovery","helpers","toDetailsCacheKey","adb","webview","curDeviceId","getPotentialWebviewProcs","out","shell","names","allMatches","line","split","flags","st","sockPath","trim","startsWith","push","test","_","isEmpty","logger","debug","JSON","stringify","length","pluralize","uniq","webviewsFromProcs","deviceSocket","socketNames","webviews","socketName","proc","socketNameMatch","exec","crosswalkMatch","allocateDevtoolsPort","webviewDevtoolsPort","remotePort","replace","startPort","endPort","localPort","findAPortNotInUse","e","Error","adbExec","collectWebviewsDetails","webviewsMapping","opts","ensureWebviewsHavePages","enableWebviewDetailsCollection","info","detailCollectors","item","cdpInfo","pages","cdpList","removePortForward","B","all","axios","url","data","procFromWebview","pidMatch","pid","pkg","getNameByPid","parseWebviewNames","isChromeSession","result","webviewName","getWebViewsMapping","androidDeviceSocket","webviewMapping","wvName","process","undefined","pkgMatch","name","id","warn","message","key","set","has","delete","getWebviewDetails","get","createChromedriverCaps","deviceId","webViewDetails","caps","chromeOptions","androidPackage","appPackage","isBoolean","chromeUseRunningApp","androidUseRunningApp","chromeAndroidPackage","chromeAndroidActivity","androidActivity","chromeAndroidProcess","androidProcess","toLower","browserName","appActivity","pageLoadStrategy","isChrome","includes","androidDeviceSerial","isPlainObject","loggingPrefs","chromeLoggingPrefs","enablePerformanceLogging","newPref","performance","Object","assign","Arguments","args","protectedCapNames","opt","val","toPairs","isUndefined","optName"],"sources":["../../lib/webview-helpers.js"],"sourcesContent":["import _ from 'lodash';\nimport logger from './logger';\nimport axios from 'axios';\nimport { util } from '@appium/support';\nimport { findAPortNotInUse } from 'portscanner';\nimport LRU from 'lru-cache';\nimport B from 'bluebird';\nimport path from 'path';\nimport os from 'os';\n\nconst NATIVE_WIN = 'NATIVE_APP';\nconst WEBVIEW_WIN = 'WEBVIEW';\nconst CHROMIUM_WIN = 'CHROMIUM';\nconst WEBVIEW_BASE = `${WEBVIEW_WIN}_`;\nconst WEBVIEW_PID_PATTERN = new RegExp(`^${WEBVIEW_BASE}(\\\\d+)`);\nconst WEBVIEW_PKG_PATTERN = new RegExp(`^${WEBVIEW_BASE}([^\\\\d\\\\s][\\\\w.]*)`);\nconst DEVTOOLS_SOCKET_PATTERN = /@[\\w.]+_devtools_remote_?(\\d+)?\\b/;\nconst CROSSWALK_SOCKET_PATTERN = /@([\\w.]+)_devtools_remote\\b/;\nconst CHROMIUM_DEVTOOLS_SOCKET = 'chrome_devtools_remote';\nconst CHROME_PACKAGE_NAME = 'com.android.chrome';\nconst KNOWN_CHROME_PACKAGE_NAMES = [\n CHROME_PACKAGE_NAME,\n 'com.chrome.beta',\n 'com.chrome.dev',\n 'com.chrome.canary',\n];\nconst DEVTOOLS_PORTS_RANGE = [10900, 11000];\nconst WEBVIEWS_DETAILS_CACHE = new LRU({\n max: 100,\n updateAgeOnGet: true,\n});\nconst CDP_REQ_TIMEOUT = 2000; // ms\nconst DEVTOOLS_PORT_ALLOCATION_GUARD = util.getLockFileGuard(\n path.resolve(os.tmpdir(), 'android_devtools_port_guard'),\n {timeout: 7, tryRecovery: true}\n);\n\nconst helpers = {};\n\nfunction toDetailsCacheKey (adb, webview) {\n return `${adb?.curDeviceId}:${webview}`;\n}\n\n/**\n * This function gets a list of android system processes and returns ones\n * that look like webviews\n * See https://cs.chromium.org/chromium/src/chrome/browser/devtools/device/android_device_info_query.cc\n * for more details\n *\n * @param {object} adb - an ADB instance\n *\n * @return {Array.<string>} - a list of matching webview socket names (including the leading '@')\n */\nasync function getPotentialWebviewProcs (adb) {\n const out = await adb.shell(['cat', '/proc/net/unix']);\n const names = [];\n const allMatches = [];\n for (const line of out.split('\\n')) {\n // Num RefCount Protocol Flags Type St Inode Path\n const [,,, flags,, st,, sockPath] = line.trim().split(/\\s+/);\n if (!sockPath) {\n continue;\n }\n if (sockPath.startsWith('@')) {\n allMatches.push(line.trim());\n }\n if (flags !== '00010000' || st !== '01') {\n continue;\n }\n if (!DEVTOOLS_SOCKET_PATTERN.test(sockPath)) {\n continue;\n }\n\n names.push(sockPath);\n }\n if (_.isEmpty(names)) {\n logger.debug('Found no active devtools sockets');\n if (!_.isEmpty(allMatches)) {\n logger.debug(`Other sockets are: ${JSON.stringify(allMatches, null, 2)}`);\n }\n } else {\n logger.debug(`Parsed ${names.length} active devtools ${util.pluralize('socket', names.length, false)}: ` +\n JSON.stringify(names));\n }\n // sometimes the webview process shows up multiple times per app\n return _.uniq(names);\n}\n\n/**\n * @typedef {Object} WebviewProc\n * @property {string} proc - The webview process name (as returned by\n * getPotentialWebviewProcs\n * @property {string} webview - The actual webview context name\n */\n/**\n * This function retrieves a list of system processes that look like webviews,\n * and returns them along with the webview context name appropriate for it.\n * If we pass in a deviceSocket, we only attempt to find webviews which match\n * that socket name (this is for apps which embed Chromium, which isn't the\n * same as chrome-backed webviews).\n *\n * @param {object} adb - an ADB instance\n * @param {?string} deviceSocket - the explictly-named device socket to use\n *\n * @return {Array.<WebviewProc>}\n */\nasync function webviewsFromProcs (adb, deviceSocket = null) {\n const socketNames = await getPotentialWebviewProcs(adb);\n const webviews = [];\n for (const socketName of socketNames) {\n if (deviceSocket === CHROMIUM_DEVTOOLS_SOCKET && socketName === `@${deviceSocket}`) {\n webviews.push({\n proc: socketName,\n webview: CHROMIUM_WIN,\n });\n continue;\n }\n\n const socketNameMatch = DEVTOOLS_SOCKET_PATTERN.exec(socketName);\n if (!socketNameMatch) {\n continue;\n }\n const crosswalkMatch = CROSSWALK_SOCKET_PATTERN.exec(socketName);\n if (!socketNameMatch[1] && !crosswalkMatch) {\n continue;\n }\n\n if (deviceSocket && socketName === `@${deviceSocket}` || !deviceSocket) {\n webviews.push({\n proc: socketName,\n webview: socketNameMatch[1]\n ? `${WEBVIEW_BASE}${socketNameMatch[1]}`\n : `${WEBVIEW_BASE}${crosswalkMatch[1]}`,\n });\n }\n }\n return webviews;\n}\n\n/**\n * Allocates a local port for devtools communication\n *\n * @param {ADB} adb ADB instance\n * @param {string} socketName The remote Unix socket name\n * @param {?number} webviewDevtoolsPort The local port number or null to apply\n * autodetection\n * @returns {number} The local port number if the remote socket has been forwarded\n * successfully or `null` otherwise\n * @throws {Error} If there was an error while allocating the local port\n */\nasync function allocateDevtoolsPort (adb, socketName, webviewDevtoolsPort = null) {\n // socket names come with '@', but this should not be a part of the abstract\n // remote port, so remove it\n const remotePort = socketName.replace(/^@/, '');\n let [startPort, endPort] = DEVTOOLS_PORTS_RANGE;\n if (webviewDevtoolsPort) {\n endPort = webviewDevtoolsPort + (endPort - startPort);\n startPort = webviewDevtoolsPort;\n }\n logger.debug(`Forwarding remote port ${remotePort} to a local ` +\n `port in range ${startPort}..${endPort}`);\n if (!webviewDevtoolsPort) {\n logger.debug(`You could use the 'webviewDevtoolsPort' capability to customize ` +\n `the starting port number`);\n }\n return await DEVTOOLS_PORT_ALLOCATION_GUARD(async () => {\n let localPort;\n try {\n localPort = await findAPortNotInUse(startPort, endPort);\n } catch (e) {\n throw new Error(`Cannot find any free port to forward the Devtools socket ` +\n `in range ${startPort}..${endPort}. You could set the starting port number ` +\n `manually by providing the 'webviewDevtoolsPort' capability`);\n }\n await adb.adbExec(['forward', `tcp:${localPort}`, `localabstract:${remotePort}`]);\n return localPort;\n });\n}\n\n/**\n * @typedef {Object} WebviewProps\n * @property {string} proc The name of the Devtools Unix socket\n * @property {string} webview The web view alias. Looks like `WEBVIEW_`\n * prefix plus PID or package name\n * @property {?Object} info Webview information as it is retrieved by\n * /json/version CDP endpoint\n * @property {?Array<Object>} pages Webview pages list as it is retrieved by\n * /json/list CDP endpoint\n */\n\n/**\n * @typedef {Object} DetailCollectionOptions\n * @property {?string|number} webviewDevtoolsPort The starting port to use for webview page\n * presence check (if not the default of 9222).\n * @property {?boolean} ensureWebviewsHavePages Whether to check for webview\n * pages presence\n * @property {boolean} enableWebviewDetailsCollection Whether to collect\n * web view details and send them to Chromedriver constructor, so it could\n * select a binary more precisely based on this info.\n */\n\n/**\n * This is a wrapper for Chrome Debugger Protocol data collection.\n * No error is thrown if CDP request fails - in such case no data will be\n * recorded into the corresponding `webviewsMapping` item.\n *\n * @param {ADB} adb The ADB instance\n * @param {Array<WebviewProps>} webviewsMapping The current webviews mapping\n * !!! Each item of this array gets mutated (`info`/`pages` properties get added\n * based on the provided `opts`) if the requested details have been\n * successfully retrieved for it !!!\n * @param {DetailCollectionOptions} opts If both `ensureWebviewsHavePages` and\n * `enableWebviewDetailsCollection` properties are falsy then no details collection\n * is performed\n */\nasync function collectWebviewsDetails (adb, webviewsMapping, opts = {}) {\n if (_.isEmpty(webviewsMapping)) {\n return;\n }\n\n const {\n webviewDevtoolsPort = null,\n ensureWebviewsHavePages = null,\n enableWebviewDetailsCollection = null,\n } = opts;\n\n if (!ensureWebviewsHavePages) {\n logger.info(`Not checking whether webviews have active pages; use the ` +\n `'ensureWebviewsHavePages' cap to turn this check on`);\n }\n\n if (!enableWebviewDetailsCollection) {\n logger.info(`Not collecting web view details. Details collection might help ` +\n `to make Chromedriver initialization more precise. Use the 'enableWebviewDetailsCollection' ` +\n `cap to turn it on`);\n }\n\n if (!ensureWebviewsHavePages && !enableWebviewDetailsCollection) {\n return;\n }\n\n // Connect to each devtools socket and retrieve web view details\n logger.debug(`Collecting CDP data of ${util.pluralize('webview', webviewsMapping.length, true)}`);\n const detailCollectors = [];\n for (const item of webviewsMapping) {\n detailCollectors.push((async () => {\n let localPort;\n try {\n localPort = await allocateDevtoolsPort(adb, item.proc, webviewDevtoolsPort);\n if (enableWebviewDetailsCollection) {\n item.info = await cdpInfo(localPort);\n }\n if (ensureWebviewsHavePages) {\n item.pages = await cdpList(localPort);\n }\n } catch (e) {\n logger.debug(e);\n } finally {\n if (localPort) {\n await adb.removePortForward(localPort);\n }\n }\n })());\n }\n await B.all(detailCollectors);\n logger.debug(`CDP data collection completed`);\n}\n\n// https://chromedevtools.github.io/devtools-protocol/\nasync function cdpList (localPort) {\n return (await axios({\n url: `http://127.0.0.1:${localPort}/json/list`,\n timeout: CDP_REQ_TIMEOUT,\n })).data;\n}\n\n// https://chromedevtools.github.io/devtools-protocol/\nasync function cdpInfo (localPort) {\n return (await axios({\n url: `http://127.0.0.1:${localPort}/json/version`,\n timeout: CDP_REQ_TIMEOUT,\n })).data;\n}\n\n/**\n * Take a webview name like WEBVIEW_4296 and use 'adb shell ps' to figure out\n * which app package is associated with that webview. One of the reasons we\n * want to do this is to make sure we're listing webviews for the actual AUT,\n * not some other running app\n *\n * @param {object} adb - an ADB instance\n * @param {string} webview - a webview process name\n *\n * @returns {string} - the package name of the app running the webview\n * @throws {Error} If there was a failure while retrieving the process name\n */\nhelpers.procFromWebview = async function procFromWebview (adb, webview) {\n const pidMatch = WEBVIEW_PID_PATTERN.exec(webview);\n if (!pidMatch) {\n throw new Error(`Could not find PID for webview '${webview}'`);\n }\n\n const pid = pidMatch[1];\n logger.debug(`${webview} mapped to pid ${pid}`);\n logger.debug(`Getting process name for webview '${webview}'`);\n const pkg = await adb.getNameByPid(pid);\n logger.debug(`Got process name: '${pkg}'`);\n return pkg;\n};\n\n/**\n * Parse webview names for getContexts\n *\n * @param {Array<WebviewsMapping>} webviewsMapping See note on getWebViewsMapping\n * @param {GetWebviewsOpts} opts See note on getWebViewsMapping\n * @return {Array.<string>} - a list of webview names\n */\nhelpers.parseWebviewNames = function parseWebviewNames (webviewsMapping, {\n ensureWebviewsHavePages = true,\n isChromeSession = false\n} = {}) {\n if (isChromeSession) {\n return [CHROMIUM_WIN];\n }\n\n const result = [];\n for (const {webview, pages, proc, webviewName} of webviewsMapping) {\n if (ensureWebviewsHavePages && pages?.length === 0) {\n logger.info(`Skipping the webview '${webview}' at '${proc}' ` +\n `since it has reported having zero pages`);\n continue;\n }\n if (webviewName) {\n result.push(webviewName);\n }\n }\n logger.debug(`Found ${util.pluralize('webview', result.length, true)}: ${JSON.stringify(result)}`);\n return result;\n};\n\n/**\n * @typedef {Object} GetWebviewsOpts\n * @property {string} androidDeviceSocket [null] - device socket name\n * @property {boolean} ensureWebviewsHavePages [true] - whether to check for webview\n * page presence\n * @property {number} webviewDevtoolsPort [9222] - port to use for webview page\n * presence check.\n * @property {boolean} enableWebviewDetailsCollection [true] - whether to collect\n * web view details and send them to Chromedriver constructor, so it could\n * select a binary more precisely based on this info.\n */\n\n/**\n * @typedef {Object} WebviewsMapping\n * @property {string} proc See note on WebviewProps\n * @property {string} webview See note on WebviewProps\n * @property {?Object} info See note on WebviewProps\n * @property {?Array<Object>} pages See note on WebviewProps\n * @propery {?string} webviewName An actual webview name for switching context\n */\n\n/**\n * Get a list of available webviews mapping by introspecting processes with adb,\n * where webviews are listed. It's possible to pass in a 'deviceSocket' arg, which\n * limits the webview possibilities to the one running on the Chromium devtools\n * socket we're interested in (see note on webviewsFromProcs). We can also\n * direct this method to verify whether a particular webview process actually\n * has any pages (if a process exists but no pages are found, Chromedriver will\n * not actually be able to connect to it, so this serves as a guard for that\n * strange failure mode). The strategy for checking whether any pages are\n * active involves sending a request to the remote debug server on the device,\n * hence it is also possible to specify the port on the host machine which\n * should be used for this communication.\n *\n * @param {object} adb - an ADB instance\n * @param {GetWebviewsOpts} opts\n *\n * @return {Array<WebviewsMapping>} webviewsMapping\n */\nhelpers.getWebViewsMapping = async function getWebViewsMapping (adb, {\n androidDeviceSocket = null,\n ensureWebviewsHavePages = true,\n webviewDevtoolsPort = null,\n enableWebviewDetailsCollection = true\n} = {}) {\n logger.debug('Getting a list of available webviews');\n const webviewsMapping = await webviewsFromProcs(adb, androidDeviceSocket);\n\n await collectWebviewsDetails(adb, webviewsMapping, {\n ensureWebviewsHavePages,\n enableWebviewDetailsCollection,\n webviewDevtoolsPort,\n });\n\n for (const webviewMapping of webviewsMapping) {\n const {webview, info} = webviewMapping;\n webviewMapping.webviewName = null;\n\n let wvName = webview;\n let process = undefined;\n if (!androidDeviceSocket) {\n const pkgMatch = WEBVIEW_PKG_PATTERN.exec(webview);\n try {\n // web view name could either be suffixed with PID or the package name\n // package names could not start with a digit\n const pkg = pkgMatch ? pkgMatch[1] : await helpers.procFromWebview(adb, webview);\n wvName = `${WEBVIEW_BASE}${pkg}`;\n const pidMatch = WEBVIEW_PID_PATTERN.exec(webview);\n process = {\n name: pkg,\n id: pidMatch ? pidMatch[1] : null,\n };\n } catch (e) {\n logger.warn(e.message);\n continue;\n }\n }\n\n webviewMapping.webviewName = wvName;\n const key = toDetailsCacheKey(adb, wvName);\n if (info || process) {\n WEBVIEWS_DETAILS_CACHE.set(key, { info, process });\n } else if (WEBVIEWS_DETAILS_CACHE.has(key)) {\n WEBVIEWS_DETAILS_CACHE.delete(key);\n }\n }\n return webviewsMapping;\n};\n\n/**\n * @typedef {Object} ProcessInfo\n * @property {string} name The process name\n * @property {?string} id The process id (if could be retrieved)\n */\n\n/**\n * @typedef {Object} WebViewDetails\n * @property {?ProcessInfo} process - Web view process details\n * @property {Object} info - Web view details as returned by /json/version CDP endpoint, for example:\n * {\n * \"Browser\": \"Chrome/72.0.3601.0\",\n * \"Protocol-Version\": \"1.3\",\n * \"User-Agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3601.0 Safari/537.36\",\n * \"V8-Version\": \"7.2.233\",\n * \"WebKit-Version\": \"537.36 (@cfede9db1d154de0468cb0538479f34c0755a0f4)\",\n * \"webSocketDebuggerUrl\": \"ws://localhost:9222/devtools/browser/b0b8a4fb-bb17-4359-9533-a8d9f3908bd8\"\n * }\n */\n\n/**\n * Retrieves web view details previously cached by `getWebviews` call\n *\n * @param {ADB} adb ADB instance\n * @param {string} webview The name of the web view\n * @returns {?WebViewDetails} Either `undefined` or the recent web view details\n */\nhelpers.getWebviewDetails = function getWebviewDetails (adb, webview) {\n const key = toDetailsCacheKey(adb, webview);\n return WEBVIEWS_DETAILS_CACHE.get(key);\n};\n\n/**\n * Create Chrome driver capabilities based on the provided\n * Appium capabilities\n *\n * @param {Object} opts User-provided capabilities object\n * @param {string} deviceId The identifier of the Android device under test\n * @param {?WebViewDetails} webViewDetails\n * @returns {Object} The capabilities object.\n * See https://chromedriver.chromium.org/capabilities for more details.\n */\nhelpers.createChromedriverCaps = function createChromedriverCaps (opts, deviceId, webViewDetails) {\n const caps = { chromeOptions: {} };\n\n const androidPackage = opts.chromeOptions?.androidPackage\n || opts.appPackage\n || webViewDetails?.info?.['Android-Package'];\n if (androidPackage) {\n // chromedriver raises an invalid argument error when androidPackage is 'null'\n caps.chromeOptions.androidPackage = androidPackage;\n }\n if (_.isBoolean(opts.chromeUseRunningApp)) {\n caps.chromeOptions.androidUseRunningApp = opts.chromeUseRunningApp;\n }\n if (opts.chromeAndroidPackage) {\n caps.chromeOptions.androidPackage = opts.chromeAndroidPackage;\n }\n if (opts.chromeAndroidActivity) {\n caps.chromeOptions.androidActivity = opts.chromeAndroidActivity;\n }\n if (opts.chromeAndroidProcess) {\n caps.chromeOptions.androidProcess = opts.chromeAndroidProcess;\n } else if (webViewDetails?.process?.name && webViewDetails?.process?.id) {\n caps.chromeOptions.androidProcess = webViewDetails.process.name;\n }\n if (_.toLower(opts.browserName) === 'chromium-webview') {\n caps.chromeOptions.androidActivity = opts.appActivity;\n }\n if (opts.pageLoadStrategy) {\n caps.pageLoadStrategy = opts.pageLoadStrategy;\n }\n const isChrome = _.toLower(caps.chromeOptions.androidPackage) === 'chrome';\n if (_.includes(KNOWN_CHROME_PACKAGE_NAMES, caps.chromeOptions.androidPackage) || isChrome) {\n // if we have extracted package from context name, it could come in as bare\n // \"chrome\", and so we should make sure the details are correct, including\n // not using an activity or process id\n if (isChrome) {\n caps.chromeOptions.androidPackage = CHROME_PACKAGE_NAME;\n }\n delete caps.chromeOptions.androidActivity;\n delete caps.chromeOptions.androidProcess;\n }\n // add device id from adb\n caps.chromeOptions.androidDeviceSerial = deviceId;\n\n if (_.isPlainObject(opts.loggingPrefs) || _.isPlainObject(opts.chromeLoggingPrefs)) {\n if (opts.loggingPrefs) {\n logger.warn(`The 'loggingPrefs' cap is deprecated; use the 'chromeLoggingPrefs' cap instead`);\n }\n caps.loggingPrefs = opts.chromeLoggingPrefs || opts.loggingPrefs;\n }\n if (opts.enablePerformanceLogging) {\n logger.warn(`The 'enablePerformanceLogging' cap is deprecated; simply use ` +\n `the 'chromeLoggingPrefs' cap instead, with a 'performance' key set to 'ALL'`);\n const newPref = {performance: 'ALL'};\n // don't overwrite other logging prefs that have been sent in if they exist\n caps.loggingPrefs = caps.loggingPrefs\n ? Object.assign({}, caps.loggingPrefs, newPref)\n : newPref;\n }\n\n if (opts.chromeOptions?.Arguments) {\n // merge `Arguments` and `args`\n opts.chromeOptions.args = [...(opts.chromeOptions.args || []), ...opts.chromeOptions.Arguments];\n delete opts.chromeOptions.Arguments;\n }\n\n logger.debug('Precalculated Chromedriver capabilities: ' +\n JSON.stringify(caps.chromeOptions, null, 2));\n\n const protectedCapNames = [];\n for (const [opt, val] of _.toPairs(opts.chromeOptions)) {\n if (_.isUndefined(caps.chromeOptions[opt])) {\n caps.chromeOptions[opt] = val;\n } else {\n protectedCapNames.push(opt);\n }\n }\n if (!_.isEmpty(protectedCapNames)) {\n logger.info('The following Chromedriver capabilities cannot be overridden ' +\n 'by the provided chromeOptions:');\n for (const optName of protectedCapNames) {\n logger.info(` ${optName} (${JSON.stringify(opts.chromeOptions[optName])})`);\n }\n }\n\n return caps;\n};\n\nexport default helpers;\nexport { helpers, NATIVE_WIN, WEBVIEW_WIN, WEBVIEW_BASE, CHROMIUM_WIN, KNOWN_CHROME_PACKAGE_NAMES };\n"],"mappings":";;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA,MAAMA,UAAU,GAAG,YAAY;AAAC;AAChC,MAAMC,WAAW,GAAG,SAAS;AAAC;AAC9B,MAAMC,YAAY,GAAG,UAAU;AAAC;AAChC,MAAMC,YAAY,GAAI,GAAEF,WAAY,GAAE;AAAC;AACvC,MAAMG,mBAAmB,GAAG,IAAIC,MAAM,CAAE,IAAGF,YAAa,QAAO,CAAC;AAChE,MAAMG,mBAAmB,GAAG,IAAID,MAAM,CAAE,IAAGF,YAAa,oBAAmB,CAAC;AAC5E,MAAMI,uBAAuB,GAAG,mCAAmC;AACnE,MAAMC,wBAAwB,GAAG,6BAA6B;AAC9D,MAAMC,wBAAwB,GAAG,wBAAwB;AACzD,MAAMC,mBAAmB,GAAG,oBAAoB;AAChD,MAAMC,0BAA0B,GAAG,CACjCD,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,CACpB;AAAC;AACF,MAAME,oBAAoB,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC;AAC3C,MAAMC,sBAAsB,GAAG,IAAIC,iBAAG,CAAC;EACrCC,GAAG,EAAE,GAAG;EACRC,cAAc,EAAE;AAClB,CAAC,CAAC;AACF,MAAMC,eAAe,GAAG,IAAI;AAC5B,MAAMC,8BAA8B,GAAGC,aAAI,CAACC,gBAAgB,CAC1DC,aAAI,CAACC,OAAO,CAACC,WAAE,CAACC,MAAM,EAAE,EAAE,6BAA6B,CAAC,EACxD;EAACC,OAAO,EAAE,CAAC;EAAEC,WAAW,EAAE;AAAI,CAAC,CAChC;AAED,MAAMC,OAAO,GAAG,CAAC,CAAC;AAAC;AAEnB,SAASC,iBAAiB,CAAEC,GAAG,EAAEC,OAAO,EAAE;EACxC,OAAQ,GAAED,GAAG,aAAHA,GAAG,uBAAHA,GAAG,CAAEE,WAAY,IAAGD,OAAQ,EAAC;AACzC;AAYA,eAAeE,wBAAwB,CAAEH,GAAG,EAAE;EAC5C,MAAMI,GAAG,GAAG,MAAMJ,GAAG,CAACK,KAAK,CAAC,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;EACtD,MAAMC,KAAK,GAAG,EAAE;EAChB,MAAMC,UAAU,GAAG,EAAE;EACrB,KAAK,MAAMC,IAAI,IAAIJ,GAAG,CAACK,KAAK,CAAC,IAAI,CAAC,EAAE;IAElC,MAAM,KAAKC,KAAK,GAAGC,EAAE,GAAGC,QAAQ,CAAC,GAAGJ,IAAI,CAACK,IAAI,EAAE,CAACJ,KAAK,CAAC,KAAK,CAAC;IAC5D,IAAI,CAACG,QAAQ,EAAE;MACb;IACF;IACA,IAAIA,QAAQ,CAACE,UAAU,CAAC,GAAG,CAAC,EAAE;MAC5BP,UAAU,CAACQ,IAAI,CAACP,IAAI,CAACK,IAAI,EAAE,CAAC;IAC9B;IACA,IAAIH,KAAK,KAAK,UAAU,IAAIC,EAAE,KAAK,IAAI,EAAE;MACvC;IACF;IACA,IAAI,CAACjC,uBAAuB,CAACsC,IAAI,CAACJ,QAAQ,CAAC,EAAE;MAC3C;IACF;IAEAN,KAAK,CAACS,IAAI,CAACH,QAAQ,CAAC;EACtB;EACA,IAAIK,eAAC,CAACC,OAAO,CAACZ,KAAK,CAAC,EAAE;IACpBa,eAAM,CAACC,KAAK,CAAC,kCAAkC,CAAC;IAChD,IAAI,CAACH,eAAC,CAACC,OAAO,CAACX,UAAU,CAAC,EAAE;MAC1BY,eAAM,CAACC,KAAK,CAAE,sBAAqBC,IAAI,CAACC,SAAS,CAACf,UAAU,EAAE,IAAI,EAAE,CAAC,CAAE,EAAC,CAAC;IAC3E;EACF,CAAC,MAAM;IACLY,eAAM,CAACC,KAAK,CAAE,UAASd,KAAK,CAACiB,MAAO,oBAAmBjC,aAAI,CAACkC,SAAS,CAAC,QAAQ,EAAElB,KAAK,CAACiB,MAAM,EAAE,KAAK,CAAE,IAAG,GACtGF,IAAI,CAACC,SAAS,CAAChB,KAAK,CAAC,CAAC;EAC1B;EAEA,OAAOW,eAAC,CAACQ,IAAI,CAACnB,KAAK,CAAC;AACtB;AAoBA,eAAeoB,iBAAiB,CAAE1B,GAAG,EAAE2B,YAAY,GAAG,IAAI,EAAE;EAC1D,MAAMC,WAAW,GAAG,MAAMzB,wBAAwB,CAACH,GAAG,CAAC;EACvD,MAAM6B,QAAQ,GAAG,EAAE;EACnB,KAAK,MAAMC,UAAU,IAAIF,WAAW,EAAE;IACpC,IAAID,YAAY,KAAK/C,wBAAwB,IAAIkD,UAAU,KAAM,IAAGH,YAAa,EAAC,EAAE;MAClFE,QAAQ,CAACd,IAAI,CAAC;QACZgB,IAAI,EAAED,UAAU;QAChB7B,OAAO,EAAE5B;MACX,CAAC,CAAC;MACF;IACF;IAEA,MAAM2D,eAAe,GAAGtD,uBAAuB,CAACuD,IAAI,CAACH,UAAU,CAAC;IAChE,IAAI,CAACE,eAAe,EAAE;MACpB;IACF;IACA,MAAME,cAAc,GAAGvD,wBAAwB,CAACsD,IAAI,CAACH,UAAU,CAAC;IAChE,IAAI,CAACE,eAAe,CAAC,CAAC,CAAC,IAAI,CAACE,cAAc,EAAE;MAC1C;IACF;IAEA,IAAIP,YAAY,IAAIG,UAAU,KAAM,IAAGH,YAAa,EAAC,IAAI,CAACA,YAAY,EAAE;MACtEE,QAAQ,CAACd,IAAI,CAAC;QACZgB,IAAI,EAAED,UAAU;QAChB7B,OAAO,EAAE+B,eAAe,CAAC,CAAC,CAAC,GACtB,GAAE1D,YAAa,GAAE0D,eAAe,CAAC,CAAC,CAAE,EAAC,GACrC,GAAE1D,YAAa,GAAE4D,cAAc,CAAC,CAAC,CAAE;MAC1C,CAAC,CAAC;IACJ;EACF;EACA,OAAOL,QAAQ;AACjB;AAaA,eAAeM,oBAAoB,CAAEnC,GAAG,EAAE8B,UAAU,EAAEM,mBAAmB,GAAG,IAAI,EAAE;EAGhF,MAAMC,UAAU,GAAGP,UAAU,CAACQ,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;EAC/C,IAAI,CAACC,SAAS,EAAEC,OAAO,CAAC,GAAGzD,oBAAoB;EAC/C,IAAIqD,mBAAmB,EAAE;IACvBI,OAAO,GAAGJ,mBAAmB,IAAII,OAAO,GAAGD,SAAS,CAAC;IACrDA,SAAS,GAAGH,mBAAmB;EACjC;EACAjB,eAAM,CAACC,KAAK,CAAE,0BAAyBiB,UAAW,cAAa,GAC5D,iBAAgBE,SAAU,KAAIC,OAAQ,EAAC,CAAC;EAC3C,IAAI,CAACJ,mBAAmB,EAAE;IACxBjB,eAAM,CAACC,KAAK,CAAE,kEAAiE,GAC5E,0BAAyB,CAAC;EAC/B;EACA,OAAO,MAAM/B,8BAA8B,CAAC,YAAY;IACtD,IAAIoD,SAAS;IACb,IAAI;MACFA,SAAS,GAAG,MAAM,IAAAC,8BAAiB,EAACH,SAAS,EAAEC,OAAO,CAAC;IACzD,CAAC,CAAC,OAAOG,CAAC,EAAE;MACV,MAAM,IAAIC,KAAK,CAAE,2DAA0D,GACxE,YAAWL,SAAU,KAAIC,OAAQ,2CAA0C,GAC3E,4DAA2D,CAAC;IACjE;IACA,MAAMxC,GAAG,CAAC6C,OAAO,CAAC,CAAC,SAAS,EAAG,OAAMJ,SAAU,EAAC,EAAG,iBAAgBJ,UAAW,EAAC,CAAC,CAAC;IACjF,OAAOI,SAAS;EAClB,CAAC,CAAC;AACJ;AAsCA,eAAeK,sBAAsB,CAAE9C,GAAG,EAAE+C,eAAe,EAAEC,IAAI,GAAG,CAAC,CAAC,EAAE;EACtE,IAAI/B,eAAC,CAACC,OAAO,CAAC6B,eAAe,CAAC,EAAE;IAC9B;EACF;EAEA,MAAM;IACJX,mBAAmB,GAAG,IAAI;IAC1Ba,uBAAuB,GAAG,IAAI;IAC9BC,8BAA8B,GAAG;EACnC,CAAC,GAAGF,IAAI;EAER,IAAI,CAACC,uBAAuB,EAAE;IAC5B9B,eAAM,CAACgC,IAAI,CAAE,2DAA0D,GACpE,qDAAoD,CAAC;EAC1D;EAEA,IAAI,CAACD,8BAA8B,EAAE;IACnC/B,eAAM,CAACgC,IAAI,CAAE,iEAAgE,GAC1E,6FAA4F,GAC5F,mBAAkB,CAAC;EACxB;EAEA,IAAI,CAACF,uBAAuB,IAAI,CAACC,8BAA8B,EAAE;IAC/D;EACF;EAGA/B,eAAM,CAACC,KAAK,CAAE,0BAAyB9B,aAAI,CAACkC,SAAS,CAAC,SAAS,EAAEuB,eAAe,CAACxB,MAAM,EAAE,IAAI,CAAE,EAAC,CAAC;EACjG,MAAM6B,gBAAgB,GAAG,EAAE;EAC3B,KAAK,MAAMC,IAAI,IAAIN,eAAe,EAAE;IAClCK,gBAAgB,CAACrC,IAAI,CAAC,CAAC,YAAY;MACjC,IAAI0B,SAAS;MACb,IAAI;QACFA,SAAS,GAAG,MAAMN,oBAAoB,CAACnC,GAAG,EAAEqD,IAAI,CAACtB,IAAI,EAAEK,mBAAmB,CAAC;QAC3E,IAAIc,8BAA8B,EAAE;UAClCG,IAAI,CAACF,IAAI,GAAG,MAAMG,OAAO,CAACb,SAAS,CAAC;QACtC;QACA,IAAIQ,uBAAuB,EAAE;UAC3BI,IAAI,CAACE,KAAK,GAAG,MAAMC,OAAO,CAACf,SAAS,CAAC;QACvC;MACF,CAAC,CAAC,OAAOE,CAAC,EAAE;QACVxB,eAAM,CAACC,KAAK,CAACuB,CAAC,CAAC;MACjB,CAAC,SAAS;QACR,IAAIF,SAAS,EAAE;UACb,MAAMzC,GAAG,CAACyD,iBAAiB,CAAChB,SAAS,CAAC;QACxC;MACF;IACF,CAAC,GAAG,CAAC;EACP;EACA,MAAMiB,iBAAC,CAACC,GAAG,CAACP,gBAAgB,CAAC;EAC7BjC,eAAM,CAACC,KAAK,CAAE,+BAA8B,CAAC;AAC/C;AAGA,eAAeoC,OAAO,CAAEf,SAAS,EAAE;EACjC,OAAO,CAAC,MAAM,IAAAmB,cAAK,EAAC;IAClBC,GAAG,EAAG,oBAAmBpB,SAAU,YAAW;IAC9C7C,OAAO,EAAER;EACX,CAAC,CAAC,EAAE0E,IAAI;AACV;AAGA,eAAeR,OAAO,CAAEb,SAAS,EAAE;EACjC,OAAO,CAAC,MAAM,IAAAmB,cAAK,EAAC;IAClBC,GAAG,EAAG,oBAAmBpB,SAAU,eAAc;IACjD7C,OAAO,EAAER;EACX,CAAC,CAAC,EAAE0E,IAAI;AACV;AAcAhE,OAAO,CAACiE,eAAe,GAAG,eAAeA,eAAe,CAAE/D,GAAG,EAAEC,OAAO,EAAE;EACtE,MAAM+D,QAAQ,GAAGzF,mBAAmB,CAAC0D,IAAI,CAAChC,OAAO,CAAC;EAClD,IAAI,CAAC+D,QAAQ,EAAE;IACb,MAAM,IAAIpB,KAAK,CAAE,mCAAkC3C,OAAQ,GAAE,CAAC;EAChE;EAEA,MAAMgE,GAAG,GAAGD,QAAQ,CAAC,CAAC,CAAC;EACvB7C,eAAM,CAACC,KAAK,CAAE,GAAEnB,OAAQ,kBAAiBgE,GAAI,EAAC,CAAC;EAC/C9C,eAAM,CAACC,KAAK,CAAE,qCAAoCnB,OAAQ,GAAE,CAAC;EAC7D,MAAMiE,GAAG,GAAG,MAAMlE,GAAG,CAACmE,YAAY,CAACF,GAAG,CAAC;EACvC9C,eAAM,CAACC,KAAK,CAAE,sBAAqB8C,GAAI,GAAE,CAAC;EAC1C,OAAOA,GAAG;AACZ,CAAC;AASDpE,OAAO,CAACsE,iBAAiB,GAAG,SAASA,iBAAiB,CAAErB,eAAe,EAAE;EACvEE,uBAAuB,GAAG,IAAI;EAC9BoB,eAAe,GAAG;AACpB,CAAC,GAAG,CAAC,CAAC,EAAE;EACN,IAAIA,eAAe,EAAE;IACnB,OAAO,CAAChG,YAAY,CAAC;EACvB;EAEA,MAAMiG,MAAM,GAAG,EAAE;EACjB,KAAK,MAAM;IAACrE,OAAO;IAAEsD,KAAK;IAAExB,IAAI;IAAEwC;EAAW,CAAC,IAAIxB,eAAe,EAAE;IACjE,IAAIE,uBAAuB,IAAI,CAAAM,KAAK,aAALA,KAAK,uBAALA,KAAK,CAAEhC,MAAM,MAAK,CAAC,EAAE;MAClDJ,eAAM,CAACgC,IAAI,CAAE,yBAAwBlD,OAAQ,SAAQ8B,IAAK,IAAG,GAC1D,yCAAwC,CAAC;MAC5C;IACF;IACA,IAAIwC,WAAW,EAAE;MACfD,MAAM,CAACvD,IAAI,CAACwD,WAAW,CAAC;IAC1B;EACF;EACApD,eAAM,CAACC,KAAK,CAAE,SAAQ9B,aAAI,CAACkC,SAAS,CAAC,SAAS,EAAE8C,MAAM,CAAC/C,MAAM,EAAE,IAAI,CAAE,KAAIF,IAAI,CAACC,SAAS,CAACgD,MAAM,CAAE,EAAC,CAAC;EAClG,OAAOA,MAAM;AACf,CAAC;AAyCDxE,OAAO,CAAC0E,kBAAkB,GAAG,eAAeA,kBAAkB,CAAExE,GAAG,EAAE;EACnEyE,mBAAmB,GAAG,IAAI;EAC1BxB,uBAAuB,GAAG,IAAI;EAC9Bb,mBAAmB,GAAG,IAAI;EAC1Bc,8BAA8B,GAAG;AACnC,CAAC,GAAG,CAAC,CAAC,EAAE;EACN/B,eAAM,CAACC,KAAK,CAAC,sCAAsC,CAAC;EACpD,MAAM2B,eAAe,GAAG,MAAMrB,iBAAiB,CAAC1B,GAAG,EAAEyE,mBAAmB,CAAC;EAEzE,MAAM3B,sBAAsB,CAAC9C,GAAG,EAAE+C,eAAe,EAAE;IACjDE,uBAAuB;IACvBC,8BAA8B;IAC9Bd;EACF,CAAC,CAAC;EAEF,KAAK,MAAMsC,cAAc,IAAI3B,eAAe,EAAE;IAC5C,MAAM;MAAC9C,OAAO;MAAEkD;IAAI,CAAC,GAAGuB,cAAc;IACtCA,cAAc,CAACH,WAAW,GAAG,IAAI;IAEjC,IAAII,MAAM,GAAG1E,OAAO;IACpB,IAAI2E,OAAO,GAAGC,SAAS;IACvB,IAAI,CAACJ,mBAAmB,EAAE;MACxB,MAAMK,QAAQ,GAAGrG,mBAAmB,CAACwD,IAAI,CAAChC,OAAO,CAAC;MAClD,IAAI;QAGF,MAAMiE,GAAG,GAAGY,QAAQ,GAAGA,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAMhF,OAAO,CAACiE,eAAe,CAAC/D,GAAG,EAAEC,OAAO,CAAC;QAChF0E,MAAM,GAAI,GAAErG,YAAa,GAAE4F,GAAI,EAAC;QAChC,MAAMF,QAAQ,GAAGzF,mBAAmB,CAAC0D,IAAI,CAAChC,OAAO,CAAC;QAClD2E,OAAO,GAAG;UACRG,IAAI,EAAEb,GAAG;UACTc,EAAE,EAAEhB,QAAQ,GAAGA,QAAQ,CAAC,CAAC,CAAC,GAAG;QAC/B,CAAC;MACH,CAAC,CAAC,OAAOrB,CAAC,EAAE;QACVxB,eAAM,CAAC8D,IAAI,CAACtC,CAAC,CAACuC,OAAO,CAAC;QACtB;MACF;IACF;IAEAR,cAAc,CAACH,WAAW,GAAGI,MAAM;IACnC,MAAMQ,GAAG,GAAGpF,iBAAiB,CAACC,GAAG,EAAE2E,MAAM,CAAC;IAC1C,IAAIxB,IAAI,IAAIyB,OAAO,EAAE;MACnB5F,sBAAsB,CAACoG,GAAG,CAACD,GAAG,EAAE;QAAEhC,IAAI;QAAEyB;MAAQ,CAAC,CAAC;IACpD,CAAC,MAAM,IAAI5F,sBAAsB,CAACqG,GAAG,CAACF,GAAG,CAAC,EAAE;MAC1CnG,sBAAsB,CAACsG,MAAM,CAACH,GAAG,CAAC;IACpC;EACF;EACA,OAAOpC,eAAe;AACxB,CAAC;AA6BDjD,OAAO,CAACyF,iBAAiB,GAAG,SAASA,iBAAiB,CAAEvF,GAAG,EAAEC,OAAO,EAAE;EACpE,MAAMkF,GAAG,GAAGpF,iBAAiB,CAACC,GAAG,EAAEC,OAAO,CAAC;EAC3C,OAAOjB,sBAAsB,CAACwG,GAAG,CAACL,GAAG,CAAC;AACxC,CAAC;AAYDrF,OAAO,CAAC2F,sBAAsB,GAAG,SAASA,sBAAsB,CAAEzC,IAAI,EAAE0C,QAAQ,EAAEC,cAAc,EAAE;EAAA;EAChG,MAAMC,IAAI,GAAG;IAAEC,aAAa,EAAE,CAAC;EAAE,CAAC;EAElC,MAAMC,cAAc,GAAG,wBAAA9C,IAAI,CAAC6C,aAAa,wDAAlB,oBAAoBC,cAAc,KACpD9C,IAAI,CAAC+C,UAAU,KACfJ,cAAc,aAAdA,cAAc,+CAAdA,cAAc,CAAExC,IAAI,yDAApB,qBAAuB,iBAAiB,CAAC;EAC9C,IAAI2C,cAAc,EAAE;IAElBF,IAAI,CAACC,aAAa,CAACC,cAAc,GAAGA,cAAc;EACpD;EACA,IAAI7E,eAAC,CAAC+E,SAAS,CAAChD,IAAI,CAACiD,mBAAmB,CAAC,EAAE;IACzCL,IAAI,CAACC,aAAa,CAACK,oBAAoB,GAAGlD,IAAI,CAACiD,mBAAmB;EACpE;EACA,IAAIjD,IAAI,CAACmD,oBAAoB,EAAE;IAC7BP,IAAI,CAACC,aAAa,CAACC,cAAc,GAAG9C,IAAI,CAACmD,oBAAoB;EAC/D;EACA,IAAInD,IAAI,CAACoD,qBAAqB,EAAE;IAC9BR,IAAI,CAACC,aAAa,CAACQ,eAAe,GAAGrD,IAAI,CAACoD,qBAAqB;EACjE;EACA,IAAIpD,IAAI,CAACsD,oBAAoB,EAAE;IAC7BV,IAAI,CAACC,aAAa,CAACU,cAAc,GAAGvD,IAAI,CAACsD,oBAAoB;EAC/D,CAAC,MAAM,IAAIX,cAAc,aAAdA,cAAc,wCAAdA,cAAc,CAAEf,OAAO,kDAAvB,sBAAyBG,IAAI,IAAIY,cAAc,aAAdA,cAAc,yCAAdA,cAAc,CAAEf,OAAO,mDAAvB,uBAAyBI,EAAE,EAAE;IACvEY,IAAI,CAACC,aAAa,CAACU,cAAc,GAAGZ,cAAc,CAACf,OAAO,CAACG,IAAI;EACjE;EACA,IAAI9D,eAAC,CAACuF,OAAO,CAACxD,IAAI,CAACyD,WAAW,CAAC,KAAK,kBAAkB,EAAE;IACtDb,IAAI,CAACC,aAAa,CAACQ,eAAe,GAAGrD,IAAI,CAAC0D,WAAW;EACvD;EACA,IAAI1D,IAAI,CAAC2D,gBAAgB,EAAE;IACzBf,IAAI,CAACe,gBAAgB,GAAG3D,IAAI,CAAC2D,gBAAgB;EAC/C;EACA,MAAMC,QAAQ,GAAG3F,eAAC,CAACuF,OAAO,CAACZ,IAAI,CAACC,aAAa,CAACC,cAAc,CAAC,KAAK,QAAQ;EAC1E,IAAI7E,eAAC,CAAC4F,QAAQ,CAAC/H,0BAA0B,EAAE8G,IAAI,CAACC,aAAa,CAACC,cAAc,CAAC,IAAIc,QAAQ,EAAE;IAIzF,IAAIA,QAAQ,EAAE;MACZhB,IAAI,CAACC,aAAa,CAACC,cAAc,GAAGjH,mBAAmB;IACzD;IACA,OAAO+G,IAAI,CAACC,aAAa,CAACQ,eAAe;IACzC,OAAOT,IAAI,CAACC,aAAa,CAACU,cAAc;EAC1C;EAEAX,IAAI,CAACC,aAAa,CAACiB,mBAAmB,GAAGpB,QAAQ;EAEjD,IAAIzE,eAAC,CAAC8F,aAAa,CAAC/D,IAAI,CAACgE,YAAY,CAAC,IAAI/F,eAAC,CAAC8F,aAAa,CAAC/D,IAAI,CAACiE,kBAAkB,CAAC,EAAE;IAClF,IAAIjE,IAAI,CAACgE,YAAY,EAAE;MACrB7F,eAAM,CAAC8D,IAAI,CAAE,gFAA+E,CAAC;IAC/F;IACAW,IAAI,CAACoB,YAAY,GAAGhE,IAAI,CAACiE,kBAAkB,IAAIjE,IAAI,CAACgE,YAAY;EAClE;EACA,IAAIhE,IAAI,CAACkE,wBAAwB,EAAE;IACjC/F,eAAM,CAAC8D,IAAI,CAAE,+DAA8D,GACxE,6EAA4E,CAAC;IAChF,MAAMkC,OAAO,GAAG;MAACC,WAAW,EAAE;IAAK,CAAC;IAEpCxB,IAAI,CAACoB,YAAY,GAAGpB,IAAI,CAACoB,YAAY,GACjCK,MAAM,CAACC,MAAM,CAAC,CAAC,CAAC,EAAE1B,IAAI,CAACoB,YAAY,EAAEG,OAAO,CAAC,GAC7CA,OAAO;EACb;EAEA,4BAAInE,IAAI,CAAC6C,aAAa,iDAAlB,qBAAoB0B,SAAS,EAAE;IAEjCvE,IAAI,CAAC6C,aAAa,CAAC2B,IAAI,GAAG,CAAC,IAAIxE,IAAI,CAAC6C,aAAa,CAAC2B,IAAI,IAAI,EAAE,CAAC,EAAE,GAAGxE,IAAI,CAAC6C,aAAa,CAAC0B,SAAS,CAAC;IAC/F,OAAOvE,IAAI,CAAC6C,aAAa,CAAC0B,SAAS;EACrC;EAEApG,eAAM,CAACC,KAAK,CAAC,2CAA2C,GACtDC,IAAI,CAACC,SAAS,CAACsE,IAAI,CAACC,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;EAE9C,MAAM4B,iBAAiB,GAAG,EAAE;EAC5B,KAAK,MAAM,CAACC,GAAG,EAAEC,GAAG,CAAC,IAAI1G,eAAC,CAAC2G,OAAO,CAAC5E,IAAI,CAAC6C,aAAa,CAAC,EAAE;IACtD,IAAI5E,eAAC,CAAC4G,WAAW,CAACjC,IAAI,CAACC,aAAa,CAAC6B,GAAG,CAAC,CAAC,EAAE;MAC1C9B,IAAI,CAACC,aAAa,CAAC6B,GAAG,CAAC,GAAGC,GAAG;IAC/B,CAAC,MAAM;MACLF,iBAAiB,CAAC1G,IAAI,CAAC2G,GAAG,CAAC;IAC7B;EACF;EACA,IAAI,CAACzG,eAAC,CAACC,OAAO,CAACuG,iBAAiB,CAAC,EAAE;IACjCtG,eAAM,CAACgC,IAAI,CAAC,+DAA+D,GACzE,gCAAgC,CAAC;IACnC,KAAK,MAAM2E,OAAO,IAAIL,iBAAiB,EAAE;MACvCtG,eAAM,CAACgC,IAAI,CAAE,KAAI2E,OAAQ,KAAIzG,IAAI,CAACC,SAAS,CAAC0B,IAAI,CAAC6C,aAAa,CAACiC,OAAO,CAAC,CAAE,GAAE,CAAC;IAC9E;EACF;EAEA,OAAOlC,IAAI;AACb,CAAC;AAAC,eAEa9F,OAAO;AAAA"}
|
package/lib/commands/general.js
CHANGED
|
@@ -4,10 +4,8 @@ import { util } from '@appium/support';
|
|
|
4
4
|
import moment from 'moment';
|
|
5
5
|
import { longSleep } from 'asyncbox';
|
|
6
6
|
import { errors } from 'appium/driver';
|
|
7
|
-
import B from 'bluebird';
|
|
8
7
|
|
|
9
8
|
const MOMENT_FORMAT_ISO8601 = 'YYYY-MM-DDTHH:mm:ssZ';
|
|
10
|
-
const ALL_PERMISSIONS_MAGIC = 'all';
|
|
11
9
|
|
|
12
10
|
let commands = {}, helpers = {}, extensions = {};
|
|
13
11
|
|
|
@@ -303,116 +301,6 @@ commands.mobilePerformEditorAction = async function mobilePerformEditorAction (o
|
|
|
303
301
|
await this.adb.performEditorAction(action);
|
|
304
302
|
};
|
|
305
303
|
|
|
306
|
-
const PERMISSION_ACTION = {
|
|
307
|
-
GRANT: 'grant',
|
|
308
|
-
REVOKE: 'revoke',
|
|
309
|
-
};
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* @typedef {Object} ChangePermissionsOptions
|
|
313
|
-
* @property {!string|Array<string>} permissions - The full name of the permission to be changed
|
|
314
|
-
* or a list of permissions. Check https://developer.android.com/reference/android/Manifest.permission
|
|
315
|
-
* to get the full list of standard Android permssion names. Mandatory argument.
|
|
316
|
-
* If 'all' magic string is passed then the chosen action is going to be applied to all
|
|
317
|
-
* permisisons requested/granted by 'appPackage'.
|
|
318
|
-
* @property {string} appPackage [this.opts.appPackage] - The application package to set change
|
|
319
|
-
* permissions on. Defaults to the package name under test.
|
|
320
|
-
* @property {string} action [grant] - One of `PERMISSION_ACTION` values
|
|
321
|
-
*/
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Changes package permissions in runtime.
|
|
325
|
-
*
|
|
326
|
-
* @param {?ChangePermissionsOptions} opts - Available options mapping.
|
|
327
|
-
* @throws {Error} if there was a failure while changing permissions
|
|
328
|
-
*/
|
|
329
|
-
commands.mobileChangePermissions = async function mobileChangePermissions (opts = {}) {
|
|
330
|
-
const {
|
|
331
|
-
permissions,
|
|
332
|
-
appPackage = this.opts.appPackage,
|
|
333
|
-
action = PERMISSION_ACTION.GRANT,
|
|
334
|
-
} = opts;
|
|
335
|
-
if (_.isNil(permissions)) {
|
|
336
|
-
throw new errors.InvalidArgumentError(`'permissions' argument is required`);
|
|
337
|
-
}
|
|
338
|
-
if (_.isEmpty(permissions)) {
|
|
339
|
-
throw new errors.InvalidArgumentError(`'permissions' argument must not be empty`);
|
|
340
|
-
}
|
|
341
|
-
const lowerAction = _.toLower(action);
|
|
342
|
-
if (![PERMISSION_ACTION.GRANT, PERMISSION_ACTION.REVOKE].includes(lowerAction)) {
|
|
343
|
-
throw new errors.InvalidArgumentError(`Unknown action '${action}'. ` +
|
|
344
|
-
`Only ${JSON.stringify(_.values(PERMISSION_ACTION))} actions are supported`);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
let affectedPermissions = _.isArray(permissions) ? permissions : [permissions];
|
|
348
|
-
if (_.toLower(permissions) === ALL_PERMISSIONS_MAGIC) {
|
|
349
|
-
const dumpsys = await this.adb.shell(['dumpsys', 'package', appPackage]);
|
|
350
|
-
const grantedPermissions = await this.adb.getGrantedPermissions(appPackage, dumpsys);
|
|
351
|
-
if (lowerAction === PERMISSION_ACTION.GRANT) {
|
|
352
|
-
const reqPermissons = await this.adb.getReqPermissions(appPackage, dumpsys);
|
|
353
|
-
affectedPermissions = _.difference(reqPermissons, grantedPermissions);
|
|
354
|
-
} else {
|
|
355
|
-
affectedPermissions = grantedPermissions;
|
|
356
|
-
}
|
|
357
|
-
if (_.isEmpty(affectedPermissions)) {
|
|
358
|
-
this.log.info(`'${appPackage}' contains no permissions to ${lowerAction}`);
|
|
359
|
-
return;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
if (lowerAction === PERMISSION_ACTION.GRANT) {
|
|
364
|
-
await this.adb.grantPermissions(appPackage, affectedPermissions);
|
|
365
|
-
} else {
|
|
366
|
-
await B.all(affectedPermissions.map((name) => this.adb.revokePermission(appPackage, name)));
|
|
367
|
-
}
|
|
368
|
-
};
|
|
369
|
-
|
|
370
|
-
const PERMISSIONS_TYPE = {
|
|
371
|
-
DENIED: 'denied',
|
|
372
|
-
GRANTED: 'granted',
|
|
373
|
-
REQUESTED: 'requested',
|
|
374
|
-
};
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* @typedef {Object} GetPermissionsOptions
|
|
378
|
-
* @property {string} type [requested] - One of possible permission types to get.
|
|
379
|
-
* Can be any of `PERMISSIONS_TYPE` values.
|
|
380
|
-
* @property {string} appPackage [this.opts.appPackage] - The application package to set change
|
|
381
|
-
* permissions on. Defaults to the package name under test.
|
|
382
|
-
*/
|
|
383
|
-
|
|
384
|
-
/**
|
|
385
|
-
* Gets runtime permissions list for the given application package.
|
|
386
|
-
*
|
|
387
|
-
* @param {GetPermissionsOptions} opts - Available options mapping.
|
|
388
|
-
* @returns {Array<string>} The list of retrieved permissions for the given type
|
|
389
|
-
* (can also be empty).
|
|
390
|
-
* @throws {Error} if there was an error while getting permissions.
|
|
391
|
-
*/
|
|
392
|
-
commands.mobileGetPermissions = async function mobileGetPermissions (opts = {}) {
|
|
393
|
-
const {
|
|
394
|
-
type = PERMISSIONS_TYPE.REQUESTED,
|
|
395
|
-
appPackage = this.opts.appPackage,
|
|
396
|
-
} = opts;
|
|
397
|
-
|
|
398
|
-
let actionFunc;
|
|
399
|
-
switch (_.toLower(type)) {
|
|
400
|
-
case PERMISSIONS_TYPE.REQUESTED:
|
|
401
|
-
actionFunc = (appPackage) => this.adb.getReqPermissions(appPackage);
|
|
402
|
-
break;
|
|
403
|
-
case PERMISSIONS_TYPE.GRANTED:
|
|
404
|
-
actionFunc = (appPackage) => this.adb.getGrantedPermissions(appPackage);
|
|
405
|
-
break;
|
|
406
|
-
case PERMISSIONS_TYPE.DENIED:
|
|
407
|
-
actionFunc = (appPackage) => this.adb.getDeniedPermissions(appPackage);
|
|
408
|
-
break;
|
|
409
|
-
default:
|
|
410
|
-
throw new errors.InvalidArgumentError(`Unknown permissions type '${type}'. ` +
|
|
411
|
-
`Only ${JSON.stringify(_.values(PERMISSIONS_TYPE))} types are supported`);
|
|
412
|
-
}
|
|
413
|
-
return await actionFunc(appPackage);
|
|
414
|
-
};
|
|
415
|
-
|
|
416
304
|
/**
|
|
417
305
|
* Retrieves the list of recent system notifications.
|
|
418
306
|
*
|
package/lib/commands/index.js
CHANGED
|
@@ -20,6 +20,7 @@ import intentCmds from './intent';
|
|
|
20
20
|
import systemBarsCmds from './system-bars';
|
|
21
21
|
import logCmds from './log';
|
|
22
22
|
import mediaProjectionCmds from './media-projection';
|
|
23
|
+
import permissionsCommands from './permissions';
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
let commands = {};
|
|
@@ -47,6 +48,7 @@ Object.assign(
|
|
|
47
48
|
fileActionsCmds,
|
|
48
49
|
logCmds,
|
|
49
50
|
mediaProjectionCmds,
|
|
51
|
+
permissionsCommands,
|
|
50
52
|
// add other command types here
|
|
51
53
|
);
|
|
52
54
|
|