UNPKG

appium-android-driver

Version:

Android UiAutomator and Chrome support for Appium

147 lines 7.31 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.mobileChangePermissions = mobileChangePermissions; exports.mobileGetPermissions = mobileGetPermissions; const driver_1 = require("appium/driver"); const bluebird_1 = __importDefault(require("bluebird")); const lodash_1 = __importDefault(require("lodash")); const utils_1 = require("../utils"); const ALL_PERMISSIONS_MAGIC = 'all'; const PM_ACTION = Object.freeze({ GRANT: 'grant', REVOKE: 'revoke', }); const APPOPS_ACTION = Object.freeze({ ALLOW: 'allow', DENY: 'deny', IGNORE: 'ignore', DEFAULT: 'default', }); const PERMISSION_TARGET = Object.freeze({ PM: 'pm', APPOPS: 'appops', }); const PERMISSIONS_TYPE = Object.freeze({ DENIED: 'denied', GRANTED: 'granted', REQUESTED: 'requested', }); /** * Changes permissions for an Android application. * * @param permissions If `target` is set to 'pm': * The full name of the permission to be changed * or a list of permissions. Check https://developer.android.com/reference/android/Manifest.permission * to get the full list of standard Android permission names. Mandatory argument. * If 'all' magic string is passed then the chosen action is going to be applied to all * permissions requested/granted by 'appPackage'. * If `target` is set to 'appops': * The full name of the appops permission to be changed * or a list of permissions. Check AppOpsManager.java sources to get the full list of * available appops permission names. Mandatory argument. * Examples: 'ACTIVITY_RECOGNITION', 'SMS_FINANCIAL_TRANSACTIONS', 'READ_SMS', 'ACCESS_NOTIFICATIONS'. * The 'all' magic string is unsupported. * @param appPackage The application package to set change permissions on. Defaults to the * package name under test. * @param action One of `PM_ACTION` values if `target` is set to 'pm', otherwise * one of `APPOPS_ACTION` values. * @param target Either 'pm' or 'appops'. The 'appops' one requires * 'adb_shell' server security option to be enabled. Defaults to 'pm'. * @returns Promise that resolves when permissions are changed. * @throws {errors.InvalidArgumentError} If permissions argument is missing, empty, or invalid. */ async function mobileChangePermissions(permissions, appPackage, action, target = PERMISSION_TARGET.PM) { appPackage ??= this.opts.appPackage; action ??= lodash_1.default.toLower(target) === PERMISSION_TARGET.APPOPS ? APPOPS_ACTION.ALLOW : PM_ACTION.GRANT; if (lodash_1.default.isNil(permissions)) { throw new driver_1.errors.InvalidArgumentError(`'permissions' argument is required`); } if (lodash_1.default.isEmpty(permissions)) { throw new driver_1.errors.InvalidArgumentError(`'permissions' argument must not be empty`); } switch (lodash_1.default.toLower(target)) { case PERMISSION_TARGET.PM: return await changePermissionsViaPm.bind(this)(permissions, appPackage, lodash_1.default.toLower(action)); case PERMISSION_TARGET.APPOPS: this.assertFeatureEnabled(utils_1.ADB_SHELL_FEATURE); return await changePermissionsViaAppops.bind(this)(permissions, appPackage, lodash_1.default.toLower(action)); default: throw new driver_1.errors.InvalidArgumentError(`'target' argument must be one of: ${lodash_1.default.values(PERMISSION_TARGET)}`); } } /** * Gets permissions for an Android application. * * @param type One of possible permission types to get. Defaults to 'requested'. * @param appPackage The application package to get permissions for. * Defaults to the package name under test. * @returns Promise that resolves to an array of permission names. * @throws {errors.InvalidArgumentError} If the permission type is unknown. */ async function mobileGetPermissions(type = PERMISSIONS_TYPE.REQUESTED, appPackage) { appPackage ??= this.opts.appPackage; let actionFunc; switch (lodash_1.default.toLower(type)) { case PERMISSIONS_TYPE.REQUESTED: actionFunc = (pkg) => this.adb.getReqPermissions(pkg); break; case PERMISSIONS_TYPE.GRANTED: actionFunc = (pkg) => this.adb.getGrantedPermissions(pkg); break; case PERMISSIONS_TYPE.DENIED: actionFunc = (pkg) => this.adb.getDeniedPermissions(pkg); break; default: throw new driver_1.errors.InvalidArgumentError(`Unknown permissions type '${type}'. ` + `Only ${JSON.stringify(lodash_1.default.values(PERMISSIONS_TYPE))} types are supported`); } return await actionFunc(appPackage); } // #region Internal helpers async function changePermissionsViaPm(permissions, appPackage, action) { if (!lodash_1.default.values(PM_ACTION).includes(action)) { throw new driver_1.errors.InvalidArgumentError(`Unknown action '${action}'. ` + `Only ${JSON.stringify(lodash_1.default.values(PM_ACTION))} actions are supported`); } let affectedPermissions = lodash_1.default.isArray(permissions) ? permissions : [permissions]; if (lodash_1.default.isString(permissions) && lodash_1.default.toLower(permissions) === ALL_PERMISSIONS_MAGIC) { const dumpsys = await this.adb.shell(['dumpsys', 'package', appPackage]); const grantedPermissions = await this.adb.getGrantedPermissions(appPackage, dumpsys); if (action === PM_ACTION.GRANT) { const reqPermissons = await this.adb.getReqPermissions(appPackage, dumpsys); affectedPermissions = lodash_1.default.difference(reqPermissons, grantedPermissions); } else { affectedPermissions = grantedPermissions; } if (lodash_1.default.isEmpty(affectedPermissions)) { this.log.info(`'${appPackage}' contains no permissions to ${action}`); return; } } if (action === PM_ACTION.GRANT) { await this.adb.grantPermissions(appPackage, affectedPermissions); } else { await bluebird_1.default.all(affectedPermissions.map((name) => this.adb.revokePermission(appPackage, name))); } } async function changePermissionsViaAppops(permissions, appPackage, action) { if (!lodash_1.default.values(APPOPS_ACTION).includes(action)) { throw new driver_1.errors.InvalidArgumentError(`Unknown action '${action}'. ` + `Only ${JSON.stringify(lodash_1.default.values(APPOPS_ACTION))} actions are supported`); } if (lodash_1.default.isString(permissions) && lodash_1.default.toLower(permissions) === ALL_PERMISSIONS_MAGIC) { throw new driver_1.errors.InvalidArgumentError(`'${ALL_PERMISSIONS_MAGIC}' permission is only supported for ` + `'${PERMISSION_TARGET.PM}' target. ` + `Check AppOpsManager.java from Android platform sources to get the full list of supported AppOps permissions`); } const promises = (lodash_1.default.isArray(permissions) ? permissions : [permissions]).map((permission) => this.adb.shell(['appops', 'set', appPackage, permission, action])); await bluebird_1.default.all(promises); } //# sourceMappingURL=permissions.js.map