Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(370)

Unified Diff: build/android/pylib/android_commands.py

Issue 10824227: Organize adb install cmds and reboot on failure (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « build/android/adb_install_content_shell ('k') | build/android/pylib/test_package_apk.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: build/android/pylib/android_commands.py
diff --git a/build/android/pylib/android_commands.py b/build/android/pylib/android_commands.py
index da87f39f4dae86130a6507681404fa322fc808f0..fbf144d548a727742f23cebe39377f8544eced4d 100644
--- a/build/android/pylib/android_commands.py
+++ b/build/android/pylib/android_commands.py
@@ -9,11 +9,8 @@ Assumes adb binary is currently on system path.
import collections
import datetime
-import io_stats_parser
import logging
-import optparse
import os
-import pexpect
import re
import shlex
import subprocess
@@ -21,10 +18,12 @@ import sys
import tempfile
import time
+import pexpect
+import io_stats_parser
# adb_interface.py is under ../../../third_party/android_testrunner/
sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), '..',
- '..', '..', 'third_party', 'android_testrunner'))
+ '..', '..', 'third_party', 'android_testrunner'))
import adb_interface
import cmd_helper
import errors # is under ../../../third_party/android_testrunner/errors.py
@@ -51,7 +50,7 @@ JAVA_ASSERT_PROPERTY = 'dalvik.vm.enableassertions'
BOOT_COMPLETE_RE = re.compile(
'android.intent.action.MEDIA_MOUNTED path: /\w+/sdcard\d?'
- + '|' + 'PowerManagerService(\(\s+\d+\))?: bootCompleted')
+ '|PowerManagerService(\(\s+\d+\))?: bootCompleted')
MEMORY_INFO_RE = re.compile('^(?P<key>\w+):\s+(?P<usage_kb>\d+) kB$')
NVIDIA_MEMORY_INFO_RE = re.compile('^\s*(?P<user>\S+)\s*(?P<name>\S+)\s*'
@@ -107,7 +106,7 @@ def GetAttachedDevices():
"""
re_device = re.compile('^([a-zA-Z0-9_:.-]+)\tdevice$', re.MULTILINE)
devices = re_device.findall(cmd_helper.GetCmdOutput(['adb', 'devices']))
- preferred_device = os.environ.get("ANDROID_SERIAL")
+ preferred_device = os.environ.get('ANDROID_SERIAL')
if preferred_device in devices:
devices.remove(preferred_device)
devices.insert(0, preferred_device)
@@ -196,7 +195,7 @@ def _GetFilesFromRecursiveLsOutput(path, ls_output, re_file, utc_offset=None):
utc_delta = datetime.timedelta(hours=int(utc_offset[1:3]),
minutes=int(utc_offset[3:5]))
if utc_offset[0:1] == '-':
- utc_delta = -utc_delta;
+ utc_delta = -utc_delta
lastmod -= utc_delta
files[filename] = (int(file_match.group('size')), lastmod)
return files
@@ -241,7 +240,7 @@ class AndroidCommands(object):
return self._root_enabled
def GetDeviceYear(self):
- """Returns the year information of the date on device"""
+ """Returns the year information of the date on device."""
return self.RunShellCommand('date +%Y')[0]
def WaitForDevicePm(self):
@@ -261,7 +260,7 @@ class AndroidCommands(object):
return # Success
except errors.WaitForResponseTimedOutError as e:
last_err = e
- logging.warning('Restarting and retrying after timeout: %s' % str(e))
+ logging.warning('Restarting and retrying after timeout: %s', e)
retries -= 1
self.RestartShell()
raise last_err # Only reached after max retries, re-raise the last error.
@@ -286,12 +285,14 @@ class AndroidCommands(object):
if os.environ.get('USING_HIVE'):
logging.warning('Ignoring reboot request as we are on hive')
return
- if full_reboot:
+ if full_reboot or not self.IsRootEnabled():
self._adb.SendCommand('reboot')
+ timeout = 300
else:
self.RestartShell()
+ timeout = 120
self.WaitForDevicePm()
- self.StartMonitoringLogcat(timeout=120)
+ self.StartMonitoringLogcat(timeout=timeout)
self.WaitForLogMatch(BOOT_COMPLETE_RE, None)
def Uninstall(self, package):
@@ -308,24 +309,59 @@ class AndroidCommands(object):
logging.info('>>> $' + uninstall_command)
return self._adb.SendCommand(uninstall_command, timeout_time=60)
- def Install(self, package_file_path):
+ def Install(self, package_file_path, reinstall=False):
"""Installs the specified package to the device.
Args:
package_file_path: Path to .apk file to install.
+ reinstall: Whether to reinstall over existing package
Returns:
A status string returned by adb install
"""
assert os.path.isfile(package_file_path)
- install_command = 'install %s' % package_file_path
+ if reinstall:
+ install_cmd = 'install -r %s'
+ else:
+ install_cmd = 'install %s'
+
+ return self._adb.SendCommand(install_cmd % package_file_path,
+ timeout_time=2*60, retry_count=0)
+
+ def ManagedInstall(self, apk_path, keep_data, package_name=None,
+ reboots_on_failure=2):
+ """Installs specified package and reboots device on timeouts.
+
+ Args:
+ apk_path: Path to .apk file to install.
+ keep_data: Whether to keep data if package already exists
+ package_name: Package name (only needed if keep_data=False)
+ reboots_on_failure: number of time to reboot if package manager is frozen.
+
+ Returns:
+ A status string returned by adb install
+ """
+ reboots_left = reboots_on_failure
+ while True:
+ try:
+ if not keep_data:
+ self.Uninstall(package_name)
+ install_status = self.Install(apk_path, keep_data)
+ if 'Success' in install_status:
+ return install_status
+ except errors.WaitForResponseTimedOutError:
+ logging.info('Timout on installing %s' % apk_path)
- logging.info('>>> $' + install_command)
- return self._adb.SendCommand(install_command, timeout_time=2*60)
+ if reboots_left <= 0:
+ raise Exception('Install failure')
+
+ # Force a hard reboot on last attempt
+ self.Reboot(full_reboot=(reboots_left == 1))
+ reboots_left -= 1
def MakeSystemFolderWritable(self):
- """Remounts the /system folder rw. """
+ """Remounts the /system folder rw."""
out = self._adb.SendCommand('remount')
if out.strip() != 'remount succeeded':
raise errors.MsgException('Remount failed: %s' % out)
@@ -388,7 +424,7 @@ class AndroidCommands(object):
wait_period = 5
while not sdcard_ready and attempts * wait_period < timeout_time:
output = self.RunShellCommand('ls /sdcard/')
- if len(output) > 0:
+ if output:
sdcard_ready = True
else:
time.sleep(wait_period)
@@ -417,8 +453,10 @@ class AndroidCommands(object):
"""
logging.info('>>> $' + command)
if "'" in command: logging.warning(command + " contains ' quotes")
- result = self._adb.SendShellCommand("'%s'" % command,
- timeout_time).splitlines()
+ result = self._adb.SendShellCommand(
+ "'%s'" % command, timeout_time).splitlines()
+ if ['error: device not found'] == result:
+ raise errors.DeviceUnresponsiveError('device not found')
if log_result:
logging.info('\n>>> '.join(result))
return result
@@ -480,7 +518,6 @@ class AndroidCommands(object):
cmd += ' --start-profiler ' + trace_file_name
self.RunShellCommand(cmd)
-
def CloseApplication(self, package):
"""Attempt to close down the application, using increasing violence.
@@ -529,7 +566,7 @@ class AndroidCommands(object):
else:
is_equal = local_contents == device_contents
if is_equal:
- logging.info('%s is up-to-date. Skipping file push.' % device_path)
+ logging.info('%s is up-to-date. Skipping file push.', device_path)
return
# They don't match, so remove everything first and then create it.
@@ -645,7 +682,7 @@ class AndroidCommands(object):
self.RunShellCommand('echo 3 > ' + DROP_CACHES)
def StartMonitoringLogcat(self, clear=True, timeout=10, logfile=None,
- filters=[]):
+ filters=None):
"""Starts monitoring the output of logcat, for use with WaitForLogMatch.
Args:
@@ -756,7 +793,7 @@ class AndroidCommands(object):
# Cannot evaluate directly as 0 is a possible value.
# Better to read the self.logcat_process.stdout before killing it,
# Otherwise the communicate may return incomplete output due to pipe break.
- if self.logcat_process.poll() == None:
+ if self.logcat_process.poll() is None:
self.logcat_process.kill()
(output, _) = self.logcat_process.communicate()
self.logcat_process = None
@@ -895,7 +932,7 @@ class AndroidCommands(object):
"""Returns the memory usage for all processes whose name contains |pacakge|.
Args:
- name: A string holding process name to lookup pid list for.
+ package: A string holding process name to lookup pid list for.
Returns:
A tuple containg:
@@ -919,8 +956,7 @@ class AndroidCommands(object):
return usage_dict, smaps
def ProcessesUsingDevicePort(self, device_port):
- """Lists the processes using the specified device port on loopback
- interface.
+ """Lists processes using the specified device port on loopback interface.
Args:
device_port: Port on device we want to check.
@@ -929,7 +965,7 @@ class AndroidCommands(object):
A list of (pid, process_name) tuples using the specified port.
"""
tcp_results = self.RunShellCommand('cat /proc/net/tcp', log_result=False)
- tcp_address = "0100007F:%04X" % device_port
+ tcp_address = '0100007F:%04X' % device_port
pids = []
for single_connect in tcp_results:
connect_results = single_connect.split()
@@ -948,7 +984,7 @@ class AndroidCommands(object):
# Column 1 is the pid
# Column 8 is the Inode in use
if process_results[8] == socket_name:
- pids.append( (int(process_results[1]), process_results[0]) )
+ pids.append((int(process_results[1]), process_results[0]))
break
logging.info('PidsUsingDevicePort: %s', pids)
return pids
« no previous file with comments | « build/android/adb_install_content_shell ('k') | build/android/pylib/test_package_apk.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698