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.
Files changed (151) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/build/index.js +43 -40
  3. package/build/lib/android-helpers.d.ts +136 -0
  4. package/build/lib/android-helpers.d.ts.map +1 -0
  5. package/build/lib/android-helpers.js +760 -679
  6. package/build/lib/android-helpers.js.map +1 -1
  7. package/build/lib/bootstrap.d.ts +29 -0
  8. package/build/lib/bootstrap.d.ts.map +1 -0
  9. package/build/lib/bootstrap.js +192 -179
  10. package/build/lib/bootstrap.js.map +1 -1
  11. package/build/lib/commands/actions.d.ts +209 -0
  12. package/build/lib/commands/actions.d.ts.map +1 -0
  13. package/build/lib/commands/actions.js +327 -265
  14. package/build/lib/commands/actions.js.map +1 -1
  15. package/build/lib/commands/alert.d.ts +10 -0
  16. package/build/lib/commands/alert.d.ts.map +1 -0
  17. package/build/lib/commands/alert.js +12 -18
  18. package/build/lib/commands/alert.js.map +1 -1
  19. package/build/lib/commands/app-management.d.ts +314 -0
  20. package/build/lib/commands/app-management.d.ts.map +1 -0
  21. package/build/lib/commands/app-management.js +278 -110
  22. package/build/lib/commands/app-management.js.map +1 -1
  23. package/build/lib/commands/context.d.ts +94 -0
  24. package/build/lib/commands/context.d.ts.map +1 -0
  25. package/build/lib/commands/context.js +412 -260
  26. package/build/lib/commands/context.js.map +1 -1
  27. package/build/lib/commands/coverage.d.ts +5 -0
  28. package/build/lib/commands/coverage.d.ts.map +1 -0
  29. package/build/lib/commands/coverage.js +14 -17
  30. package/build/lib/commands/coverage.js.map +1 -1
  31. package/build/lib/commands/element.d.ts +36 -0
  32. package/build/lib/commands/element.d.ts.map +1 -0
  33. package/build/lib/commands/element.js +97 -127
  34. package/build/lib/commands/element.js.map +1 -1
  35. package/build/lib/commands/emu-console.d.ts +49 -0
  36. package/build/lib/commands/emu-console.d.ts.map +1 -0
  37. package/build/lib/commands/emu-console.js +36 -25
  38. package/build/lib/commands/emu-console.js.map +1 -1
  39. package/build/lib/commands/execute.d.ts +6 -0
  40. package/build/lib/commands/execute.d.ts.map +1 -0
  41. package/build/lib/commands/execute.js +68 -69
  42. package/build/lib/commands/execute.js.map +1 -1
  43. package/build/lib/commands/file-actions.d.ts +129 -0
  44. package/build/lib/commands/file-actions.d.ts.map +1 -0
  45. package/build/lib/commands/file-actions.js +321 -178
  46. package/build/lib/commands/file-actions.js.map +1 -1
  47. package/build/lib/commands/find.d.ts +13 -0
  48. package/build/lib/commands/find.d.ts.map +1 -0
  49. package/build/lib/commands/find.js +69 -51
  50. package/build/lib/commands/find.js.map +1 -1
  51. package/build/lib/commands/general.d.ts +133 -0
  52. package/build/lib/commands/general.d.ts.map +1 -0
  53. package/build/lib/commands/general.js +275 -216
  54. package/build/lib/commands/general.js.map +1 -1
  55. package/build/lib/commands/ime.d.ts +11 -0
  56. package/build/lib/commands/ime.d.ts.map +1 -0
  57. package/build/lib/commands/ime.js +27 -33
  58. package/build/lib/commands/ime.js.map +1 -1
  59. package/build/lib/commands/index.d.ts +3 -0
  60. package/build/lib/commands/index.d.ts.map +1 -0
  61. package/build/lib/commands/index.js +32 -35
  62. package/build/lib/commands/index.js.map +1 -1
  63. package/build/lib/commands/intent.d.ts +418 -0
  64. package/build/lib/commands/intent.d.ts.map +1 -0
  65. package/build/lib/commands/intent.js +281 -151
  66. package/build/lib/commands/intent.js.map +1 -1
  67. package/build/lib/commands/keyboard.d.ts +6 -0
  68. package/build/lib/commands/keyboard.d.ts.map +1 -0
  69. package/build/lib/commands/keyboard.js +6 -14
  70. package/build/lib/commands/keyboard.js.map +1 -1
  71. package/build/lib/commands/log.d.ts +45 -0
  72. package/build/lib/commands/log.d.ts.map +1 -0
  73. package/build/lib/commands/log.js +117 -103
  74. package/build/lib/commands/log.js.map +1 -1
  75. package/build/lib/commands/media-projection.d.ts +144 -0
  76. package/build/lib/commands/media-projection.d.ts.map +1 -0
  77. package/build/lib/commands/media-projection.js +228 -171
  78. package/build/lib/commands/media-projection.js.map +1 -1
  79. package/build/lib/commands/network.d.ts +139 -0
  80. package/build/lib/commands/network.d.ts.map +1 -0
  81. package/build/lib/commands/network.js +249 -181
  82. package/build/lib/commands/network.js.map +1 -1
  83. package/build/lib/commands/performance.d.ts +101 -0
  84. package/build/lib/commands/performance.d.ts.map +1 -0
  85. package/build/lib/commands/performance.js +390 -236
  86. package/build/lib/commands/performance.js.map +1 -1
  87. package/build/lib/commands/permissions.d.ts +93 -0
  88. package/build/lib/commands/permissions.d.ts.map +1 -0
  89. package/build/lib/commands/permissions.js +133 -93
  90. package/build/lib/commands/permissions.js.map +1 -1
  91. package/build/lib/commands/recordscreen.d.ts +194 -0
  92. package/build/lib/commands/recordscreen.d.ts.map +1 -0
  93. package/build/lib/commands/recordscreen.js +293 -224
  94. package/build/lib/commands/recordscreen.js.map +1 -1
  95. package/build/lib/commands/shell.d.ts +8 -0
  96. package/build/lib/commands/shell.d.ts.map +1 -0
  97. package/build/lib/commands/shell.js +38 -43
  98. package/build/lib/commands/shell.js.map +1 -1
  99. package/build/lib/commands/streamscreen.d.ts +104 -0
  100. package/build/lib/commands/streamscreen.d.ts.map +1 -0
  101. package/build/lib/commands/streamscreen.js +364 -305
  102. package/build/lib/commands/streamscreen.js.map +1 -1
  103. package/build/lib/commands/system-bars.d.ts +100 -0
  104. package/build/lib/commands/system-bars.d.ts.map +1 -0
  105. package/build/lib/commands/system-bars.js +148 -90
  106. package/build/lib/commands/system-bars.js.map +1 -1
  107. package/build/lib/commands/touch.d.ts +30 -0
  108. package/build/lib/commands/touch.d.ts.map +1 -0
  109. package/build/lib/commands/touch.js +311 -287
  110. package/build/lib/commands/touch.js.map +1 -1
  111. package/build/lib/desired-caps.d.ts +353 -0
  112. package/build/lib/desired-caps.d.ts.map +1 -0
  113. package/build/lib/desired-caps.js +291 -292
  114. package/build/lib/desired-caps.js.map +1 -1
  115. package/build/lib/driver.d.ts +430 -0
  116. package/build/lib/driver.d.ts.map +1 -0
  117. package/build/lib/driver.js +449 -384
  118. package/build/lib/driver.js.map +1 -1
  119. package/build/lib/logger.d.ts +3 -0
  120. package/build/lib/logger.d.ts.map +1 -0
  121. package/build/lib/logger.js +5 -11
  122. package/build/lib/logger.js.map +1 -1
  123. package/build/lib/method-map.d.ts +389 -0
  124. package/build/lib/method-map.d.ts.map +1 -0
  125. package/build/lib/method-map.js +220 -394
  126. package/build/lib/method-map.js.map +1 -1
  127. package/build/lib/stubs.d.ts +8 -0
  128. package/build/lib/stubs.d.ts.map +1 -0
  129. package/build/lib/stubs.js +5 -0
  130. package/build/lib/stubs.js.map +1 -0
  131. package/build/lib/uiautomator.d.ts +24 -0
  132. package/build/lib/uiautomator.d.ts.map +1 -0
  133. package/build/lib/uiautomator.js +86 -82
  134. package/build/lib/uiautomator.js.map +1 -1
  135. package/build/lib/unlock-helpers.d.ts +38 -0
  136. package/build/lib/unlock-helpers.d.ts.map +1 -0
  137. package/build/lib/unlock-helpers.js +228 -204
  138. package/build/lib/unlock-helpers.js.map +1 -1
  139. package/build/lib/utils.d.ts +11 -0
  140. package/build/lib/utils.d.ts.map +1 -0
  141. package/build/lib/utils.js +23 -18
  142. package/build/lib/utils.js.map +1 -1
  143. package/build/lib/webview-helpers.d.ts +223 -0
  144. package/build/lib/webview-helpers.d.ts.map +1 -0
  145. package/build/lib/webview-helpers.js +476 -298
  146. package/build/lib/webview-helpers.js.map +1 -1
  147. package/index.js +3 -1
  148. package/lib/android-helpers.js +2 -1
  149. package/lib/stubs.ts +8 -0
  150. package/lib/unlock-helpers.js +2 -2
  151. package/package.json +23 -14
