| Index: build/android/devil/android/device_utils.py
|
| diff --git a/build/android/devil/android/device_utils.py b/build/android/devil/android/device_utils.py
|
| index c35bc264ef9e48da1cfbcb10aa4df75fbaf2c42f..8a70c3c9e539551c8171dcbd29784933f82a9533 100644
|
| --- a/build/android/devil/android/device_utils.py
|
| +++ b/build/android/devil/android/device_utils.py
|
| @@ -53,30 +53,6 @@ _DEFAULT_RETRIES = 3
|
| # the timeout_retry decorators.
|
| DEFAULT = object()
|
|
|
| -_CONTROL_CHARGING_COMMANDS = [
|
| - {
|
| - # Nexus 4
|
| - 'witness_file': '/sys/module/pm8921_charger/parameters/disabled',
|
| - 'enable_command': 'echo 0 > /sys/module/pm8921_charger/parameters/disabled',
|
| - 'disable_command':
|
| - 'echo 1 > /sys/module/pm8921_charger/parameters/disabled',
|
| - },
|
| - {
|
| - # Nexus 5
|
| - # Setting the HIZ bit of the bq24192 causes the charger to actually ignore
|
| - # energy coming from USB. Setting the power_supply offline just updates the
|
| - # Android system to reflect that.
|
| - 'witness_file': '/sys/kernel/debug/bq24192/INPUT_SRC_CONT',
|
| - 'enable_command': (
|
| - 'echo 0x4A > /sys/kernel/debug/bq24192/INPUT_SRC_CONT && '
|
| - 'echo 1 > /sys/class/power_supply/usb/online'),
|
| - 'disable_command': (
|
| - 'echo 0xCA > /sys/kernel/debug/bq24192/INPUT_SRC_CONT && '
|
| - 'chmod 644 /sys/class/power_supply/usb/online && '
|
| - 'echo 0 > /sys/class/power_supply/usb/online'),
|
| - },
|
| -]
|
| -
|
| _RESTART_ADBD_SCRIPT = """
|
| trap '' HUP
|
| trap '' TERM
|
| @@ -88,6 +64,34 @@ _RESTART_ADBD_SCRIPT = """
|
| restart &
|
| """
|
|
|
| +# Not all permissions can be set.
|
| +_PERMISSIONS_BLACKLIST = [
|
| + 'android.permission.ACCESS_MOCK_LOCATION',
|
| + 'android.permission.ACCESS_NETWORK_STATE',
|
| + 'android.permission.BLUETOOTH',
|
| + 'android.permission.BLUETOOTH_ADMIN',
|
| + 'android.permission.INTERNET',
|
| + 'android.permission.MANAGE_ACCOUNTS',
|
| + 'android.permission.MODIFY_AUDIO_SETTINGS',
|
| + 'android.permission.NFC',
|
| + 'android.permission.READ_SYNC_SETTINGS',
|
| + 'android.permission.READ_SYNC_STATS',
|
| + 'android.permission.USE_CREDENTIALS',
|
| + 'android.permission.VIBRATE',
|
| + 'android.permission.WAKE_LOCK',
|
| + 'android.permission.WRITE_SYNC_SETTINGS',
|
| + 'com.android.browser.permission.READ_HISTORY_BOOKMARKS',
|
| + 'com.android.browser.permission.WRITE_HISTORY_BOOKMARKS',
|
| + 'com.android.launcher.permission.INSTALL_SHORTCUT',
|
| + 'com.chrome.permission.DEVICE_EXTRAS',
|
| + 'com.google.android.apps.chrome.permission.C2D_MESSAGE',
|
| + 'com.google.android.apps.chrome.permission.READ_WRITE_BOOKMARK_FOLDERS',
|
| + 'com.google.android.apps.chrome.TOS_ACKED',
|
| + 'com.google.android.c2dm.permission.RECEIVE',
|
| + 'com.google.android.providers.gsf.permission.READ_GSERVICES',
|
| + 'com.sec.enterprise.knox.MDM_CONTENT_PROVIDER',
|
| +]
|
| +
|
| _CURRENT_FOCUS_CRASH_RE = re.compile(
|
| r'\s*mCurrentFocus.*Application (Error|Not Responding): (\S+)}')
|
|
|
| @@ -517,13 +521,16 @@ class DeviceUtils(object):
|
| @decorators.WithTimeoutAndRetriesDefaults(
|
| INSTALL_DEFAULT_TIMEOUT,
|
| INSTALL_DEFAULT_RETRIES)
|
| - def Install(self, apk_path, reinstall=False, timeout=None, retries=None):
|
| + def Install(self, apk_path, reinstall=False, permissions=None, timeout=None,
|
| + retries=None):
|
| """Install an APK.
|
|
|
| Noop if an identical APK is already installed.
|
|
|
| Args:
|
| apk_path: A string containing the path to the APK to install.
|
| + permissions: Set of permissions to set. If not set, finds permissions with
|
| + apk helper. To set no permissions, pass [].
|
| reinstall: A boolean indicating if we should keep any existing app data.
|
| timeout: timeout in seconds
|
| retries: number of retries
|
| @@ -555,6 +562,12 @@ class DeviceUtils(object):
|
| self.adb.Install(apk_path, reinstall=reinstall)
|
| self._cache['package_apk_checksums'][package_name] = host_checksums
|
|
|
| + if (permissions is None
|
| + and self.build_version_sdk >= version_codes.MARSHMALLOW):
|
| + permissions = apk_helper.ApkHelper(apk_path).GetPermissions()
|
| + self.GrantPermissions(package_name, permissions)
|
| +
|
| +
|
| @decorators.WithTimeoutAndRetriesDefaults(
|
| INSTALL_DEFAULT_TIMEOUT,
|
| INSTALL_DEFAULT_RETRIES)
|
| @@ -1934,3 +1947,24 @@ class DeviceUtils(object):
|
| self.WriteFile(script.name, _RESTART_ADBD_SCRIPT)
|
| self.RunShellCommand(['source', script.name], as_root=True)
|
| self.adb.WaitForDevice()
|
| +
|
| + @decorators.WithTimeoutAndRetriesFromInstance()
|
| + def GrantPermissions(self, package, permissions, timeout=None, retries=None):
|
| + # Permissions only need to be set on M and above because of the changes to
|
| + # the permission model.
|
| + if not permissions or self.build_version_sdk < version_codes.MARSHMALLOW:
|
| + return
|
| + # TODO(rnephew): After permission blacklist is complete, switch to using
|
| + # &&s instead of ;s.
|
| + cmd = ''
|
| + logging.info('Setting permissions for %s', package)
|
| + for p in permissions:
|
| + if p not in _PERMISSIONS_BLACKLIST:
|
| + cmd += 'pm grant %s %s;' % (package, p)
|
| + logging.info(' %s', p)
|
| + if cmd:
|
| + output = self.RunShellCommand(cmd)
|
| + if output:
|
| + logging.warning('Possible problem when granting permissions. Blacklist '
|
| + 'may need to be updated.')
|
| + logging.warning(output)
|
|
|