[Android] Set permission when installing apks.
To support M testing, we need to explicilty grant permissions to apps when we install them. BUG= Review URL: https://codereview.chromium.org/1316803004 Cr-Original-Commit-Position: refs/heads/master@{#347787} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: de468d72d9eeeb86b439e6a7c877de0ebb349fca
This commit is contained in:
Родитель
f536e96df0
Коммит
f526e23829
|
@ -110,6 +110,13 @@ class ApkHelper(object):
|
|||
return self._package_name
|
||||
raise Exception('Failed to determine package name of %s' % self._apk_path)
|
||||
|
||||
def GetPermissions(self):
|
||||
manifest_info = self._GetManifest()
|
||||
try:
|
||||
return manifest_info['manifest']['uses-permission']['android:name']
|
||||
except KeyError:
|
||||
return []
|
||||
|
||||
def GetSplitName(self):
|
||||
"""Returns the name of the split of the apk."""
|
||||
if self._split_name:
|
||||
|
|
|
@ -51,30 +51,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
|
||||
|
@ -86,6 +62,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+)}')
|
||||
|
||||
|
@ -515,13 +519,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
|
||||
|
@ -553,6 +560,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)
|
||||
|
@ -1940,3 +1953,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)
|
||||
|
|
|
@ -548,13 +548,51 @@ class DeviceUtilsRebootTest(DeviceUtilsTest):
|
|||
class DeviceUtilsInstallTest(DeviceUtilsTest):
|
||||
|
||||
def testInstall_noPriorInstall(self):
|
||||
with self.patch_call(self.call.device.build_version_sdk, return_value=23):
|
||||
with self.assertCalls(
|
||||
(mock.call.devil.android.apk_helper.GetPackageName(
|
||||
'/fake/test/app.apk'),
|
||||
'test.package'),
|
||||
(self.call.device._GetApplicationPathsInternal('test.package'), []),
|
||||
self.call.adb.Install('/fake/test/app.apk', reinstall=False),
|
||||
(mock.call.devil.android.apk_helper.ApkHelper.GetPermissions(),
|
||||
['p1']),
|
||||
(self.call.device.GrantPermissions('test.package', ['p1']), [])):
|
||||
self.device.Install('/fake/test/app.apk', retries=0)
|
||||
|
||||
def testIntsall_permissionsPreM(self):
|
||||
with self.patch_call(self.call.device.build_version_sdk, return_value=20):
|
||||
with self.assertCalls(
|
||||
(mock.call.devil.android.apk_helper.GetPackageName(
|
||||
'/fake/test/app.apk'),
|
||||
'test.package'),
|
||||
(self.call.device._GetApplicationPathsInternal('test.package'), []),
|
||||
(self.call.adb.Install('/fake/test/app.apk', reinstall=False))):
|
||||
self.device.Install('/fake/test/app.apk', retries=0)
|
||||
|
||||
def testInstall_findPermissions(self):
|
||||
with self.patch_call(self.call.device.build_version_sdk, return_value=23):
|
||||
with self.assertCalls(
|
||||
(mock.call.devil.android.apk_helper.GetPackageName(
|
||||
'/fake/test/app.apk'),
|
||||
'test.package'),
|
||||
(self.call.device._GetApplicationPathsInternal('test.package'), []),
|
||||
(self.call.adb.Install('/fake/test/app.apk', reinstall=False)),
|
||||
(mock.call.devil.android.apk_helper.ApkHelper.GetPermissions(),
|
||||
['p1']),
|
||||
(self.call.device.GrantPermissions('test.package', ['p1']), [])):
|
||||
self.device.Install('/fake/test/app.apk', retries=0)
|
||||
|
||||
def testInstall_passPermissions(self):
|
||||
with self.assertCalls(
|
||||
(mock.call.devil.android.apk_helper.GetPackageName(
|
||||
'/fake/test/app.apk'),
|
||||
'test.package'),
|
||||
(self.call.device._GetApplicationPathsInternal('test.package'), []),
|
||||
self.call.adb.Install('/fake/test/app.apk', reinstall=False)):
|
||||
self.device.Install('/fake/test/app.apk', retries=0)
|
||||
(self.call.adb.Install('/fake/test/app.apk', reinstall=False)),
|
||||
(self.call.device.GrantPermissions('test.package', ['p1', 'p2']), [])):
|
||||
self.device.Install(
|
||||
'/fake/test/app.apk', retries=0, permissions=['p1', 'p2'])
|
||||
|
||||
def testInstall_differentPriorInstall(self):
|
||||
with self.assertCalls(
|
||||
|
@ -568,7 +606,7 @@ class DeviceUtilsInstallTest(DeviceUtilsTest):
|
|||
(['/fake/test/app.apk'], None)),
|
||||
self.call.adb.Uninstall('test.package', False),
|
||||
self.call.adb.Install('/fake/test/app.apk', reinstall=False)):
|
||||
self.device.Install('/fake/test/app.apk', retries=0)
|
||||
self.device.Install('/fake/test/app.apk', retries=0, permissions=[])
|
||||
|
||||
def testInstall_differentPriorInstall_reinstall(self):
|
||||
with self.assertCalls(
|
||||
|
@ -581,7 +619,8 @@ class DeviceUtilsInstallTest(DeviceUtilsTest):
|
|||
['/fake/test/app.apk']),
|
||||
(['/fake/test/app.apk'], None)),
|
||||
self.call.adb.Install('/fake/test/app.apk', reinstall=True)):
|
||||
self.device.Install('/fake/test/app.apk', reinstall=True, retries=0)
|
||||
self.device.Install(
|
||||
'/fake/test/app.apk', reinstall=True, retries=0, permissions=[])
|
||||
|
||||
def testInstall_identicalPriorInstall(self):
|
||||
with self.assertCalls(
|
||||
|
@ -593,7 +632,7 @@ class DeviceUtilsInstallTest(DeviceUtilsTest):
|
|||
(self.call.device._ComputeStaleApks('test.package',
|
||||
['/fake/test/app.apk']),
|
||||
([], None))):
|
||||
self.device.Install('/fake/test/app.apk', retries=0)
|
||||
self.device.Install('/fake/test/app.apk', retries=0, permissions=[])
|
||||
|
||||
def testInstall_fails(self):
|
||||
with self.assertCalls(
|
||||
|
@ -2014,6 +2053,33 @@ class DeviceUtilsRestartAdbdTest(DeviceUtilsTest):
|
|||
self.device.RestartAdbd()
|
||||
|
||||
|
||||
class DeviceUtilsGrantPermissionsTest(DeviceUtilsTest):
|
||||
|
||||
def testGrantPermissions_none(self):
|
||||
self.device.GrantPermissions('package', [])
|
||||
|
||||
def testGrantPermissions_underM(self):
|
||||
with self.patch_call(self.call.device.build_version_sdk,
|
||||
return_value=20):
|
||||
self.device.GrantPermissions('package', ['p1'])
|
||||
|
||||
def testGrantPermissions_one(self):
|
||||
permissions_cmd = 'pm grant package p1;'
|
||||
with self.patch_call(self.call.device.build_version_sdk,
|
||||
return_value=23):
|
||||
with self.assertCalls(
|
||||
(self.call.device.RunShellCommand(permissions_cmd), [])):
|
||||
self.device.GrantPermissions('package', ['p1'])
|
||||
|
||||
def testGrantPermissions_multiple(self):
|
||||
permissions_cmd = 'pm grant package p1;pm grant package p2;'
|
||||
with self.patch_call(self.call.device.build_version_sdk,
|
||||
return_value=23):
|
||||
with self.assertCalls(
|
||||
(self.call.device.RunShellCommand(permissions_cmd), [])):
|
||||
self.device.GrantPermissions('package', ['p1', 'p2'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
logging.getLogger().setLevel(logging.DEBUG)
|
||||
unittest.main(verbosity=2)
|
||||
|
|
|
@ -144,6 +144,7 @@ class GtestTestInstance(test_instance.TestInstance):
|
|||
self._activity = helper.GetActivityName()
|
||||
self._package = helper.GetPackageName()
|
||||
self._runner = helper.GetInstrumentationName()
|
||||
self._permissions = helper.GetPermissions()
|
||||
self._extras = {
|
||||
_EXTRA_NATIVE_TEST_ACTIVITY: self._activity,
|
||||
}
|
||||
|
@ -319,6 +320,10 @@ class GtestTestInstance(test_instance.TestInstance):
|
|||
def package(self):
|
||||
return self._package
|
||||
|
||||
@property
|
||||
def permissions(self):
|
||||
return self._permissions
|
||||
|
||||
@property
|
||||
def runner(self):
|
||||
return self._runner
|
||||
|
|
|
@ -55,12 +55,13 @@ class _ApkDelegate(object):
|
|||
self._apk = test_instance.apk
|
||||
self._package = test_instance.package
|
||||
self._runner = test_instance.runner
|
||||
self._permissions = test_instance.permissions
|
||||
|
||||
self._component = '%s/%s' % (self._package, self._runner)
|
||||
self._extras = test_instance.extras
|
||||
|
||||
def Install(self, device):
|
||||
device.Install(self._apk)
|
||||
device.Install(self._apk, permissions=self._permissions)
|
||||
|
||||
def Run(self, test, device, flags=None, **kwargs):
|
||||
extras = dict(self._extras)
|
||||
|
|
|
@ -15,6 +15,7 @@ from pylib.base import base_test_runner
|
|||
from pylib.local import local_test_server_spawner
|
||||
from pylib.perf import perf_control
|
||||
|
||||
|
||||
# Test case statuses.
|
||||
RE_RUN = re.compile('\\[ RUN \\] ?(.*)\r\n')
|
||||
RE_FAIL = re.compile('\\[ FAILED \\] ?(.*?)( \\((\\d+) ms\\))?\r\r\n')
|
||||
|
|
|
@ -138,11 +138,13 @@ class InstrumentationTestInstance(test_instance.TestInstance):
|
|||
super(InstrumentationTestInstance, self).__init__()
|
||||
|
||||
self._apk_under_test = None
|
||||
self._apk_under_test_permissions = None
|
||||
self._package_info = None
|
||||
self._suite = None
|
||||
self._test_apk = None
|
||||
self._test_jar = None
|
||||
self._test_package = None
|
||||
self._test_permissions = None
|
||||
self._test_runner = None
|
||||
self._test_support_apk = None
|
||||
self._initializeApkAttributes(args, error_func)
|
||||
|
@ -178,6 +180,9 @@ class InstrumentationTestInstance(test_instance.TestInstance):
|
|||
if not os.path.exists(self._apk_under_test):
|
||||
error_func('Unable to find APK under test: %s' % self._apk_under_test)
|
||||
|
||||
apk = apk_helper.ApkHelper(self._apk_under_test)
|
||||
self._apk_under_test_permissions = apk.GetPermissions()
|
||||
|
||||
if args.test_apk.endswith('.apk'):
|
||||
self._suite = os.path.splitext(os.path.basename(args.test_apk))[0]
|
||||
self._test_apk = args.test_apk
|
||||
|
@ -201,6 +206,7 @@ class InstrumentationTestInstance(test_instance.TestInstance):
|
|||
|
||||
apk = apk_helper.ApkHelper(self.test_apk)
|
||||
self._test_package = apk.GetPackageName()
|
||||
self._test_permissions = apk.GetPermissions()
|
||||
self._test_runner = apk.GetInstrumentationName()
|
||||
|
||||
self._package_info = None
|
||||
|
@ -283,6 +289,10 @@ class InstrumentationTestInstance(test_instance.TestInstance):
|
|||
def apk_under_test(self):
|
||||
return self._apk_under_test
|
||||
|
||||
@property
|
||||
def apk_under_test_permissions(self):
|
||||
return self._apk_under_test_permissions
|
||||
|
||||
@property
|
||||
def flags(self):
|
||||
return self._flags
|
||||
|
@ -323,6 +333,10 @@ class InstrumentationTestInstance(test_instance.TestInstance):
|
|||
def test_package(self):
|
||||
return self._test_package
|
||||
|
||||
@property
|
||||
def test_permissions(self):
|
||||
return self._test_permissions
|
||||
|
||||
@property
|
||||
def test_runner(self):
|
||||
return self._test_runner
|
||||
|
|
|
@ -39,4 +39,3 @@ class TestPackage(test_jar.TestJar):
|
|||
if (self._test_support_apk_path and
|
||||
os.path.exists(self._test_support_apk_path)):
|
||||
device.Install(self._test_support_apk_path)
|
||||
|
||||
|
|
|
@ -64,8 +64,10 @@ class LocalDeviceInstrumentationTestRun(
|
|||
return d
|
||||
|
||||
def individual_device_set_up(dev, host_device_tuples):
|
||||
dev.Install(self._test_instance.apk_under_test)
|
||||
dev.Install(self._test_instance.test_apk)
|
||||
dev.Install(self._test_instance.apk_under_test,
|
||||
permissions=self._test_instance.apk_under_test_permissions)
|
||||
dev.Install(self._test_instance.test_apk,
|
||||
permissions=self._test_instance.test_permissions)
|
||||
|
||||
external_storage = dev.GetExternalStoragePath()
|
||||
host_device_tuples = [
|
||||
|
|
Загрузка…
Ссылка в новой задаче