io.appium.settings 7.0.7 → 7.0.9

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.
@@ -1,26 +1,27 @@
1
1
  /**
2
- * RFC 2152 UTF-7 encoding with all optionals.
2
+ * RFC 2152 UTF-7 encoding.
3
3
  *
4
- * @param {string} str
5
- * @returns {string}
4
+ * @param mask Optional mask characters to exclude from encoding
5
+ */
6
+ export declare const encode: (str: string, mask?: string | null) => string;
7
+ /**
8
+ * RFC 2152 UTF-7 encoding with all optionals.
9
+ * Encodes all non-ASCII characters, including those that would normally
10
+ * be represented directly in standard UTF-7 encoding.
11
+ */
12
+ export declare function encodeAll(str: string): string;
13
+ /**
14
+ * RFC 2152 UTF-7 decoding.
6
15
  */
7
- export function encodeAll(str: string): string;
8
- export namespace imap {
16
+ export declare const decode: (str: string) => string;
17
+ export declare const imap: {
9
18
  /**
10
19
  * RFC 3501, section 5.1.3 UTF-7 encoding.
11
- *
12
- * @param {string} str
13
- * @returns {string}
14
20
  */
15
- function encode(str: string): string;
21
+ encode(str: string): string;
16
22
  /**
17
23
  * RFC 3501, section 5.1.3 UTF-7 decoding.
18
- *
19
- * @param {string} str
20
- * @returns {string}
21
24
  */
22
- function decode(str: string): string;
23
- }
24
- export function encode(str: string, mask?: string | null): string;
25
- export function decode(str: string): string;
25
+ decode(str: string): string;
26
+ };
26
27
  //# sourceMappingURL=utf7.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utf7.d.ts","sourceRoot":"","sources":["../../../lib/commands/utf7.js"],"names":[],"mappings":"AAmGA;;;;;GAKG;AACH,+BAHW,MAAM,GACJ,MAAM,CAQlB;;IAED;;;;;OAKG;IACH,qBAHW,MAAM,GACJ,MAAM,CAUlB;IAeD;;;;;OAKG;IACH,qBAHW,MAAM,GACJ,MAAM,CAOlB;;AAtEM,4BAJI,MAAM,SACN,MAAM,OAAC,GACL,MAAM,CAgBlB;AAsCM,4BAHI,MAAM,GACJ,MAAM,CAOlB"}
1
+ {"version":3,"file":"utf7.d.ts","sourceRoot":"","sources":["../../../lib/commands/utf7.ts"],"names":[],"mappings":"AAaA;;;;GAIG;AACH,eAAO,MAAM,MAAM,GAAmB,KAAK,MAAM,EAAE,OAAM,MAAM,GAAG,IAAW,KAAG,MAc/E,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM7C;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,GAAmB,KAAK,MAAM,KAAG,MAKnD,CAAC;AAEF,eAAO,MAAM,IAAI;IACf;;OAEG;gBACS,MAAM,GAAG,MAAM;IAU3B;;OAEG;gBACS,MAAM,GAAG,MAAM;CAM5B,CAAC"}
@@ -3,78 +3,19 @@
3
3
  * The code below has been adopted from https://www.npmjs.com/package/utf7
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.decode = exports.encode = exports.imap = void 0;
6
+ exports.imap = exports.decode = exports.encode = void 0;
7
7
  exports.encodeAll = encodeAll;
