appium-android-driver 5.13.0 → 5.13.2
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 +14 -0
- package/build/index.js +43 -40
- package/build/lib/android-helpers.d.ts +136 -0
- package/build/lib/android-helpers.d.ts.map +1 -0
- package/build/lib/android-helpers.js +760 -679
- package/build/lib/android-helpers.js.map +1 -1
- package/build/lib/bootstrap.d.ts +29 -0
- package/build/lib/bootstrap.d.ts.map +1 -0
- package/build/lib/bootstrap.js +192 -179
- package/build/lib/bootstrap.js.map +1 -1
- package/build/lib/commands/actions.d.ts +209 -0
- package/build/lib/commands/actions.d.ts.map +1 -0
- package/build/lib/commands/actions.js +327 -265
- package/build/lib/commands/actions.js.map +1 -1
- package/build/lib/commands/alert.d.ts +10 -0
- package/build/lib/commands/alert.d.ts.map +1 -0
- package/build/lib/commands/alert.js +12 -18
- package/build/lib/commands/alert.js.map +1 -1
- package/build/lib/commands/app-management.d.ts +314 -0
- package/build/lib/commands/app-management.d.ts.map +1 -0
- package/build/lib/commands/app-management.js +278 -110
- package/build/lib/commands/app-management.js.map +1 -1
- package/build/lib/commands/context.d.ts +94 -0
- package/build/lib/commands/context.d.ts.map +1 -0
- package/build/lib/commands/context.js +412 -260
- package/build/lib/commands/context.js.map +1 -1
- package/build/lib/commands/coverage.d.ts +5 -0
- package/build/lib/commands/coverage.d.ts.map +1 -0
- package/build/lib/commands/coverage.js +14 -17
- package/build/lib/commands/coverage.js.map +1 -1
- package/build/lib/commands/element.d.ts +36 -0
- package/build/lib/commands/element.d.ts.map +1 -0
- package/build/lib/commands/element.js +97 -127
- package/build/lib/commands/element.js.map +1 -1
- package/build/lib/commands/emu-console.d.ts +49 -0
- package/build/lib/commands/emu-console.d.ts.map +1 -0
- package/build/lib/commands/emu-console.js +36 -25
- package/build/lib/commands/emu-console.js.map +1 -1
- package/build/lib/commands/execute.d.ts +6 -0
- package/build/lib/commands/execute.d.ts.map +1 -0
- package/build/lib/commands/execute.js +68 -69
- package/build/lib/commands/execute.js.map +1 -1
- package/build/lib/commands/file-actions.d.ts +129 -0
- package/build/lib/commands/file-actions.d.ts.map +1 -0
- package/build/lib/commands/file-actions.js +321 -178
- package/build/lib/commands/file-actions.js.map +1 -1
- package/build/lib/commands/find.d.ts +13 -0
- package/build/lib/commands/find.d.ts.map +1 -0
- package/build/lib/commands/find.js +69 -51
- package/build/lib/commands/find.js.map +1 -1
- package/build/lib/commands/general.d.ts +133 -0
- package/build/lib/commands/general.d.ts.map +1 -0
- package/build/lib/commands/general.js +275 -216
- package/build/lib/commands/general.js.map +1 -1
- package/build/lib/commands/ime.d.ts +11 -0
- package/build/lib/commands/ime.d.ts.map +1 -0
- package/build/lib/commands/ime.js +27 -33
- package/build/lib/commands/ime.js.map +1 -1
- package/build/lib/commands/index.d.ts +3 -0
- package/build/lib/commands/index.d.ts.map +1 -0
- package/build/lib/commands/index.js +32 -35
- package/build/lib/commands/index.js.map +1 -1
- package/build/lib/commands/intent.d.ts +418 -0
- package/build/lib/commands/intent.d.ts.map +1 -0
- package/build/lib/commands/intent.js +281 -151
- package/build/lib/commands/intent.js.map +1 -1
- package/build/lib/commands/keyboard.d.ts +6 -0
- package/build/lib/commands/keyboard.d.ts.map +1 -0
- package/build/lib/commands/keyboard.js +6 -14
- package/build/lib/commands/keyboard.js.map +1 -1
- package/build/lib/commands/log.d.ts +45 -0
- package/build/lib/commands/log.d.ts.map +1 -0
- package/build/lib/commands/log.js +117 -103
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/media-projection.d.ts +144 -0
- package/build/lib/commands/media-projection.d.ts.map +1 -0
- package/build/lib/commands/media-projection.js +228 -171
- package/build/lib/commands/media-projection.js.map +1 -1
- package/build/lib/commands/network.d.ts +139 -0
- package/build/lib/commands/network.d.ts.map +1 -0
- package/build/lib/commands/network.js +249 -181
- package/build/lib/commands/network.js.map +1 -1
- package/build/lib/commands/performance.d.ts +101 -0
- package/build/lib/commands/performance.d.ts.map +1 -0
- package/build/lib/commands/performance.js +390 -236
- package/build/lib/commands/performance.js.map +1 -1
- package/build/lib/commands/permissions.d.ts +93 -0
- package/build/lib/commands/permissions.d.ts.map +1 -0
- package/build/lib/commands/permissions.js +133 -93
- package/build/lib/commands/permissions.js.map +1 -1
- package/build/lib/commands/recordscreen.d.ts +194 -0
- package/build/lib/commands/recordscreen.d.ts.map +1 -0
- package/build/lib/commands/recordscreen.js +293 -224
- package/build/lib/commands/recordscreen.js.map +1 -1
- package/build/lib/commands/shell.d.ts +8 -0
- package/build/lib/commands/shell.d.ts.map +1 -0
- package/build/lib/commands/shell.js +38 -43
- package/build/lib/commands/shell.js.map +1 -1
- package/build/lib/commands/streamscreen.d.ts +104 -0
- package/build/lib/commands/streamscreen.d.ts.map +1 -0
- package/build/lib/commands/streamscreen.js +364 -305
- package/build/lib/commands/streamscreen.js.map +1 -1
- package/build/lib/commands/system-bars.d.ts +100 -0
- package/build/lib/commands/system-bars.d.ts.map +1 -0
- package/build/lib/commands/system-bars.js +148 -90
- package/build/lib/commands/system-bars.js.map +1 -1
- package/build/lib/commands/touch.d.ts +30 -0
- package/build/lib/commands/touch.d.ts.map +1 -0
- package/build/lib/commands/touch.js +311 -287
- package/build/lib/commands/touch.js.map +1 -1
- package/build/lib/desired-caps.d.ts +353 -0
- package/build/lib/desired-caps.d.ts.map +1 -0
- package/build/lib/desired-caps.js +291 -292
- package/build/lib/desired-caps.js.map +1 -1
- package/build/lib/driver.d.ts +430 -0
- package/build/lib/driver.d.ts.map +1 -0
- package/build/lib/driver.js +449 -384
- package/build/lib/driver.js.map +1 -1
- package/build/lib/logger.d.ts +3 -0
- package/build/lib/logger.d.ts.map +1 -0
- package/build/lib/logger.js +5 -11
- package/build/lib/logger.js.map +1 -1
- package/build/lib/method-map.d.ts +389 -0
- package/build/lib/method-map.d.ts.map +1 -0
- package/build/lib/method-map.js +220 -394
- package/build/lib/method-map.js.map +1 -1
- package/build/lib/stubs.d.ts +8 -0
- package/build/lib/stubs.d.ts.map +1 -0
- package/build/lib/stubs.js +5 -0
- package/build/lib/stubs.js.map +1 -0
- package/build/lib/uiautomator.d.ts +24 -0
- package/build/lib/uiautomator.d.ts.map +1 -0
- package/build/lib/uiautomator.js +86 -82
- package/build/lib/uiautomator.js.map +1 -1
- package/build/lib/unlock-helpers.d.ts +38 -0
- package/build/lib/unlock-helpers.d.ts.map +1 -0
- package/build/lib/unlock-helpers.js +228 -204
- package/build/lib/unlock-helpers.js.map +1 -1
- package/build/lib/utils.d.ts +11 -0
- package/build/lib/utils.d.ts.map +1 -0
- package/build/lib/utils.js +23 -18
- package/build/lib/utils.js.map +1 -1
- package/build/lib/webview-helpers.d.ts +223 -0
- package/build/lib/webview-helpers.d.ts.map +1 -0
- package/build/lib/webview-helpers.js +476 -298
- package/build/lib/webview-helpers.js.map +1 -1
- package/index.js +3 -1
- package/lib/android-helpers.js +2 -1
- package/lib/stubs.ts +8 -0
- package/lib/unlock-helpers.js +2 -2
- package/package.json +23 -14
package/build/lib/driver.js
CHANGED
|
@@ -1,409 +1,474 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
require("
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
var _sharedPreferencesBuilder = require("shared-preferences-builder");
|
|
19
|
-
var _bluebird = _interopRequireDefault(require("bluebird"));
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.AndroidDriver = void 0;
|
|
7
|
+
const driver_1 = require("appium/driver");
|
|
8
|
+
const desired_caps_1 = __importDefault(require("./desired-caps"));
|
|
9
|
+
const index_1 = __importDefault(require("./commands/index"));
|
|
10
|
+
const method_map_1 = require("./method-map");
|
|
11
|
+
const android_helpers_1 = require("./android-helpers");
|
|
12
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
13
|
+
const appium_adb_1 = require("appium-adb");
|
|
14
|
+
const support_1 = require("@appium/support");
|
|
15
|
+
const asyncbox_1 = require("asyncbox");
|
|
16
|
+
const shared_preferences_builder_1 = require("shared-preferences-builder");
|
|
17
|
+
const bluebird_1 = __importDefault(require("bluebird"));
|
|
20
18
|
const APP_EXTENSION = '.apk';
|
|
21
19
|
const DEVICE_PORT = 4724;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
flags: '0x10200000',
|
|
62
|
-
disableAndroidWatchers: false,
|
|
63
|
-
tmpDir: await _support.tempDir.staticDir(),
|
|
64
|
-
fullReset: false,
|
|
65
|
-
autoLaunch: true,
|
|
66
|
-
adbPort: _appiumAdb.DEFAULT_ADB_PORT,
|
|
67
|
-
bootstrapPort: DEVICE_PORT,
|
|
68
|
-
androidInstallTimeout: 90000
|
|
69
|
-
};
|
|
70
|
-
_lodash.default.defaults(this.opts, defaultOpts);
|
|
71
|
-
this.useUnlockHelperApp = _lodash.default.isUndefined(this.caps.unlockType);
|
|
72
|
-
if (this.opts.noReset === true) {
|
|
73
|
-
this.opts.fullReset = false;
|
|
74
|
-
}
|
|
75
|
-
if (this.opts.fullReset === true) {
|
|
76
|
-
this.opts.noReset = false;
|
|
77
|
-
}
|
|
78
|
-
this.opts.fastReset = !this.opts.fullReset && !this.opts.noReset;
|
|
79
|
-
this.opts.skipUninstall = this.opts.fastReset || this.opts.noReset;
|
|
80
|
-
if (this.isChromeSession) {
|
|
81
|
-
_androidHelpers.helpers.adjustBrowserSessionCaps(this.opts);
|
|
82
|
-
}
|
|
83
|
-
if (this.opts.nativeWebScreenshot) {
|
|
84
|
-
this.jwpProxyAvoid.push(['GET', new RegExp('^/session/[^/]+/screenshot')]);
|
|
85
|
-
}
|
|
86
|
-
if (this.opts.reboot) {
|
|
87
|
-
this.setAvdFromCapabilities(caps);
|
|
88
|
-
}
|
|
89
|
-
let {
|
|
90
|
-
udid,
|
|
91
|
-
emPort
|
|
92
|
-
} = await _androidHelpers.helpers.getDeviceInfoFromCaps(this.opts);
|
|
93
|
-
this.opts.udid = udid;
|
|
94
|
-
this.opts.emPort = emPort;
|
|
95
|
-
this.adb = await _androidHelpers.helpers.createADB({
|
|
96
|
-
udid: this.opts.udid,
|
|
97
|
-
emPort: this.opts.emPort,
|
|
98
|
-
adbPort: this.opts.adbPort,
|
|
99
|
-
suppressKillServer: this.opts.suppressKillServer,
|
|
100
|
-
remoteAdbHost: this.opts.remoteAdbHost,
|
|
101
|
-
clearDeviceLogsOnStart: this.opts.clearDeviceLogsOnStart,
|
|
102
|
-
adbExecTimeout: this.opts.adbExecTimeout,
|
|
103
|
-
allowOfflineDevices: this.opts.allowOfflineDevices
|
|
104
|
-
});
|
|
105
|
-
if ((await this.adb.getApiLevel()) >= 23) {
|
|
106
|
-
this.log.warn("Consider setting 'automationName' capability to " + "'uiautomator2' on Android >= 6, since UIAutomator framework " + 'is not maintained anymore by the OS vendor.');
|
|
107
|
-
}
|
|
108
|
-
if (this.helpers.isPackageOrBundle(this.opts.app)) {
|
|
109
|
-
this.opts.appPackage = this.opts.app;
|
|
110
|
-
this.opts.app = null;
|
|
111
|
-
}
|
|
112
|
-
if (this.opts.app) {
|
|
113
|
-
this.opts.app = await this.helpers.configureApp(this.opts.app, APP_EXTENSION);
|
|
114
|
-
await this.checkAppPresent();
|
|
115
|
-
} else if (this.appOnDevice) {
|
|
116
|
-
this.log.info(`App file was not listed, instead we're going to run ` + `${this.opts.appPackage} directly on the device`);
|
|
117
|
-
await this.checkPackagePresent();
|
|
118
|
-
}
|
|
119
|
-
if (_support.util.hasValue(this.opts.networkSpeed)) {
|
|
120
|
-
if (!this.isEmulator()) {
|
|
121
|
-
this.log.warn('Sorry, networkSpeed capability is only available for emulators');
|
|
122
|
-
} else {
|
|
123
|
-
const networkSpeed = (0, _androidHelpers.ensureNetworkSpeed)(this.adb, this.opts.networkSpeed);
|
|
124
|
-
await this.adb.networkSpeed(networkSpeed);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
if (_support.util.hasValue(this.opts.gpsEnabled)) {
|
|
128
|
-
if (this.isEmulator()) {
|
|
129
|
-
this.log.info(`Trying to ${this.opts.gpsEnabled ? 'enable' : 'disable'} gps location provider`);
|
|
130
|
-
await this.adb.toggleGPSLocationProvider(this.opts.gpsEnabled);
|
|
131
|
-
} else {
|
|
132
|
-
this.log.warn('Sorry! gpsEnabled capability is only available for emulators');
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
await this.startAndroidSession(this.opts);
|
|
136
|
-
return [sessionId, this.caps];
|
|
137
|
-
} catch (e) {
|
|
138
|
-
try {
|
|
139
|
-
await this.deleteSession();
|
|
140
|
-
} catch (ign) {}
|
|
141
|
-
throw e;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
isEmulator() {
|
|
145
|
-
return _androidHelpers.helpers.isEmulator(this.adb, this.opts);
|
|
146
|
-
}
|
|
147
|
-
setAvdFromCapabilities(caps) {
|
|
148
|
-
if (this.opts.avd) {
|
|
149
|
-
this.log.info('avd name defined, ignoring device name and platform version');
|
|
150
|
-
} else {
|
|
151
|
-
if (!caps.deviceName) {
|
|
152
|
-
this.log.errorAndThrow('avd or deviceName should be specified when reboot option is enables');
|
|
153
|
-
}
|
|
154
|
-
if (!caps.platformVersion) {
|
|
155
|
-
this.log.errorAndThrow('avd or platformVersion should be specified when reboot option is enabled');
|
|
156
|
-
}
|
|
157
|
-
let avdDevice = caps.deviceName.replace(/[^a-zA-Z0-9_.]/g, '-');
|
|
158
|
-
this.opts.avd = `${avdDevice}__${caps.platformVersion}`;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
get appOnDevice() {
|
|
162
|
-
return this.helpers.isPackageOrBundle(this.opts.app) || !this.opts.app && this.helpers.isPackageOrBundle(this.opts.appPackage);
|
|
163
|
-
}
|
|
164
|
-
get isChromeSession() {
|
|
165
|
-
return _androidHelpers.helpers.isChromeBrowser(this.opts.browserName);
|
|
166
|
-
}
|
|
167
|
-
async onSettingsUpdate(key, value) {
|
|
168
|
-
if (key === 'ignoreUnimportantViews') {
|
|
169
|
-
await this.setCompressedLayoutHierarchy(value);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
async startAndroidSession() {
|
|
173
|
-
this.log.info(`Starting Android session`);
|
|
174
|
-
this.defaultIME = await _androidHelpers.helpers.initDevice(this.adb, this.opts);
|
|
175
|
-
this.caps.deviceName = this.adb.curDeviceId;
|
|
176
|
-
this.caps.deviceUDID = this.opts.udid;
|
|
177
|
-
this.caps.platformVersion = await this.adb.getPlatformVersion();
|
|
178
|
-
this.caps.deviceScreenSize = await this.adb.getScreenSize();
|
|
179
|
-
this.caps.deviceModel = await this.adb.getModel();
|
|
180
|
-
this.caps.deviceManufacturer = await this.adb.getManufacturer();
|
|
181
|
-
if (this.opts.disableWindowAnimation) {
|
|
182
|
-
if (await this.adb.isAnimationOn()) {
|
|
183
|
-
if ((await this.adb.getApiLevel()) >= 28) {
|
|
184
|
-
this.log.warn('Relaxing hidden api policy to manage animation scale');
|
|
185
|
-
await this.adb.setHiddenApiPolicy('1', !!this.opts.ignoreHiddenApiPolicyError);
|
|
186
|
-
}
|
|
187
|
-
this.log.info('Disabling window animation as it is requested by "disableWindowAnimation" capability');
|
|
188
|
-
await this.adb.setAnimationState(false);
|
|
189
|
-
this._wasWindowAnimationDisabled = true;
|
|
190
|
-
} else {
|
|
191
|
-
this.log.info('Window animation is already disabled');
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
await this.initAUT();
|
|
195
|
-
this.bootstrap = new _androidHelpers.helpers.bootstrap(this.adb, this.opts.bootstrapPort, this.opts.websocket);
|
|
196
|
-
await this.bootstrap.start(this.opts.appPackage, this.opts.disableAndroidWatchers, this.opts.acceptSslCerts);
|
|
197
|
-
(async () => {
|
|
198
|
-
try {
|
|
199
|
-
await this.bootstrap.onUnexpectedShutdown;
|
|
200
|
-
} catch (err) {
|
|
201
|
-
if (!this.bootstrap.ignoreUnexpectedShutdown) {
|
|
202
|
-
await this.startUnexpectedShutdown(err);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
})();
|
|
206
|
-
if (this.opts.skipUnlock) {
|
|
207
|
-
this.log.info('Skipping lockscreen check');
|
|
208
|
-
} else {
|
|
209
|
-
this.log.info('Checking for lockscreen presence. ' + `This could be skipped by setting the 'appium:skipUnlock' capability to true.`);
|
|
210
|
-
await _androidHelpers.helpers.unlock(this, this.adb, this.caps);
|
|
211
|
-
}
|
|
212
|
-
if (this.opts.ignoreUnimportantViews) {
|
|
213
|
-
await this.settings.update({
|
|
214
|
-
ignoreUnimportantViews: this.opts.ignoreUnimportantViews
|
|
215
|
-
});
|
|
20
|
+
// This is a set of methods and paths that we never want to proxy to
|
|
21
|
+
// Chromedriver
|
|
22
|
+
const NO_PROXY = [
|
|
23
|
+
['POST', new RegExp('^/session/[^/]+/context')],
|
|
24
|
+
['GET', new RegExp('^/session/[^/]+/context')],
|
|
25
|
+
['POST', new RegExp('^/session/[^/]+/appium')],
|
|
26
|
+
['GET', new RegExp('^/session/[^/]+/appium')],
|
|
27
|
+
['POST', new RegExp('^/session/[^/]+/touch/perform')],
|
|
28
|
+
['POST', new RegExp('^/session/[^/]+/touch/multi/perform')],
|
|
29
|
+
['POST', new RegExp('^/session/[^/]+/orientation')],
|
|
30
|
+
['GET', new RegExp('^/session/[^/]+/orientation')],
|
|
31
|
+
['POST', new RegExp('^/session/[^/]+/execute')],
|
|
32
|
+
['POST', new RegExp('^/session/[^/]+/execute/sync')],
|
|
33
|
+
['GET', new RegExp('^/session/[^/]+/network_connection')],
|
|
34
|
+
['POST', new RegExp('^/session/[^/]+/network_connection')],
|
|
35
|
+
];
|
|
36
|
+
class AndroidDriver extends driver_1.BaseDriver {
|
|
37
|
+
constructor(opts = {}, shouldValidateCaps = true) {
|
|
38
|
+
super(opts, shouldValidateCaps);
|
|
39
|
+
this.locatorStrategies = [
|
|
40
|
+
'xpath',
|
|
41
|
+
'id',
|
|
42
|
+
'class name',
|
|
43
|
+
'accessibility id',
|
|
44
|
+
'-android uiautomator'
|
|
45
|
+
];
|
|
46
|
+
this.desiredCapConstraints = desired_caps_1.default;
|
|
47
|
+
this.sessionChromedrivers = {};
|
|
48
|
+
this.jwpProxyActive = false;
|
|
49
|
+
this.jwpProxyAvoid = lodash_1.default.clone(NO_PROXY);
|
|
50
|
+
this.settings = new driver_1.DeviceSettings({ ignoreUnimportantViews: false }, this.onSettingsUpdate.bind(this));
|
|
51
|
+
this.chromedriver = null;
|
|
52
|
+
this.apkStrings = {};
|
|
53
|
+
this.unlocker = android_helpers_1.helpers.unlocker;
|
|
54
|
+
for (let [cmd, fn] of lodash_1.default.toPairs(index_1.default)) {
|
|
55
|
+
AndroidDriver.prototype[cmd] = fn;
|
|
56
|
+
}
|
|
57
|
+
// needs to be after the line which assigns commands to AndroidDriver.prototype, so that `this.defaultContextName` is defined.
|
|
58
|
+
this.curContext = this.defaultContextName();
|
|
216
59
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
60
|
+
async createSession(...args) {
|
|
61
|
+
// the whole createSession flow is surrounded in a try-catch statement
|
|
62
|
+
// if creating a session fails at any point, we teardown everything we
|
|
63
|
+
// set up before throwing the error.
|
|
64
|
+
try {
|
|
65
|
+
let [sessionId, caps] = await super.createSession(...args);
|
|
66
|
+
let serverDetails = {
|
|
67
|
+
platform: 'LINUX',
|
|
68
|
+
webStorageEnabled: false,
|
|
69
|
+
takesScreenshot: true,
|
|
70
|
+
javascriptEnabled: true,
|
|
71
|
+
databaseEnabled: false,
|
|
72
|
+
networkConnectionEnabled: true,
|
|
73
|
+
locationContextEnabled: false,
|
|
74
|
+
warnings: {},
|
|
75
|
+
desired: this.caps
|
|
76
|
+
};
|
|
77
|
+
this.caps = Object.assign(serverDetails, this.caps);
|
|
78
|
+
// assigning defaults
|
|
79
|
+
let defaultOpts = {
|
|
80
|
+
action: 'android.intent.action.MAIN',
|
|
81
|
+
category: 'android.intent.category.LAUNCHER',
|
|
82
|
+
flags: '0x10200000',
|
|
83
|
+
disableAndroidWatchers: false,
|
|
84
|
+
tmpDir: await support_1.tempDir.staticDir(),
|
|
85
|
+
fullReset: false,
|
|
86
|
+
autoLaunch: true,
|
|
87
|
+
adbPort: appium_adb_1.DEFAULT_ADB_PORT,
|
|
88
|
+
bootstrapPort: DEVICE_PORT,
|
|
89
|
+
androidInstallTimeout: 90000,
|
|
90
|
+
};
|
|
91
|
+
lodash_1.default.defaults(this.opts, defaultOpts);
|
|
92
|
+
this.useUnlockHelperApp = lodash_1.default.isUndefined(this.caps.unlockType);
|
|
93
|
+
// not user visible via caps
|
|
94
|
+
if (this.opts.noReset === true) {
|
|
95
|
+
this.opts.fullReset = false;
|
|
96
|
+
}
|
|
97
|
+
if (this.opts.fullReset === true) {
|
|
98
|
+
this.opts.noReset = false;
|
|
99
|
+
}
|
|
100
|
+
this.opts.fastReset = !this.opts.fullReset && !this.opts.noReset;
|
|
101
|
+
this.opts.skipUninstall = this.opts.fastReset || this.opts.noReset;
|
|
102
|
+
if (this.isChromeSession) {
|
|
103
|
+
android_helpers_1.helpers.adjustBrowserSessionCaps(this.opts);
|
|
104
|
+
}
|
|
105
|
+
if (this.opts.nativeWebScreenshot) {
|
|
106
|
+
this.jwpProxyAvoid.push(['GET', new RegExp('^/session/[^/]+/screenshot')]);
|
|
107
|
+
}
|
|
108
|
+
if (this.opts.reboot) {
|
|
109
|
+
this.setAvdFromCapabilities(caps);
|
|
110
|
+
}
|
|
111
|
+
// get device udid for this session
|
|
112
|
+
let { udid, emPort } = await android_helpers_1.helpers.getDeviceInfoFromCaps(this.opts);
|
|
113
|
+
this.opts.udid = udid;
|
|
114
|
+
this.opts.emPort = emPort;
|
|
115
|
+
// set up an instance of ADB
|
|
116
|
+
this.adb = await android_helpers_1.helpers.createADB({
|
|
117
|
+
udid: this.opts.udid,
|
|
118
|
+
emPort: this.opts.emPort,
|
|
119
|
+
adbPort: this.opts.adbPort,
|
|
120
|
+
suppressKillServer: this.opts.suppressKillServer,
|
|
121
|
+
remoteAdbHost: this.opts.remoteAdbHost,
|
|
122
|
+
clearDeviceLogsOnStart: this.opts.clearDeviceLogsOnStart,
|
|
123
|
+
adbExecTimeout: this.opts.adbExecTimeout,
|
|
124
|
+
allowOfflineDevices: this.opts.allowOfflineDevices,
|
|
125
|
+
});
|
|
126
|
+
if (await this.adb.getApiLevel() >= 23) {
|
|
127
|
+
this.log.warn("Consider setting 'automationName' capability to " +
|
|
128
|
+
"'uiautomator2' on Android >= 6, since UIAutomator framework " +
|
|
129
|
+
'is not maintained anymore by the OS vendor.');
|
|
130
|
+
}
|
|
131
|
+
if (this.helpers.isPackageOrBundle(this.opts.app)) {
|
|
132
|
+
// user provided package instead of app for 'app' capability, massage options
|
|
133
|
+
this.opts.appPackage = this.opts.app;
|
|
134
|
+
this.opts.app = null;
|
|
135
|
+
}
|
|
136
|
+
if (this.opts.app) {
|
|
137
|
+
// find and copy, or download and unzip an app url or path
|
|
138
|
+
this.opts.app = await this.helpers.configureApp(this.opts.app, APP_EXTENSION);
|
|
139
|
+
await this.checkAppPresent();
|
|
140
|
+
}
|
|
141
|
+
else if (this.appOnDevice) {
|
|
142
|
+
// the app isn't an actual app file but rather something we want to
|
|
143
|
+
// assume is on the device and just launch via the appPackage
|
|
144
|
+
this.log.info(`App file was not listed, instead we're going to run ` +
|
|
145
|
+
`${this.opts.appPackage} directly on the device`);
|
|
146
|
+
await this.checkPackagePresent();
|
|
147
|
+
}
|
|
148
|
+
// Some cloud services using appium launch the avd themselves, so we ensure netspeed
|
|
149
|
+
// is set for emulators by calling adb.networkSpeed before running the app
|
|
150
|
+
if (support_1.util.hasValue(this.opts.networkSpeed)) {
|
|
151
|
+
if (!this.isEmulator()) {
|
|
152
|
+
this.log.warn('Sorry, networkSpeed capability is only available for emulators');
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
const networkSpeed = (0, android_helpers_1.ensureNetworkSpeed)(this.adb, this.opts.networkSpeed);
|
|
156
|
+
await this.adb.networkSpeed(networkSpeed);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// check if we have to enable/disable gps before running the application
|
|
160
|
+
if (support_1.util.hasValue(this.opts.gpsEnabled)) {
|
|
161
|
+
if (this.isEmulator()) {
|
|
162
|
+
this.log.info(`Trying to ${this.opts.gpsEnabled ? 'enable' : 'disable'} gps location provider`);
|
|
163
|
+
await this.adb.toggleGPSLocationProvider(this.opts.gpsEnabled);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
this.log.warn('Sorry! gpsEnabled capability is only available for emulators');
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
await this.startAndroidSession(this.opts);
|
|
170
|
+
return [sessionId, this.caps];
|
|
171
|
+
}
|
|
172
|
+
catch (e) {
|
|
173
|
+
// ignoring delete session exception if any and throw the real error
|
|
174
|
+
// that happened while creating the session.
|
|
175
|
+
try {
|
|
176
|
+
await this.deleteSession();
|
|
177
|
+
}
|
|
178
|
+
catch (ign) { }
|
|
179
|
+
throw e;
|
|
180
|
+
}
|
|
223
181
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
await this.setOrientation(this.opts.orientation);
|
|
182
|
+
isEmulator() {
|
|
183
|
+
return android_helpers_1.helpers.isEmulator(this.adb, this.opts);
|
|
227
184
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
185
|
+
setAvdFromCapabilities(caps) {
|
|
186
|
+
if (this.opts.avd) {
|
|
187
|
+
this.log.info('avd name defined, ignoring device name and platform version');
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
if (!caps.deviceName) {
|
|
191
|
+
this.log.errorAndThrow('avd or deviceName should be specified when reboot option is enables');
|
|
192
|
+
}
|
|
193
|
+
if (!caps.platformVersion) {
|
|
194
|
+
this.log.errorAndThrow('avd or platformVersion should be specified when reboot option is enabled');
|
|
195
|
+
}
|
|
196
|
+
let avdDevice = caps.deviceName.replace(/[^a-zA-Z0-9_.]/g, '-');
|
|
197
|
+
this.opts.avd = `${avdDevice}__${caps.platformVersion}`;
|
|
198
|
+
}
|
|
238
199
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
Object.assign(this.opts, launchInfo);
|
|
243
|
-
Object.assign(this.caps, launchInfo);
|
|
244
|
-
if (this.opts.uninstallOtherPackages) {
|
|
245
|
-
_androidHelpers.helpers.validateDesiredCaps(this.opts);
|
|
246
|
-
await _androidHelpers.helpers.uninstallOtherPackages(this.adb, _androidHelpers.helpers.parseArray(this.opts.uninstallOtherPackages), [_androidHelpers.SETTINGS_HELPER_PKG_ID]);
|
|
200
|
+
get appOnDevice() {
|
|
201
|
+
return this.helpers.isPackageOrBundle(this.opts.app) || (!this.opts.app &&
|
|
202
|
+
this.helpers.isPackageOrBundle(this.opts.appPackage));
|
|
247
203
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
try {
|
|
251
|
-
otherApps = _androidHelpers.helpers.parseArray(this.opts.otherApps);
|
|
252
|
-
} catch (e) {
|
|
253
|
-
this.log.errorAndThrow(`Could not parse "otherApps" capability: ${e.message}`);
|
|
254
|
-
}
|
|
255
|
-
otherApps = await _bluebird.default.all(otherApps.map(app => this.helpers.configureApp(app, APP_EXTENSION)));
|
|
256
|
-
await _androidHelpers.helpers.installOtherApks(otherApps, this.adb, this.opts);
|
|
204
|
+
get isChromeSession() {
|
|
205
|
+
return android_helpers_1.helpers.isChromeBrowser(this.opts.browserName);
|
|
257
206
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
this.log.debug('No app capability. Assuming it is already on the device');
|
|
263
|
-
if (this.opts.fastReset) {
|
|
264
|
-
await _androidHelpers.helpers.resetApp(this.adb, this.opts);
|
|
265
|
-
}
|
|
266
|
-
return;
|
|
207
|
+
async onSettingsUpdate(key, value) {
|
|
208
|
+
if (key === 'ignoreUnimportantViews') {
|
|
209
|
+
await this.setCompressedLayoutHierarchy(value);
|
|
210
|
+
}
|
|
267
211
|
}
|
|
268
|
-
|
|
269
|
-
|
|
212
|
+
async startAndroidSession() {
|
|
213
|
+
this.log.info(`Starting Android session`);
|
|
214
|
+
// set up the device to run on (real or emulator, etc)
|
|
215
|
+
this.defaultIME = await android_helpers_1.helpers.initDevice(this.adb, this.opts);
|
|
216
|
+
// set actual device name, udid, platform version, screen size, model and manufacturer details.
|
|
217
|
+
this.caps.deviceName = this.adb.curDeviceId;
|
|
218
|
+
this.caps.deviceUDID = this.opts.udid;
|
|
219
|
+
this.caps.platformVersion = await this.adb.getPlatformVersion();
|
|
220
|
+
this.caps.deviceScreenSize = await this.adb.getScreenSize();
|
|
221
|
+
this.caps.deviceModel = await this.adb.getModel();
|
|
222
|
+
this.caps.deviceManufacturer = await this.adb.getManufacturer();
|
|
223
|
+
if (this.opts.disableWindowAnimation) {
|
|
224
|
+
if (await this.adb.isAnimationOn()) {
|
|
225
|
+
if (await this.adb.getApiLevel() >= 28) { // API level 28 is Android P
|
|
226
|
+
// Don't forget to reset the relaxing in delete session
|
|
227
|
+
this.log.warn('Relaxing hidden api policy to manage animation scale');
|
|
228
|
+
await this.adb.setHiddenApiPolicy('1', !!this.opts.ignoreHiddenApiPolicyError);
|
|
229
|
+
}
|
|
230
|
+
this.log.info('Disabling window animation as it is requested by "disableWindowAnimation" capability');
|
|
231
|
+
await this.adb.setAnimationState(false);
|
|
232
|
+
this._wasWindowAnimationDisabled = true;
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
this.log.info('Window animation is already disabled');
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// set up app under test
|
|
239
|
+
await this.initAUT();
|
|
240
|
+
// start UiAutomator
|
|
241
|
+
this.bootstrap = new android_helpers_1.helpers.bootstrap(this.adb, this.opts.bootstrapPort, this.opts.websocket);
|
|
242
|
+
await this.bootstrap.start(this.opts.appPackage, this.opts.disableAndroidWatchers, this.opts.acceptSslCerts);
|
|
243
|
+
// handling unexpected shutdown
|
|
244
|
+
(async () => {
|
|
245
|
+
try {
|
|
246
|
+
await this.bootstrap.onUnexpectedShutdown;
|
|
247
|
+
}
|
|
248
|
+
catch (err) {
|
|
249
|
+
if (!this.bootstrap.ignoreUnexpectedShutdown) {
|
|
250
|
+
await this.startUnexpectedShutdown(err);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
})();
|
|
254
|
+
if (this.opts.skipUnlock) {
|
|
255
|
+
this.log.info('Skipping lockscreen check');
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
this.log.info('Checking for lockscreen presence. ' +
|
|
259
|
+
`This could be skipped by setting the 'appium:skipUnlock' capability to true.`);
|
|
260
|
+
await android_helpers_1.helpers.unlock(this, this.adb, this.caps);
|
|
261
|
+
}
|
|
262
|
+
// Set CompressedLayoutHierarchy on the device based on current settings object
|
|
263
|
+
// this has to happen _after_ bootstrap is initialized
|
|
264
|
+
if (this.opts.ignoreUnimportantViews) {
|
|
265
|
+
await this.settings.update({ ignoreUnimportantViews: this.opts.ignoreUnimportantViews });
|
|
266
|
+
}
|
|
267
|
+
if (this.isChromeSession) {
|
|
268
|
+
// start a chromedriver session and proxy to it
|
|
269
|
+
await this.startChromeSession();
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
if (this.opts.autoLaunch) {
|
|
273
|
+
// start app
|
|
274
|
+
await this.startAUT();
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (support_1.util.hasValue(this.opts.orientation)) {
|
|
278
|
+
this.log.debug(`Setting initial orientation to '${this.opts.orientation}'`);
|
|
279
|
+
await this.setOrientation(this.opts.orientation);
|
|
280
|
+
}
|
|
281
|
+
await this.initAutoWebview();
|
|
270
282
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
283
|
+
async initAutoWebview() {
|
|
284
|
+
if (this.opts.autoWebview) {
|
|
285
|
+
let viewName = this.defaultWebviewName();
|
|
286
|
+
let timeout = (this.opts.autoWebviewTimeout) || 2000;
|
|
287
|
+
this.log.info(`Setting auto webview to context '${viewName}' with timeout ${timeout}ms`);
|
|
288
|
+
// try every 500ms until timeout is over
|
|
289
|
+
await (0, asyncbox_1.retryInterval)(timeout / 500, 500, async () => {
|
|
290
|
+
await this.setContext(viewName);
|
|
291
|
+
});
|
|
292
|
+
}
|
|
275
293
|
}
|
|
276
|
-
|
|
277
|
-
|
|
294
|
+
async initAUT() {
|
|
295
|
+
// populate appPackage, appActivity, appWaitPackage, appWaitActivity,
|
|
296
|
+
// and the device being used
|
|
297
|
+
// in the opts and caps (so it gets back to the user on session creation)
|
|
298
|
+
let launchInfo = await android_helpers_1.helpers.getLaunchInfo(this.adb, this.opts);
|
|
299
|
+
Object.assign(this.opts, launchInfo);
|
|
300
|
+
Object.assign(this.caps, launchInfo);
|
|
301
|
+
// Uninstall any uninstallOtherPackages which were specified in caps
|
|
302
|
+
if (this.opts.uninstallOtherPackages) {
|
|
303
|
+
android_helpers_1.helpers.validateDesiredCaps(this.opts);
|
|
304
|
+
// Only SETTINGS_HELPER_PKG_ID package is used by UIA1
|
|
305
|
+
await android_helpers_1.helpers.uninstallOtherPackages(this.adb, android_helpers_1.helpers.parseArray(this.opts.uninstallOtherPackages), [android_helpers_1.SETTINGS_HELPER_PKG_ID]);
|
|
306
|
+
}
|
|
307
|
+
// Install any "otherApps" that were specified in caps
|
|
308
|
+
if (this.opts.otherApps) {
|
|
309
|
+
let otherApps;
|
|
310
|
+
try {
|
|
311
|
+
otherApps = android_helpers_1.helpers.parseArray(this.opts.otherApps);
|
|
312
|
+
}
|
|
313
|
+
catch (e) {
|
|
314
|
+
this.log.errorAndThrow(`Could not parse "otherApps" capability: ${e.message}`);
|
|
315
|
+
}
|
|
316
|
+
otherApps = await bluebird_1.default.all(otherApps.map((app) => this.helpers.configureApp(app, APP_EXTENSION)));
|
|
317
|
+
await android_helpers_1.helpers.installOtherApks(otherApps, this.adb, this.opts);
|
|
318
|
+
}
|
|
319
|
+
// install app
|
|
320
|
+
if (!this.opts.app) {
|
|
321
|
+
if (this.opts.fullReset) {
|
|
322
|
+
this.log.errorAndThrow('Full reset requires an app capability, use fastReset if app is not provided');
|
|
323
|
+
}
|
|
324
|
+
this.log.debug('No app capability. Assuming it is already on the device');
|
|
325
|
+
if (this.opts.fastReset) {
|
|
326
|
+
await android_helpers_1.helpers.resetApp(this.adb, this.opts);
|
|
327
|
+
}
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
if (!this.opts.skipUninstall) {
|
|
331
|
+
await this.adb.uninstallApk(this.opts.appPackage);
|
|
332
|
+
}
|
|
333
|
+
await android_helpers_1.helpers.installApk(this.adb, this.opts);
|
|
334
|
+
const apkStringsForLanguage = await android_helpers_1.helpers.pushStrings(this.opts.language, this.adb, this.opts);
|
|
335
|
+
if (this.opts.language) {
|
|
336
|
+
this.apkStrings[this.opts.language] = apkStringsForLanguage;
|
|
337
|
+
}
|
|
338
|
+
// This must run after installing the apk, otherwise it would cause the
|
|
339
|
+
// install to fail. And before running the app.
|
|
340
|
+
if (!lodash_1.default.isUndefined(this.opts.sharedPreferences)) {
|
|
341
|
+
await this.setSharedPreferences(this.opts);
|
|
342
|
+
}
|
|
278
343
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
344
|
+
async checkAppPresent() {
|
|
345
|
+
this.log.debug('Checking whether app is actually present');
|
|
346
|
+
if (!(await support_1.fs.exists(this.opts.app))) {
|
|
347
|
+
this.log.errorAndThrow(`Could not find app apk at ${this.opts.app}`);
|
|
348
|
+
}
|
|
284
349
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
350
|
+
async checkPackagePresent() {
|
|
351
|
+
this.log.debug('Checking whether package is present on the device');
|
|
352
|
+
if (!(await this.adb.shell(['pm', 'list', 'packages', this.opts.appPackage]))) {
|
|
353
|
+
this.log.errorAndThrow(`Could not find package ${this.opts.appPackage} on the device`);
|
|
354
|
+
}
|
|
290
355
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
compressLayout: compress
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
async deleteSession() {
|
|
298
|
-
var _this$adb5;
|
|
299
|
-
this.log.debug('Shutting down Android driver');
|
|
300
|
-
try {
|
|
301
|
-
if (!_lodash.default.isEmpty(this._screenRecordingProperties)) {
|
|
302
|
-
await this.stopRecordingScreen();
|
|
303
|
-
}
|
|
304
|
-
} catch (ign) {}
|
|
305
|
-
await _androidHelpers.helpers.removeAllSessionWebSocketHandlers(this.server, this.sessionId);
|
|
306
|
-
await this.mobileStopScreenStreaming();
|
|
307
|
-
await super.deleteSession();
|
|
308
|
-
if (this.bootstrap) {
|
|
309
|
-
var _this$adb3;
|
|
310
|
-
await this.stopChromedriverProxies();
|
|
311
|
-
if (this.opts.unicodeKeyboard && this.opts.resetKeyboard && this.defaultIME) {
|
|
312
|
-
var _this$adb;
|
|
313
|
-
this.log.debug(`Resetting IME to ${this.defaultIME}`);
|
|
314
|
-
await ((_this$adb = this.adb) === null || _this$adb === void 0 ? void 0 : _this$adb.setIME(this.defaultIME));
|
|
315
|
-
}
|
|
316
|
-
if (!this.isChromeSession && !this.opts.dontStopAppOnReset) {
|
|
317
|
-
var _this$adb2;
|
|
318
|
-
await ((_this$adb2 = this.adb) === null || _this$adb2 === void 0 ? void 0 : _this$adb2.forceStop(this.opts.appPackage));
|
|
319
|
-
}
|
|
320
|
-
await ((_this$adb3 = this.adb) === null || _this$adb3 === void 0 ? void 0 : _this$adb3.goToHome());
|
|
321
|
-
if (this.opts.fullReset && !this.opts.skipUninstall && !this.appOnDevice) {
|
|
322
|
-
var _this$adb4;
|
|
323
|
-
await ((_this$adb4 = this.adb) === null || _this$adb4 === void 0 ? void 0 : _this$adb4.uninstallApk(this.opts.appPackage));
|
|
324
|
-
}
|
|
325
|
-
await this.bootstrap.shutdown();
|
|
326
|
-
this.bootstrap = null;
|
|
327
|
-
} else {
|
|
328
|
-
this.log.debug("Called deleteSession but bootstrap wasn't active");
|
|
356
|
+
// Set CompressedLayoutHierarchy on the device
|
|
357
|
+
async setCompressedLayoutHierarchy(compress) {
|
|
358
|
+
await this.bootstrap.sendAction('compressedLayoutHierarchy', { compressLayout: compress });
|
|
329
359
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
360
|
+
async deleteSession() {
|
|
361
|
+
this.log.debug('Shutting down Android driver');
|
|
362
|
+
try {
|
|
363
|
+
if (!lodash_1.default.isEmpty(this._screenRecordingProperties)) {
|
|
364
|
+
await this.stopRecordingScreen();
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
catch (ign) { }
|
|
368
|
+
await android_helpers_1.helpers.removeAllSessionWebSocketHandlers(this.server, this.sessionId);
|
|
369
|
+
await this.mobileStopScreenStreaming();
|
|
370
|
+
await super.deleteSession();
|
|
371
|
+
if (this.bootstrap) {
|
|
372
|
+
// certain cleanup we only care to do if the bootstrap was ever run
|
|
373
|
+
await this.stopChromedriverProxies();
|
|
374
|
+
if (this.opts.unicodeKeyboard && this.opts.resetKeyboard && this.defaultIME) {
|
|
375
|
+
this.log.debug(`Resetting IME to ${this.defaultIME}`);
|
|
376
|
+
await this.adb?.setIME(this.defaultIME);
|
|
377
|
+
}
|
|
378
|
+
if (!this.isChromeSession && !this.opts.dontStopAppOnReset) {
|
|
379
|
+
await this.adb?.forceStop(this.opts.appPackage);
|
|
380
|
+
}
|
|
381
|
+
await this.adb?.goToHome();
|
|
382
|
+
if (this.opts.fullReset && !this.opts.skipUninstall && !this.appOnDevice) {
|
|
383
|
+
await this.adb?.uninstallApk(this.opts.appPackage);
|
|
384
|
+
}
|
|
385
|
+
await this.bootstrap.shutdown();
|
|
386
|
+
this.bootstrap = null;
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
this.log.debug("Called deleteSession but bootstrap wasn't active");
|
|
390
|
+
}
|
|
391
|
+
// some cleanup we want to do regardless, in case we are shutting down
|
|
392
|
+
// mid-startup
|
|
393
|
+
await this.adb?.stopLogcat();
|
|
394
|
+
if (this.useUnlockHelperApp) {
|
|
395
|
+
await this.adb?.forceStop('io.appium.unlock');
|
|
396
|
+
}
|
|
397
|
+
if (this._wasWindowAnimationDisabled) {
|
|
398
|
+
this.log.info('Restoring window animation state');
|
|
399
|
+
await this.adb?.setAnimationState(true);
|
|
400
|
+
// This was necessary to change animation scale over Android P. We must reset the policy for the security.
|
|
401
|
+
if (await this.adb?.getApiLevel() >= 28) {
|
|
402
|
+
this.log.info('Restoring hidden api policy to the device default configuration');
|
|
403
|
+
await this.adb?.setDefaultHiddenApiPolicy(!!this.opts.ignoreHiddenApiPolicyError);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
if (this.opts.reboot) {
|
|
407
|
+
let avdName = this.opts.avd.replace('@', '');
|
|
408
|
+
this.log.debug(`closing emulator '${avdName}'`);
|
|
409
|
+
await this.adb?.killEmulator(avdName);
|
|
410
|
+
}
|
|
334
411
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
412
|
+
async setSharedPreferences() {
|
|
413
|
+
let sharedPrefs = this.opts.sharedPreferences;
|
|
414
|
+
this.log.info('Trying to set shared preferences');
|
|
415
|
+
let name = sharedPrefs.name;
|
|
416
|
+
if (lodash_1.default.isUndefined(name)) {
|
|
417
|
+
this.log.warn(`Skipping setting Shared preferences, name is undefined: ${JSON.stringify(sharedPrefs)}`);
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
let remotePath = `/data/data/${this.opts.appPackage}/shared_prefs`;
|
|
421
|
+
let remoteFile = `${remotePath}/${name}.xml`;
|
|
422
|
+
let localPath = `/tmp/${name}.xml`;
|
|
423
|
+
let builder = this.getPrefsBuilder();
|
|
424
|
+
builder.build(sharedPrefs.prefs);
|
|
425
|
+
this.log.info(`Creating temporary shared preferences: ${localPath}`);
|
|
426
|
+
builder.toFile(localPath);
|
|
427
|
+
this.log.info(`Creating shared_prefs remote folder: ${remotePath}`);
|
|
428
|
+
await this.adb.shell(['mkdir', '-p', remotePath]);
|
|
429
|
+
this.log.info(`Pushing shared_prefs to ${remoteFile}`);
|
|
430
|
+
await this.adb.push(localPath, remoteFile);
|
|
431
|
+
try {
|
|
432
|
+
this.log.info(`Trying to remove shared preferences temporary file`);
|
|
433
|
+
if (await support_1.fs.exists(localPath)) {
|
|
434
|
+
await support_1.fs.unlink(localPath);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
catch (e) {
|
|
438
|
+
this.log.warn(`Error trying to remove temporary file ${localPath}`);
|
|
439
|
+
}
|
|
440
|
+
return true;
|
|
344
441
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
442
|
+
getPrefsBuilder() {
|
|
443
|
+
/* Add this method to create a new SharedPrefsBuilder instead of
|
|
444
|
+
* directly creating the object on setSharedPreferences for testing purposes
|
|
445
|
+
*/
|
|
446
|
+
return new shared_preferences_builder_1.SharedPrefsBuilder();
|
|
350
447
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
448
|
+
validateDesiredCaps(caps) {
|
|
449
|
+
if (!super.validateDesiredCaps(caps)) {
|
|
450
|
+
return false;
|
|
451
|
+
}
|
|
452
|
+
if ((!caps.browserName || !android_helpers_1.helpers.isChromeBrowser(caps.browserName)) && !caps.app && !caps.appPackage) {
|
|
453
|
+
this.log.errorAndThrow('The desired capabilities must include either an app, appPackage or browserName');
|
|
454
|
+
}
|
|
455
|
+
return android_helpers_1.helpers.validateDesiredCaps(caps);
|
|
359
456
|
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
let builder = this.getPrefsBuilder();
|
|
364
|
-
builder.build(sharedPrefs.prefs);
|
|
365
|
-
this.log.info(`Creating temporary shared preferences: ${localPath}`);
|
|
366
|
-
builder.toFile(localPath);
|
|
367
|
-
this.log.info(`Creating shared_prefs remote folder: ${remotePath}`);
|
|
368
|
-
await this.adb.shell(['mkdir', '-p', remotePath]);
|
|
369
|
-
this.log.info(`Pushing shared_prefs to ${remoteFile}`);
|
|
370
|
-
await this.adb.push(localPath, remoteFile);
|
|
371
|
-
try {
|
|
372
|
-
this.log.info(`Trying to remove shared preferences temporary file`);
|
|
373
|
-
if (await _support.fs.exists(localPath)) {
|
|
374
|
-
await _support.fs.unlink(localPath);
|
|
375
|
-
}
|
|
376
|
-
} catch (e) {
|
|
377
|
-
this.log.warn(`Error trying to remove temporary file ${localPath}`);
|
|
457
|
+
proxyActive(sessionId) {
|
|
458
|
+
super.proxyActive(sessionId);
|
|
459
|
+
return this.jwpProxyActive;
|
|
378
460
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
return new _sharedPreferencesBuilder.SharedPrefsBuilder();
|
|
383
|
-
}
|
|
384
|
-
validateDesiredCaps(caps) {
|
|
385
|
-
if (!super.validateDesiredCaps(caps)) {
|
|
386
|
-
return false;
|
|
461
|
+
getProxyAvoidList(sessionId) {
|
|
462
|
+
super.getProxyAvoidList(sessionId);
|
|
463
|
+
return this.jwpProxyAvoid;
|
|
387
464
|
}
|
|
388
|
-
|
|
389
|
-
|
|
465
|
+
canProxy(sessionId) {
|
|
466
|
+
super.canProxy(sessionId);
|
|
467
|
+
// this will change depending on ChromeDriver status
|
|
468
|
+
return lodash_1.default.isFunction(this.proxyReqRes);
|
|
390
469
|
}
|
|
391
|
-
return _androidHelpers.helpers.validateDesiredCaps(caps);
|
|
392
|
-
}
|
|
393
|
-
proxyActive(sessionId) {
|
|
394
|
-
super.proxyActive(sessionId);
|
|
395
|
-
return this.jwpProxyActive;
|
|
396
|
-
}
|
|
397
|
-
getProxyAvoidList(sessionId) {
|
|
398
|
-
super.getProxyAvoidList(sessionId);
|
|
399
|
-
return this.jwpProxyAvoid;
|
|
400
|
-
}
|
|
401
|
-
canProxy(sessionId) {
|
|
402
|
-
super.canProxy(sessionId);
|
|
403
|
-
return _lodash.default.isFunction(this.proxyReqRes);
|
|
404
|
-
}
|
|
405
470
|
}
|
|
406
471
|
exports.AndroidDriver = AndroidDriver;
|
|
407
|
-
|
|
408
|
-
exports.default =
|
|
409
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZHJpdmVyIiwicmVxdWlyZSIsIl9kZXNpcmVkQ2FwcyIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfaW5kZXgiLCJfbWV0aG9kTWFwIiwiX2FuZHJvaWRIZWxwZXJzIiwiX2xvZGFzaCIsIl9hcHBpdW1BZGIiLCJfc3VwcG9ydCIsIl9hc3luY2JveCIsIl9zaGFyZWRQcmVmZXJlbmNlc0J1aWxkZXIiLCJfYmx1ZWJpcmQiLCJBUFBfRVhURU5TSU9OIiwiREVWSUNFX1BPUlQiLCJOT19QUk9YWSIsIlJlZ0V4cCIsIkFuZHJvaWREcml2ZXIiLCJCYXNlRHJpdmVyIiwibmV3TWV0aG9kTWFwIiwiY29uc3RydWN0b3IiLCJvcHRzIiwic2hvdWxkVmFsaWRhdGVDYXBzIiwibG9jYXRvclN0cmF0ZWdpZXMiLCJkZXNpcmVkQ2FwQ29uc3RyYWludHMiLCJkZXNpcmVkQ29uc3RyYWludHMiLCJzZXNzaW9uQ2hyb21lZHJpdmVycyIsImp3cFByb3h5QWN0aXZlIiwiandwUHJveHlBdm9pZCIsIl8iLCJjbG9uZSIsInNldHRpbmdzIiwiRGV2aWNlU2V0dGluZ3MiLCJpZ25vcmVVbmltcG9ydGFudFZpZXdzIiwib25TZXR0aW5nc1VwZGF0ZSIsImJpbmQiLCJjaHJvbWVkcml2ZXIiLCJhcGtTdHJpbmdzIiwidW5sb2NrZXIiLCJoZWxwZXJzIiwiY21kIiwiZm4iLCJ0b1BhaXJzIiwiY29tbWFuZHMiLCJwcm90b3R5cGUiLCJjdXJDb250ZXh0IiwiZGVmYXVsdENvbnRleHROYW1lIiwiY3JlYXRlU2Vzc2lvbiIsImFyZ3MiLCJzZXNzaW9uSWQiLCJjYXBzIiwic2VydmVyRGV0YWlscyIsInBsYXRmb3JtIiwid2ViU3RvcmFnZUVuYWJsZWQiLCJ0YWtlc1NjcmVlbnNob3QiLCJqYXZhc2NyaXB0RW5hYmxlZCIsImRhdGFiYXNlRW5hYmxlZCIsIm5ldHdvcmtDb25uZWN0aW9uRW5hYmxlZCIsImxvY2F0aW9uQ29udGV4dEVuYWJsZWQiLCJ3YXJuaW5ncyIsImRlc2lyZWQiLCJPYmplY3QiLCJhc3NpZ24iLCJkZWZhdWx0T3B0cyIsImFjdGlvbiIsImNhdGVnb3J5IiwiZmxhZ3MiLCJkaXNhYmxlQW5kcm9pZFdhdGNoZXJzIiwidG1wRGlyIiwidGVtcERpciIsInN0YXRpY0RpciIsImZ1bGxSZXNldCIsImF1dG9MYXVuY2giLCJhZGJQb3J0IiwiREVGQVVMVF9BREJfUE9SVCIsImJvb3RzdHJhcFBvcnQiLCJhbmRyb2lkSW5zdGFsbFRpbWVvdXQiLCJkZWZhdWx0cyIsInVzZVVubG9ja0hlbHBlckFwcCIsImlzVW5kZWZpbmVkIiwidW5sb2NrVHlwZSIsIm5vUmVzZXQiLCJmYXN0UmVzZXQiLCJza2lwVW5pbnN0YWxsIiwiaXNDaHJvbWVTZXNzaW9uIiwiYWRqdXN0QnJvd3NlclNlc3Npb25DYXBzIiwibmF0aXZlV2ViU2NyZWVuc2hvdCIsInB1c2giLCJyZWJvb3QiLCJzZXRBdmRGcm9tQ2FwYWJpbGl0aWVzIiwidWRpZCIsImVtUG9ydCIsImdldERldmljZUluZm9Gcm9tQ2FwcyIsImFkYiIsImNyZWF0ZUFEQiIsInN1cHByZXNzS2lsbFNlcnZlciIsInJlbW90ZUFkYkhvc3QiLCJjbGVhckRldmljZUxvZ3NPblN0YXJ0IiwiYWRiRXhlY1RpbWVvdXQiLCJhbGxvd09mZmxpbmVEZXZpY2VzIiwiZ2V0QXBpTGV2ZWwiLCJsb2ciLCJ3YXJuIiwiaXNQYWNrYWdlT3JCdW5kbGUiLCJhcHAiLCJhcHBQYWNrYWdlIiwiY29uZmlndXJlQXBwIiwiY2hlY2tBcHBQcmVzZW50IiwiYXBwT25EZXZpY2UiLCJpbmZvIiwiY2hlY2tQYWNrYWdlUHJlc2VudCIsInV0aWwiLCJoYXNWYWx1ZSIsIm5ldHdvcmtTcGVlZCIsImlzRW11bGF0b3IiLCJlbnN1cmVOZXR3b3JrU3BlZWQiLCJncHNFbmFibGVkIiwidG9nZ2xlR1BTTG9jYXRpb25Qcm92aWRlciIsInN0YXJ0QW5kcm9pZFNlc3Npb24iLCJlIiwiZGVsZXRlU2Vzc2lvbiIsImlnbiIsImF2ZCIsImRldmljZU5hbWUiLCJlcnJvckFuZFRocm93IiwicGxhdGZvcm1WZXJzaW9uIiwiYXZkRGV2aWNlIiwicmVwbGFjZSIsImlzQ2hyb21lQnJvd3NlciIsImJyb3dzZXJOYW1lIiwia2V5IiwidmFsdWUiLCJzZXRDb21wcmVzc2VkTGF5b3V0SGllcmFyY2h5IiwiZGVmYXVsdElNRSIsImluaXREZXZpY2UiLCJjdXJEZXZpY2VJZCIsImRldmljZVVESUQiLCJnZXRQbGF0Zm9ybVZlcnNpb24iLCJkZXZpY2VTY3JlZW5TaXplIiwiZ2V0U2NyZWVuU2l6ZSIsImRldmljZU1vZGVsIiwiZ2V0TW9kZWwiLCJkZXZpY2VNYW51ZmFjdHVyZXIiLCJnZXRNYW51ZmFjdHVyZXIiLCJkaXNhYmxlV2luZG93QW5pbWF0aW9uIiwiaXNBbmltYXRpb25PbiIsInNldEhpZGRlbkFwaVBvbGljeSIsImlnbm9yZUhpZGRlbkFwaVBvbGljeUVycm9yIiwic2V0QW5pbWF0aW9uU3RhdGUiLCJfd2FzV2luZG93QW5pbWF0aW9uRGlzYWJsZWQiLCJpbml0QVVUIiwiYm9vdHN0cmFwIiwid2Vic29ja2V0Iiwic3RhcnQiLCJhY2NlcHRTc2xDZXJ0cyIsIm9uVW5leHBlY3RlZFNodXRkb3duIiwiZXJyIiwiaWdub3JlVW5leHBlY3RlZFNodXRkb3duIiwic3RhcnRVbmV4cGVjdGVkU2h1dGRvd24iLCJza2lwVW5sb2NrIiwidW5sb2NrIiwidXBkYXRlIiwic3RhcnRDaHJvbWVTZXNzaW9uIiwic3RhcnRBVVQiLCJvcmllbnRhdGlvbiIsImRlYnVnIiwic2V0T3JpZW50YXRpb24iLCJpbml0QXV0b1dlYnZpZXciLCJhdXRvV2VidmlldyIsInZpZXdOYW1lIiwiZGVmYXVsdFdlYnZpZXdOYW1lIiwidGltZW91dCIsImF1dG9XZWJ2aWV3VGltZW91dCIsInJldHJ5SW50ZXJ2YWwiLCJzZXRDb250ZXh0IiwibGF1bmNoSW5mbyIsImdldExhdW5jaEluZm8iLCJ1bmluc3RhbGxPdGhlclBhY2thZ2VzIiwidmFsaWRhdGVEZXNpcmVkQ2FwcyIsInBhcnNlQXJyYXkiLCJTRVRUSU5HU19IRUxQRVJfUEtHX0lEIiwib3RoZXJBcHBzIiwibWVzc2FnZSIsIkIiLCJhbGwiLCJtYXAiLCJpbnN0YWxsT3RoZXJBcGtzIiwicmVzZXRBcHAiLCJ1bmluc3RhbGxBcGsiLCJpbnN0YWxsQXBrIiwiYXBrU3RyaW5nc0Zvckxhbmd1YWdlIiwicHVzaFN0cmluZ3MiLCJsYW5ndWFnZSIsInNoYXJlZFByZWZlcmVuY2VzIiwic2V0U2hhcmVkUHJlZmVyZW5jZXMiLCJmcyIsImV4aXN0cyIsInNoZWxsIiwiY29tcHJlc3MiLCJzZW5kQWN0aW9uIiwiY29tcHJlc3NMYXlvdXQiLCJfdGhpcyRhZGI1IiwiaXNFbXB0eSIsIl9zY3JlZW5SZWNvcmRpbmdQcm9wZXJ0aWVzIiwic3RvcFJlY29yZGluZ1NjcmVlbiIsInJlbW92ZUFsbFNlc3Npb25XZWJTb2NrZXRIYW5kbGVycyIsInNlcnZlciIsIm1vYmlsZVN0b3BTY3JlZW5TdHJlYW1pbmciLCJfdGhpcyRhZGIzIiwic3RvcENocm9tZWRyaXZlclByb3hpZXMiLCJ1bmljb2RlS2V5Ym9hcmQiLCJyZXNldEtleWJvYXJkIiwiX3RoaXMkYWRiIiwic2V0SU1FIiwiZG9udFN0b3BBcHBPblJlc2V0IiwiX3RoaXMkYWRiMiIsImZvcmNlU3RvcCIsImdvVG9Ib21lIiwiX3RoaXMkYWRiNCIsInNodXRkb3duIiwic3RvcExvZ2NhdCIsIl90aGlzJGFkYjYiLCJfdGhpcyRhZGI3IiwiX3RoaXMkYWRiOCIsIl90aGlzJGFkYjkiLCJzZXREZWZhdWx0SGlkZGVuQXBpUG9saWN5IiwiX3RoaXMkYWRiMTAiLCJhdmROYW1lIiwia2lsbEVtdWxhdG9yIiwic2hhcmVkUHJlZnMiLCJuYW1lIiwiSlNPTiIsInN0cmluZ2lmeSIsInJlbW90ZVBhdGgiLCJyZW1vdGVGaWxlIiwibG9jYWxQYXRoIiwiYnVpbGRlciIsImdldFByZWZzQnVpbGRlciIsImJ1aWxkIiwicHJlZnMiLCJ0b0ZpbGUiLCJ1bmxpbmsiLCJTaGFyZWRQcmVmc0J1aWxkZXIiLCJwcm94eUFjdGl2ZSIsImdldFByb3h5QXZvaWRMaXN0IiwiY2FuUHJveHkiLCJpc0Z1bmN0aW9uIiwicHJveHlSZXFSZXMiLCJleHBvcnRzIiwiX2RlZmF1bHQiLCJkZWZhdWx0Il0sInNvdXJjZXMiOlsiLi4vLi4vbGliL2RyaXZlci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCYXNlRHJpdmVyLCBEZXZpY2VTZXR0aW5ncyB9IGZyb20gJ2FwcGl1bS9kcml2ZXInO1xuaW1wb3J0IGRlc2lyZWRDb25zdHJhaW50cyBmcm9tICcuL2Rlc2lyZWQtY2Fwcyc7XG5pbXBvcnQgY29tbWFuZHMgZnJvbSAnLi9jb21tYW5kcy9pbmRleCc7XG5pbXBvcnQgeyBuZXdNZXRob2RNYXAgfSBmcm9tICcuL21ldGhvZC1tYXAnO1xuaW1wb3J0IHtcbiAgaGVscGVycywgZW5zdXJlTmV0d29ya1NwZWVkLFxuICBTRVRUSU5HU19IRUxQRVJfUEtHX0lELFxufSBmcm9tICcuL2FuZHJvaWQtaGVscGVycyc7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgREVGQVVMVF9BREJfUE9SVCB9IGZyb20gJ2FwcGl1bS1hZGInO1xuaW1wb3J0IHsgZnMsIHRlbXBEaXIsIHV0aWwgfSBmcm9tICdAYXBwaXVtL3N1cHBvcnQnO1xuaW1wb3J0IHsgcmV0cnlJbnRlcnZhbCB9IGZyb20gJ2FzeW5jYm94JztcbmltcG9ydCB7IFNoYXJlZFByZWZzQnVpbGRlciB9IGZyb20gJ3NoYXJlZC1wcmVmZXJlbmNlcy1idWlsZGVyJztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcblxuY29uc3QgQVBQX0VYVEVOU0lPTiA9ICcuYXBrJztcbmNvbnN0IERFVklDRV9QT1JUID0gNDcyNDtcblxuLy8gVGhpcyBpcyBhIHNldCBvZiBtZXRob2RzIGFuZCBwYXRocyB0aGF0IHdlIG5ldmVyIHdhbnQgdG8gcHJveHkgdG9cbi8vIENocm9tZWRyaXZlclxuY29uc3QgTk9fUFJPWFkgPSBbXG4gIFsnUE9TVCcsIG5ldyBSZWdFeHAoJ14vc2Vzc2lvbi9bXi9dKy9jb250ZXh0JyldLFxuICBbJ0dFVCcsIG5ldyBSZWdFeHAoJ14vc2Vzc2lvbi9bXi9dKy9jb250ZXh0JyldLFxuICBbJ1BPU1QnLCBuZXcgUmVnRXhwKCdeL3Nlc3Npb24vW14vXSsvYXBwaXVtJyldLFxuICBbJ0dFVCcsIG5ldyBSZWdFeHAoJ14vc2Vzc2lvbi9bXi9dKy9hcHBpdW0nKV0sXG4gIFsnUE9TVCcsIG5ldyBSZWdFeHAoJ14vc2Vzc2lvbi9bXi9dKy90b3VjaC9wZXJmb3JtJyldLFxuICBbJ1BPU1QnLCBuZXcgUmVnRXhwKCdeL3Nlc3Npb24vW14vXSsvdG91Y2gvbXVsdGkvcGVyZm9ybScpXSxcbiAgWydQT1NUJywgbmV3IFJlZ0V4cCgnXi9zZXNzaW9uL1teL10rL29yaWVudGF0aW9uJyldLFxuICBbJ0dFVCcsIG5ldyBSZWdFeHAoJ14vc2Vzc2lvbi9bXi9dKy9vcmllbnRhdGlvbicpXSxcbiAgWydQT1NUJywgbmV3IFJlZ0V4cCgnXi9zZXNzaW9uL1teL10rL2V4ZWN1dGUnKV0sXG4gIFsnUE9TVCcsIG5ldyBSZWdFeHAoJ14vc2Vzc2lvbi9bXi9dKy9leGVjdXRlL3N5bmMnKV0sXG4gIFsnR0VUJywgbmV3IFJlZ0V4cCgnXi9zZXNzaW9uL1teL10rL25ldHdvcmtfY29ubmVjdGlvbicpXSxcbiAgWydQT1NUJywgbmV3IFJlZ0V4cCgnXi9zZXNzaW9uL1teL10rL25ldHdvcmtfY29ubmVjdGlvbicpXSxcbl07XG5cbmNsYXNzIEFuZHJvaWREcml2ZXIgZXh0ZW5kcyBCYXNlRHJpdmVyIHtcblxuICBzdGF0aWMgbmV3TWV0aG9kTWFwID0gbmV3TWV0aG9kTWFwO1xuXG4gIGNvbnN0cnVjdG9yIChvcHRzID0ge30sIHNob3VsZFZhbGlkYXRlQ2FwcyA9IHRydWUpIHtcbiAgICBzdXBlcihvcHRzLCBzaG91bGRWYWxpZGF0ZUNhcHMpO1xuXG4gICAgdGhpcy5sb2NhdG9yU3RyYXRlZ2llcyA9IFtcbiAgICAgICd4cGF0aCcsXG4gICAgICAnaWQnLFxuICAgICAgJ2NsYXNzIG5hbWUnLFxuICAgICAgJ2FjY2Vzc2liaWxpdHkgaWQnLFxuICAgICAgJy1hbmRyb2lkIHVpYXV0b21hdG9yJ1xuICAgIF07XG4gICAgdGhpcy5kZXNpcmVkQ2FwQ29uc3RyYWludHMgPSBkZXNpcmVkQ29uc3RyYWludHM7XG4gICAgdGhpcy5zZXNzaW9uQ2hyb21lZHJpdmVycyA9IHt9O1xuICAgIHRoaXMuandwUHJveHlBY3RpdmUgPSBmYWxzZTtcbiAgICB0aGlzLmp3cFByb3h5QXZvaWQgPSBfLmNsb25lKE5PX1BST1hZKTtcbiAgICB0aGlzLnNldHRpbmdzID0gbmV3IERldmljZVNldHRpbmdzKHtpZ25vcmVVbmltcG9ydGFudFZpZXdzOiBmYWxzZX0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uU2V0dGluZ3NVcGRhdGUuYmluZCh0aGlzKSk7XG4gICAgdGhpcy5jaHJvbWVkcml2ZXIgPSBudWxsO1xuICAgIHRoaXMuYXBrU3RyaW5ncyA9IHt9O1xuICAgIHRoaXMudW5sb2NrZXIgPSBoZWxwZXJzLnVubG9ja2VyO1xuXG4gICAgZm9yIChsZXQgW2NtZCwgZm5dIG9mIF8udG9QYWlycyhjb21tYW5kcykpIHtcbiAgICAgIEFuZHJvaWREcml2ZXIucHJvdG90eXBlW2NtZF0gPSBmbjtcbiAgICB9XG5cbiAgICAvLyBuZWVkcyB0byBiZSBhZnRlciB0aGUgbGluZSB3aGljaCBhc3NpZ25zIGNvbW1hbmRzIHRvIEFuZHJvaWREcml2ZXIucHJvdG90eXBlLCBzbyB0aGF0IGB0aGlzLmRlZmF1bHRDb250ZXh0TmFtZWAgaXMgZGVmaW5lZC5cbiAgICB0aGlzLmN1ckNvbnRleHQgPSB0aGlzLmRlZmF1bHRDb250ZXh0TmFtZSgpO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlU2Vzc2lvbiAoLi4uYXJncykge1xuICAgIC8vIHRoZSB3aG9sZSBjcmVhdGVTZXNzaW9uIGZsb3cgaXMgc3Vycm91bmRlZCBpbiBhIHRyeS1jYXRjaCBzdGF0ZW1lbnRcbiAgICAvLyBpZiBjcmVhdGluZyBhIHNlc3Npb24gZmFpbHMgYXQgYW55IHBvaW50LCB3ZSB0ZWFyZG93biBldmVyeXRoaW5nIHdlXG4gICAgLy8gc2V0IHVwIGJlZm9yZSB0aHJvd2luZyB0aGUgZXJyb3IuXG4gICAgdHJ5IHtcbiAgICAgIGxldCBbc2Vzc2lvbklkLCBjYXBzXSA9IGF3YWl0IHN1cGVyLmNyZWF0ZVNlc3Npb24oLi4uYXJncyk7XG5cbiAgICAgIGxldCBzZXJ2ZXJEZXRhaWxzID0ge1xuICAgICAgICBwbGF0Zm9ybTogJ0xJTlVYJyxcbiAgICAgICAgd2ViU3RvcmFnZUVuYWJsZWQ6IGZhbHNlLFxuICAgICAgICB0YWtlc1NjcmVlbnNob3Q6IHRydWUsXG4gICAgICAgIGphdmFzY3JpcHRFbmFibGVkOiB0cnVlLFxuICAgICAgICBkYXRhYmFzZUVuYWJsZWQ6IGZhbHNlLFxuICAgICAgICBuZXR3b3JrQ29ubmVjdGlvbkVuYWJsZWQ6IHRydWUsXG4gICAgICAgIGxvY2F0aW9uQ29udGV4dEVuYWJsZWQ6IGZhbHNlLFxuICAgICAgICB3YXJuaW5nczoge30sXG4gICAgICAgIGRlc2lyZWQ6IHRoaXMuY2Fwc1xuICAgICAgfTtcblxuICAgICAgdGhpcy5jYXBzID0gT2JqZWN0LmFzc2lnbihzZXJ2ZXJEZXRhaWxzLCB0aGlzLmNhcHMpO1xuXG4gICAgICAvLyBhc3NpZ25pbmcgZGVmYXVsdHNcbiAgICAgIGxldCBkZWZhdWx0T3B0cyA9IHtcbiAgICAgICAgYWN0aW9uOiAnYW5kcm9pZC5pbnRlbnQuYWN0aW9uLk1BSU4nLFxuICAgICAgICBjYXRlZ29yeTogJ2FuZHJvaWQuaW50ZW50LmNhdGVnb3J5LkxBVU5DSEVSJyxcbiAgICAgICAgZmxhZ3M6ICcweDEwMjAwMDAwJyxcbiAgICAgICAgZGlzYWJsZUFuZHJvaWRXYXRjaGVyczogZmFsc2UsXG4gICAgICAgIHRtcERpcjogYXdhaXQgdGVtcERpci5zdGF0aWNEaXIoKSxcbiAgICAgICAgZnVsbFJlc2V0OiBmYWxzZSxcbiAgICAgICAgYXV0b0xhdW5jaDogdHJ1ZSxcbiAgICAgICAgYWRiUG9ydDogREVGQVVMVF9BREJfUE9SVCxcbiAgICAgICAgYm9vdHN0cmFwUG9ydDogREVWSUNFX1BPUlQsXG4gICAgICAgIGFuZHJvaWRJbnN0YWxsVGltZW91dDogOTAwMDAsXG4gICAgICB9O1xuICAgICAgXy5kZWZhdWx0cyh0aGlzLm9wdHMsIGRlZmF1bHRPcHRzKTtcbiAgICAgIHRoaXMudXNlVW5sb2NrSGVscGVyQXBwID0gXy5pc1VuZGVmaW5lZCh0aGlzLmNhcHMudW5sb2NrVHlwZSk7XG5cbiAgICAgIC8vIG5vdCB1c2VyIHZpc2libGUgdmlhIGNhcHNcbiAgICAgIGlmICh0aGlzLm9wdHMubm9SZXNldCA9PT0gdHJ1ZSkge1xuICAgICAgICB0aGlzLm9wdHMuZnVsbFJlc2V0ID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5vcHRzLmZ1bGxSZXNldCA9PT0gdHJ1ZSkge1xuICAgICAgICB0aGlzLm9wdHMubm9SZXNldCA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgdGhpcy5vcHRzLmZhc3RSZXNldCA9ICF0aGlzLm9wdHMuZnVsbFJlc2V0ICYmICF0aGlzLm9wdHMubm9SZXNldDtcbiAgICAgIHRoaXMub3B0cy5za2lwVW5pbnN0YWxsID0gdGhpcy5vcHRzLmZhc3RSZXNldCB8fCB0aGlzLm9wdHMubm9SZXNldDtcblxuICAgICAgaWYgKHRoaXMuaXNDaHJvbWVTZXNzaW9uKSB7XG4gICAgICAgIGhlbHBlcnMuYWRqdXN0QnJvd3NlclNlc3Npb25DYXBzKHRoaXMub3B0cyk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLm9wdHMubmF0aXZlV2ViU2NyZWVuc2hvdCkge1xuICAgICAgICB0aGlzLmp3cFByb3h5QXZvaWQucHVzaChbJ0dFVCcsIG5ldyBSZWdFeHAoJ14vc2Vzc2lvbi9bXi9dKy9zY3JlZW5zaG90JyldKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMub3B0cy5yZWJvb3QpIHtcbiAgICAgICAgdGhpcy5zZXRBdmRGcm9tQ2FwYWJpbGl0aWVzKGNhcHMpO1xuICAgICAgfVxuXG4gICAgICAvLyBnZXQgZGV2aWNlIHVkaWQgZm9yIHRoaXMgc2Vzc2lvblxuICAgICAgbGV0IHt1ZGlkLCBlbVBvcnR9ID0gYXdhaXQgaGVscGVycy5nZXREZXZpY2VJbmZvRnJvbUNhcHModGhpcy5vcHRzKTtcbiAgICAgIHRoaXMub3B0cy51ZGlkID0gdWRpZDtcbiAgICAgIHRoaXMub3B0cy5lbVBvcnQgPSBlbVBvcnQ7XG5cbiAgICAgIC8vIHNldCB1cCBhbiBpbnN0YW5jZSBvZiBBREJcbiAgICAgIHRoaXMuYWRiID0gYXdhaXQgaGVscGVycy5jcmVhdGVBREIoe1xuICAgICAgICB1ZGlkOiB0aGlzLm9wdHMudWRpZCxcbiAgICAgICAgZW1Qb3J0OiB0aGlzLm9wdHMuZW1Qb3J0LFxuICAgICAgICBhZGJQb3J0OiB0aGlzLm9wdHMuYWRiUG9ydCxcbiAgICAgICAgc3VwcHJlc3NLaWxsU2VydmVyOiB0aGlzLm9wdHMuc3VwcHJlc3NLaWxsU2VydmVyLFxuICAgICAgICByZW1vdGVBZGJIb3N0OiB0aGlzLm9wdHMucmVtb3RlQWRiSG9zdCxcbiAgICAgICAgY2xlYXJEZXZpY2VMb2dzT25TdGFydDogdGhpcy5vcHRzLmNsZWFyRGV2aWNlTG9nc09uU3RhcnQsXG4gICAgICAgIGFkYkV4ZWNUaW1lb3V0OiB0aGlzLm9wdHMuYWRiRXhlY1RpbWVvdXQsXG4gICAgICAgIGFsbG93T2ZmbGluZURldmljZXM6IHRoaXMub3B0cy5hbGxvd09mZmxpbmVEZXZpY2VzLFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChhd2FpdCB0aGlzLmFkYi5nZXRBcGlMZXZlbCgpID49IDIzKSB7XG4gICAgICAgIHRoaXMubG9nLndhcm4oXCJDb25zaWRlciBzZXR0aW5nICdhdXRvbWF0aW9uTmFtZScgY2FwYWJpbGl0eSB0byBcIiArXG4gICAgICAgICAgXCIndWlhdXRvbWF0b3IyJyBvbiBBbmRyb2lkID49IDYsIHNpbmNlIFVJQXV0b21hdG9yIGZyYW1ld29yayBcIiArXG4gICAgICAgICAgJ2lzIG5vdCBtYWludGFpbmVkIGFueW1vcmUgYnkgdGhlIE9TIHZlbmRvci4nKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuaGVscGVycy5pc1BhY2thZ2VPckJ1bmRsZSh0aGlzLm9wdHMuYXBwKSkge1xuICAgICAgICAvLyB1c2VyIHByb3ZpZGVkIHBhY2thZ2UgaW5zdGVhZCBvZiBhcHAgZm9yICdhcHAnIGNhcGFiaWxpdHksIG1hc3NhZ2Ugb3B0aW9uc1xuICAgICAgICB0aGlzLm9wdHMuYXBwUGFja2FnZSA9IHRoaXMub3B0cy5hcHA7XG4gICAgICAgIHRoaXMub3B0cy5hcHAgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5vcHRzLmFwcCkge1xuICAgICAgICAvLyBmaW5kIGFuZCBjb3B5LCBvciBkb3dubG9hZCBhbmQgdW56aXAgYW4gYXBwIHVybCBvciBwYXRoXG4gICAgICAgIHRoaXMub3B0cy5hcHAgPSBhd2FpdCB0aGlzLmhlbHBlcnMuY29uZmlndXJlQXBwKHRoaXMub3B0cy5hcHAsIEFQUF9FWFRFTlNJT04pO1xuICAgICAgICBhd2FpdCB0aGlzLmNoZWNrQXBwUHJlc2VudCgpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmFwcE9uRGV2aWNlKSB7XG4gICAgICAgIC8vIHRoZSBhcHAgaXNuJ3QgYW4gYWN0dWFsIGFwcCBmaWxlIGJ1dCByYXRoZXIgc29tZXRoaW5nIHdlIHdhbnQgdG9cbiAgICAgICAgLy8gYXNzdW1lIGlzIG9uIHRoZSBkZXZpY2UgYW5kIGp1c3QgbGF1bmNoIHZpYSB0aGUgYXBwUGFja2FnZVxuICAgICAgICB0aGlzLmxvZy5pbmZvKGBBcHAgZmlsZSB3YXMgbm90IGxpc3RlZCwgaW5zdGVhZCB3ZSdyZSBnb2luZyB0byBydW4gYCArXG4gICAgICAgICAgYCR7dGhpcy5vcHRzLmFwcFBhY2thZ2V9IGRpcmVjdGx5IG9uIHRoZSBkZXZpY2VgKTtcbiAgICAgICAgYXdhaXQgdGhpcy5jaGVja1BhY2thZ2VQcmVzZW50KCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFNvbWUgY2xvdWQgc2VydmljZXMgdXNpbmcgYXBwaXVtIGxhdW5jaCB0aGUgYXZkIHRoZW1zZWx2ZXMsIHNvIHdlIGVuc3VyZSBuZXRzcGVlZFxuICAgICAgLy8gaXMgc2V0IGZvciBlbXVsYXRvcnMgYnkgY2FsbGluZyBhZGIubmV0d29ya1NwZWVkIGJlZm9yZSBydW5uaW5nIHRoZSBhcHBcbiAgICAgIGlmICh1dGlsLmhhc1ZhbHVlKHRoaXMub3B0cy5uZXR3b3JrU3BlZWQpKSB7XG4gICAgICAgIGlmICghdGhpcy5pc0VtdWxhdG9yKCkpIHtcbiAgICAgICAgICB0aGlzLmxvZy53YXJuKCdTb3JyeSwgbmV0d29ya1NwZWVkIGNhcGFiaWxpdHkgaXMgb25seSBhdmFpbGFibGUgZm9yIGVtdWxhdG9ycycpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IG5ldHdvcmtTcGVlZCA9IGVuc3VyZU5ldHdvcmtTcGVlZCh0aGlzLmFkYiwgdGhpcy5vcHRzLm5ldHdvcmtTcGVlZCk7XG4gICAgICAgICAgYXdhaXQgdGhpcy5hZGIubmV0d29ya1NwZWVkKG5ldHdvcmtTcGVlZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIGNoZWNrIGlmIHdlIGhhdmUgdG8gZW5hYmxlL2Rpc2FibGUgZ3BzIGJlZm9yZSBydW5uaW5nIHRoZSBhcHBsaWNhdGlvblxuICAgICAgaWYgKHV0aWwuaGFzVmFsdWUodGhpcy5vcHRzLmdwc0VuYWJsZWQpKSB7XG4gICAgICAgIGlmICh0aGlzLmlzRW11bGF0b3IoKSkge1xuICAgICAgICAgIHRoaXMubG9nLmluZm8oYFRyeWluZyB0byAke3RoaXMub3B0cy5ncHNFbmFibGVkID8gJ2VuYWJsZScgOiAnZGlzYWJsZSd9IGdwcyBsb2NhdGlvbiBwcm92aWRlcmApO1xuICAgICAgICAgIGF3YWl0IHRoaXMuYWRiLnRvZ2dsZUdQU0xvY2F0aW9uUHJvdmlkZXIodGhpcy5vcHRzLmdwc0VuYWJsZWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMubG9nLndhcm4oJ1NvcnJ5ISBncHNFbmFibGVkIGNhcGFiaWxpdHkgaXMgb25seSBhdmFpbGFibGUgZm9yIGVtdWxhdG9ycycpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHRoaXMuc3RhcnRBbmRyb2lkU2Vzc2lvbih0aGlzLm9wdHMpO1xuICAgICAgcmV0dXJuIFtzZXNzaW9uSWQsIHRoaXMuY2Fwc107XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gaWdub3JpbmcgZGVsZXRlIHNlc3Npb24gZXhjZXB0aW9uIGlmIGFueSBhbmQgdGhyb3cgdGhlIHJlYWwgZXJyb3JcbiAgICAgIC8vIHRoYXQgaGFwcGVuZWQgd2hpbGUgY3JlYXRpbmcgdGhlIHNlc3Npb24uXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLmRlbGV0ZVNlc3Npb24oKTtcbiAgICAgIH0gY2F0Y2ggKGlnbikge31cbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG5cbiAgaXNFbXVsYXRvciAoKSB7XG4gICAgcmV0dXJuIGhlbHBlcnMuaXNFbXVsYXRvcih0aGlzLmFkYiwgdGhpcy5vcHRzKTtcbiAgfVxuXG4gIHNldEF2ZEZyb21DYXBhYmlsaXRpZXMgKGNhcHMpIHtcbiAgICBpZiAodGhpcy5vcHRzLmF2ZCkge1xuICAgICAgdGhpcy5sb2cuaW5mbygnYXZkIG5hbWUgZGVmaW5lZCwgaWdub3JpbmcgZGV2aWNlIG5hbWUgYW5kIHBsYXRmb3JtIHZlcnNpb24nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFjYXBzLmRldmljZU5hbWUpIHtcbiAgICAgICAgdGhpcy5sb2cuZXJyb3JBbmRUaHJvdygnYXZkIG9yIGRldmljZU5hbWUgc2hvdWxkIGJlIHNwZWNpZmllZCB3aGVuIHJlYm9vdCBvcHRpb24gaXMgZW5hYmxlcycpO1xuICAgICAgfVxuICAgICAgaWYgKCFjYXBzLnBsYXRmb3JtVmVyc2lvbikge1xuICAgICAgICB0aGlzLmxvZy5lcnJvckFuZFRocm93KCdhdmQgb3IgcGxhdGZvcm1WZXJzaW9uIHNob3VsZCBiZSBzcGVjaWZpZWQgd2hlbiByZWJvb3Qgb3B0aW9uIGlzIGVuYWJsZWQnKTtcbiAgICAgIH1cbiAgICAgIGxldCBhdmREZXZpY2UgPSBjYXBzLmRldmljZU5hbWUucmVwbGFjZSgvW15hLXpBLVowLTlfLl0vZywgJy0nKTtcbiAgICAgIHRoaXMub3B0cy5hdmQgPSBgJHthdmREZXZpY2V9X18ke2NhcHMucGxhdGZvcm1WZXJzaW9ufWA7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGFwcE9uRGV2aWNlICgpIHtcbiAgICByZXR1cm4gdGhpcy5oZWxwZXJzLmlzUGFja2FnZU9yQnVuZGxlKHRoaXMub3B0cy5hcHApIHx8ICghdGhpcy5vcHRzLmFwcCAmJlxuICAgICAgICAgICB0aGlzLmhlbHBlcnMuaXNQYWNrYWdlT3JCdW5kbGUodGhpcy5vcHRzLmFwcFBhY2thZ2UpKTtcbiAgfVxuXG4gIGdldCBpc0Nocm9tZVNlc3Npb24gKCkge1xuICAgIHJldHVybiBoZWxwZXJzLmlzQ2hyb21lQnJvd3Nlcih0aGlzLm9wdHMuYnJvd3Nlck5hbWUpO1xuICB9XG5cbiAgYXN5bmMgb25TZXR0aW5nc1VwZGF0ZSAoa2V5LCB2YWx1ZSkge1xuICAgIGlmIChrZXkgPT09ICdpZ25vcmVVbmltcG9ydGFudFZpZXdzJykge1xuICAgICAgYXdhaXQgdGhpcy5zZXRDb21wcmVzc2VkTGF5b3V0SGllcmFyY2h5KHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBzdGFydEFuZHJvaWRTZXNzaW9uICgpIHtcbiAgICB0aGlzLmxvZy5pbmZvKGBTdGFydGluZyBBbmRyb2lkIHNlc3Npb25gKTtcbiAgICAvLyBzZXQgdXAgdGhlIGRldmljZSB0byBydW4gb24gKHJlYWwgb3IgZW11bGF0b3IsIGV0YylcbiAgICB0aGlzLmRlZmF1bHRJTUUgPSBhd2FpdCBoZWxwZXJzLmluaXREZXZpY2UodGhpcy5hZGIsIHRoaXMub3B0cyk7XG5cbiAgICAvLyBzZXQgYWN0dWFsIGRldmljZSBuYW1lLCB1ZGlkLCBwbGF0Zm9ybSB2ZXJzaW9uLCBzY3JlZW4gc2l6ZSwgbW9kZWwgYW5kIG1hbnVmYWN0dXJlciBkZXRhaWxzLlxuICAgIHRoaXMuY2Fwcy5kZXZpY2VOYW1lID0gdGhpcy5hZGIuY3VyRGV2aWNlSWQ7XG4gICAgdGhpcy5jYXBzLmRldmljZVVESUQgPSB0aGlzLm9wdHMudWRpZDtcbiAgICB0aGlzLmNhcHMucGxhdGZvcm1WZXJzaW9uID0gYXdhaXQgdGhpcy5hZGIuZ2V0UGxhdGZvcm1WZXJzaW9uKCk7XG4gICAgdGhpcy5jYXBzLmRldmljZVNjcmVlblNpemUgPSBhd2FpdCB0aGlzLmFkYi5nZXRTY3JlZW5TaXplKCk7XG4gICAgdGhpcy5jYXBzLmRldmljZU1vZGVsID0gYXdhaXQgdGhpcy5hZGIuZ2V0TW9kZWwoKTtcbiAgICB0aGlzLmNhcHMuZGV2aWNlTWFudWZhY3R1cmVyID0gYXdhaXQgdGhpcy5hZGIuZ2V0TWFudWZhY3R1cmVyKCk7XG5cbiAgICBpZiAodGhpcy5vcHRzLmRpc2FibGVXaW5kb3dBbmltYXRpb24pIHtcbiAgICAgIGlmIChhd2FpdCB0aGlzLmFkYi5pc0FuaW1hdGlvbk9uKCkpIHtcbiAgICAgICAgaWYgKGF3YWl0IHRoaXMuYWRiLmdldEFwaUxldmVsKCkgPj0gMjgpIHsgLy8gQVBJIGxldmVsIDI4IGlzIEFuZHJvaWQgUFxuICAgICAgICAgIC8vIERvbid0IGZvcmdldCB0byByZXNldCB0aGUgcmVsYXhpbmcgaW4gZGVsZXRlIHNlc3Npb25cbiAgICAgICAgICB0aGlzLmxvZy53YXJuKCdSZWxheGluZyBoaWRkZW4gYXBpIHBvbGljeSB0byBtYW5hZ2UgYW5pbWF0aW9uIHNjYWxlJyk7XG4gICAgICAgICAgYXdhaXQgdGhpcy5hZGIuc2V0SGlkZGVuQXBpUG9saWN5KCcxJywgISF0aGlzLm9wdHMuaWdub3JlSGlkZGVuQXBpUG9saWN5RXJyb3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5sb2cuaW5mbygnRGlzYWJsaW5nIHdpbmRvdyBhbmltYXRpb24gYXMgaXQgaXMgcmVxdWVzdGVkIGJ5IFwiZGlzYWJsZVdpbmRvd0FuaW1hdGlvblwiIGNhcGFiaWxpdHknKTtcbiAgICAgICAgYXdhaXQgdGhpcy5hZGIuc2V0QW5pbWF0aW9uU3RhdGUoZmFsc2UpO1xuICAgICAgICB0aGlzLl93YXNXaW5kb3dBbmltYXRpb25EaXNhYmxlZCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmxvZy5pbmZvKCdXaW5kb3cgYW5pbWF0aW9uIGlzIGFscmVhZHkgZGlzYWJsZWQnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzZXQgdXAgYXBwIHVuZGVyIHRlc3RcbiAgICBhd2FpdCB0aGlzLmluaXRBVVQoKTtcblxuICAgIC8vIHN0YXJ0IFVpQXV0b21hdG9yXG4gICAgdGhpcy5ib290c3RyYXAgPSBuZXcgaGVscGVycy5ib290c3RyYXAodGhpcy5hZGIsIHRoaXMub3B0cy5ib290c3RyYXBQb3J0LCB0aGlzLm9wdHMud2Vic29ja2V0KTtcbiAgICBhd2FpdCB0aGlzLmJvb3RzdHJhcC5zdGFydCh0aGlzLm9wdHMuYXBwUGFja2FnZSwgdGhpcy5vcHRzLmRpc2FibGVBbmRyb2lkV2F0Y2hlcnMsIHRoaXMub3B0cy5hY2NlcHRTc2xDZXJ0cyk7XG4gICAgLy8gaGFuZGxpbmcgdW5leHBlY3RlZCBzaHV0ZG93blxuICAgIChhc3luYyAoKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLmJvb3RzdHJhcC5vblVuZXhwZWN0ZWRTaHV0ZG93bjtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBpZiAoIXRoaXMuYm9vdHN0cmFwLmlnbm9yZVVuZXhwZWN0ZWRTaHV0ZG93bikge1xuICAgICAgICAgIGF3YWl0IHRoaXMuc3RhcnRVbmV4cGVjdGVkU2h1dGRvd24oZXJyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pKCk7XG5cblxuICAgIGlmICh0aGlzLm9wdHMuc2tpcFVubG9jaykge1xuICAgICAgdGhpcy5sb2cuaW5mbygnU2tpcHBpbmcgbG9ja3NjcmVlbiBjaGVjaycpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvZy5pbmZvKCdDaGVja2luZyBmb3IgbG9ja3NjcmVlbiBwcmVzZW5jZS4gJyArXG4gICAgICAgIGBUaGlzIGNvdWxkIGJlIHNraXBwZWQgYnkgc2V0dGluZyB0aGUgJ2FwcGl1bTpza2lwVW5sb2NrJyBjYXBhYmlsaXR5IHRvIHRydWUuYCk7XG4gICAgICBhd2FpdCBoZWxwZXJzLnVubG9jayh0aGlzLCB0aGlzLmFkYiwgdGhpcy5jYXBzKTtcbiAgICB9XG5cbiAgICAvLyBTZXQgQ29tcHJlc3NlZExheW91dEhpZXJhcmNoeSBvbiB0aGUgZGV2aWNlIGJhc2VkIG9uIGN1cnJlbnQgc2V0dGluZ3Mgb2JqZWN0XG4gICAgLy8gdGhpcyBoYXMgdG8gaGFwcGVuIF9hZnRlcl8gYm9vdHN0cmFwIGlzIGluaXRpYWxpemVkXG4gICAgaWYgKHRoaXMub3B0cy5pZ25vcmVVbmltcG9ydGFudFZpZXdzKSB7XG4gICAgICBhd2FpdCB0aGlzLnNldHRpbmdzLnVwZGF0ZSh7aWdub3JlVW5pbXBvcnRhbnRWaWV3czogdGhpcy5vcHRzLmlnbm9yZVVuaW1wb3J0YW50Vmlld3N9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc0Nocm9tZVNlc3Npb24pIHtcbiAgICAgIC8vIHN0YXJ0IGEgY2hyb21lZHJpdmVyIHNlc3Npb24gYW5kIHByb3h5IHRvIGl0XG4gICAgICBhd2FpdCB0aGlzLnN0YXJ0Q2hyb21lU2Vzc2lvbigpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5vcHRzLmF1dG9MYXVuY2gpIHtcbiAgICAgICAgLy8gc3RhcnQgYXBwXG4gICAgICAgIGF3YWl0IHRoaXMuc3RhcnRBVVQoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodXRpbC5oYXNWYWx1ZSh0aGlzLm9wdHMub3JpZW50YXRpb24pKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgU2V0dGluZyBpbml0aWFsIG9yaWVudGF0aW9uIHRvICcke3RoaXMub3B0cy5vcmllbnRhdGlvbn0nYCk7XG4gICAgICBhd2FpdCB0aGlzLnNldE9yaWVudGF0aW9uKHRoaXMub3B0cy5vcmllbnRhdGlvbik7XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5pbml0QXV0b1dlYnZpZXcoKTtcbiAgfVxuXG4gIGFzeW5jIGluaXRBdXRvV2VidmlldyAoKSB7XG4gICAgaWYgKHRoaXMub3B0cy5hdXRvV2Vidmlldykge1xuICAgICAgbGV0IHZpZXdOYW1lID0gdGhpcy5kZWZhdWx0V2Vidmlld05hbWUoKTtcbiAgICAgIGxldCB0aW1lb3V0ID0gKHRoaXMub3B0cy5hdXRvV2Vidmlld1RpbWVvdXQpIHx8IDIwMDA7XG5cbiAgICAgIHRoaXMubG9nLmluZm8oYFNldHRpbmcgYXV0byB3ZWJ2aWV3IHRvIGNvbnRleHQgJyR7dmlld05hbWV9JyB3aXRoIHRpbWVvdXQgJHt0aW1lb3V0fW1zYCk7XG5cbiAgICAgIC8vIHRyeSBldmVyeSA1MDBtcyB1bnRpbCB0aW1lb3V0IGlzIG92ZXJcbiAgICAgIGF3YWl0IHJldHJ5SW50ZXJ2YWwodGltZW91dCAvIDUwMCwgNTAwLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHRoaXMuc2V0Q29udGV4dCh2aWV3TmFtZSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBpbml0QVVUICgpIHtcbiAgICAvLyBwb3B1bGF0ZSBhcHBQYWNrYWdlLCBhcHBBY3Rpdml0eSwgYXBwV2FpdFBhY2thZ2UsIGFwcFdhaXRBY3Rpdml0eSxcbiAgICAvLyBhbmQgdGhlIGRldmljZSBiZWluZyB1c2VkXG4gICAgLy8gaW4gdGhlIG9wdHMgYW5kIGNhcHMgKHNvIGl0IGdldHMgYmFjayB0byB0aGUgdXNlciBvbiBzZXNzaW9uIGNyZWF0aW9uKVxuICAgIGxldCBsYXVuY2hJbmZvID0gYXdhaXQgaGVscGVycy5nZXRMYXVuY2hJbmZvKHRoaXMuYWRiLCB0aGlzLm9wdHMpO1xuICAgIE9iamVjdC5hc3NpZ24odGhpcy5vcHRzLCBsYXVuY2hJbmZvKTtcbiAgICBPYmplY3QuYXNzaWduKHRoaXMuY2FwcywgbGF1bmNoSW5mbyk7XG5cbiAgICAvLyBVbmluc3RhbGwgYW55IHVuaW5zdGFsbE90aGVyUGFja2FnZXMgd2hpY2ggd2VyZSBzcGVjaWZpZWQgaW4gY2Fwc1xuICAgIGlmICh0aGlzLm9wdHMudW5pbnN0YWxsT3RoZXJQYWNrYWdlcykge1xuICAgICAgaGVscGVycy52YWxpZGF0ZURlc2lyZWRDYXBzKHRoaXMub3B0cyk7XG4gICAgICAvLyBPbmx5IFNFVFRJTkdTX0hFTFBFUl9QS0dfSUQgcGFja2FnZSBpcyB1c2VkIGJ5IFVJQTFcbiAgICAgIGF3YWl0IGhlbHBlcnMudW5pbnN0YWxsT3RoZXJQYWNrYWdlcyhcbiAgICAgICAgdGhpcy5hZGIsXG4gICAgICAgIGhlbHBlcnMucGFyc2VBcnJheSh0aGlzLm9wdHMudW5pbnN0YWxsT3RoZXJQYWNrYWdlcyksXG4gICAgICAgIFtTRVRUSU5HU19IRUxQRVJfUEtHX0lEXVxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBJbnN0YWxsIGFueSBcIm90aGVyQXBwc1wiIHRoYXQgd2VyZSBzcGVjaWZpZWQgaW4gY2Fwc1xuICAgIGlmICh0aGlzLm9wdHMub3RoZXJBcHBzKSB7XG4gICAgICBsZXQgb3RoZXJBcHBzO1xuICAgICAgdHJ5IHtcbiAgICAgICAgb3RoZXJBcHBzID0gaGVscGVycy5wYXJzZUFycmF5KHRoaXMub3B0cy5vdGhlckFwcHMpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aGlzLmxvZy5lcnJvckFuZFRocm93KGBDb3VsZCBub3QgcGFyc2UgXCJvdGhlckFwcHNcIiBjYXBhYmlsaXR5OiAke2UubWVzc2FnZX1gKTtcbiAgICAgIH1cbiAgICAgIG90aGVyQXBwcyA9IGF3YWl0IEIuYWxsKG90aGVyQXBwcy5tYXAoKGFwcCkgPT4gdGhpcy5oZWxwZXJzLmNvbmZpZ3VyZUFwcChhcHAsIEFQUF9FWFRFTlNJT04pKSk7XG4gICAgICBhd2FpdCBoZWxwZXJzLmluc3RhbGxPdGhlckFwa3Mob3RoZXJBcHBzLCB0aGlzLmFkYiwgdGhpcy5vcHRzKTtcbiAgICB9XG5cbiAgICAvLyBpbnN0YWxsIGFwcFxuICAgIGlmICghdGhpcy5vcHRzLmFwcCkge1xuICAgICAgaWYgKHRoaXMub3B0cy5mdWxsUmVzZXQpIHtcbiAgICAgICAgdGhpcy5sb2cuZXJyb3JBbmRUaHJvdygnRnVsbCByZXNldCByZXF1aXJlcyBhbiBhcHAgY2FwYWJpbGl0eSwgdXNlIGZhc3RSZXNldCBpZiBhcHAgaXMgbm90IHByb3ZpZGVkJyk7XG4gICAgICB9XG4gICAgICB0aGlzLmxvZy5kZWJ1ZygnTm8gYXBwIGNhcGFiaWxpdHkuIEFzc3VtaW5nIGl0IGlzIGFscmVhZHkgb24gdGhlIGRldmljZScpO1xuICAgICAgaWYgKHRoaXMub3B0cy5mYXN0UmVzZXQpIHtcbiAgICAgICAgYXdhaXQgaGVscGVycy5yZXNldEFwcCh0aGlzLmFkYiwgdGhpcy5vcHRzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCF0aGlzLm9wdHMuc2tpcFVuaW5zdGFsbCkge1xuICAgICAgYXdhaXQgdGhpcy5hZGIudW5pbnN0YWxsQXBrKHRoaXMub3B0cy5hcHBQYWNrYWdlKTtcbiAgICB9XG4gICAgYXdhaXQgaGVscGVycy5pbnN0YWxsQXBrKHRoaXMuYWRiLCB0aGlzLm9wdHMpO1xuICAgIGNvbnN0IGFwa1N0cmluZ3NGb3JMYW5ndWFnZSA9IGF3YWl0IGhlbHBlcnMucHVzaFN0cmluZ3ModGhpcy5vcHRzLmxhbmd1YWdlLCB0aGlzLmFkYiwgdGhpcy5vcHRzKTtcbiAgICBpZiAodGhpcy5vcHRzLmxhbmd1YWdlKSB7XG4gICAgICB0aGlzLmFwa1N0cmluZ3NbdGhpcy5vcHRzLmxhbmd1YWdlXSA9IGFwa1N0cmluZ3NGb3JMYW5ndWFnZTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIG11c3QgcnVuIGFmdGVyIGluc3RhbGxpbmcgdGhlIGFwaywgb3RoZXJ3aXNlIGl0IHdvdWxkIGNhdXNlIHRoZVxuICAgIC8vIGluc3RhbGwgdG8gZmFpbC4gQW5kIGJlZm9yZSBydW5uaW5nIHRoZSBhcHAuXG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKHRoaXMub3B0cy5zaGFyZWRQcmVmZXJlbmNlcykpIHtcbiAgICAgIGF3YWl0IHRoaXMuc2V0U2hhcmVkUHJlZmVyZW5jZXModGhpcy5vcHRzKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjaGVja0FwcFByZXNlbnQgKCkge1xuICAgIHRoaXMubG9nLmRlYnVnKCdDaGVja2luZyB3aGV0aGVyIGFwcCBpcyBhY3R1YWxseSBwcmVzZW50Jyk7XG4gICAgaWYgKCEoYXdhaXQgZnMuZXhpc3RzKHRoaXMub3B0cy5hcHApKSkge1xuICAgICAgdGhpcy5sb2cuZXJyb3JBbmRUaHJvdyhgQ291bGQgbm90IGZpbmQgYXBwIGFwayBhdCAke3RoaXMub3B0cy5hcHB9YCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgY2hlY2tQYWNrYWdlUHJlc2VudCAoKSB7XG4gICAgdGhpcy5sb2cuZGVidWcoJ0NoZWNraW5nIHdoZXRoZXIgcGFja2FnZSBpcyBwcmVzZW50IG9uIHRoZSBkZXZpY2UnKTtcbiAgICBpZiAoIShhd2FpdCB0aGlzLmFkYi5zaGVsbChbJ3BtJywgJ2xpc3QnLCAncGFja2FnZXMnLCB0aGlzLm9wdHMuYXBwUGFja2FnZV0pKSkge1xuICAgICAgdGhpcy5sb2cuZXJyb3JBbmRUaHJvdyhgQ291bGQgbm90IGZpbmQgcGFja2FnZSAke3RoaXMub3B0cy5hcHBQYWNrYWdlfSBvbiB0aGUgZGV2aWNlYCk7XG4gICAgfVxuICB9XG5cbiAgLy8gU2V0IENvbXByZXNzZWRMYXlvdXRIaWVyYXJjaHkgb24gdGhlIGRldmljZVxuICBhc3luYyBzZXRDb21wcmVzc2VkTGF5b3V0SGllcmFyY2h5IChjb21wcmVzcykge1xuICAgIGF3YWl0IHRoaXMuYm9vdHN0cmFwLnNlbmRBY3Rpb24oJ2NvbXByZXNzZWRMYXlvdXRIaWVyYXJjaHknLCB7Y29tcHJlc3NMYXlvdXQ6IGNvbXByZXNzfSk7XG4gIH1cblxuICBhc3luYyBkZWxldGVTZXNzaW9uICgpIHtcbiAgICB0aGlzLmxvZy5kZWJ1ZygnU2h1dHRpbmcgZG93biBBbmRyb2lkIGRyaXZlcicpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGlmICghXy5pc0VtcHR5KHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMpKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuc3RvcFJlY29yZGluZ1NjcmVlbigpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGlnbikge31cblxuICAgIGF3YWl0IGhlbHBlcnMucmVtb3ZlQWxsU2Vzc2lvbldlYlNvY2tldEhhbmRsZXJzKHRoaXMuc2VydmVyLCB0aGlzLnNlc3Npb25JZCk7XG5cbiAgICBhd2FpdCB0aGlzLm1vYmlsZVN0b3BTY3JlZW5TdHJlYW1pbmcoKTtcblxuICAgIGF3YWl0IHN1cGVyLmRlbGV0ZVNlc3Npb24oKTtcblxuICAgIGlmICh0aGlzLmJvb3RzdHJhcCkge1xuICAgICAgLy8gY2VydGFpbiBjbGVhbnVwIHdlIG9ubHkgY2FyZSB0byBkbyBpZiB0aGUgYm9vdHN0cmFwIHdhcyBldmVyIHJ1blxuICAgICAgYXdhaXQgdGhpcy5zdG9wQ2hyb21lZHJpdmVyUHJveGllcygpO1xuICAgICAgaWYgKHRoaXMub3B0cy51bmljb2RlS2V5Ym9hcmQgJiYgdGhpcy5vcHRzLnJlc2V0S2V5Ym9hcmQgJiYgdGhpcy5kZWZhdWx0SU1FKSB7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKGBSZXNldHRpbmcgSU1FIHRvICR7dGhpcy5kZWZhdWx0SU1FfWApO1xuICAgICAgICBhd2FpdCB0aGlzLmFkYj8uc2V0SU1FKHRoaXMuZGVmYXVsdElNRSk7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuaXNDaHJvbWVTZXNzaW9uICYmICF0aGlzLm9wdHMuZG9udFN0b3BBcHBPblJlc2V0KSB7XG4gICAgICAgIGF3YWl0IHRoaXMuYWRiPy5mb3JjZVN0b3AodGhpcy5vcHRzLmFwcFBhY2thZ2UpO1xuICAgICAgfVxuICAgICAgYXdhaXQgdGhpcy5hZGI/LmdvVG9Ib21lKCk7XG4gICAgICBpZiAodGhpcy5vcHRzLmZ1bGxSZXNldCAmJiAhdGhpcy5vcHRzLnNraXBVbmluc3RhbGwgJiYgIXRoaXMuYXBwT25EZXZpY2UpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5hZGI/LnVuaW5zdGFsbEFwayh0aGlzLm9wdHMuYXBwUGFja2FnZSk7XG4gICAgICB9XG4gICAgICBhd2FpdCB0aGlzLmJvb3RzdHJhcC5zaHV0ZG93bigpO1xuICAgICAgdGhpcy5ib290c3RyYXAgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhcIkNhbGxlZCBkZWxldGVTZXNzaW9uIGJ1dCBib290c3RyYXAgd2Fzbid0IGFjdGl2ZVwiKTtcbiAgICB9XG4gICAgLy8gc29tZSBjbGVhbnVwIHdlIHdhbnQgdG8gZG8gcmVnYXJkbGVzcywgaW4gY2FzZSB3ZSBhcmUgc2h1dHRpbmcgZG93blxuICAgIC8vIG1pZC1zdGFydHVwXG4gICAgYXdhaXQgdGhpcy5hZGI/LnN0b3BMb2djYXQoKTtcbiAgICBpZiAodGhpcy51c2VVbmxvY2tIZWxwZXJBcHApIHtcbiAgICAgIGF3YWl0IHRoaXMuYWRiPy5mb3JjZVN0b3AoJ2lvLmFwcGl1bS51bmxvY2snKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX3dhc1dpbmRvd0FuaW1hdGlvbkRpc2FibGVkKSB7XG4gICAgICB0aGlzLmxvZy5pbmZvKCdSZXN0b3Jpbmcgd2luZG93IGFuaW1hdGlvbiBzdGF0ZScpO1xuICAgICAgYXdhaXQgdGhpcy5hZGI/LnNldEFuaW1hdGlvblN0YXRlKHRydWUpO1xuXG4gICAgICAvLyBUaGlzIHdhcyBuZWNlc3NhcnkgdG8gY2hhbmdlIGFuaW1hdGlvbiBzY2FsZSBvdmVyIEFuZHJvaWQgUC4gV2UgbXVzdCByZXNldCB0aGUgcG9saWN5IGZvciB0aGUgc2VjdXJpdHkuXG4gICAgICBpZiAoYXdhaXQgdGhpcy5hZGI/LmdldEFwaUxldmVsKCkgPj0gMjgpIHtcbiAgICAgICAgdGhpcy5sb2cuaW5mbygnUmVzdG9yaW5nIGhpZGRlbiBhcGkgcG9saWN5IHRvIHRoZSBkZXZpY2UgZGVmYXVsdCBjb25maWd1cmF0aW9uJyk7XG4gICAgICAgIGF3YWl0IHRoaXMuYWRiPy5zZXREZWZhdWx0SGlkZGVuQXBpUG9saWN5KCEhdGhpcy5vcHRzLmlnbm9yZUhpZGRlbkFwaVBvbGljeUVycm9yKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRzLnJlYm9vdCkge1xuICAgICAgbGV0IGF2ZE5hbWUgPSB0aGlzLm9wdHMuYXZkLnJlcGxhY2UoJ0AnLCAnJyk7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgY2xvc2luZyBlbXVsYXRvciAnJHthdmROYW1lfSdgKTtcbiAgICAgIGF3YWl0IHRoaXMuYWRiPy5raWxsRW11bGF0b3IoYXZkTmFtZSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgc2V0U2hhcmVkUHJlZmVyZW5jZXMgKCkge1xuICAgIGxldCBzaGFyZWRQcmVmcyA9IHRoaXMub3B0cy5zaGFyZWRQcmVmZXJlbmNlcztcbiAgICB0aGlzLmxvZy5pbmZvKCdUcnlpbmcgdG8gc2V0IHNoYXJlZCBwcmVmZXJlbmNlcycpO1xuICAgIGxldCBuYW1lID0gc2hhcmVkUHJlZnMubmFtZTtcbiAgICBpZiAoXy5pc1VuZGVmaW5lZChuYW1lKSkge1xuICAgICAgdGhpcy5sb2cud2FybihgU2tpcHBpbmcgc2V0dGluZyBTaGFyZWQgcHJlZmVyZW5jZXMsIG5hbWUgaXMgdW5kZWZpbmVkOiAke0pTT04uc3RyaW5naWZ5KHNoYXJlZFByZWZzKX1gKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgbGV0IHJlbW90ZVBhdGggPSBgL2RhdGEvZGF0YS8ke3RoaXMub3B0cy5hcHBQYWNrYWdlfS9zaGFyZWRfcHJlZnNgO1xuICAgIGxldCByZW1vdGVGaWxlID0gYCR7cmVtb3RlUGF0aH0vJHtuYW1lfS54bWxgO1xuICAgIGxldCBsb2NhbFBhdGggPSBgL3RtcC8ke25hbWV9LnhtbGA7XG4gICAgbGV0IGJ1aWxkZXIgPSB0aGlzLmdldFByZWZzQnVpbGRlcigpO1xuICAgIGJ1aWxkZXIuYnVpbGQoc2hhcmVkUHJlZnMucHJlZnMpO1xuICAgIHRoaXMubG9nLmluZm8oYENyZWF0aW5nIHRlbXBvcmFyeSBzaGFyZWQgcHJlZmVyZW5jZXM6ICR7bG9jYWxQYXRofWApO1xuICAgIGJ1aWxkZXIudG9GaWxlKGxvY2FsUGF0aCk7XG4gICAgdGhpcy5sb2cuaW5mbyhgQ3JlYXRpbmcgc2hhcmVkX3ByZWZzIHJlbW90ZSBmb2xkZXI6ICR7cmVtb3RlUGF0aH1gKTtcbiAgICBhd2FpdCB0aGlzLmFkYi5zaGVsbChbJ21rZGlyJywgJy1wJywgcmVtb3RlUGF0aF0pO1xuICAgIHRoaXMubG9nLmluZm8oYFB1c2hpbmcgc2hhcmVkX3ByZWZzIHRvICR7cmVtb3RlRmlsZX1gKTtcbiAgICBhd2FpdCB0aGlzLmFkYi5wdXNoKGxvY2FsUGF0aCwgcmVtb3RlRmlsZSk7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMubG9nLmluZm8oYFRyeWluZyB0byByZW1vdmUgc2hhcmVkIHByZWZlcmVuY2VzIHRlbXBvcmFyeSBmaWxlYCk7XG4gICAgICBpZiAoYXdhaXQgZnMuZXhpc3RzKGxvY2FsUGF0aCkpIHtcbiAgICAgICAgYXdhaXQgZnMudW5saW5rKGxvY2FsUGF0aCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5sb2cud2FybihgRXJyb3IgdHJ5aW5nIHRvIHJlbW92ZSB0ZW1wb3JhcnkgZmlsZSAke2xvY2FsUGF0aH1gKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBnZXRQcmVmc0J1aWxkZXIgKCkge1xuICAgIC8qIEFkZCB0aGlzIG1ldGhvZCB0byBjcmVhdGUgYSBuZXcgU2hhcmVkUHJlZnNCdWlsZGVyIGluc3RlYWQgb2ZcbiAgICAgKiBkaXJlY3RseSBjcmVhdGluZyB0aGUgb2JqZWN0IG9uIHNldFNoYXJlZFByZWZlcmVuY2VzIGZvciB0ZXN0aW5nIHB1cnBvc2VzXG4gICAgKi9cbiAgICByZXR1cm4gbmV3IFNoYXJlZFByZWZzQnVpbGRlcigpO1xuICB9XG5cbiAgdmFsaWRhdGVEZXNpcmVkQ2FwcyAoY2Fwcykge1xuICAgIGlmICghc3VwZXIudmFsaWRhdGVEZXNpcmVkQ2FwcyhjYXBzKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoKCFjYXBzLmJyb3dzZXJOYW1lIHx8ICFoZWxwZXJzLmlzQ2hyb21lQnJvd3NlcihjYXBzLmJyb3dzZXJOYW1lKSkgJiYgIWNhcHMuYXBwICYmICFjYXBzLmFwcFBhY2thZ2UpIHtcbiAgICAgIHRoaXMubG9nLmVycm9yQW5kVGhyb3coJ1RoZSBkZXNpcmVkIGNhcGFiaWxpdGllcyBtdXN0IGluY2x1ZGUgZWl0aGVyIGFuIGFwcCwgYXBwUGFja2FnZSBvciBicm93c2VyTmFtZScpO1xuICAgIH1cbiAgICByZXR1cm4gaGVscGVycy52YWxpZGF0ZURlc2lyZWRDYXBzKGNhcHMpO1xuICB9XG5cbiAgcHJveHlBY3RpdmUgKHNlc3Npb25JZCkge1xuICAgIHN1cGVyLnByb3h5QWN0aXZlKHNlc3Npb25JZCk7XG5cbiAgICByZXR1cm4gdGhpcy5qd3BQcm94eUFjdGl2ZTtcbiAgfVxuXG4gIGdldFByb3h5QXZvaWRMaXN0IChzZXNzaW9uSWQpIHtcbiAgICBzdXBlci5nZXRQcm94eUF2b2lkTGlzdChzZXNzaW9uSWQpO1xuXG4gICAgcmV0dXJuIHRoaXMuandwUHJveHlBdm9pZDtcbiAgfVxuXG4gIGNhblByb3h5IChzZXNzaW9uSWQpIHtcbiAgICBzdXBlci5jYW5Qcm94eShzZXNzaW9uSWQpO1xuXG4gICAgLy8gdGhpcyB3aWxsIGNoYW5nZSBkZXBlbmRpbmcgb24gQ2hyb21lRHJpdmVyIHN0YXR1c1xuICAgIHJldHVybiBfLmlzRnVuY3Rpb24odGhpcy5wcm94eVJlcVJlcyk7XG4gIH1cbn1cblxuZXhwb3J0IHsgQW5kcm9pZERyaXZlciB9O1xuZXhwb3J0IGRlZmF1bHQgQW5kcm9pZERyaXZlcjtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFBQSxJQUFBQSxPQUFBLEdBQUFDLE9BQUE7QUFDQSxJQUFBQyxZQUFBLEdBQUFDLHNCQUFBLENBQUFGLE9BQUE7QUFDQSxJQUFBRyxNQUFBLEdBQUFELHNCQUFBLENBQUFGLE9BQUE7QUFDQSxJQUFBSSxVQUFBLEdBQUFKLE9BQUE7QUFDQSxJQUFBSyxlQUFBLEdBQUFMLE9BQUE7QUFJQSxJQUFBTSxPQUFBLEdBQUFKLHNCQUFBLENBQUFGLE9BQUE7QUFDQSxJQUFBTyxVQUFBLEdBQUFQLE9BQUE7QUFDQSxJQUFBUSxRQUFBLEdBQUFSLE9BQUE7QUFDQSxJQUFBUyxTQUFBLEdBQUFULE9BQUE7QUFDQSxJQUFBVSx5QkFBQSxHQUFBVixPQUFBO0FBQ0EsSUFBQVcsU0FBQSxHQUFBVCxzQkFBQSxDQUFBRixPQUFBO0FBRUEsTUFBTVksYUFBYSxHQUFHLE1BQU07QUFDNUIsTUFBTUMsV0FBVyxHQUFHLElBQUk7QUFJeEIsTUFBTUMsUUFBUSxHQUFHLENBQ2YsQ0FBQyxNQUFNLEVBQUUsSUFBSUMsTUFBTSxDQUFDLHlCQUF5QixDQUFDLENBQUMsRUFDL0MsQ0FBQyxLQUFLLEVBQUUsSUFBSUEsTUFBTSxDQUFDLHlCQUF5QixDQUFDLENBQUMsRUFDOUMsQ0FBQyxNQUFNLEVBQUUsSUFBSUEsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUMsRUFDOUMsQ0FBQyxLQUFLLEVBQUUsSUFBSUEsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUMsRUFDN0MsQ0FBQyxNQUFNLEVBQUUsSUFBSUEsTUFBTSxDQUFDLCtCQUErQixDQUFDLENBQUMsRUFDckQsQ0FBQyxNQUFNLEVBQUUsSUFBSUEsTUFBTSxDQUFDLHFDQUFxQyxDQUFDLENBQUMsRUFDM0QsQ0FBQyxNQUFNLEVBQUUsSUFBSUEsTUFBTSxDQUFDLDZCQUE2QixDQUFDLENBQUMsRUFDbkQsQ0FBQyxL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
|
|
472
|
+
AndroidDriver.newMethodMap = method_map_1.newMethodMap;
|
|
473
|
+
exports.default = AndroidDriver;
|
|
474
|
+
//# sourceMappingURL=driver.js.map
|