io.appium.settings 5.4.2 → 5.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## [5.6.0](https://github.com/appium/io.appium.settings/compare/v5.5.0...v5.6.0) (2024-01-10)
2
+
3
+
4
+ ### Features
5
+
6
+ * Add media-projection-based video recorder ([#138](https://github.com/appium/io.appium.settings/issues/138)) ([ba357e8](https://github.com/appium/io.appium.settings/commit/ba357e8541e2f86e9db902ace4850fd04fb3ec57))
7
+
8
+ ## [5.5.0](https://github.com/appium/io.appium.settings/compare/v5.4.2...v5.5.0) (2024-01-10)
9
+
10
+
11
+ ### Features
12
+
13
+ * Add a helper to adjust notifications permissions ([#139](https://github.com/appium/io.appium.settings/issues/139)) ([e0b88e6](https://github.com/appium/io.appium.settings/commit/e0b88e6f4c3291c5932e9773aa2594280efe80ba))
14
+ * Update method to set device locale ([#136](https://github.com/appium/io.appium.settings/issues/136)) ([329c29f](https://github.com/appium/io.appium.settings/commit/329c29f31fcb1774a569820b06bf26b9462df6cd))
15
+
1
16
  ## [5.4.2](https://github.com/appium/io.appium.settings/compare/v5.4.1...v5.4.2) (2024-01-10)
2
17
 
3
18
 
Binary file
@@ -64,14 +64,17 @@ export class SettingsApp {
64
64
  setGeoLocation: typeof setGeoLocation;
65
65
  getGeoLocation: typeof getGeoLocation;
66
66
  refreshGeoLocationCache: typeof refreshGeoLocationCache;
67
- setDeviceSysLocale: typeof setDeviceSysLocale;
67
+ setDeviceLocale: typeof setDeviceLocale;
68
68
  scanMedia: typeof scanMedia;
69
69
  setDataState: typeof setDataState;
70
70
  setWifiState: typeof setWifiState;
71
71
  getNotifications: typeof getNotifications;
72
+ adjustNotificationsPermissions: typeof adjustNotificationsPermissions;
72
73
  getSmsList: typeof getSmsList;
73
74
  performEditorAction: typeof performEditorAction;
74
75
  typeUnicode: typeof typeUnicode;
76
+ makeMediaProjectionRecorder: typeof makeMediaProjectionRecorder;
77
+ adjustMediaProjectionServicePermissions: typeof adjustMediaProjectionServicePermissions;
75
78
  }
76
79
  export type SettingsAppOpts = {
77
80
  adb: import('appium-adb').ADB;
@@ -81,12 +84,15 @@ import { getClipboard } from './commands/clipboard';
81
84
  import { setGeoLocation } from './commands/geolocation';
82
85
  import { getGeoLocation } from './commands/geolocation';
83
86
  import { refreshGeoLocationCache } from './commands/geolocation';
84
- import { setDeviceSysLocale } from './commands/locale';
87
+ import { setDeviceLocale } from './commands/locale';
85
88
  import { scanMedia } from './commands/media';
86
89
  import { setDataState } from './commands/network';
87
90
  import { setWifiState } from './commands/network';
88
91
  import { getNotifications } from './commands/notifications';
92
+ import { adjustNotificationsPermissions } from './commands/notifications';
89
93
  import { getSmsList } from './commands/sms';
90
94
  import { performEditorAction } from './commands/typing';
91
95
  import { typeUnicode } from './commands/typing';
96
+ import { makeMediaProjectionRecorder } from './commands/media-projection';
97
+ import { adjustMediaProjectionServicePermissions } from './commands/media-projection';
92
98
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../lib/client.js"],"names":[],"mappings":"AAcA;;;GAGG;AAGH;IAOE;;OAEG;IACH,kBAFW,eAAe,EAKzB;IAZD,uCAAuC;IACvC,KADW,OAAO,YAAY,EAAE,GAAG,CAC/B;IAEJ,sCAAsC;IACtC,KADW,OAAO,QAAQ,EAAE,MAAM,CAC9B;IAUJ;;;;;;OAMG;IAEH;;;;;;;OAOG;IACH;;;;;;;;;;;oBAFa,QAAQ,WAAW,CAAC,CA4ChC;IAED;;;;;;;OAOG;IACH,yBAFa,QAAQ,OAAO,CAAC,CAY5B;IAED;;;;;;;;;;OAUG;IACH,uBAPW,MAAM,cACN,MAAM,OAgChB;IAED,4CAAsC;IAEtC,kCAA4B;IAE5B,sCAAgC;IAChC,sCAAgC;IAChC,wDAAkD;IAElD,8CAAwC;IAExC,4BAAsB;IAEtB,kCAA4B;IAC5B,kCAA4B;IAE5B,0CAAoC;IACpC,8BAAwB;IAExB,gDAA0C;IAC1C,gCAA0B;CAC3B;;SA9Ja,OAAO,YAAY,EAAE,GAAG;;kCAZJ,sBAAsB;6BAC3B,sBAAsB;+BACqB,wBAAwB;+BAAxB,wBAAwB;wCAAxB,wBAAwB;mCAC7D,mBAAmB;0BAC5B,kBAAkB;6BACD,oBAAoB;6BAApB,oBAAoB;iCAC9B,0BAA0B;2BAChC,gBAAgB;oCACM,mBAAmB;4BAAnB,mBAAmB"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../lib/client.js"],"names":[],"mappings":"AAkBA;;;GAGG;AAGH;IAOE;;OAEG;IACH,kBAFW,eAAe,EAKzB;IAZD,uCAAuC;IACvC,KADW,OAAO,YAAY,EAAE,GAAG,CAC/B;IAEJ,sCAAsC;IACtC,KADW,OAAO,QAAQ,EAAE,MAAM,CAC9B;IAUJ;;;;;;OAMG;IAEH;;;;;;;OAOG;IACH;;;;;;;;;;;oBAFa,QAAQ,WAAW,CAAC,CA4ChC;IAED;;;;;;;OAOG;IACH,yBAFa,QAAQ,OAAO,CAAC,CAY5B;IAED;;;;;;;;;;OAUG;IACH,uBAPW,MAAM,cACN,MAAM,OAgChB;IAED,4CAAsC;IAEtC,kCAA4B;IAE5B,sCAAgC;IAChC,sCAAgC;IAChC,wDAAkD;IAElD,wCAAkC;IAElC,4BAAsB;IAEtB,kCAA4B;IAC5B,kCAA4B;IAE5B,0CAAoC;IACpC,sEAAgE;IAChE,8BAAwB;IAExB,gDAA0C;IAC1C,gCAA0B;IAE1B,gEAA0D;IAC1D,wFAAkF;CACnF;;SAlKa,OAAO,YAAY,EAAE,GAAG;;kCAhBJ,sBAAsB;6BAC3B,sBAAsB;+BACqB,wBAAwB;+BAAxB,wBAAwB;wCAAxB,wBAAwB;gCAChE,mBAAmB;0BACzB,kBAAkB;6BACD,oBAAoB;6BAApB,oBAAoB;iCACE,0BAA0B;+CAA1B,0BAA0B;2BAChE,gBAAgB;oCACM,mBAAmB;4BAAnB,mBAAmB;4CAI7D,6BAA6B;wDAA7B,6BAA6B"}
@@ -17,6 +17,7 @@ const network_1 = require("./commands/network");
17
17
  const notifications_1 = require("./commands/notifications");
18
18
  const sms_1 = require("./commands/sms");
19
19
  const typing_1 = require("./commands/typing");
20
+ const media_projection_1 = require("./commands/media-projection");
20
21
  /**
21
22
  * @typedef {Object} SettingsAppOpts
22
23
  * @property {import('appium-adb').ADB} adb
@@ -31,14 +32,17 @@ class SettingsApp {
31
32
  this.setGeoLocation = geolocation_1.setGeoLocation;
32
33
  this.getGeoLocation = geolocation_1.getGeoLocation;
33
34
  this.refreshGeoLocationCache = geolocation_1.refreshGeoLocationCache;
34
- this.setDeviceSysLocale = locale_1.setDeviceSysLocale;
35
+ this.setDeviceLocale = locale_1.setDeviceLocale;
35
36
  this.scanMedia = media_1.scanMedia;
36
37
  this.setDataState = network_1.setDataState;
37
38
  this.setWifiState = network_1.setWifiState;
38
39
  this.getNotifications = notifications_1.getNotifications;
40
+ this.adjustNotificationsPermissions = notifications_1.adjustNotificationsPermissions;
39
41
  this.getSmsList = sms_1.getSmsList;
40
42
  this.performEditorAction = typing_1.performEditorAction;
41
43
  this.typeUnicode = typing_1.typeUnicode;
44
+ this.makeMediaProjectionRecorder = media_projection_1.makeMediaProjectionRecorder;
45
+ this.adjustMediaProjectionServicePermissions = media_projection_1.adjustMediaProjectionServicePermissions;
42
46
  this.adb = opts.adb;
43
47
  this.log = logger_1.log;
44
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../lib/client.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../lib/client.js"],"names":[],"mappings":"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"}
@@ -1,13 +1,13 @@
1
1
  /**
2
- * Change the locale on the device under test. Don't need to reboot the device after changing the locale.
3
- * This method sets an arbitrary locale following:
4
- * https://developer.android.com/reference/java/util/Locale.html
5
- * https://developer.android.com/reference/java/util/Locale.html#Locale(java.lang.String,%20java.lang.String)
2
+ * Set the locale name of the device under test.
6
3
  *
7
4
  * @this {import('../client').SettingsApp}
8
- * @param {string} language - Language. e.g. en, ja
9
- * @param {string} country - Country. e.g. US, JP
10
- * @param {string?} [script=null] - Script. e.g. Hans in `zh-Hans-CN`
5
+ * @param {string} language - Language. The language field is case insensitive, but Locale always canonicalizes to lower case.
6
+ * format: [a-zA-Z]{2,8}. e.g. en, ja : https://developer.android.com/reference/java/util/Locale.html
7
+ * @param {string} country - Country. The country (region) field is case insensitive, but Locale always canonicalizes to upper case.
8
+ * format: [a-zA-Z]{2} | [0-9]{3}. e.g. US, JP : https://developer.android.com/reference/java/util/Locale.html
9
+ * @param {string?} [script=null] - Script. The script field is case insensitive but Locale always canonicalizes to title case.
10
+ * format: [a-zA-Z]{4}. e.g. Hans in zh-Hans-CN : https://developer.android.com/reference/java/util/Locale.html
11
11
  */
12
- export function setDeviceSysLocale(this: import("../client").SettingsApp, language: string, country: string, script?: string | null | undefined): Promise<void>;
12
+ export function setDeviceLocale(this: import("../client").SettingsApp, language: string, country: string, script?: string | null | undefined): Promise<void>;
13
13
  //# sourceMappingURL=locale.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../../lib/commands/locale.js"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,oFAJW,MAAM,WACN,MAAM,qDAiBhB"}
1
+ {"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../../lib/commands/locale.js"],"names":[],"mappings":"AAgCA;;;;;;;;;;GAUG;AACH,iFAPW,MAAM,WAEN,MAAM,qDAqChB"}
@@ -1,6 +1,12 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setDeviceSysLocale = void 0;
6
+ exports.setDeviceLocale = void 0;
7
+ const lodash_1 = __importDefault(require("lodash"));
8
+ const logger_js_1 = require("../logger.js");
9
+ const bluebird_1 = __importDefault(require("bluebird"));
4
10
  const constants_js_1 = require("../constants.js");
5
11
  /**
6
12
  * Change the locale on the device under test. Don't need to reboot the device after changing the locale.
@@ -13,7 +19,7 @@ const constants_js_1 = require("../constants.js");
13
19
  * @param {string} country - Country. e.g. US, JP
14
20
  * @param {string?} [script=null] - Script. e.g. Hans in `zh-Hans-CN`
15
21
  */
16
- async function setDeviceSysLocale(language, country, script = null) {
22
+ async function setDeviceLocaleInternal(language, country, script = null) {
17
23
  const params = [
18
24
  'am', 'broadcast',
19
25
  '-a', constants_js_1.LOCALE_SETTING_ACTION,
@@ -26,6 +32,48 @@ async function setDeviceSysLocale(language, country, script = null) {
26
32
  }
27
33
  await this.adb.shell(params);
28
34
  }
29
- exports.setDeviceSysLocale = setDeviceSysLocale;
30
- ;
35
+ /**
36
+ * Set the locale name of the device under test.
37
+ *
38
+ * @this {import('../client').SettingsApp}
39
+ * @param {string} language - Language. The language field is case insensitive, but Locale always canonicalizes to lower case.
40
+ * format: [a-zA-Z]{2,8}. e.g. en, ja : https://developer.android.com/reference/java/util/Locale.html
41
+ * @param {string} country - Country. The country (region) field is case insensitive, but Locale always canonicalizes to upper case.
42
+ * format: [a-zA-Z]{2} | [0-9]{3}. e.g. US, JP : https://developer.android.com/reference/java/util/Locale.html
43
+ * @param {string?} [script=null] - Script. The script field is case insensitive but Locale always canonicalizes to title case.
44
+ * format: [a-zA-Z]{4}. e.g. Hans in zh-Hans-CN : https://developer.android.com/reference/java/util/Locale.html
45
+ */
46
+ async function setDeviceLocale(language, country, script = null) {
47
+ if (lodash_1.default.isEmpty(language)) {
48
+ throw new Error('Language name must be provided');
49
+ }
50
+ if (lodash_1.default.isEmpty(country)) {
51
+ throw new Error('Country name must be provided');
52
+ }
53
+ const lcLanguage = language.toLowerCase();
54
+ const ucCountry = country.toUpperCase();
55
+ if (await this.adb.getApiLevel() < 23) {
56
+ const [curLanguageRaw, curCountryRaw] = await bluebird_1.default.all([
57
+ this.adb.getDeviceLanguage(),
58
+ this.adb.getDeviceCountry(),
59
+ ]);
60
+ const curLanguage = curLanguageRaw.toLowerCase();
61
+ const curCountry = curCountryRaw.toUpperCase();
62
+ this.log.debug(logger_js_1.LOG_PREFIX, `Current language: '${curLanguage}'; requested language: '${lcLanguage}'`);
63
+ this.log.debug(logger_js_1.LOG_PREFIX, `Current country: '${curCountry}'; requested country: '${ucCountry}'`);
64
+ if (lcLanguage !== curLanguage || ucCountry !== curCountry) {
65
+ await setDeviceLocaleInternal.bind(this)(lcLanguage, ucCountry);
66
+ }
67
+ }
68
+ else {
69
+ const curLocale = await this.adb.getDeviceLocale();
70
+ // zh-Hans-CN : zh-CN
71
+ const localeCode = script ? `${lcLanguage}-${script}-${ucCountry}` : `${lcLanguage}-${ucCountry}`;
72
+ this.log.debug(logger_js_1.LOG_PREFIX, `Current locale: '${curLocale}'; requested locale: '${localeCode}'`);
73
+ if (localeCode.toLowerCase() !== curLocale.toLowerCase()) {
74
+ await setDeviceLocaleInternal.bind(this)(lcLanguage, ucCountry, script);
75
+ }
76
+ }
77
+ }
78
+ exports.setDeviceLocale = setDeviceLocale;
31
79
  //# sourceMappingURL=locale.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"locale.js","sourceRoot":"","sources":["../../../lib/commands/locale.js"],"names":[],"mappings":";;;AAAA,kDAAiF;AAEjF;;;;;;;;;;GAUG;AACI,KAAK,UAAU,kBAAkB,CAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IACxE,MAAM,MAAM,GAAG;QACb,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,oCAAqB;QAC3B,IAAI,EAAE,sCAAuB;QAC7B,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,WAAW,EAAE;QACtC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,WAAW,EAAE;KACzC,CAAC;IAEF,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAdD,gDAcC;AAAA,CAAC"}
1
+ {"version":3,"file":"locale.js","sourceRoot":"","sources":["../../../lib/commands/locale.js"],"names":[],"mappings":";;;;;;AAAA,oDAAuB;AACvB,4CAA0C;AAC1C,wDAAyB;AACzB,kDAAiF;AAEjF;;;;;;;;;;GAUG;AACH,KAAK,UAAU,uBAAuB,CAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IACtE,MAAM,MAAM,GAAG;QACb,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,oCAAqB;QAC3B,IAAI,EAAE,sCAAuB;QAC7B,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,WAAW,EAAE;QACtC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,WAAW,EAAE;KACzC,CAAC;IAEF,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED;;;;;;;;;;GAUG;AACI,KAAK,UAAU,eAAe,CAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IACrE,IAAI,gBAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,gBAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC1C,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACxC,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,EAAE,CAAC;QACtC,MAAM,CAAC,cAAc,EAAE,aAAa,CAAC,GAAG,MAAM,kBAAC,CAAC,GAAG,CAAC;YAClD,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE;YAC5B,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE;SAC5B,CAAC,CAAC;QACH,MAAM,WAAW,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC;QACjD,MAAM,UAAU,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC;QAC/C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAU,EAAE,sBAAsB,WAAW,2BAA2B,UAAU,GAAG,CAAC,CAAC;QACtG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAU,EAAE,qBAAqB,UAAU,0BAA0B,SAAS,GAAG,CAAC,CAAC;QAClG,IAAI,UAAU,KAAK,WAAW,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;YAC3D,MAAM,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QAEnD,qBAAqB;QACrB,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,MAAM,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,SAAS,EAAE,CAAC;QAClG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAU,EAAE,oBAAoB,SAAS,yBAAyB,UAAU,GAAG,CAAC,CAAC;QAChG,IAAI,UAAU,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;YACzD,MAAM,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;AACH,CAAC;AAhCD,0CAgCC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Creates a new instance of the MediaProjection-based recorder
3
+ * The recorder only works since Android API 29+
4
+ *
5
+ * @this {import('../client').SettingsApp}
6
+ * @returns {MediaProjectionRecorder} The recorder instance
7
+ */
8
+ export function makeMediaProjectionRecorder(this: import("../client").SettingsApp): MediaProjectionRecorder;
9
+ /**
10
+ * Adjusts the necessary permissions for the
11
+ * Media Projection-based recording service
12
+ *
13
+ * @this {import('../client').SettingsApp}
14
+ * @returns {Promise<boolean>} If the permssions adjustment has actually been made
15
+ */
16
+ export function adjustMediaProjectionServicePermissions(this: import("../client").SettingsApp): Promise<boolean>;
17
+ export type StartMediaProjectionRecordingOpts = {
18
+ /**
19
+ * Maximum supported resolution on-device (Detected automatically by the app
20
+ * itself), which usually equals to Full HD 1920x1080 on most phones however
21
+ * you can change it to following supported resolutions as well: "1920x1080",
22
+ * "1280x720", "720x480", "320x240", "176x144".
23
+ */
24
+ resolution?: string | undefined;
25
+ /**
26
+ * Maximum allowed duration is 15 minutes; you can increase it if your test
27
+ * takes longer than that.
28
+ */
29
+ maxDurationSec?: number | undefined;
30
+ /**
31
+ * Recording thread priority.
32
+ * If you face performance drops during testing with recording enabled, you
33
+ * can reduce recording priority
34
+ */
35
+ priority?: "high" | "normal" | "low" | undefined;
36
+ /**
37
+ * You can type recording video file name as you want, but recording currently
38
+ * supports only "mp4" format so your filename must end with ".mp4". An
39
+ * invalid file name will fail to start the recording.
40
+ */
41
+ filename?: string | undefined;
42
+ };
43
+ export type ADB = import('appium-adb').ADB;
44
+ /**
45
+ * @typedef {Object} StartMediaProjectionRecordingOpts
46
+ * @property {string} [resolution] Maximum supported resolution on-device (Detected automatically by the app
47
+ * itself), which usually equals to Full HD 1920x1080 on most phones however
48
+ * you can change it to following supported resolutions as well: "1920x1080",
49
+ * "1280x720", "720x480", "320x240", "176x144".
50
+ * @property {number} [maxDurationSec=900] Maximum allowed duration is 15 minutes; you can increase it if your test
51
+ * takes longer than that.
52
+ * @property {'high' | 'normal' | 'low'} [priority='high'] Recording thread priority.
53
+ * If you face performance drops during testing with recording enabled, you
54
+ * can reduce recording priority
55
+ * @property {string} [filename] You can type recording video file name as you want, but recording currently
56
+ * supports only "mp4" format so your filename must end with ".mp4". An
57
+ * invalid file name will fail to start the recording.
58
+ */
59
+ declare class MediaProjectionRecorder {
60
+ /**
61
+ * @param {ADB} adb
62
+ */
63
+ constructor(adb: ADB);
64
+ adb: import("appium-adb").default;
65
+ /**
66
+ *
67
+ * @returns {Promise<boolean>}
68
+ */
69
+ isRunning(): Promise<boolean>;
70
+ /**
71
+ *
72
+ * @param {StartMediaProjectionRecordingOpts} opts
73
+ * @returns {Promise<boolean>}
74
+ */
75
+ start(opts?: StartMediaProjectionRecordingOpts): Promise<boolean>;
76
+ /**
77
+ * @returns {Promise<void>}
78
+ */
79
+ cleanup(): Promise<void>;
80
+ /**
81
+ *
82
+ * @returns {Promise<string?>}
83
+ */
84
+ pullRecent(): Promise<string | null>;
85
+ /**
86
+ * @returns {Promise<boolean>}
87
+ */
88
+ stop(): Promise<boolean>;
89
+ }
90
+ export {};
91
+ //# sourceMappingURL=media-projection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-projection.d.ts","sourceRoot":"","sources":["../../../lib/commands/media-projection.js"],"names":[],"mappings":"AAwJA;;;;;;GAMG;AACH,oFAFa,uBAAuB,CAInC;AAED;;;;;;GAMG;AACH,gGAFa,QAAQ,OAAO,CAAC,CAQ5B;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAGY,OAAO,YAAY,EAAE,GAAG;AAlKrC;;;;;;;;;;;;;;GAcG;AAEH;IACE;;OAEG;IACH,iBAFW,GAAG,EAIb;IADC,kCAAc;IAGhB;;;OAGG;IACH,aAFa,QAAQ,OAAO,CAAC,CAU5B;IAED;;;;OAIG;IACH,aAHW,iCAAiC,GAC/B,QAAQ,OAAO,CAAC,CAqC5B;IAED;;OAEG;IACH,WAFa,QAAQ,IAAI,CAAC,CAIzB;IAED;;;OAGG;IACH,cAFa,QAAQ,MAAM,QAAE,CAa5B;IAED;;OAEG;IACH,QAFa,QAAQ,OAAO,CAAC,CA2B5B;CACF"}
@@ -0,0 +1,165 @@
1
+ "use strict";
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.adjustMediaProjectionServicePermissions = exports.makeMediaProjectionRecorder = void 0;
7
+ const asyncbox_1 = require("asyncbox");
8
+ const bluebird_1 = __importDefault(require("bluebird"));
9
+ const lodash_1 = __importDefault(require("lodash"));
10
+ const promises_1 = __importDefault(require("fs/promises"));
11
+ const node_path_1 = __importDefault(require("node:path"));
12
+ const constants_1 = require("../constants");
13
+ const RECORDING_STARTUP_TIMEOUT_MS = 3 * 1000;
14
+ const RECORDING_STOP_TIMEOUT_MS = 3 * 1000;
15
+ const RECORDINGS_ROOT = `/storage/emulated/0/Android/data/${constants_1.SETTINGS_HELPER_ID}/files`;
16
+ /**
17
+ * @typedef {Object} StartMediaProjectionRecordingOpts
18
+ * @property {string} [resolution] Maximum supported resolution on-device (Detected automatically by the app
19
+ * itself), which usually equals to Full HD 1920x1080 on most phones however
20
+ * you can change it to following supported resolutions as well: "1920x1080",
21
+ * "1280x720", "720x480", "320x240", "176x144".
22
+ * @property {number} [maxDurationSec=900] Maximum allowed duration is 15 minutes; you can increase it if your test
23
+ * takes longer than that.
24
+ * @property {'high' | 'normal' | 'low'} [priority='high'] Recording thread priority.
25
+ * If you face performance drops during testing with recording enabled, you
26
+ * can reduce recording priority
27
+ * @property {string} [filename] You can type recording video file name as you want, but recording currently
28
+ * supports only "mp4" format so your filename must end with ".mp4". An
29
+ * invalid file name will fail to start the recording.
30
+ */
31
+ class MediaProjectionRecorder {
32
+ /**
33
+ * @param {ADB} adb
34
+ */
35
+ constructor(adb) {
36
+ this.adb = adb;
37
+ }
38
+ /**
39
+ *
40
+ * @returns {Promise<boolean>}
41
+ */
42
+ async isRunning() {
43
+ const stdout = await this.adb.shell([
44
+ 'dumpsys',
45
+ 'activity',
46
+ 'services',
47
+ constants_1.RECORDING_SERVICE_NAME,
48
+ ]);
49
+ return stdout.includes(constants_1.RECORDING_SERVICE_NAME);
50
+ }
51
+ /**
52
+ *
53
+ * @param {StartMediaProjectionRecordingOpts} opts
54
+ * @returns {Promise<boolean>}
55
+ */
56
+ async start(opts = {}) {
57
+ if (await this.isRunning()) {
58
+ return false;
59
+ }
60
+ await this.cleanup();
61
+ const { filename, maxDurationSec, priority, resolution } = opts;
62
+ const args = ['am', 'start', '-n', constants_1.RECORDING_ACTIVITY_NAME, '-a', constants_1.RECORDING_ACTION_START];
63
+ if (filename) {
64
+ args.push('--es', 'filename', filename);
65
+ }
66
+ if (maxDurationSec) {
67
+ args.push('--es', 'max_duration_sec', `${maxDurationSec}`);
68
+ }
69
+ if (priority) {
70
+ args.push('--es', 'priority', priority);
71
+ }
72
+ if (resolution) {
73
+ args.push('--es', 'resolution', resolution);
74
+ }
75
+ await this.adb.shell(args);
76
+ await new bluebird_1.default((resolve, reject) => {
77
+ setTimeout(async () => {
78
+ if (!(await this.isRunning())) {
79
+ return reject(new Error(`The media projection recording is not running after ${RECORDING_STARTUP_TIMEOUT_MS}ms. ` +
80
+ `Please check the logcat output for more details.`));
81
+ }
82
+ resolve();
83
+ }, RECORDING_STARTUP_TIMEOUT_MS);
84
+ });
85
+ return true;
86
+ }
87
+ /**
88
+ * @returns {Promise<void>}
89
+ */
90
+ async cleanup() {
91
+ await this.adb.shell([`rm -f ${RECORDINGS_ROOT}/*`]);
92
+ }
93
+ /**
94
+ *
95
+ * @returns {Promise<string?>}
96
+ */
97
+ async pullRecent() {
98
+ const recordings = await this.adb.ls(RECORDINGS_ROOT, ['-tr']);
99
+ if (lodash_1.default.isEmpty(recordings)) {
100
+ return null;
101
+ }
102
+ const tmpRoot = await promises_1.default.mkdtemp('recording');
103
+ const dstPath = node_path_1.default.join(tmpRoot, recordings[0]);
104
+ // increase timeout to 5 minutes because it might take a while to pull a large video file
105
+ await this.adb.pull(`${RECORDINGS_ROOT}/${recordings[0]}`, dstPath, { timeout: 300000 });
106
+ return dstPath;
107
+ }
108
+ /**
109
+ * @returns {Promise<boolean>}
110
+ */
111
+ async stop() {
112
+ if (!(await this.isRunning())) {
113
+ return false;
114
+ }
115
+ await this.adb.shell([
116
+ 'am',
117
+ 'start',
118
+ '-n',
119
+ constants_1.RECORDING_ACTIVITY_NAME,
120
+ '-a',
121
+ constants_1.RECORDING_ACTION_STOP,
122
+ ]);
123
+ try {
124
+ await (0, asyncbox_1.waitForCondition)(async () => !(await this.isRunning()), {
125
+ waitMs: RECORDING_STOP_TIMEOUT_MS,
126
+ intervalMs: 500,
127
+ });
128
+ }
129
+ catch (e) {
130
+ throw new Error(`The attempt to stop the current media projection recording timed out after ` +
131
+ `${RECORDING_STOP_TIMEOUT_MS}ms`);
132
+ }
133
+ return true;
134
+ }
135
+ }
136
+ /**
137
+ * Creates a new instance of the MediaProjection-based recorder
138
+ * The recorder only works since Android API 29+
139
+ *
140
+ * @this {import('../client').SettingsApp}
141
+ * @returns {MediaProjectionRecorder} The recorder instance
142
+ */
143
+ function makeMediaProjectionRecorder() {
144
+ return new MediaProjectionRecorder(this.adb);
145
+ }
146
+ exports.makeMediaProjectionRecorder = makeMediaProjectionRecorder;
147
+ /**
148
+ * Adjusts the necessary permissions for the
149
+ * Media Projection-based recording service
150
+ *
151
+ * @this {import('../client').SettingsApp}
152
+ * @returns {Promise<boolean>} If the permssions adjustment has actually been made
153
+ */
154
+ async function adjustMediaProjectionServicePermissions() {
155
+ if (await this.adb.getApiLevel() >= 29) {
156
+ await this.adb.shell(['appops', 'set', constants_1.SETTINGS_HELPER_ID, 'PROJECT_MEDIA', 'allow']);
157
+ return true;
158
+ }
159
+ return false;
160
+ }
161
+ exports.adjustMediaProjectionServicePermissions = adjustMediaProjectionServicePermissions;
162
+ /**
163
+ * @typedef {import('appium-adb').ADB} ADB
164
+ */
165
+ //# sourceMappingURL=media-projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-projection.js","sourceRoot":"","sources":["../../../lib/commands/media-projection.js"],"names":[],"mappings":"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"}
@@ -47,4 +47,12 @@
47
47
  * @throws {Error} If there was an error while getting the notifications list
48
48
  */
49
49
  export function getNotifications(this: import("../client").SettingsApp): Promise<Record<string, any>>;
50
+ /**
51
+ * Adjusts the necessary permissions for the
52
+ * Notifications retreval service for Android API level 29+
53
+ *
54
+ * @this {import('../client').SettingsApp}
55
+ * @returns {Promise<boolean>} If permissions adjustment has been actually made
56
+ */
57
+ export function adjustNotificationsPermissions(this: import("../client").SettingsApp): Promise<boolean>;
50
58
  //# sourceMappingURL=notifications.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../../lib/commands/notifications.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,yEAjCa,QAAQ,OAAO,MAAM,EAAE,GAAG,CAAC,CAAC,CAoDxC"}
1
+ {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../../lib/commands/notifications.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,yEAjCa,QAAQ,OAAO,MAAM,EAAE,GAAG,CAAC,CAAC,CAoDxC;AAED;;;;;;GAMG;AACH,uFAFa,QAAQ,OAAO,CAAC,CAa5B"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getNotifications = void 0;
3
+ exports.adjustNotificationsPermissions = exports.getNotifications = void 0;
4
4
  const logger_1 = require("../logger");
5
5
  const constants_1 = require("../constants");
6
6
  /**
@@ -74,4 +74,24 @@ async function getNotifications() {
74
74
  }
75
75
  exports.getNotifications = getNotifications;
76
76
  ;
77
+ /**
78
+ * Adjusts the necessary permissions for the
79
+ * Notifications retreval service for Android API level 29+
80
+ *
81
+ * @this {import('../client').SettingsApp}
82
+ * @returns {Promise<boolean>} If permissions adjustment has been actually made
83
+ */
84
+ async function adjustNotificationsPermissions() {
85
+ if (await this.adb.getApiLevel() >= 29) {
86
+ await this.adb.shell([
87
+ 'cmd',
88
+ 'notification',
89
+ 'allow_listener',
90
+ constants_1.SETTING_NOTIFICATIONS_LISTENER_SERVICE,
91
+ ]);
92
+ return true;
93
+ }
94
+ return false;
95
+ }
96
+ exports.adjustNotificationsPermissions = adjustNotificationsPermissions;
77
97
  //# sourceMappingURL=notifications.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"notifications.js","sourceRoot":"","sources":["../../../lib/commands/notifications.js"],"names":[],"mappings":";;;AAAA,sCAAuC;AACvC,4CAA8D;AAE9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACI,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mBAAU,EAAE,0BAA0B,CAAC,CAAC;IACvD,wDAAwD;IACxD,wDAAwD;IACxD,8DAA8D;IAC9D,WAAW;IACX,MAAM,IAAI,CAAC,cAAc,CAAC,EAAC,uBAAuB,EAAE,IAAI,EAAC,CAAC,CAAC;IAC3D,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;YAC5B,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,0CAA8B;SACrC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,iDAAiD;YAC/D,4EAA4E;YAC5E,mBAAmB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AACtD,CAAC;AAnBD,4CAmBC;AAAA,CAAC"}
1
+ {"version":3,"file":"notifications.js","sourceRoot":"","sources":["../../../lib/commands/notifications.js"],"names":[],"mappings":";;;AAAA,sCAAuC;AACvC,4CAGsB;AAEtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACI,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mBAAU,EAAE,0BAA0B,CAAC,CAAC;IACvD,wDAAwD;IACxD,wDAAwD;IACxD,8DAA8D;IAC9D,WAAW;IACX,MAAM,IAAI,CAAC,cAAc,CAAC,EAAC,uBAAuB,EAAE,IAAI,EAAC,CAAC,CAAC;IAC3D,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;YAC5B,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,0CAA8B;SACrC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,iDAAiD;YAC/D,4EAA4E;YAC5E,mBAAmB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AACtD,CAAC;AAnBD,4CAmBC;AAAA,CAAC;AAEF;;;;;;GAMG;AACI,KAAK,UAAU,8BAA8B;IAClD,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC;QACvC,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;YACnB,KAAK;YACL,cAAc;YACd,gBAAgB;YAChB,kDAAsC;SACvC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAXD,wEAWC"}
@@ -16,10 +16,14 @@ export const LOCALE_SETTING_ACTION: "io.appium.settings.locale";
16
16
  export const LOCATION_SERVICE: "io.appium.settings/.LocationService";
17
17
  export const LOCATION_RECEIVER: "io.appium.settings/.receivers.LocationInfoReceiver";
18
18
  export const LOCATION_RETRIEVAL_ACTION: "io.appium.settings.location";
19
- export const NOTIFICATIONS_RETRIEVAL_ACTION: "io.appium.settings.notifications";
20
19
  export const SMS_LIST_RECEIVER: "io.appium.settings/.receivers.SmsReader";
21
20
  export const SMS_LIST_RETRIEVAL_ACTION: "io.appium.settings.sms.read";
22
21
  export const MEDIA_SCAN_RECEIVER: "io.appium.settings/.receivers.MediaScannerReceiver";
23
22
  export const MEDIA_SCAN_ACTION: "io.appium.settings.scan_media";
24
23
  export const SETTING_NOTIFICATIONS_LISTENER_SERVICE: "io.appium.settings/.NLService";
24
+ export const NOTIFICATIONS_RETRIEVAL_ACTION: "io.appium.settings.notifications";
25
+ export const RECORDING_SERVICE_NAME: "io.appium.settings/.recorder.RecorderService";
26
+ export const RECORDING_ACTIVITY_NAME: "io.appium.settings/io.appium.settings.Settings";
27
+ export const RECORDING_ACTION_START: "io.appium.settings.recording.ACTION_START";
28
+ export const RECORDING_ACTION_STOP: "io.appium.settings.recording.ACTION_STOP";
25
29
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../lib/constants.js"],"names":[],"mappings":"AAAA,sDAAuD;AACvD,wDAAyD;AAEzD,mFAAuF;AACvF,4EAAgF;AAEhF,yDAA6D;AAC7D,2DAA+D;AAC/D,uDAA2D;AAE3D,6GAAiH;AACjH,uEAA2E;AAC3E,6GAAiH;AACjH,kFAAsF;AAEtF,kGAAsG;AACtG,sEAA0E;AAE1E,4FAAgG;AAChG,gEAAoE;AAEpE,qEAAyE;AACzE,qFAAyF;AACzF,sEAA0E;AAE1E,gFAAoF;AAEpF,0EAA8E;AAC9E,sEAA0E;AAE1E,uFAA2F;AAC3F,gEAAoE;AAEpE,qFAAyF"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../lib/constants.js"],"names":[],"mappings":"AAAA,sDAAuD;AACvD,wDAAyD;AAEzD,mFAAuF;AACvF,4EAAgF;AAEhF,yDAA6D;AAC7D,2DAA+D;AAC/D,uDAA2D;AAE3D,6GAAiH;AACjH,uEAA2E;AAC3E,6GAAiH;AACjH,kFAAsF;AAEtF,kGAAsG;AACtG,sEAA0E;AAE1E,4FAAgG;AAChG,gEAAoE;AAEpE,qEAAyE;AACzE,qFAAyF;AACzF,sEAA0E;AAE1E,0EAA8E;AAC9E,sEAA0E;AAE1E,uFAA2F;AAC3F,gEAAoE;AAEpE,qFAAyF;AACzF,gFAAoF;AAEpF,oFAAwF;AACxF,uFAA2F;AAC3F,iFAAqF;AACrF,+EAAmF"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SETTING_NOTIFICATIONS_LISTENER_SERVICE = exports.MEDIA_SCAN_ACTION = exports.MEDIA_SCAN_RECEIVER = exports.SMS_LIST_RETRIEVAL_ACTION = exports.SMS_LIST_RECEIVER = exports.NOTIFICATIONS_RETRIEVAL_ACTION = exports.LOCATION_RETRIEVAL_ACTION = exports.LOCATION_RECEIVER = exports.LOCATION_SERVICE = exports.LOCALE_SETTING_ACTION = exports.LOCALE_SETTING_RECEIVER = exports.ANIMATION_SETTING_ACTION = exports.ANIMATION_SETTING_RECEIVER = exports.DATA_CONNECTION_SETTING_ACTION = exports.DATA_CONNECTION_SETTING_RECEIVER = exports.WIFI_CONNECTION_SETTING_ACTION = exports.WIFI_CONNECTION_SETTING_RECEIVER = exports.EMPTY_IME = exports.UNICODE_IME = exports.APPIUM_IME = exports.CLIPBOARD_RETRIEVAL_ACTION = exports.CLIPBOARD_RECEIVER = exports.SETTINGS_HELPER_MAIN_ACTIVITY = exports.SETTINGS_HELPER_ID = void 0;
3
+ exports.RECORDING_ACTION_STOP = exports.RECORDING_ACTION_START = exports.RECORDING_ACTIVITY_NAME = exports.RECORDING_SERVICE_NAME = exports.NOTIFICATIONS_RETRIEVAL_ACTION = exports.SETTING_NOTIFICATIONS_LISTENER_SERVICE = exports.MEDIA_SCAN_ACTION = exports.MEDIA_SCAN_RECEIVER = exports.SMS_LIST_RETRIEVAL_ACTION = exports.SMS_LIST_RECEIVER = exports.LOCATION_RETRIEVAL_ACTION = exports.LOCATION_RECEIVER = exports.LOCATION_SERVICE = exports.LOCALE_SETTING_ACTION = exports.LOCALE_SETTING_RECEIVER = exports.ANIMATION_SETTING_ACTION = exports.ANIMATION_SETTING_RECEIVER = exports.DATA_CONNECTION_SETTING_ACTION = exports.DATA_CONNECTION_SETTING_RECEIVER = exports.WIFI_CONNECTION_SETTING_ACTION = exports.WIFI_CONNECTION_SETTING_RECEIVER = exports.EMPTY_IME = exports.UNICODE_IME = exports.APPIUM_IME = exports.CLIPBOARD_RETRIEVAL_ACTION = exports.CLIPBOARD_RECEIVER = exports.SETTINGS_HELPER_MAIN_ACTIVITY = exports.SETTINGS_HELPER_ID = void 0;
4
4
  exports.SETTINGS_HELPER_ID = 'io.appium.settings';
5
5
  exports.SETTINGS_HELPER_MAIN_ACTIVITY = '.Settings';
6
6
  exports.CLIPBOARD_RECEIVER = `${exports.SETTINGS_HELPER_ID}/.receivers.ClipboardReceiver`;
@@ -19,10 +19,14 @@ exports.LOCALE_SETTING_ACTION = `${exports.SETTINGS_HELPER_ID}.locale`;
19
19
  exports.LOCATION_SERVICE = `${exports.SETTINGS_HELPER_ID}/.LocationService`;
20
20
  exports.LOCATION_RECEIVER = `${exports.SETTINGS_HELPER_ID}/.receivers.LocationInfoReceiver`;
21
21
  exports.LOCATION_RETRIEVAL_ACTION = `${exports.SETTINGS_HELPER_ID}.location`;
22
- exports.NOTIFICATIONS_RETRIEVAL_ACTION = `${exports.SETTINGS_HELPER_ID}.notifications`;
23
22
  exports.SMS_LIST_RECEIVER = `${exports.SETTINGS_HELPER_ID}/.receivers.SmsReader`;
24
23
  exports.SMS_LIST_RETRIEVAL_ACTION = `${exports.SETTINGS_HELPER_ID}.sms.read`;
25
24
  exports.MEDIA_SCAN_RECEIVER = `${exports.SETTINGS_HELPER_ID}/.receivers.MediaScannerReceiver`;
26
25
  exports.MEDIA_SCAN_ACTION = `${exports.SETTINGS_HELPER_ID}.scan_media`;
27
26
  exports.SETTING_NOTIFICATIONS_LISTENER_SERVICE = `${exports.SETTINGS_HELPER_ID}/.NLService`;
27
+ exports.NOTIFICATIONS_RETRIEVAL_ACTION = `${exports.SETTINGS_HELPER_ID}.notifications`;
28
+ exports.RECORDING_SERVICE_NAME = `${exports.SETTINGS_HELPER_ID}/.recorder.RecorderService`;
29
+ exports.RECORDING_ACTIVITY_NAME = `${exports.SETTINGS_HELPER_ID}/io.appium.settings.Settings`;
30
+ exports.RECORDING_ACTION_START = `${exports.SETTINGS_HELPER_ID}.recording.ACTION_START`;
31
+ exports.RECORDING_ACTION_STOP = `${exports.SETTINGS_HELPER_ID}.recording.ACTION_STOP`;
28
32
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../lib/constants.js"],"names":[],"mappings":";;;AAAa,QAAA,kBAAkB,GAAG,oBAAoB,CAAC;AAC1C,QAAA,6BAA6B,GAAG,WAAW,CAAC;AAE5C,QAAA,kBAAkB,GAAG,GAAG,0BAAkB,+BAA+B,CAAC;AAC1E,QAAA,0BAA0B,GAAG,GAAG,0BAAkB,gBAAgB,CAAC;AAEnE,QAAA,UAAU,GAAG,GAAG,0BAAkB,aAAa,CAAC;AAChD,QAAA,WAAW,GAAG,GAAG,0BAAkB,cAAc,CAAC;AAClD,QAAA,SAAS,GAAG,GAAG,0BAAkB,YAAY,CAAC;AAE9C,QAAA,gCAAgC,GAAG,GAAG,0BAAkB,2CAA2C,CAAC;AACpG,QAAA,8BAA8B,GAAG,GAAG,0BAAkB,OAAO,CAAC;AAC9D,QAAA,gCAAgC,GAAG,GAAG,0BAAkB,2CAA2C,CAAC;AACpG,QAAA,8BAA8B,GAAG,GAAG,0BAAkB,kBAAkB,CAAC;AAEzE,QAAA,0BAA0B,GAAG,GAAG,0BAAkB,sCAAsC,CAAC;AACzF,QAAA,wBAAwB,GAAG,GAAG,0BAAkB,YAAY,CAAC;AAE7D,QAAA,uBAAuB,GAAG,GAAG,0BAAkB,mCAAmC,CAAC;AACnF,QAAA,qBAAqB,GAAG,GAAG,0BAAkB,SAAS,CAAC;AAEvD,QAAA,gBAAgB,GAAG,GAAG,0BAAkB,mBAAmB,CAAC;AAC5D,QAAA,iBAAiB,GAAG,GAAG,0BAAkB,kCAAkC,CAAC;AAC5E,QAAA,yBAAyB,GAAG,GAAG,0BAAkB,WAAW,CAAC;AAE7D,QAAA,8BAA8B,GAAG,GAAG,0BAAkB,gBAAgB,CAAC;AAEvE,QAAA,iBAAiB,GAAG,GAAG,0BAAkB,uBAAuB,CAAC;AACjE,QAAA,yBAAyB,GAAG,GAAG,0BAAkB,WAAW,CAAC;AAE7D,QAAA,mBAAmB,GAAG,GAAG,0BAAkB,kCAAkC,CAAC;AAC9E,QAAA,iBAAiB,GAAG,GAAG,0BAAkB,aAAa,CAAC;AAEvD,QAAA,sCAAsC,GAAG,GAAG,0BAAkB,aAAa,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../lib/constants.js"],"names":[],"mappings":";;;AAAa,QAAA,kBAAkB,GAAG,oBAAoB,CAAC;AAC1C,QAAA,6BAA6B,GAAG,WAAW,CAAC;AAE5C,QAAA,kBAAkB,GAAG,GAAG,0BAAkB,+BAA+B,CAAC;AAC1E,QAAA,0BAA0B,GAAG,GAAG,0BAAkB,gBAAgB,CAAC;AAEnE,QAAA,UAAU,GAAG,GAAG,0BAAkB,aAAa,CAAC;AAChD,QAAA,WAAW,GAAG,GAAG,0BAAkB,cAAc,CAAC;AAClD,QAAA,SAAS,GAAG,GAAG,0BAAkB,YAAY,CAAC;AAE9C,QAAA,gCAAgC,GAAG,GAAG,0BAAkB,2CAA2C,CAAC;AACpG,QAAA,8BAA8B,GAAG,GAAG,0BAAkB,OAAO,CAAC;AAC9D,QAAA,gCAAgC,GAAG,GAAG,0BAAkB,2CAA2C,CAAC;AACpG,QAAA,8BAA8B,GAAG,GAAG,0BAAkB,kBAAkB,CAAC;AAEzE,QAAA,0BAA0B,GAAG,GAAG,0BAAkB,sCAAsC,CAAC;AACzF,QAAA,wBAAwB,GAAG,GAAG,0BAAkB,YAAY,CAAC;AAE7D,QAAA,uBAAuB,GAAG,GAAG,0BAAkB,mCAAmC,CAAC;AACnF,QAAA,qBAAqB,GAAG,GAAG,0BAAkB,SAAS,CAAC;AAEvD,QAAA,gBAAgB,GAAG,GAAG,0BAAkB,mBAAmB,CAAC;AAC5D,QAAA,iBAAiB,GAAG,GAAG,0BAAkB,kCAAkC,CAAC;AAC5E,QAAA,yBAAyB,GAAG,GAAG,0BAAkB,WAAW,CAAC;AAE7D,QAAA,iBAAiB,GAAG,GAAG,0BAAkB,uBAAuB,CAAC;AACjE,QAAA,yBAAyB,GAAG,GAAG,0BAAkB,WAAW,CAAC;AAE7D,QAAA,mBAAmB,GAAG,GAAG,0BAAkB,kCAAkC,CAAC;AAC9E,QAAA,iBAAiB,GAAG,GAAG,0BAAkB,aAAa,CAAC;AAEvD,QAAA,sCAAsC,GAAG,GAAG,0BAAkB,aAAa,CAAC;AAC5E,QAAA,8BAA8B,GAAG,GAAG,0BAAkB,gBAAgB,CAAC;AAEvE,QAAA,sBAAsB,GAAG,GAAG,0BAAkB,4BAA4B,CAAC;AAC3E,QAAA,uBAAuB,GAAG,GAAG,0BAAkB,8BAA8B,CAAC;AAC9E,QAAA,sBAAsB,GAAG,GAAG,0BAAkB,yBAAyB,CAAC;AACxE,QAAA,qBAAqB,GAAG,GAAG,0BAAkB,wBAAwB,CAAC"}
package/lib/client.js CHANGED
@@ -5,12 +5,16 @@ import { SETTINGS_HELPER_ID, SETTINGS_HELPER_MAIN_ACTIVITY } from './constants.j
5
5
  import { setAnimationState } from './commands/animation';
6
6
  import { getClipboard } from './commands/clipboard';
7
7
  import { setGeoLocation, getGeoLocation, refreshGeoLocationCache } from './commands/geolocation';
8
- import { setDeviceSysLocale } from './commands/locale';
8
+ import { setDeviceLocale } from './commands/locale';
9
9
  import { scanMedia } from './commands/media';
10
10
  import { setDataState, setWifiState } from './commands/network';
11
- import { getNotifications } from './commands/notifications';
11
+ import { getNotifications, adjustNotificationsPermissions } from './commands/notifications';
12
12
  import { getSmsList } from './commands/sms';
13
13
  import { performEditorAction, typeUnicode } from './commands/typing';
14
+ import {
15
+ makeMediaProjectionRecorder,
16
+ adjustMediaProjectionServicePermissions,
17
+ } from './commands/media-projection';
14
18
 
15
19
  /**
16
20
  * @typedef {Object} SettingsAppOpts
@@ -160,7 +164,7 @@ export class SettingsApp {
160
164
  getGeoLocation = getGeoLocation;
161
165
  refreshGeoLocationCache = refreshGeoLocationCache;
162
166
 
163
- setDeviceSysLocale = setDeviceSysLocale;
167
+ setDeviceLocale = setDeviceLocale;
164
168
 
165
169
  scanMedia = scanMedia;
166
170
 
@@ -168,8 +172,12 @@ export class SettingsApp {
168
172
  setWifiState = setWifiState;
169
173
 
170
174
  getNotifications = getNotifications;
175
+ adjustNotificationsPermissions = adjustNotificationsPermissions;
171
176
  getSmsList = getSmsList;
172
177
 
173
178
  performEditorAction = performEditorAction;
174
179
  typeUnicode = typeUnicode;
180
+
181
+ makeMediaProjectionRecorder = makeMediaProjectionRecorder;
182
+ adjustMediaProjectionServicePermissions = adjustMediaProjectionServicePermissions;
175
183
  }
@@ -1,3 +1,6 @@
1
+ import _ from 'lodash';
2
+ import { LOG_PREFIX } from '../logger.js';
3
+ import B from 'bluebird';
1
4
  import { LOCALE_SETTING_ACTION, LOCALE_SETTING_RECEIVER } from '../constants.js';
2
5
 
3
6
  /**
@@ -11,7 +14,7 @@ import { LOCALE_SETTING_ACTION, LOCALE_SETTING_RECEIVER } from '../constants.js'
11
14
  * @param {string} country - Country. e.g. US, JP
12
15
  * @param {string?} [script=null] - Script. e.g. Hans in `zh-Hans-CN`
13
16
  */
14
- export async function setDeviceSysLocale (language, country, script = null) {
17
+ async function setDeviceLocaleInternal (language, country, script = null) {
15
18
  const params = [
16
19
  'am', 'broadcast',
17
20
  '-a', LOCALE_SETTING_ACTION,
@@ -25,4 +28,49 @@ export async function setDeviceSysLocale (language, country, script = null) {
25
28
  }
26
29
 
27
30
  await this.adb.shell(params);
28
- };
31
+ }
32
+
33
+ /**
34
+ * Set the locale name of the device under test.
35
+ *
36
+ * @this {import('../client').SettingsApp}
37
+ * @param {string} language - Language. The language field is case insensitive, but Locale always canonicalizes to lower case.
38
+ * format: [a-zA-Z]{2,8}. e.g. en, ja : https://developer.android.com/reference/java/util/Locale.html
39
+ * @param {string} country - Country. The country (region) field is case insensitive, but Locale always canonicalizes to upper case.
40
+ * format: [a-zA-Z]{2} | [0-9]{3}. e.g. US, JP : https://developer.android.com/reference/java/util/Locale.html
41
+ * @param {string?} [script=null] - Script. The script field is case insensitive but Locale always canonicalizes to title case.
42
+ * format: [a-zA-Z]{4}. e.g. Hans in zh-Hans-CN : https://developer.android.com/reference/java/util/Locale.html
43
+ */
44
+ export async function setDeviceLocale (language, country, script = null) {
45
+ if (_.isEmpty(language)) {
46
+ throw new Error('Language name must be provided');
47
+ }
48
+ if (_.isEmpty(country)) {
49
+ throw new Error('Country name must be provided');
50
+ }
51
+
52
+ const lcLanguage = language.toLowerCase();
53
+ const ucCountry = country.toUpperCase();
54
+ if (await this.adb.getApiLevel() < 23) {
55
+ const [curLanguageRaw, curCountryRaw] = await B.all([
56
+ this.adb.getDeviceLanguage(),
57
+ this.adb.getDeviceCountry(),
58
+ ]);
59
+ const curLanguage = curLanguageRaw.toLowerCase();
60
+ const curCountry = curCountryRaw.toUpperCase();
61
+ this.log.debug(LOG_PREFIX, `Current language: '${curLanguage}'; requested language: '${lcLanguage}'`);
62
+ this.log.debug(LOG_PREFIX, `Current country: '${curCountry}'; requested country: '${ucCountry}'`);
63
+ if (lcLanguage !== curLanguage || ucCountry !== curCountry) {
64
+ await setDeviceLocaleInternal.bind(this)(lcLanguage, ucCountry);
65
+ }
66
+ } else {
67
+ const curLocale = await this.adb.getDeviceLocale();
68
+
69
+ // zh-Hans-CN : zh-CN
70
+ const localeCode = script ? `${lcLanguage}-${script}-${ucCountry}` : `${lcLanguage}-${ucCountry}`;
71
+ this.log.debug(LOG_PREFIX, `Current locale: '${curLocale}'; requested locale: '${localeCode}'`);
72
+ if (localeCode.toLowerCase() !== curLocale.toLowerCase()) {
73
+ await setDeviceLocaleInternal.bind(this)(lcLanguage, ucCountry, script);
74
+ }
75
+ }
76
+ }
@@ -0,0 +1,181 @@
1
+ import {waitForCondition} from 'asyncbox';
2
+ import B from 'bluebird';
3
+ import _ from 'lodash';
4
+ import fs from 'fs/promises';
5
+ import path from 'node:path';
6
+ import {
7
+ SETTINGS_HELPER_ID,
8
+ RECORDING_ACTION_START,
9
+ RECORDING_ACTION_STOP,
10
+ RECORDING_ACTIVITY_NAME,
11
+ RECORDING_SERVICE_NAME,
12
+ } from '../constants';
13
+
14
+ const RECORDING_STARTUP_TIMEOUT_MS = 3 * 1000;
15
+ const RECORDING_STOP_TIMEOUT_MS = 3 * 1000;
16
+ const RECORDINGS_ROOT = `/storage/emulated/0/Android/data/${SETTINGS_HELPER_ID}/files`;
17
+
18
+ /**
19
+ * @typedef {Object} StartMediaProjectionRecordingOpts
20
+ * @property {string} [resolution] Maximum supported resolution on-device (Detected automatically by the app
21
+ * itself), which usually equals to Full HD 1920x1080 on most phones however
22
+ * you can change it to following supported resolutions as well: "1920x1080",
23
+ * "1280x720", "720x480", "320x240", "176x144".
24
+ * @property {number} [maxDurationSec=900] Maximum allowed duration is 15 minutes; you can increase it if your test
25
+ * takes longer than that.
26
+ * @property {'high' | 'normal' | 'low'} [priority='high'] Recording thread priority.
27
+ * If you face performance drops during testing with recording enabled, you
28
+ * can reduce recording priority
29
+ * @property {string} [filename] You can type recording video file name as you want, but recording currently
30
+ * supports only "mp4" format so your filename must end with ".mp4". An
31
+ * invalid file name will fail to start the recording.
32
+ */
33
+
34
+ class MediaProjectionRecorder {
35
+ /**
36
+ * @param {ADB} adb
37
+ */
38
+ constructor(adb) {
39
+ this.adb = adb;
40
+ }
41
+
42
+ /**
43
+ *
44
+ * @returns {Promise<boolean>}
45
+ */
46
+ async isRunning() {
47
+ const stdout = await this.adb.shell([
48
+ 'dumpsys',
49
+ 'activity',
50
+ 'services',
51
+ RECORDING_SERVICE_NAME,
52
+ ]);
53
+ return stdout.includes(RECORDING_SERVICE_NAME);
54
+ }
55
+
56
+ /**
57
+ *
58
+ * @param {StartMediaProjectionRecordingOpts} opts
59
+ * @returns {Promise<boolean>}
60
+ */
61
+ async start(opts = {}) {
62
+ if (await this.isRunning()) {
63
+ return false;
64
+ }
65
+
66
+ await this.cleanup();
67
+ const {filename, maxDurationSec, priority, resolution} = opts;
68
+ const args = ['am', 'start', '-n', RECORDING_ACTIVITY_NAME, '-a', RECORDING_ACTION_START];
69
+ if (filename) {
70
+ args.push('--es', 'filename', filename);
71
+ }
72
+ if (maxDurationSec) {
73
+ args.push('--es', 'max_duration_sec', `${maxDurationSec}`);
74
+ }
75
+ if (priority) {
76
+ args.push('--es', 'priority', priority);
77
+ }
78
+ if (resolution) {
79
+ args.push('--es', 'resolution', resolution);
80
+ }
81
+ await this.adb.shell(args);
82
+ await new B((resolve, reject) => {
83
+ setTimeout(async () => {
84
+ if (!(await this.isRunning())) {
85
+ return reject(
86
+ new Error(
87
+ `The media projection recording is not running after ${RECORDING_STARTUP_TIMEOUT_MS}ms. ` +
88
+ `Please check the logcat output for more details.`
89
+ )
90
+ );
91
+ }
92
+ resolve();
93
+ }, RECORDING_STARTUP_TIMEOUT_MS);
94
+ });
95
+ return true;
96
+ }
97
+
98
+ /**
99
+ * @returns {Promise<void>}
100
+ */
101
+ async cleanup() {
102
+ await this.adb.shell([`rm -f ${RECORDINGS_ROOT}/*`]);
103
+ }
104
+
105
+ /**
106
+ *
107
+ * @returns {Promise<string?>}
108
+ */
109
+ async pullRecent() {
110
+ const recordings = await this.adb.ls(RECORDINGS_ROOT, ['-tr']);
111
+ if (_.isEmpty(recordings)) {
112
+ return null;
113
+ }
114
+
115
+ const tmpRoot = await fs.mkdtemp('recording');
116
+ const dstPath = path.join(tmpRoot, recordings[0]);
117
+ // increase timeout to 5 minutes because it might take a while to pull a large video file
118
+ await this.adb.pull(`${RECORDINGS_ROOT}/${recordings[0]}`, dstPath, {timeout: 300000});
119
+ return dstPath;
120
+ }
121
+
122
+ /**
123
+ * @returns {Promise<boolean>}
124
+ */
125
+ async stop() {
126
+ if (!(await this.isRunning())) {
127
+ return false;
128
+ }
129
+
130
+ await this.adb.shell([
131
+ 'am',
132
+ 'start',
133
+ '-n',
134
+ RECORDING_ACTIVITY_NAME,
135
+ '-a',
136
+ RECORDING_ACTION_STOP,
137
+ ]);
138
+ try {
139
+ await waitForCondition(async () => !(await this.isRunning()), {
140
+ waitMs: RECORDING_STOP_TIMEOUT_MS,
141
+ intervalMs: 500,
142
+ });
143
+ } catch (e) {
144
+ throw new Error(
145
+ `The attempt to stop the current media projection recording timed out after ` +
146
+ `${RECORDING_STOP_TIMEOUT_MS}ms`
147
+ );
148
+ }
149
+ return true;
150
+ }
151
+ }
152
+
153
+ /**
154
+ * Creates a new instance of the MediaProjection-based recorder
155
+ * The recorder only works since Android API 29+
156
+ *
157
+ * @this {import('../client').SettingsApp}
158
+ * @returns {MediaProjectionRecorder} The recorder instance
159
+ */
160
+ export function makeMediaProjectionRecorder() {
161
+ return new MediaProjectionRecorder(this.adb);
162
+ }
163
+
164
+ /**
165
+ * Adjusts the necessary permissions for the
166
+ * Media Projection-based recording service
167
+ *
168
+ * @this {import('../client').SettingsApp}
169
+ * @returns {Promise<boolean>} If the permssions adjustment has actually been made
170
+ */
171
+ export async function adjustMediaProjectionServicePermissions() {
172
+ if (await this.adb.getApiLevel() >= 29) {
173
+ await this.adb.shell(['appops', 'set', SETTINGS_HELPER_ID, 'PROJECT_MEDIA', 'allow']);
174
+ return true;
175
+ }
176
+ return false;
177
+ }
178
+
179
+ /**
180
+ * @typedef {import('appium-adb').ADB} ADB
181
+ */
@@ -1,5 +1,8 @@
1
1
  import { LOG_PREFIX } from '../logger';
2
- import { NOTIFICATIONS_RETRIEVAL_ACTION } from '../constants';
2
+ import {
3
+ NOTIFICATIONS_RETRIEVAL_ACTION,
4
+ SETTING_NOTIFICATIONS_LISTENER_SERVICE,
5
+ } from '../constants';
3
6
 
4
7
  /**
5
8
  * Retrieves Android notifications via Appium Settings helper.
@@ -69,3 +72,23 @@ export async function getNotifications () {
69
72
  }
70
73
  return this._parseJsonData(output, 'notifications');
71
74
  };
75
+
76
+ /**
77
+ * Adjusts the necessary permissions for the
78
+ * Notifications retreval service for Android API level 29+
79
+ *
80
+ * @this {import('../client').SettingsApp}
81
+ * @returns {Promise<boolean>} If permissions adjustment has been actually made
82
+ */
83
+ export async function adjustNotificationsPermissions() {
84
+ if (await this.adb.getApiLevel() >= 29) {
85
+ await this.adb.shell([
86
+ 'cmd',
87
+ 'notification',
88
+ 'allow_listener',
89
+ SETTING_NOTIFICATIONS_LISTENER_SERVICE,
90
+ ]);
91
+ return true;
92
+ }
93
+ return false;
94
+ }
package/lib/constants.js CHANGED
@@ -23,8 +23,6 @@ export const LOCATION_SERVICE = `${SETTINGS_HELPER_ID}/.LocationService`;
23
23
  export const LOCATION_RECEIVER = `${SETTINGS_HELPER_ID}/.receivers.LocationInfoReceiver`;
24
24
  export const LOCATION_RETRIEVAL_ACTION = `${SETTINGS_HELPER_ID}.location`;
25
25
 
26
- export const NOTIFICATIONS_RETRIEVAL_ACTION = `${SETTINGS_HELPER_ID}.notifications`;
27
-
28
26
  export const SMS_LIST_RECEIVER = `${SETTINGS_HELPER_ID}/.receivers.SmsReader`;
29
27
  export const SMS_LIST_RETRIEVAL_ACTION = `${SETTINGS_HELPER_ID}.sms.read`;
30
28
 
@@ -32,3 +30,9 @@ export const MEDIA_SCAN_RECEIVER = `${SETTINGS_HELPER_ID}/.receivers.MediaScanne
32
30
  export const MEDIA_SCAN_ACTION = `${SETTINGS_HELPER_ID}.scan_media`;
33
31
 
34
32
  export const SETTING_NOTIFICATIONS_LISTENER_SERVICE = `${SETTINGS_HELPER_ID}/.NLService`;
33
+ export const NOTIFICATIONS_RETRIEVAL_ACTION = `${SETTINGS_HELPER_ID}.notifications`;
34
+
35
+ export const RECORDING_SERVICE_NAME = `${SETTINGS_HELPER_ID}/.recorder.RecorderService`;
36
+ export const RECORDING_ACTIVITY_NAME = `${SETTINGS_HELPER_ID}/io.appium.settings.Settings`;
37
+ export const RECORDING_ACTION_START = `${SETTINGS_HELPER_ID}.recording.ACTION_START`;
38
+ export const RECORDING_ACTION_STOP = `${SETTINGS_HELPER_ID}.recording.ACTION_STOP`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "io.appium.settings",
3
- "version": "5.4.2",
3
+ "version": "5.6.0",
4
4
  "description": "App for dealing with Android settings",
5
5
  "main": "index.js",
6
6
  "scripts": {