Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 34 additions & 15 deletions lib/commands/general.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import { util } from 'appium/support';
import moment from 'moment';
import { longSleep } from 'asyncbox';
import { errors } from 'appium/driver';
import B from 'bluebird';

const MOMENT_FORMAT_ISO8601 = 'YYYY-MM-DDTHH:mm:ssZ';
const ALL_PERMISSIONS_MAGIC = 'all';

let commands = {}, helpers = {}, extensions = {};

Expand Down Expand Up @@ -309,7 +311,10 @@ const PERMISSION_ACTION = {
/**
* @typedef {Object} ChangePermissionsOptions
* @property {!string|Array<string>} permissions - The full name of the permission to be changed
* or a list of permissions. Mandatory argument.
* or a list of permissions. Check https://developer.android.com/reference/android/Manifest.permission
* to get the full list of standard Android permssion names. Mandatory argument.
* If 'all' magic string is passed then the chosen action is going to be applied to all
* permisisons requested/granted by 'appPackage'.
* @property {string} appPackage [this.opts.appPackage] - The application package to set change
* permissions on. Defaults to the package name under test.
* @property {string} action [grant] - One of `PERMISSION_ACTION` values
Expand All @@ -327,24 +332,38 @@ commands.mobileChangePermissions = async function mobileChangePermissions (opts
appPackage = this.opts.appPackage,
action = PERMISSION_ACTION.GRANT,
} = opts;
if (!util.hasValue(permissions)) {
if (_.isNil(permissions)) {
throw new errors.InvalidArgumentError(`'permissions' argument is required`);
}
if (_.isEmpty(permissions)) {
throw new errors.InvalidArgumentError(`'permissions' argument must not be empty`);
}
const lowerAction = _.toLower(action);
if (![PERMISSION_ACTION.GRANT, PERMISSION_ACTION.REVOKE].includes(lowerAction)) {
throw new errors.InvalidArgumentError(`Unknown action '${action}'. ` +
`Only ${JSON.stringify(_.values(PERMISSION_ACTION))} actions are supported`);
}

let actionFunc;
switch (_.toLower(action)) {
case PERMISSION_ACTION.GRANT:
actionFunc = (appPackage, permission) => this.adb.grantPermission(appPackage, permission);
break;
case PERMISSION_ACTION.REVOKE:
actionFunc = (appPackage, permission) => this.adb.revokePermission(appPackage, permission);
break;
default:
throw new errors.InvalidArgumentError(`Unknown action '${action}'. ` +
`Only ${JSON.stringify(_.values(PERMISSION_ACTION))} actions are supported`);
let affectedPermissions = _.isArray(permissions) ? permissions : [permissions];
if (_.toLower(permissions) === ALL_PERMISSIONS_MAGIC) {
const dumpsys = await this.adb.shell(['dumpsys', 'package', appPackage]);
const grantedPermissions = await this.adb.getGrantedPermissions(appPackage, dumpsys);
if (lowerAction === PERMISSION_ACTION.GRANT) {
const reqPermissons = await this.adb.getReqPermissions(appPackage, dumpsys);
affectedPermissions = _.difference(reqPermissons, grantedPermissions);
} else {
affectedPermissions = grantedPermissions;
}
if (_.isEmpty(affectedPermissions)) {
this.log.info(`'${appPackage}' contains no permissions to ${lowerAction}`);
return;
}
}
for (const permission of (_.isArray(permissions) ? permissions : [permissions])) {
await actionFunc(appPackage, permission);

if (lowerAction === PERMISSION_ACTION.GRANT) {
await this.adb.grantPermissions(appPackage, affectedPermissions);
} else {
await B.all(affectedPermissions.map((name) => this.adb.revokePermission(appPackage, name)));
}
};

Expand Down