summaryrefslogtreecommitdiffstats
path: root/build/android
diff options
context:
space:
mode:
authorjbudorick <jbudorick@chromium.org>2015-02-17 09:22:56 -0800
committerCommit bot <commit-bot@chromium.org>2015-02-17 17:24:00 +0000
commitd28bff28f9b6621227be975d620f89a0a200ea90 (patch)
tree0290f0705e01f881dbdd2c25abc016f51287b7f4 /build/android
parent759bbd2f8ecc15d79a67a7e368819ab422a10cb3 (diff)
downloadchromium_src-d28bff28f9b6621227be975d620f89a0a200ea90.zip
chromium_src-d28bff28f9b6621227be975d620f89a0a200ea90.tar.gz
chromium_src-d28bff28f9b6621227be975d620f89a0a200ea90.tar.bz2
[Android] Add PIE support for ICS devices.
BUG=458658 Review URL: https://codereview.chromium.org/929603002 Cr-Commit-Position: refs/heads/master@{#316595}
Diffstat (limited to 'build/android')
-rw-r--r--build/android/pylib/device/device_utils.py39
-rwxr-xr-xbuild/android/pylib/device/device_utils_test.py18
-rw-r--r--build/android/pylib/utils/md5sum.py7
-rw-r--r--build/android/pylib/utils/mock_calls.py7
-rwxr-xr-xbuild/android/pylib/utils/mock_calls_test.py16
5 files changed, 82 insertions, 5 deletions
diff --git a/build/android/pylib/device/device_utils.py b/build/android/pylib/device/device_utils.py
index 5dca0e5..eba5e02 100644
--- a/build/android/pylib/device/device_utils.py
+++ b/build/android/pylib/device/device_utils.py
@@ -412,8 +412,8 @@ class DeviceUtils(object):
@decorators.WithTimeoutAndRetriesFromInstance()
def RunShellCommand(self, cmd, check_return=False, cwd=None, env=None,
- as_root=False, single_line=False,
- timeout=None, retries=None):
+ as_root=False, single_line=False, timeout=None,
+ retries=None):
"""Run an ADB shell command.
The command to run |cmd| should be a sequence of program arguments or else
@@ -1332,6 +1332,41 @@ class DeviceUtils(object):
"""Returns the device serial."""
return self.adb.GetDeviceSerial()
+ @decorators.WithTimeoutAndRetriesFromInstance()
+ def GetDevicePieWrapper(self, timeout=None, retries=None):
+ """Gets the absolute path to the run_pie wrapper on the device.
+
+ We have to build our device executables to be PIE, but they need to be able
+ to run on versions of android that don't support PIE (i.e. ICS and below).
+ To do so, we push a wrapper to the device that lets older android versions
+ run PIE executables. This method pushes that wrapper to the device if
+ necessary and returns the path to it.
+
+ This is exposed publicly to allow clients to write scripts using run_pie
+ (e.g. md5sum.CalculateDeviceMd5Sum).
+
+ Args:
+ timeout: timeout in seconds
+ retries: number of retries
+
+ Returns:
+ The path to the PIE wrapper on the device, or an empty string if the
+ device does not require the wrapper.
+ """
+ if 'run_pie' not in self._cache:
+ pie = ''
+ if (self.build_version_sdk <
+ constants.ANDROID_SDK_VERSION_CODES.JELLY_BEAN):
+ host_pie_path = os.path.join(constants.GetOutDirectory(), 'run_pie')
+ if not os.path.exists(host_pie_path):
+ raise device_errors.CommandFailedError('Please build run_pie')
+ pie = '%s/run_pie' % constants.TEST_EXECUTABLE_DIR
+ self.adb.Push(host_pie_path, pie)
+
+ self._cache['run_pie'] = pie
+
+ return self._cache['run_pie']
+
@classmethod
def parallel(cls, devices=None, async=False):
"""Creates a Parallelizer to operate over the provided list of devices.
diff --git a/build/android/pylib/device/device_utils_test.py b/build/android/pylib/device/device_utils_test.py
index 4ef158e..8a25f25 100755
--- a/build/android/pylib/device/device_utils_test.py
+++ b/build/android/pylib/device/device_utils_test.py
@@ -656,6 +656,24 @@ class DeviceUtilsRunShellCommandTest(DeviceUtilsNewImplTest):
self.device.RunShellCommand(cmd, check_return=False))
+class DeviceUtilsGetDevicePieWrapper(DeviceUtilsNewImplTest):
+
+ def testGetDevicePieWrapper_jb(self):
+ with self.assertCall(
+ self.call.device.build_version_sdk(),
+ constants.ANDROID_SDK_VERSION_CODES.JELLY_BEAN):
+ self.assertEqual('', self.device.GetDevicePieWrapper())
+
+ def testGetDevicePieWrapper_ics(self):
+ with self.assertCalls(
+ (self.call.device.build_version_sdk(),
+ constants.ANDROID_SDK_VERSION_CODES.ICE_CREAM_SANDWICH),
+ (mock.call.pylib.constants.GetOutDirectory(), '/foo/bar'),
+ (mock.call.os.path.exists(mock.ANY), True),
+ (self.call.adb.Push(mock.ANY, mock.ANY), '')):
+ self.assertNotEqual('', self.device.GetDevicePieWrapper())
+
+
@mock.patch('time.sleep', mock.Mock())
class DeviceUtilsKillAllTest(DeviceUtilsNewImplTest):
diff --git a/build/android/pylib/utils/md5sum.py b/build/android/pylib/utils/md5sum.py
index 4d0d703..da3cd15 100644
--- a/build/android/pylib/utils/md5sum.py
+++ b/build/android/pylib/utils/md5sum.py
@@ -19,7 +19,7 @@ MD5SUM_DEVICE_BIN_PATH = MD5SUM_DEVICE_LIB_PATH + 'md5sum_bin'
MD5SUM_DEVICE_SCRIPT_FORMAT = (
'test -f {path} -o -d {path} '
- '&& LD_LIBRARY_PATH={md5sum_lib} {md5sum_bin} {path}')
+ '&& LD_LIBRARY_PATH={md5sum_lib} {device_pie_wrapper} {md5sum_bin} {path}')
def CalculateHostMd5Sums(paths):
@@ -56,12 +56,15 @@ def CalculateDeviceMd5Sums(paths, device):
MD5SUM_DEVICE_LIB_PATH)
out = []
+
with tempfile.NamedTemporaryFile() as md5sum_script_file:
with device_temp_file.DeviceTempFile(
device.adb) as md5sum_device_script_file:
+ device_pie_wrapper = device.GetDevicePieWrapper()
md5sum_script = (
MD5SUM_DEVICE_SCRIPT_FORMAT.format(
path=p, md5sum_lib=MD5SUM_DEVICE_LIB_PATH,
+ device_pie_wrapper=device_pie_wrapper,
md5sum_bin=MD5SUM_DEVICE_BIN_PATH)
for p in paths)
md5sum_script_file.write('; '.join(md5sum_script))
@@ -69,5 +72,5 @@ def CalculateDeviceMd5Sums(paths, device):
device.adb.Push(md5sum_script_file.name, md5sum_device_script_file.name)
out = device.RunShellCommand(['sh', md5sum_device_script_file.name])
- return [HashAndPath(*l.split(None, 1)) for l in out]
+ return [HashAndPath(*l.split(None, 1)) for l in out if l]
diff --git a/build/android/pylib/utils/mock_calls.py b/build/android/pylib/utils/mock_calls.py
index fab9f2b..3052b0d 100644
--- a/build/android/pylib/utils/mock_calls.py
+++ b/build/android/pylib/utils/mock_calls.py
@@ -110,7 +110,12 @@ class TestCase(unittest.TestCase):
if call.name.startswith('self.'):
target = self.call_target(call.parent)
_, attribute = call.name.rsplit('.', 1)
- return mock.patch.object(target, attribute, **kwargs)
+ if (hasattr(type(target), attribute)
+ and isinstance(getattr(type(target), attribute), property)):
+ return mock.patch.object(
+ type(target), attribute, new_callable=mock.PropertyMock, **kwargs)
+ else:
+ return mock.patch.object(target, attribute, **kwargs)
else:
return mock.patch(call.name, **kwargs)
diff --git a/build/android/pylib/utils/mock_calls_test.py b/build/android/pylib/utils/mock_calls_test.py
index 1b474af..4dbafd4 100755
--- a/build/android/pylib/utils/mock_calls_test.py
+++ b/build/android/pylib/utils/mock_calls_test.py
@@ -38,6 +38,11 @@ class _DummyAdb(object):
def Reboot(self):
logging.debug('(device %s) rebooted!', self)
+ @property
+ def build_version_sdk(self):
+ logging.debug('(device %s) getting build_version_sdk', self)
+ return constants.ANDROID_SDK_VERSION_CODES.LOLLIPOP
+
class TestCaseWithAssertCallsTest(mock_calls.TestCase):
def setUp(self):
@@ -91,6 +96,17 @@ class TestCaseWithAssertCallsTest(mock_calls.TestCase):
with self.assertRaises(ValueError):
self.adb.Shell('echo hello')
+ def testPatchCall_property(self):
+ self.assertEquals(constants.ANDROID_SDK_VERSION_CODES.LOLLIPOP,
+ self.adb.build_version_sdk)
+ with self.patch_call(
+ self.call.adb.build_version_sdk,
+ return_value=constants.ANDROID_SDK_VERSION_CODES.KITKAT):
+ self.assertEquals(constants.ANDROID_SDK_VERSION_CODES.KITKAT,
+ self.adb.build_version_sdk)
+ self.assertEquals(constants.ANDROID_SDK_VERSION_CODES.LOLLIPOP,
+ self.adb.build_version_sdk)
+
def testAssertCalls_succeeds_simple(self):
self.assertEquals(42, self.get_answer())
with self.assertCall(self.call.get_answer(), 123):