@@ -1,409 +1,474 @@
1
1
  "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.default = exports.AndroidDriver = void 0;
8
- require("source-map-support/register");
9
- var _driver = require("appium/driver");
10
- var _desiredCaps = _interopRequireDefault(require("./desired-caps"));
11
- var _index = _interopRequireDefault(require("./commands/index"));
12
- var _methodMap = require("./method-map");
13
- var _androidHelpers = require("./android-helpers");
14
- var _lodash = _interopRequireDefault(require("lodash"));
15
- var _appiumAdb = require("appium-adb");
16
- var _support = require("@appium/support");
17
- var _asyncbox = require("asyncbox");
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
- const NO_PROXY = [['POST', new RegExp('^/session/[^/]+/context')], ['GET', new RegExp('^/session/[^/]+/context')], ['POST', new RegExp('^/session/[^/]+/appium')], ['GET', new RegExp('^/session/[^/]+/appium')], ['POST', new RegExp('^/session/[^/]+/touch/perform')], ['POST', new RegExp('^/session/[^/]+/touch/multi/perform')], ['POST', new RegExp('^/session/[^/]+/orientation')], ['GET', new RegExp('^/session/[^/]+/orientation')], ['POST', new RegExp('^/session/[^/]+/execute')], ['POST', new RegExp('^/session/[^/]+/execute/sync')], ['GET', new RegExp('^/session/[^/]+/network_connection')], ['POST', new RegExp('^/session/[^/]+/network_connection')]];
23
- class AndroidDriver extends _driver.BaseDriver {
24
- static newMethodMap = _methodMap.newMethodMap;
25
- constructor(opts = {}, shouldValidateCaps = true) {
26
- super(opts, shouldValidateCaps);
27
- this.locatorStrategies = ['xpath', 'id', 'class name', 'accessibility id', '-android uiautomator'];
28
- this.desiredCapConstraints = _desiredCaps.default;
29
- this.sessionChromedrivers = {};
30
- this.jwpProxyActive = false;
31
- this.jwpProxyAvoid = _lodash.default.clone(NO_PROXY);
32
- this.settings = new _driver.DeviceSettings({
33
- ignoreUnimportantViews: false
34
- }, this.onSettingsUpdate.bind(this));
35
- this.chromedriver = null;
36
- this.apkStrings = {};
37
- this.unlocker = _androidHelpers.helpers.unlocker;
38
- for (let [cmd, fn] of _lodash.default.toPairs(_index.default)) {
39
- AndroidDriver.prototype[cmd] = fn;
40
- }
41
- this.curContext = this.defaultContextName();
42
- }
43
- async createSession(...args) {
44
- try {
45
- let [sessionId, caps] = await super.createSession(...args);
46
- let serverDetails = {
47
- platform: 'LINUX',
48
- webStorageEnabled: false,
49
- takesScreenshot: true,
50
- javascriptEnabled: true,
51
- databaseEnabled: false,
52
- networkConnectionEnabled: true,
53
- locationContextEnabled: false,
54
- warnings: {},
55
- desired: this.caps
56
- };
57
- this.caps = Object.assign(serverDetails, this.caps);
58
- let defaultOpts = {
59
- action: 'android.intent.action.MAIN',
60
- category: 'android.intent.category.LAUNCHER',
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
- if (this.isChromeSession) {
218
- await this.startChromeSession();
219
- } else {
220
- if (this.opts.autoLaunch) {
221
- await this.startAUT();
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
- if (_support.util.hasValue(this.opts.orientation)) {
225
- this.log.debug(`Setting initial orientation to '${this.opts.orientation}'`);
226
- await this.setOrientation(this.opts.orientation);
182
+ isEmulator() {
183
+ return android_helpers_1.helpers.isEmulator(this.adb, this.opts);
227
184
  }
228
- await this.initAutoWebview();
229
- }
230
- async initAutoWebview() {
231
- if (this.opts.autoWebview) {
232
- let viewName = this.defaultWebviewName();
233
- let timeout = this.opts.autoWebviewTimeout || 2000;
234
- this.log.info(`Setting auto webview to context '${viewName}' with timeout ${timeout}ms`);
235
- await (0, _asyncbox.retryInterval)(timeout / 500, 500, async () => {
236
- await this.setContext(viewName);
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
- async initAUT() {
241
- let launchInfo = await _androidHelpers.helpers.getLaunchInfo(this.adb, this.opts);
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
- if (this.opts.otherApps) {
249
- let otherApps;
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
- if (!this.opts.app) {
259
- if (this.opts.fullReset) {
260
- this.log.errorAndThrow('Full reset requires an app capability, use fastReset if app is not provided');
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
- if (!this.opts.skipUninstall) {
269
- await this.adb.uninstallApk(this.opts.appPackage);
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
- await _androidHelpers.helpers.installApk(this.adb, this.opts);
272
- const apkStringsForLanguage = await _androidHelpers.helpers.pushStrings(this.opts.language, this.adb, this.opts);
273
- if (this.opts.language) {
274
- this.apkStrings[this.opts.language] = apkStringsForLanguage;
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
- if (!_lodash.default.isUndefined(this.opts.sharedPreferences)) {
277
- await this.setSharedPreferences(this.opts);
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
- async checkAppPresent() {
281
- this.log.debug('Checking whether app is actually present');
282
- if (!(await _support.fs.exists(this.opts.app))) {
283
- this.log.errorAndThrow(`Could not find app apk at ${this.opts.app}`);
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
- async checkPackagePresent() {
287
- this.log.debug('Checking whether package is present on the device');
288
- if (!(await this.adb.shell(['pm', 'list', 'packages', this.opts.appPackage]))) {
289
- this.log.errorAndThrow(`Could not find package ${this.opts.appPackage} on the device`);
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
- async setCompressedLayoutHierarchy(compress) {
293
- await this.bootstrap.sendAction('compressedLayoutHierarchy', {
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
- await ((_this$adb5 = this.adb) === null || _this$adb5 === void 0 ? void 0 : _this$adb5.stopLogcat());
331
- if (this.useUnlockHelperApp) {
332
- var _this$adb6;
333
- await ((_this$adb6 = this.adb) === null || _this$adb6 === void 0 ? void 0 : _this$adb6.forceStop('io.appium.unlock'));
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
- if (this._wasWindowAnimationDisabled) {
336
- var _this$adb7, _this$adb8;
337
- this.log.info('Restoring window animation state');
338
- await ((_this$adb7 = this.adb) === null || _this$adb7 === void 0 ? void 0 : _this$adb7.setAnimationState(true));
339
- if ((await ((_this$adb8 = this.adb) === null || _this$adb8 === void 0 ? void 0 : _this$adb8.getApiLevel())) >= 28) {
340
- var _this$adb9;
341
- this.log.info('Restoring hidden api policy to the device default configuration');
342
- await ((_this$adb9 = this.adb) === null || _this$adb9 === void 0 ? void 0 : _this$adb9.setDefaultHiddenApiPolicy(!!this.opts.ignoreHiddenApiPolicyError));
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
- if (this.opts.reboot) {
346
- var _this$adb10;
347
- let avdName = this.opts.avd.replace('@', '');
348
- this.log.debug(`closing emulator '${avdName}'`);
349
- await ((_this$adb10 = this.adb) === null || _this$adb10 === void 0 ? void 0 : _this$adb10.killEmulator(avdName));
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
- async setSharedPreferences() {
353
- let sharedPrefs = this.opts.sharedPreferences;
354
- this.log.info('Trying to set shared preferences');
355
- let name = sharedPrefs.name;
356
- if (_lodash.default.isUndefined(name)) {
357
- this.log.warn(`Skipping setting Shared preferences, name is undefined: ${JSON.stringify(sharedPrefs)}`);
358
- return false;
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
- let remotePath = `/data/data/${this.opts.appPackage}/shared_prefs`;
361
- let remoteFile = `${remotePath}/${name}.xml`;
362
- let localPath = `/tmp/${name}.xml`;
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
- return true;
380
- }
381
- getPrefsBuilder() {
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
- if ((!caps.browserName || !_androidHelpers.helpers.isChromeBrowser(caps.browserName)) && !caps.app && !caps.appPackage) {
389
- this.log.errorAndThrow('The desired capabilities must include either an app, appPackage or browserName');
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
- var _default = AndroidDriver;
408
- exports.default = _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