@@ -4,8 +4,10 @@ import { util } from 'appium/support';
44import moment from 'moment' ;
55import { longSleep } from 'asyncbox' ;
66import { errors } from 'appium/driver' ;
7+ import B from 'bluebird' ;
78
89const MOMENT_FORMAT_ISO8601 = 'YYYY-MM-DDTHH:mm:ssZ' ;
10+ const ALL_PERMISSIONS_MAGIC = 'all' ;
911
1012let commands = { } , helpers = { } , extensions = { } ;
1113
@@ -309,7 +311,10 @@ const PERMISSION_ACTION = {
309311/**
310312 * @typedef {Object } ChangePermissionsOptions
311313 * @property {!string|Array<string> } permissions - The full name of the permission to be changed
312- * or a list of permissions. Mandatory argument.
314+ * or a list of permissions. Check https://developer.android.com/reference/android/Manifest.permission
315+ * to get the full list of standard Android permssion names. Mandatory argument.
316+ * If 'all' magic string is passed then the chosen action is going to be applied to all
317+ * permisisons requested/granted by 'appPackage'.
313318 * @property {string } appPackage [this.opts.appPackage] - The application package to set change
314319 * permissions on. Defaults to the package name under test.
315320 * @property {string } action [grant] - One of `PERMISSION_ACTION` values
@@ -327,24 +332,38 @@ commands.mobileChangePermissions = async function mobileChangePermissions (opts
327332 appPackage = this . opts . appPackage ,
328333 action = PERMISSION_ACTION . GRANT ,
329334 } = opts ;
330- if ( ! util . hasValue ( permissions ) ) {
335+ if ( _ . isNil ( permissions ) ) {
331336 throw new errors . InvalidArgumentError ( `'permissions' argument is required` ) ;
332337 }
338+ if ( _ . isEmpty ( permissions ) ) {
339+ throw new errors . InvalidArgumentError ( `'permissions' argument must not be empty` ) ;
340+ }
341+ const lowerAction = _ . toLower ( action ) ;
342+ if ( ! [ PERMISSION_ACTION . GRANT , PERMISSION_ACTION . REVOKE ] . includes ( lowerAction ) ) {
343+ throw new errors . InvalidArgumentError ( `Unknown action '${ action } '. ` +
344+ `Only ${ JSON . stringify ( _ . values ( PERMISSION_ACTION ) ) } actions are supported` ) ;
345+ }
333346
334- let actionFunc ;
335- switch ( _ . toLower ( action ) ) {
336- case PERMISSION_ACTION . GRANT :
337- actionFunc = ( appPackage , permission ) => this . adb . grantPermission ( appPackage , permission ) ;
338- break ;
339- case PERMISSION_ACTION . REVOKE :
340- actionFunc = ( appPackage , permission ) => this . adb . revokePermission ( appPackage , permission ) ;
341- break ;
342- default :
343- throw new errors . InvalidArgumentError ( `Unknown action '${ action } '. ` +
344- `Only ${ JSON . stringify ( _ . values ( PERMISSION_ACTION ) ) } actions are supported` ) ;
347+ let affectedPermissions = _ . isArray ( permissions ) ? permissions : [ permissions ] ;
348+ if ( _ . toLower ( permissions ) === ALL_PERMISSIONS_MAGIC ) {
349+ const dumpsys = await this . adb . shell ( [ 'dumpsys' , 'package' , appPackage ] ) ;
350+ const grantedPermissions = await this . adb . getGrantedPermissions ( appPackage , dumpsys ) ;
351+ if ( lowerAction === PERMISSION_ACTION . GRANT ) {
352+ const reqPermissons = await this . adb . getReqPermissions ( appPackage , dumpsys ) ;
353+ affectedPermissions = _ . difference ( reqPermissons , grantedPermissions ) ;
354+ } else {
355+ affectedPermissions = grantedPermissions ;
356+ }
357+ if ( _ . isEmpty ( affectedPermissions ) ) {
358+ this . log . info ( `'${ appPackage } ' contains no permissions to ${ lowerAction } ` ) ;
359+ return ;
360+ }
345361 }
346- for ( const permission of ( _ . isArray ( permissions ) ? permissions : [ permissions ] ) ) {
347- await actionFunc ( appPackage , permission ) ;
362+
363+ if ( lowerAction === PERMISSION_ACTION . GRANT ) {
364+ await this . adb . grantPermissions ( appPackage , affectedPermissions ) ;
365+ } else {
366+ await B . all ( affectedPermissions . map ( ( name ) => this . adb . revokePermission ( appPackage , name ) ) ) ;
348367 }
349368} ;
350369
0 commit comments