8
- /**
9
- * @param {number} length
10
- * @returns {Buffer}
11
- */
12
- function allocateAsciiBuffer(length) {
13
- return Buffer.alloc(length, 'ascii');
14
- }
15
- /**
16
- * @param {string} str
17
- * @returns {string}
18
- */
19
- function _encode(str) {
20
- const b = allocateAsciiBuffer(str.length * 2);
21
- for (let i = 0, bi = 0; i < str.length; i++) {
22
- // Note that we can't simply convert a UTF-8 string to Base64 because
23
- // UTF-8 uses a different encoding. In modified UTF-7, all characters
24
- // are represented by their two byte Unicode ID.
25
- const c = str.charCodeAt(i);
26
- // Upper 8 bits shifted into lower 8 bits so that they fit into 1 byte.
27
- b[bi++] = c >> 8;
28
- // Lower 8 bits. Cut off the upper 8 bits so that they fit into 1 byte.
29
- b[bi++] = c & 0xFF;
30
- }
31
- // Modified Base64 uses , instead of / and omits trailing =.
32
- return b.toString('base64').replace(/=+$/, '');
33
- }
34
- /**
35
- * @param {string} str
36
- * @returns {Buffer}
37
- */
38
- function allocateBase64Buffer(str) {
39
- return Buffer.from(str, 'base64');
40
- }
41
- /**
42
- * @param {string} str
43
- * @returns {string}
44
- */
45
- function _decode(str) {
46
- const b = allocateBase64Buffer(str);
47
- const r = [];
48
- for (let i = 0; i < b.length;) {
49
- // Calculate charcode from two adjacent bytes.
50
- r.push(String.fromCharCode(b[i++] << 8 | b[i++]));
51
- }
52
- return r.join('');
53
- }
54
- /**
55
- * Escape RegEx from http://simonwillison.net/2006/Jan/20/escape/
56
- *
57
- * @param {string} chars
58
- * @returns {string}
59
- */
60
- function escape(chars) {
61
- return chars.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
62
- }
63
8
  // Character classes defined by RFC 2152.
64
9
  const setD = 'A-Za-z0-9' + escape(`'(),-./:?`);
65
10
  const setO = escape(`!"#$%&*;<=>@[]^_'{|}`);
66
11
  const setW = escape(` \r\n\t`);
67
12
  // Stores compiled regexes for various replacement pattern.
68
- /** @type {Record<string, RegExp>} */
69
13
  const regexes = {};
70
14
  const regexAll = new RegExp(`[^${setW}${setD}${setO}]+`, 'g');
71
- exports.imap = {};
72
15
  /**
73
16
  * RFC 2152 UTF-7 encoding.
74
17
  *
75
- * @param {string} str
76
- * @param {string?} mask
77
- * @returns {string}
18
+ * @param mask Optional mask characters to exclude from encoding
78
19
  */
79
20
  const encode = function encode(str, mask = null) {
80
21
  // Generate a RegExp object from the string of mask characters.
@@ -92,9 +33,8 @@ const encode = function encode(str, mask = null) {
92
33
  exports.encode = encode;
93
34
  /**
94
35
  * RFC 2152 UTF-7 encoding with all optionals.
95
- *
96
- * @param {string} str
97
- * @returns {string}
36
+ * Encodes all non-ASCII characters, including those that would normally
37
+ * be represented directly in standard UTF-7 encoding.
98
38
  */
99
39
  function encodeAll(str) {
100
40
  // We replace subsequent disallowed chars with their escape sequence.
@@ -102,26 +42,8 @@ function encodeAll(str) {
102
42
  // + is represented by an empty sequence +-, otherwise call encode().
103
43
  `+${chunk === '+' ? '' : _encode(chunk)}-`);
104
44
  }
105
- /**
106
- * RFC 3501, section 5.1.3 UTF-7 encoding.
107
- *
108
- * @param {string} str
109
- * @returns {string}
110
- */
111
- exports.imap.encode = function encode(str) {
112
- // All printable ASCII chars except for & must be represented by themselves.
113
- // We replace subsequent non-representable chars with their escape sequence.
114
- return str.replace(/&/g, '&-').replace(/[^\x20-\x7e]+/g, (chunk) => {
115
- // & is represented by an empty sequence &-, otherwise call encode().
116
- chunk = (chunk === '&' ? '' : _encode(chunk)).replace(/\//g, ',');
117
- return `&${chunk}-`;
118
- });
119
- };
120
45
  /**
121
46
  * RFC 2152 UTF-7 decoding.
122
- *
123
- * @param {string} str
124
- * @returns {string}
125
47
  */
126
48
  const decode = function decode(str) {
127
49
  return str.replace(/\+([A-Za-z0-9/]*)-?/gi, (_, chunk) =>
@@ -129,15 +51,75 @@ const decode = function decode(str) {
129
51
  chunk === '' ? '+' : _decode(chunk));
130
52
  };
131
53
  exports.decode = decode;
54
+ exports.imap = {
55
+ /**
56
+ * RFC 3501, section 5.1.3 UTF-7 encoding.
57
+ */
58
+ encode(str) {
59
+ // All printable ASCII chars except for & must be represented by themselves.
60
+ // We replace subsequent non-representable chars with their escape sequence.
61
+ return str.replace(/&/g, '&-').replace(/[^\x20-\x7e]+/g, (chunk) => {
62
+ // & is represented by an empty sequence &-, otherwise call encode().
63
+ chunk = (chunk === '&' ? '' : _encode(chunk)).replace(/\//g, ',');
64
+ return `&${chunk}-`;
65
+ });
66
+ },
67
+ /**
68
+ * RFC 3501, section 5.1.3 UTF-7 decoding.
69
+ */
70
+ decode(str) {
71
+ return str.replace(/&([^-]*)-/g, (_, chunk) =>
72
+ // &- represents &.
73
+ chunk === '' ? '&' : _decode(chunk.replace(/,/g, '/')));
74
+ },
75
+ };
132
76
  /**
133
- * RFC 3501, section 5.1.3 UTF-7 decoding.
134
- *
135
- * @param {string} str
136
- * @returns {string}
77
+ * Allocates an ASCII buffer of the specified length.
137
78
  */
138
- exports.imap.decode = function decode(str) {
139
- return str.replace(/&([^-]*)-/g, (_, chunk) =>
140
- // &- represents &.
141
- chunk === '' ? '&' : _decode(chunk.replace(/,/g, '/')));
142
- };
79
+ function allocateAsciiBuffer(length) {
80
+ return Buffer.alloc(length, 'ascii');
81
+ }
82
+ /**
83
+ * Encodes a string using modified UTF-7 encoding.
84
+ */
85
+ function _encode(str) {
86
+ const b = allocateAsciiBuffer(str.length * 2);
87
+ for (let i = 0, bi = 0; i < str.length; i++) {
88
+ // Note that we can't simply convert a UTF-8 string to Base64 because
89
+ // UTF-8 uses a different encoding. In modified UTF-7, all characters
90
+ // are represented by their two byte Unicode ID.
91
+ const c = str.charCodeAt(i);
92
+ // Upper 8 bits shifted into lower 8 bits so that they fit into 1 byte.
93
+ b[bi++] = c >> 8;
94
+ // Lower 8 bits. Cut off the upper 8 bits so that they fit into 1 byte.
95
+ b[bi++] = c & 0xFF;
96
+ }
97
+ // Modified Base64 uses , instead of / and omits trailing =.
98
+ return b.toString('base64').replace(/=+$/, '');
99
+ }
100
+ /**
101
+ * Allocates a buffer from a base64 string.
102
+ */
103
+ function allocateBase64Buffer(str) {
104
+ return Buffer.from(str, 'base64');
105
+ }
106
+ /**
107
+ * Decodes a string using modified UTF-7 encoding.
108
+ */
109
+ function _decode(str) {
110
+ const b = allocateBase64Buffer(str);
111
+ const r = [];
112
+ for (let i = 0; i < b.length;) {
113
+ // Calculate charcode from two adjacent bytes.
114
+ r.push(String.fromCharCode(b[i++] << 8 | b[i++]));
115
+ }
116
+ return r.join('');
117
+ }
118
+ /**
119
+ * Escapes special regex characters.
120
+ * From http://simonwillison.net/2006/Jan/20/escape/
121
+ */
122
+ function escape(chars) {
123
+ return chars.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
124
+ }
143
125
  //# sourceMappingURL=utf7.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utf7.js","sourceRoot":"","sources":["../../../lib/commands/utf7.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utf7.js","sourceRoot":"","sources":["../../../lib/commands/utf7.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,8 @@ import {
7
7
  import { SubProcess } from 'teen_process';
8
8
  import B from 'bluebird';
9
9
  import { LOG_PREFIX } from '../logger.js';
10
+ import type { SettingsApp } from '../client.js';
11
+ import type { Location } from './types.js';
10
12
 
11
13
  const DEFAULT_SATELLITES_COUNT = 12;
12
14
  const DEFAULT_ALTITUDE = 0.0;
@@ -18,42 +20,23 @@ const GPS_CACHE_REFRESHED_LOGS = [
18
20
 
19
21
  const GPS_COORDINATES_PATTERN = /data="(-?[\d.]+)\s+(-?[\d.]+)\s+(-?[\d.]+)"/;
20
22
 
21
- /**
22
- * @typedef {Object} Location
23
- * @property {number|string} longitude - Valid longitude value.
24
- * @property {number|string} latitude - Valid latitude value.
25
- * @property {number|string|null} [altitude] - Valid altitude value.
26
- * @property {number|string|null} [satellites=12] - Number of satellites being tracked (1-12).
27
- * This value is ignored on real devices.
28
- * @property {number|string|null} [speed] - Valid speed value.
29
- * https://developer.android.com/reference/android/location/Location#setSpeed(float)
30
- * @property {number|string|null} [bearing] - Valid bearing value.
31
- * https://developer.android.com/reference/android/location/Location#setBearing(float)
32
- * @property {number|string|null} [accuracy] - Valid accuracy value.
33
- * https://developer.android.com/reference/android/location/Location#setAccuracy(float),
34
- * https://developer.android.com/reference/android/location/Criteria
35
- * Should be greater than 0.0 meters/second for real devices or 0.0 knots
36
- * for emulators.
37
- */
38
-
39
23
  /**
40
24
  * Emulate geolocation coordinates on the device under test.
25
+ * The `altitude` value is ignored while mocking the position.
41
26
  *
42
- * @this {import('../client').SettingsApp}
43
- * @param {Location} location - Location object. The `altitude` value is ignored
44
- * while mocking the position.
45
- * @param {boolean} [isEmulator=false] - Set it to true if the device under test
46
- * is an emulator rather than a real device.
27
+ * @param location - Location object containing coordinates and optional metadata
28
+ * @param isEmulator - Set it to true if the device under test is an emulator rather than a real device
29
+ * @throws {Error} If required location values are missing or invalid
47
30
  */
48
- export async function setGeoLocation (location, isEmulator = false) {
49
- const formatLocationValue = (valueName, isRequired = true) => {
31
+ export async function setGeoLocation(this: SettingsApp, location: Location, isEmulator = false): Promise<void> {
32
+ const formatLocationValue = (valueName: keyof Location, isRequired = true): string | null => {
50
33
  if (_.isNil(location[valueName])) {
51
34
  if (isRequired) {
52
35
  throw new Error(`${valueName} must be provided`);
53
36
  }
54
37
  return null;
55
38
  }
56
- const floatValue = parseFloat(location[valueName]);
39
+ const floatValue = parseFloat(String(location[valueName]));
57
40
  if (!isNaN(floatValue)) {
58
41
  return `${_.ceil(floatValue, 5)}`;
59
42
  }
@@ -63,15 +46,14 @@ export async function setGeoLocation (location, isEmulator = false) {
63
46
  }
64
47
  return null;
65
48
  };
66
- const longitude = /** @type {string} */ (formatLocationValue('longitude'));
67
- const latitude = /** @type {string} */ (formatLocationValue('latitude'));
49
+ const longitude = formatLocationValue('longitude') as string;
50
+ const latitude = formatLocationValue('latitude') as string;
68
51
  const altitude = formatLocationValue('altitude', false);
69
52
  const speed = formatLocationValue('speed', false);
70
53
  const bearing = formatLocationValue('bearing', false);
71
54
  const accuracy = formatLocationValue('accuracy', false);
72
55
  if (isEmulator) {
73
- /** @type {string[]} */
74
- const args = [longitude, latitude];
56
+ const args: string[] = [longitude, latitude];
75
57
  if (!_.isNil(altitude)) {
76
58
  args.push(altitude);
77
59
  }
@@ -96,7 +78,7 @@ export async function setGeoLocation (location, isEmulator = false) {
96
78
  // A workaround for https://code.google.com/p/android/issues/detail?id=206180
97
79
  await this.adb.adbExec(['emu', 'geo', 'fix', ...(args.map((arg) => arg.replace('.', ',')))]);
98
80
  } else {
99
- const args = [
81
+ const args: string[] = [
100
82
  'am', 'start-foreground-service',
101
83
  '-e', 'longitude', longitude,
102
84
  '-e', 'latitude', latitude,
@@ -130,11 +112,10 @@ export async function setGeoLocation (location, isEmulator = false) {
130
112
  /**
131
113
  * Get the current cached GPS location from the device under test.
132
114
  *
133
- * @this {import('../client').SettingsApp}
134
- * @returns {Promise<Location>} The current location
115
+ * @returns The current location
135
116
  * @throws {Error} If the current location cannot be retrieved
136
117
  */
137
- export async function getGeoLocation () {
118
+ export async function getGeoLocation(this: SettingsApp): Promise<Location> {
138
119
  const output = await this.checkBroadcast([
139
120
  '-n', LOCATION_RECEIVER,
140
121
  '-a', LOCATION_RETRIEVAL_ACTION,
@@ -144,7 +125,7 @@ export async function getGeoLocation () {
144
125
  if (!match) {
145
126
  throw new Error(`Cannot parse the actual location values from the command output: ${output}`);
146
127
  }
147
- const location = {
128
+ const location: Location = {
148
129
  latitude: match[1],
149
130
  longitude: match[2],
150
131
  altitude: match[3],
@@ -160,18 +141,15 @@ export async function getGeoLocation () {
160
141
  * LocationManager is used the device API level must be at
161
142
  * version 30 (Android R) or higher.
162
143
  *
163
- * @this {import('../client').SettingsApp}
164
- * @param {number} timeoutMs The maximum number of milliseconds
165
- * to block until GPS cache is refreshed. Providing zero or a negative
166
- * value to it skips waiting completely.
167
- *
144
+ * @param timeoutMs The maximum number of milliseconds to block until GPS cache is refreshed.
145
+ * Providing zero or a negative value to it skips waiting completely.
168
146
  * @throws {Error} If the GPS cache cannot be refreshed.
169
147
  */
170
- export async function refreshGeoLocationCache (timeoutMs = 20000) {
148
+ export async function refreshGeoLocationCache(this: SettingsApp, timeoutMs = 20000): Promise<void> {
171
149
  await this.requireRunning({shouldRestoreCurrentApp: true});
172
150
 
173
- let logcatMonitor;
174
- let monitoringPromise;
151
+ let logcatMonitor: SubProcess | undefined;
152
+ let monitoringPromise: Promise<void> | undefined;
175
153
 
176
154
  if (timeoutMs > 0) {
177
155
  const cmd = [
@@ -183,11 +161,12 @@ export async function refreshGeoLocationCache (timeoutMs = 20000) {
183
161
  `Please make sure the device under test has Appium Settings app installed and running. ` +
184
162
  `Also, it is required that the device has Google Play Services installed or is running ` +
185
163
  `Android 10+ otherwise.`;
186
- monitoringPromise = new B((resolve, reject) => {
164
+ const monitor = logcatMonitor;
165
+ monitoringPromise = new B<void>((resolve, reject) => {
187
166
  setTimeout(() => reject(new Error(timeoutErrorMsg)), timeoutMs);
188
167
 
189
- logcatMonitor.on('exit', () => reject(new Error(timeoutErrorMsg)));
190
- ['lines-stderr', 'lines-stdout'].map((evt) => logcatMonitor.on(evt, (lines) => {
168
+ monitor.on('exit', () => reject(new Error(timeoutErrorMsg)));
169
+ (['lines-stderr', 'lines-stdout'] as const).map((evt) => monitor.on(evt, (lines: string[]) => {
191
170
  if (lines.some((line) => GPS_CACHE_REFRESHED_LOGS.some((x) => line.includes(x)))) {
192
171
  resolve();
193
172
  }
@@ -9,25 +9,60 @@ import {
9
9
  RECORDING_ACTION_STOP,
10
10
  RECORDING_ACTIVITY_NAME,
11
11
  RECORDING_SERVICE_NAME,
12
- } from '../constants';
12
+ } from '../constants.js';
13
+ import type { ADB } from 'appium-adb';
14
+ import type { SettingsApp } from '../client.js';
15
+ import type { StartMediaProjectionRecordingOpts } from './types.js';
16
+
17
+ /**
18
+ * Creates a new instance of the MediaProjection-based recorder.
19
+ * The recorder only works since Android API 29+
20
+ *
21
+ * @returns The recorder instance
22
+ */
23
+ export function makeMediaProjectionRecorder(this: SettingsApp): MediaProjectionRecorder {
24
+ return new MediaProjectionRecorder(this.adb);
25
+ }
26
+
27
+ /**
28
+ * Adjusts the necessary permissions for the Media Projection-based recording service.
29
+ * This method only applies to devices running Android API 29 or higher.
30
+ *
31
+ * @returns True if permissions were adjusted, false if device API level is below 29
32
+ */
33
+ export async function adjustMediaProjectionServicePermissions(this: SettingsApp): Promise<boolean> {
34
+ if (await this.adb.getApiLevel() >= 29) {
35
+ await this.adb.shell(['appops', 'set', SETTINGS_HELPER_ID, 'PROJECT_MEDIA', 'allow']);
36
+ return true;
37
+ }
38
+ return false;
39
+ }
13
40
 
14
41
  const RECORDING_STARTUP_TIMEOUT_MS = 3 * 1000;
15
42
  const RECORDING_STOP_TIMEOUT_MS = 3 * 1000;
16
43
  const RECORDINGS_ROOT = `/storage/emulated/0/Android/data/${SETTINGS_HELPER_ID}/files`;
17
44
 
45
+ /**
46
+ * Media projection recorder for capturing device screen recordings.
47
+ * This class provides methods to start, stop, and manage screen recordings
48
+ * using Android's MediaProjection API (API 29+).
49
+ */
18
50
  class MediaProjectionRecorder {
51
+ private readonly adb: ADB;
52
+
19
53
  /**
20
- * @param {ADB} adb
54
+ * Creates a new MediaProjectionRecorder instance.
55
+ *
56
+ * @param adb - ADB instance for device communication
21
57
  */
22
- constructor(adb) {
58
+ constructor(adb: ADB) {
23
59
  this.adb = adb;
24
60
  }
25
61
 
26
62
  /**
27
- *
28
- * @returns {Promise<boolean>}
63
+ * Checks if the recording is currently running.
29
64
  */
30
- async isRunning() {
65
+ async isRunning(): Promise<boolean> {
31
66
  const stdout = await this.adb.shell([
32
67
  'dumpsys',
33
68
  'activity',
@@ -38,18 +73,21 @@ class MediaProjectionRecorder {
38
73
  }
39
74
 
40
75
  /**
76
+ * Starts the media projection recording.
77
+ * If a recording is already running, this method will return false without starting a new one.
41
78
  *
42
- * @param {StartMediaProjectionRecordingOpts} opts
43
- * @returns {Promise<boolean>}
79
+ * @param opts Recording options including filename, resolution, duration, and priority
80
+ * @returns True if recording was started successfully, false if already running
81
+ * @throws {Error} If recording fails to start within the timeout period
44
82
  */
45
- async start(opts = {}) {
83
+ async start(opts: StartMediaProjectionRecordingOpts = {}): Promise<boolean> {
46
84
  if (await this.isRunning()) {
47
85
  return false;
48
86
  }
49
87
 
50
88
  await this.cleanup();
51
89
  const {filename, maxDurationSec, priority, resolution} = opts;
52
- const args = ['am', 'start', '-n', RECORDING_ACTIVITY_NAME, '-a', RECORDING_ACTION_START];
90
+ const args: string[] = ['am', 'start', '-n', RECORDING_ACTIVITY_NAME, '-a', RECORDING_ACTION_START];
53
91
  if (filename) {
54
92
  args.push('--es', 'filename', filename);
55
93
  }
@@ -63,7 +101,7 @@ class MediaProjectionRecorder {
63
101
  args.push('--es', 'resolution', resolution);
64
102
  }
65
103
  await this.adb.shell(args);
66
- await new B((resolve, reject) => {
104
+ await new B<void>((resolve, reject) => {
67
105
  setTimeout(async () => {
68
106
  if (!(await this.isRunning())) {
69
107
  return reject(
@@ -80,17 +118,18 @@ class MediaProjectionRecorder {
80
118
  }
81
119
 
82
120
  /**
83
- * @returns {Promise<void>}
121
+ * Cleans up old recording files.
84
122
  */
85
- async cleanup() {
123
+ async cleanup(): Promise<void> {
86
124
  await this.adb.shell([`rm -f ${RECORDINGS_ROOT}/*`]);
87
125
  }
88
126
 
89
127
  /**
128
+ * Pulls the most recent recording file from the device.
90
129
  *
91
- * @returns {Promise<string?>}
130
+ * @returns Path to the pulled file, or null if no recordings exist
92
131
  */
93
- async pullRecent() {
132
+ async pullRecent(): Promise<string | null> {
94
133
  const recordings = await this.adb.ls(RECORDINGS_ROOT, ['-tr']);
95
134
  if (_.isEmpty(recordings)) {
96
135
  return null;
@@ -104,9 +143,12 @@ class MediaProjectionRecorder {
104
143
  }
105
144
 
106
145
  /**
107
- * @returns {Promise<boolean>}
146
+ * Stops the current recording.
147
+ *
148
+ * @returns True if recording was stopped successfully, false if no recording was running
149
+ * @throws {Error} If the recording fails to stop within the timeout period
108
150
  */
109
- async stop() {
151
+ async stop(): Promise<boolean> {
110
152
  if (!(await this.isRunning())) {
111
153
  return false;
112
154
  }
@@ -133,49 +175,3 @@ class MediaProjectionRecorder {
133
175
  return true;
134
176
  }
135
177
  }
136
-
137
- /**
138
- * Creates a new instance of the MediaProjection-based recorder
139
- * The recorder only works since Android API 29+
140
- *
141
- * @this {import('../client').SettingsApp}
142
- * @returns {MediaProjectionRecorder} The recorder instance
143
- */
144
- export function makeMediaProjectionRecorder() {
145
- return new MediaProjectionRecorder(this.adb);
146
- }
147
-
148
- /**
149
- * Adjusts the necessary permissions for the
150
- * Media Projection-based recording service
151
- *
152
- * @this {import('../client').SettingsApp}
153
- * @returns {Promise<boolean>} If the permissions adjustment has actually been made
154
- */
155
- export async function adjustMediaProjectionServicePermissions() {
156
- if (await this.adb.getApiLevel() >= 29) {
157
- await this.adb.shell(['appops', 'set', SETTINGS_HELPER_ID, 'PROJECT_MEDIA', 'allow']);
158
- return true;
159
- }
160
- return false;
161
- }
162
-
163
- /**
164
- * @typedef {import('appium-adb').ADB} ADB
165
- */
166
-
167
- /**
168
- * @typedef {Object} StartMediaProjectionRecordingOpts
169
- * @property {string} [resolution] Maximum supported resolution on-device (Detected automatically by the app
170
- * itself), which usually equals to Full HD 1920x1080 on most phones however
171
- * you can change it to following supported resolutions as well: "1920x1080",
172
- * "1280x720", "720x480", "320x240", "176x144".
173
- * @property {number} [maxDurationSec=900] Maximum allowed duration is 15 minutes; you can increase it if your test
174
- * takes longer than that.
175
- * @property {'high' | 'normal' | 'low'} [priority='high'] Recording thread priority.
176
- * If you face performance drops during testing with recording enabled, you
177
- * can reduce recording priority
178
- * @property {string} [filename] You can type recording video file name as you want, but recording currently
179
- * supports only "mp4" format so your filename must end with ".mp4". An
180
- * invalid file name will fail to start the recording.
181
- */
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Location object containing geolocation coordinates and optional metadata.
3
+ */
4
+ export interface Location {
5
+ longitude: number | string;
6
+ latitude: number | string;
7
+ altitude?: number | string | null;
8
+ /** Number of satellites being tracked (1-12). This value is ignored on real devices. */
9
+ satellites?: number | string | null;
10
+ /** Valid speed value. https://developer.android.com/reference/android/location/Location#setSpeed(float) */
11
+ speed?: number | string | null;
12
+ /** Valid bearing value. https://developer.android.com/reference/android/location/Location#setBearing(float) */
13
+ bearing?: number | string | null;
14
+ /** Valid accuracy value. https://developer.android.com/reference/android/location/Location#setAccuracy(float), https://developer.android.com/reference/android/location/Criteria. Should be greater than 0.0 meters/second for real devices or 0.0 knots for emulators. */
15
+ accuracy?: number | string | null;
16
+ }
17
+
18
+ /**
19
+ * Options for starting a media projection recording session.
20
+ */
21
+ export interface StartMediaProjectionRecordingOpts {
22
+ /** Maximum supported resolution on-device (Detected automatically by the app
23
+ * itself), which usually equals to Full HD 1920x1080 on most phones however
24
+ * you can change it to following supported resolutions as well: "1920x1080",
25
+ * "1280x720", "720x480", "320x240", "176x144". */
26
+ resolution?: string;
27
+ /** Maximum allowed duration is 15 minutes; you can increase it if your test
28
+ * takes longer than that. */
29
+ maxDurationSec?: number;
30
+ /** Recording thread priority.
31
+ * If you face performance drops during testing with recording enabled, you
32
+ * can reduce recording priority */
33
+ priority?: 'high' | 'normal' | 'low';
34
+ /** You can type recording video file name as you want, but recording currently
35
+ * supports only "mp4" format so your filename must end with ".mp4". An
36
+ * invalid file name will fail to start the recording. */
37
+ filename?: string;
38
+ }