зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset cc61b087dfb1 (bug 1145680) for possibly breaking gij(8) CLOSED TREE
This commit is contained in:
Родитель
bcd09a7c72
Коммит
5b2b80e960
|
@ -169,39 +169,31 @@ Device Shell methods
|
|||
|
||||
Informational methods
|
||||
+++++++++++++++++++++
|
||||
.. automethod:: ADBDevice.clear_logcat
|
||||
.. automethod:: ADBDevice.get_battery_percentage
|
||||
.. automethod:: ADBDevice.get_info
|
||||
.. automethod:: ADBDevice.get_logcat
|
||||
.. automethod:: ADBDevice.get_prop
|
||||
.. automethod:: ADBDevice.get_state
|
||||
|
||||
System control methods
|
||||
++++++++++++++++++++++
|
||||
.. automethod:: ADBDevice.is_device_ready
|
||||
.. automethod:: ADBDevice.reboot
|
||||
.. automethod:: ADBDevice.clear_logcat(self, timeout=None)
|
||||
.. automethod:: ADBDevice.get_logcat(self, filterSpecs=["dalvikvm:I", "ConnectivityService:S", "WifiMonitor:S", "WifiStateTracker:S", "wpa_supplicant:S", "NetworkStateTracker:S"], format="time", filter_out_regexps=[], timeout=None)
|
||||
.. automethod:: ADBDevice.get_prop(self, prop, timeout=None)
|
||||
.. automethod:: ADBDevice.get_state(self, timeout=None)
|
||||
|
||||
File management methods
|
||||
+++++++++++++++++++++++
|
||||
.. automethod:: ADBDevice.chmod
|
||||
.. automethod:: ADBDevice.cp
|
||||
.. automethod:: ADBDevice.exists
|
||||
.. automethod:: ADBDevice.is_dir
|
||||
.. automethod:: ADBDevice.is_file
|
||||
.. automethod:: ADBDevice.list_files
|
||||
.. automethod:: ADBDevice.mkdir
|
||||
.. automethod:: ADBDevice.mv
|
||||
.. automethod:: ADBDevice.push
|
||||
.. automethod:: ADBDevice.rm
|
||||
.. automethod:: ADBDevice.rmdir
|
||||
.. automethod:: ADBDevice.chmod(self, path, recursive=False, mask="777", timeout=None, root=False)
|
||||
.. automethod:: ADBDevice.exists(self, path, timeout=None, root=False)
|
||||
.. automethod:: ADBDevice.is_dir(self, path, timeout=None, root=False)
|
||||
.. automethod:: ADBDevice.is_file(self, path, timeout=None, root=False)
|
||||
.. automethod:: ADBDevice.list_files(self, path, timeout=None, root=False)
|
||||
.. automethod:: ADBDevice.mkdir(self, path, parents=False, timeout=None, root=False)
|
||||
.. automethod:: ADBDevice.push(self, local, remote, timeout=None)
|
||||
.. automethod:: ADBDevice.rm(self, path, recursive=False, force=False, timeout=None, root=False)
|
||||
.. automethod:: ADBDevice.rmdir(self, path, timeout=None, root=False)
|
||||
.. autoattribute:: ADBDevice.test_root
|
||||
|
||||
Process management methods
|
||||
++++++++++++++++++++++++++
|
||||
.. automethod:: ADBDevice.get_process_list
|
||||
.. automethod:: ADBDevice.kill
|
||||
.. automethod:: ADBDevice.pkill
|
||||
.. automethod:: ADBDevice.process_exist
|
||||
.. automethod:: ADBDevice.get_process_list(self, timeout=None)
|
||||
.. automethod:: ADBDevice.kill(self, pids, sig=None, attempts=3, wait=5, timeout=None, root=False)
|
||||
.. automethod:: ADBDevice.pkill(self, appname, sig=None, attempts=3, wait=5, timeout=None, root=False)
|
||||
.. automethod:: ADBDevice.process_exist(self, process_name, timeout=None)
|
||||
|
||||
|
||||
ADBAndroid
|
||||
``````````
|
||||
|
@ -209,32 +201,24 @@ ADBAndroid
|
|||
|
||||
Informational methods
|
||||
+++++++++++++++++++++
|
||||
.. automethod:: ADBAndroid.get_battery_percentage
|
||||
.. automethod:: ADBAndroid.get_battery_percentage(self, timeout=None)
|
||||
|
||||
System control methods
|
||||
++++++++++++++++++++++
|
||||
.. automethod:: ADBAndroid.is_device_ready
|
||||
.. automethod:: ADBAndroid.power_on
|
||||
.. automethod:: ADBAndroid.is_device_ready(self, timeout=None)
|
||||
.. automethod:: ADBAndroid.power_on(self, timeout=None)
|
||||
.. automethod:: ADBAndroid.reboot(self, timeout=None)
|
||||
|
||||
Application management methods
|
||||
++++++++++++++++++++++++++++++
|
||||
.. automethod:: ADBAndroid.install_app
|
||||
.. automethod:: ADBAndroid.is_app_installed
|
||||
.. automethod:: ADBAndroid.launch_application
|
||||
.. automethod:: ADBAndroid.launch_fennec
|
||||
.. automethod:: ADBAndroid.stop_application
|
||||
.. automethod:: ADBAndroid.uninstall_app
|
||||
.. automethod:: ADBAndroid.update_app
|
||||
.. automethod:: ADBAndroid.install_app(self, apk_path, timeout=None)
|
||||
.. automethod:: ADBAndroid.is_app_installed(self, app_name, timeout=None)
|
||||
.. automethod:: ADBAndroid.launch_application(self, app_name, activity_name, intent, url=None, extras=None, wait=True, fail_if_running=True, timeout=None)
|
||||
.. automethod:: ADBAndroid.launch_fennec(self, app_name, intent="android.intent.action.VIEW", moz_env=None, extra_args=None, url=None, wait=True, fail_if_running=True, timeout=None)
|
||||
.. automethod:: ADBAndroid.stop_application(self, app_name, timeout=None, root=False)
|
||||
.. automethod:: ADBAndroid.uninstall_app(self, app_name, reboot=False, timeout=None)
|
||||
.. automethod:: ADBAndroid.update_app(self, apk_path, timeout=None)
|
||||
|
||||
ADBB2G
|
||||
``````
|
||||
.. autoclass:: ADBB2G
|
||||
|
||||
Informational methods
|
||||
+++++++++++++++++++++
|
||||
.. automethod:: ADBB2G.get_battery_percentage
|
||||
.. automethod:: ADBB2G.get_info
|
||||
.. automethod:: ADBB2G.get_memory_total
|
||||
|
||||
ADBProcess
|
||||
``````````
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
from adb import ADBError, ADBRootError, ADBTimeoutError, ADBProcess, ADBCommand, ADBHost, ADBDevice
|
||||
from adb_android import ADBAndroid
|
||||
from adb_b2g import ADBB2G
|
||||
from devicemanager import DeviceManager, DMError, ZeroconfListener
|
||||
from devicemanagerADB import DeviceManagerADB
|
||||
from devicemanagerSUT import DeviceManagerSUT
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import abc
|
||||
import os
|
||||
import posixpath
|
||||
import re
|
||||
|
@ -13,7 +12,9 @@ import traceback
|
|||
|
||||
|
||||
class ADBProcess(object):
|
||||
"""ADBProcess encapsulates the data related to executing the adb process."""
|
||||
"""ADBProcess encapsulates the data related to executing the adb process.
|
||||
|
||||
"""
|
||||
def __init__(self, args):
|
||||
#: command argument argument list.
|
||||
self.args = args
|
||||
|
@ -63,6 +64,7 @@ class ADBError(Exception):
|
|||
device either exited with a non-zero exitcode or when an
|
||||
unexpected error condition has occurred. Generally, ADBErrors can
|
||||
be handled and the device can continue to be used.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
|
@ -71,6 +73,7 @@ class ADBRootError(Exception):
|
|||
root but the device does not support it. This error is fatal since
|
||||
there is no recovery possible by the script. You must either root
|
||||
your device or change your scripts to not require running as root.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
|
@ -91,6 +94,7 @@ class ADBTimeoutError(Exception):
|
|||
|
||||
* Rebooting the device manually.
|
||||
* Rebooting the host.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
|
@ -113,6 +117,7 @@ class ADBCommand(object):
|
|||
adbcommand = ADBCommand()
|
||||
except NotImplementedError:
|
||||
print "ADBCommand can not be instantiated."
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
|
@ -131,6 +136,7 @@ class ADBCommand(object):
|
|||
|
||||
:raises: * ADBError
|
||||
* ADBTimeoutError
|
||||
|
||||
"""
|
||||
if self.__class__ == ADBCommand:
|
||||
raise NotImplementedError
|
||||
|
@ -201,6 +207,7 @@ class ADBCommand(object):
|
|||
|
||||
It is the caller's responsibilty to clean up by closing
|
||||
the stdout and stderr temporary files.
|
||||
|
||||
"""
|
||||
args = [self._adb_path]
|
||||
if self._adb_host:
|
||||
|
@ -250,6 +257,7 @@ class ADBCommand(object):
|
|||
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
adb_process = None
|
||||
try:
|
||||
|
@ -292,6 +300,7 @@ class ADBHost(ADBCommand):
|
|||
|
||||
adbhost = ADBHost()
|
||||
adbhost.start_server()
|
||||
|
||||
"""
|
||||
def __init__(self,
|
||||
adb='adb',
|
||||
|
@ -309,6 +318,7 @@ class ADBHost(ADBCommand):
|
|||
|
||||
:raises: * ADBError
|
||||
* ADBTimeoutError
|
||||
|
||||
"""
|
||||
ADBCommand.__init__(self, adb=adb, adb_host=adb_host,
|
||||
adb_port=adb_port, logger_name=logger_name,
|
||||
|
@ -343,6 +353,7 @@ class ADBHost(ADBCommand):
|
|||
|
||||
It is the caller's responsibilty to clean up by closing
|
||||
the stdout and stderr temporary files.
|
||||
|
||||
"""
|
||||
return ADBCommand.command(self, cmds, timeout=timeout)
|
||||
|
||||
|
@ -361,6 +372,7 @@ class ADBHost(ADBCommand):
|
|||
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
return ADBCommand.command_output(self, cmds, timeout=timeout)
|
||||
|
||||
|
@ -392,6 +404,7 @@ class ADBHost(ADBCommand):
|
|||
while true; do
|
||||
adb -a fork-server server
|
||||
done
|
||||
|
||||
"""
|
||||
self.command_output(["start-server"], timeout=timeout)
|
||||
|
||||
|
@ -405,6 +418,7 @@ class ADBHost(ADBCommand):
|
|||
specified, the value set in the ADBHost constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
self.command_output(["kill-server"], timeout=timeout)
|
||||
|
||||
|
@ -430,6 +444,7 @@ class ADBHost(ADBCommand):
|
|||
|
||||
[{'device_serial': 'b313b945', 'state': 'device', 'product': 'd2vzw',
|
||||
'usb': '1-7', 'device': 'd2vzw', 'model': 'SCH_I535' }]
|
||||
|
||||
"""
|
||||
# b313b945 device usb:1-7 product:d2vzw model:SCH_I535 device:d2vzw
|
||||
# from Android system/core/adb/transport.c statename()
|
||||
|
@ -458,12 +473,22 @@ class ADBHost(ADBCommand):
|
|||
|
||||
|
||||
class ADBDevice(ADBCommand):
|
||||
"""ADBDevice is an abstract base class which provides methods which
|
||||
can be used to interact with the associated Android or B2G based
|
||||
device. It must be used via one of the concrete implementations in
|
||||
:class:`ADBAndroid` or :class:`ADBB2G`.
|
||||
"""ADBDevice provides methods which can be used to interact with
|
||||
the associated Android-based device.
|
||||
|
||||
Android specific features such as Application management are not
|
||||
included but are provided via the ADBAndroid interface.
|
||||
|
||||
::
|
||||
|
||||
from mozdevice import ADBDevice
|
||||
|
||||
adbdevice = ADBDevice()
|
||||
print adbdevice.list_files("/mnt/sdcard")
|
||||
if adbdevice.process_exist("org.mozilla.fennec"):
|
||||
print "Fennec is running"
|
||||
|
||||
"""
|
||||
__metaclass__ = abc.ABCMeta
|
||||
|
||||
def __init__(self,
|
||||
device=None,
|
||||
|
@ -507,6 +532,8 @@ class ADBDevice(ADBCommand):
|
|||
:raises: * ADBError
|
||||
* ADBTimeoutError
|
||||
* ValueError
|
||||
|
||||
|
||||
"""
|
||||
ADBCommand.__init__(self, adb=adb, adb_host=adb_host,
|
||||
adb_port=adb_port, logger_name=logger_name,
|
||||
|
@ -562,9 +589,6 @@ class ADBDevice(ADBCommand):
|
|||
except ADBError:
|
||||
self._ls += " -a"
|
||||
|
||||
# Do we have cp?
|
||||
self._have_cp = self.shell_bool("type cp")
|
||||
|
||||
self._logger.debug("ADBDevice: %s" % self.__dict__)
|
||||
|
||||
def _get_device_serial(self, device):
|
||||
|
@ -605,6 +629,7 @@ class ADBDevice(ADBCommand):
|
|||
def _escape_command_line(cmd):
|
||||
"""Utility function to return escaped and quoted version of command
|
||||
line.
|
||||
|
||||
"""
|
||||
quoted_cmd = []
|
||||
|
||||
|
@ -627,6 +652,7 @@ class ADBDevice(ADBCommand):
|
|||
def _get_exitcode(file_obj):
|
||||
"""Get the exitcode from the last line of the file_obj for shell
|
||||
commands.
|
||||
|
||||
"""
|
||||
file_obj.seek(0, os.SEEK_END)
|
||||
|
||||
|
@ -764,6 +790,7 @@ class ADBDevice(ADBCommand):
|
|||
|
||||
It is the caller's responsibilty to clean up by closing
|
||||
the stdout and stderr temporary files.
|
||||
|
||||
"""
|
||||
|
||||
return ADBCommand.command(self, cmds,
|
||||
|
@ -786,6 +813,7 @@ class ADBDevice(ADBCommand):
|
|||
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
return ADBCommand.command_output(self, cmds,
|
||||
device_serial=self._device_serial,
|
||||
|
@ -933,6 +961,7 @@ class ADBDevice(ADBCommand):
|
|||
|
||||
It is the caller's responsibilty to clean up by closing
|
||||
the stdout and stderr temporary files.
|
||||
|
||||
"""
|
||||
if root:
|
||||
ld_library_path='LD_LIBRARY_PATH=/vendor/lib:/system/lib'
|
||||
|
@ -1008,6 +1037,7 @@ class ADBDevice(ADBCommand):
|
|||
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBRootError
|
||||
|
||||
"""
|
||||
adb_process = None
|
||||
try:
|
||||
|
@ -1041,6 +1071,7 @@ class ADBDevice(ADBCommand):
|
|||
:raises: * ADBTimeoutError
|
||||
* ADBRootError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
adb_process = None
|
||||
try:
|
||||
|
@ -1084,6 +1115,7 @@ class ADBDevice(ADBCommand):
|
|||
in the ADBDevice constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
self.command_output(["logcat", "-c"], timeout=timeout)
|
||||
|
||||
|
@ -1114,6 +1146,7 @@ class ADBDevice(ADBCommand):
|
|||
:returns: list of lines logcat output.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
cmds = ["logcat", "-v", format, "-d"] + filter_specs
|
||||
lines = self.command_output(cmds, timeout=timeout).split('\r')
|
||||
|
@ -1136,6 +1169,7 @@ class ADBDevice(ADBCommand):
|
|||
:returns: string value of property.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
output = self.shell_output('getprop %s' % prop, timeout=timeout)
|
||||
return output
|
||||
|
@ -1152,6 +1186,7 @@ class ADBDevice(ADBCommand):
|
|||
:returns: string value of adb get-state.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
output = self.command_output(["get-state"], timeout=timeout).strip()
|
||||
return output
|
||||
|
@ -1171,6 +1206,7 @@ class ADBDevice(ADBCommand):
|
|||
be found.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
ip_regexp = re.compile(r'(\w+)\s+UP\s+([1-9]\d{0,2}\.\d{1,3}\.\d{1,3}\.\d{1,3})')
|
||||
data = self.shell_output('netcfg')
|
||||
|
@ -1224,6 +1260,7 @@ class ADBDevice(ADBCommand):
|
|||
:raises: * ADBTimeoutError
|
||||
* ADBRootError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
path = posixpath.normpath(path.strip())
|
||||
self._logger.debug('chmod: path=%s, recursive=%s, mask=%s, root=%s' %
|
||||
|
@ -1269,6 +1306,7 @@ class ADBDevice(ADBCommand):
|
|||
:returns: boolean - True if path exists.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBRootError
|
||||
|
||||
"""
|
||||
path = posixpath.normpath(path)
|
||||
return self.shell_bool('ls -a %s' % path, timeout=timeout, root=root)
|
||||
|
@ -1289,6 +1327,7 @@ class ADBDevice(ADBCommand):
|
|||
directory.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBRootError
|
||||
|
||||
"""
|
||||
path = posixpath.normpath(path)
|
||||
return self.shell_bool('ls -a %s/' % path, timeout=timeout, root=root)
|
||||
|
@ -1309,6 +1348,7 @@ class ADBDevice(ADBCommand):
|
|||
file.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBRootError
|
||||
|
||||
"""
|
||||
path = posixpath.normpath(path)
|
||||
return (
|
||||
|
@ -1331,6 +1371,7 @@ class ADBDevice(ADBCommand):
|
|||
:returns: list of files/directories contained in the directory.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBRootError
|
||||
|
||||
"""
|
||||
path = posixpath.normpath(path.strip())
|
||||
data = []
|
||||
|
@ -1366,6 +1407,7 @@ class ADBDevice(ADBCommand):
|
|||
:raises: * ADBTimeoutError
|
||||
* ADBRootError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
path = posixpath.normpath(path)
|
||||
if parents:
|
||||
|
@ -1407,6 +1449,7 @@ class ADBDevice(ADBCommand):
|
|||
set in the ADBDevice constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
self.command_output(["push", os.path.realpath(local), remote],
|
||||
timeout=timeout)
|
||||
|
@ -1426,6 +1469,7 @@ class ADBDevice(ADBCommand):
|
|||
set in the ADBDevice constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
self.command_output(["pull", remote, os.path.realpath(local)],
|
||||
timeout=timeout)
|
||||
|
@ -1451,6 +1495,7 @@ class ADBDevice(ADBCommand):
|
|||
:raises: * ADBTimeoutError
|
||||
* ADBRootError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
cmd = "rm"
|
||||
if recursive:
|
||||
|
@ -1478,6 +1523,7 @@ class ADBDevice(ADBCommand):
|
|||
:raises: * ADBTimeoutError
|
||||
* ADBRootError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
self.shell_output("rmdir %s" % path, timeout=timeout, root=root)
|
||||
if self.is_dir(path, timeout=timeout, root=root):
|
||||
|
@ -1499,6 +1545,7 @@ class ADBDevice(ADBCommand):
|
|||
on the device.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
adb_process = None
|
||||
try:
|
||||
|
@ -1560,6 +1607,7 @@ class ADBDevice(ADBCommand):
|
|||
:raises: * ADBTimeoutError
|
||||
* ADBRootError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
pid_list = [str(pid) for pid in pids]
|
||||
for attempt in range(attempts):
|
||||
|
@ -1607,6 +1655,7 @@ class ADBDevice(ADBCommand):
|
|||
:raises: * ADBTimeoutError
|
||||
* ADBRootError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
procs = self.get_process_list(timeout=timeout)
|
||||
# limit the comparion to the first 75 characters due to a
|
||||
|
@ -1639,6 +1688,7 @@ class ADBDevice(ADBCommand):
|
|||
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
if not isinstance(process_name, basestring):
|
||||
raise ADBError("Process name %s is not a string" % process_name)
|
||||
|
@ -1668,204 +1718,3 @@ class ADBDevice(ADBCommand):
|
|||
if proc_name == app[:75]:
|
||||
return True
|
||||
return False
|
||||
|
||||
def cp(self, source, destination, recursive=False, timeout=None,
|
||||
root=False):
|
||||
"""Copies a file or directory on the device.
|
||||
|
||||
:param source: string containing the path of the source file or
|
||||
directory.
|
||||
:param destination: string containing the path of the destination file
|
||||
or directory.
|
||||
:param recursive: optional boolean indicating if a recursive copy is to
|
||||
be performed. Required if the source is a directory. Defaults to
|
||||
False. Think cp -R source destination.
|
||||
:param timeout: optional integer specifying the maximum time in
|
||||
seconds for any spawned adb process to complete before
|
||||
throwing an ADBTimeoutError.
|
||||
This timeout is per adb call. The total time spent
|
||||
may exceed this value. If it is not specified, the value
|
||||
set in the ADBDevice constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBRootError
|
||||
* ADBError
|
||||
"""
|
||||
source = posixpath.normpath(source)
|
||||
destination = posixpath.normpath(destination)
|
||||
if self._have_cp:
|
||||
r = '-R' if recursive else ''
|
||||
self.shell_output('cp %s %s %s' % (r, source, destination),
|
||||
timeout=timeout, root=root)
|
||||
return
|
||||
|
||||
# Emulate cp behavior depending on if source and destination
|
||||
# already exists and whether they are a directory or file.
|
||||
if not self.exists(source, timeout=timeout, root=root):
|
||||
raise ADBError("cp: can't stat '%s': No such file or directory" %
|
||||
source)
|
||||
|
||||
if self.is_file(source, timeout=timeout, root=root):
|
||||
if self.is_dir(destination, timeout=timeout, root=root):
|
||||
# Copy the source file into the destination directory
|
||||
destination = posixpath.join(destination,
|
||||
posixpath.basename(source))
|
||||
self.shell_output('dd if=%s of=%s' % (source, destination),
|
||||
timeout=timeout, root=root)
|
||||
return
|
||||
|
||||
if self.is_file(destination, timeout=timeout, root=root):
|
||||
raise ADBError('cp: %s: Not a directory' % destination)
|
||||
|
||||
if not recursive:
|
||||
raise ADBError("cp: omitting directory '%s'" % source)
|
||||
|
||||
if self.is_dir(destination, timeout=timeout, root=root):
|
||||
# Copy the source directory into the destination directory.
|
||||
destination_dir = posixpath.join(destination,
|
||||
posixpath.basename(source))
|
||||
else:
|
||||
# Copy the contents of the source directory into the
|
||||
# destination directory.
|
||||
destination_dir = destination
|
||||
|
||||
try:
|
||||
# Do not create parent directories since cp does not.
|
||||
self.mkdir(destination_dir, timeout=timeout, root=root)
|
||||
except ADBError as e:
|
||||
if 'File exists' not in e.message:
|
||||
raise
|
||||
|
||||
for i in self.list_files(source, timeout=timeout, root=root):
|
||||
self.cp(posixpath.join(source, i),
|
||||
posixpath.join(destination_dir, i),
|
||||
recursive=recursive,
|
||||
timeout=timeout, root=root)
|
||||
|
||||
def mv(self, source, destination, timeout=None, root=False):
|
||||
"""Moves a file or directory on the device.
|
||||
|
||||
:param source: string containing the path of the source file or
|
||||
directory.
|
||||
:param destination: string containing the path of the destination file
|
||||
or directory.
|
||||
:param timeout: optional integer specifying the maximum time in
|
||||
seconds for any spawned adb process to complete before
|
||||
throwing an ADBTimeoutError.
|
||||
This timeout is per adb call. The total time spent
|
||||
may exceed this value. If it is not specified, the value
|
||||
set in the ADBDevice constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBRootError
|
||||
* ADBError
|
||||
"""
|
||||
source = posixpath.normpath(source)
|
||||
destination = posixpath.normpath(destination)
|
||||
self.shell_output('mv %s %s' % (source, destination), timeout=timeout,
|
||||
root=root)
|
||||
|
||||
def reboot(self, timeout=None):
|
||||
"""Reboots the device.
|
||||
|
||||
:param timeout: optional integer specifying the maximum time in
|
||||
seconds for any spawned adb process to complete before
|
||||
throwing an ADBTimeoutError.
|
||||
This timeout is per adb call. The total time spent
|
||||
may exceed this value. If it is not specified, the value
|
||||
set in the ADB constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
reboot() reboots the device, issues an adb wait-for-device in order to
|
||||
wait for the device to complete rebooting, then calls is_device_ready()
|
||||
to determine if the device has completed booting.
|
||||
"""
|
||||
self.command_output(["reboot"], timeout=timeout)
|
||||
self.command_output(["wait-for-device"], timeout=timeout)
|
||||
return self.is_device_ready(timeout=timeout)
|
||||
|
||||
@abc.abstractmethod
|
||||
def is_device_ready(self, timeout=None):
|
||||
"""Abstract class that returns True if the device is ready.
|
||||
|
||||
:param timeout: optional integer specifying the maximum time in
|
||||
seconds for any spawned adb process to complete before
|
||||
throwing an ADBTimeoutError.
|
||||
This timeout is per adb call. The total time spent
|
||||
may exceed this value. If it is not specified, the value
|
||||
set in the ADB constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
"""
|
||||
return
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_battery_percentage(self, timeout=None):
|
||||
"""Abstract class that returns the battery charge as a percentage.
|
||||
|
||||
:param timeout: optional integer specifying the maximum time in
|
||||
seconds for any spawned adb process to complete before
|
||||
throwing an ADBTimeoutError.
|
||||
This timeout is per adb call. The total time spent
|
||||
may exceed this value. If it is not specified, the value
|
||||
set in the ADBDevice constructor is used.
|
||||
:returns: battery charge as a percentage.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
"""
|
||||
return
|
||||
|
||||
def get_info(self, directive=None, timeout=None):
|
||||
"""
|
||||
Returns a dictionary of information strings about the device.
|
||||
|
||||
:param directive: information you want to get. Options are:
|
||||
- `battery` - battery charge as a percentage
|
||||
- `disk` - total, free, available bytes on disk
|
||||
- `id` - unique id of the device
|
||||
- `os` - name of the os
|
||||
- `process` - list of running processes (same as ps)
|
||||
- `systime` - system time of the device
|
||||
- `uptime` - uptime of the device
|
||||
|
||||
If `directive` is `None`, will return all available information
|
||||
:param timeout: optional integer specifying the maximum time in
|
||||
seconds for any spawned adb process to complete before
|
||||
throwing an ADBTimeoutError.
|
||||
This timeout is per adb call. The total time spent
|
||||
may exceed this value. If it is not specified, the value
|
||||
set in the ADB constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
"""
|
||||
directives = ['battery', 'disk', 'id', 'os', 'process', 'systime',
|
||||
'uptime']
|
||||
|
||||
if (directive in directives):
|
||||
directives = [directive]
|
||||
|
||||
info = {}
|
||||
if 'battery' in directives:
|
||||
info['battery'] = self.get_battery_percentage(timeout=timeout)
|
||||
if 'disk' in directives:
|
||||
info['disk'] = self.shell_output('df /data /system /sdcard',
|
||||
timeout=timeout).splitlines()
|
||||
if 'id' in directives:
|
||||
info['id'] = self.command_output(['get-serialno'], timeout=timeout)
|
||||
if 'os' in directives:
|
||||
info['os'] = self.shell_output('getprop ro.build.display.id',
|
||||
timeout=timeout)
|
||||
if 'process' in directives:
|
||||
ps = self.shell_output('ps', timeout=timeout)
|
||||
info['process'] = ps.splitlines()
|
||||
if 'systime' in directives:
|
||||
info['systime'] = self.shell_output('date', timeout=timeout)
|
||||
if 'uptime' in directives:
|
||||
uptime = self.shell_output('uptime', timeout=timeout)
|
||||
if uptime:
|
||||
m = re.match('up time: ((\d+) days, )*(\d{2}):(\d{2}):(\d{2})',
|
||||
uptime)
|
||||
if m:
|
||||
uptime = '%d days %d hours %d minutes %d seconds' % tuple(
|
||||
[int(g or 0) for g in m.groups()[1:]])
|
||||
info['uptime'] = uptime
|
||||
return info
|
||||
|
|
|
@ -10,19 +10,8 @@ from adb import ADBDevice, ADBError
|
|||
from distutils.version import StrictVersion
|
||||
|
||||
|
||||
class ADBAndroid(ADBDevice):
|
||||
"""ADBAndroid implements :class:`ADBDevice` providing Android-specific
|
||||
functionality.
|
||||
|
||||
::
|
||||
|
||||
from mozdevice import ADBAndroid
|
||||
|
||||
adbdevice = ADBAndroid()
|
||||
print adbdevice.list_files("/mnt/sdcard")
|
||||
if adbdevice.process_exist("org.mozilla.fennec"):
|
||||
print "Fennec is running"
|
||||
"""
|
||||
class ADBAndroidMixin(object):
|
||||
"""Mixin to extend ADB with Android-specific functionality"""
|
||||
|
||||
# Informational methods
|
||||
|
||||
|
@ -38,6 +27,7 @@ class ADBAndroid(ADBDevice):
|
|||
:returns: battery charge as a percentage.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
level = None
|
||||
scale = None
|
||||
|
@ -75,6 +65,7 @@ class ADBAndroid(ADBDevice):
|
|||
set in the ADB constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
self.command_output(["wait-for-device"], timeout=timeout)
|
||||
pm_error_string = "Error: Could not access the Package Manager"
|
||||
|
@ -126,6 +117,7 @@ class ADBAndroid(ADBDevice):
|
|||
set in the ADB constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
try:
|
||||
self.shell_output('svc power stayon true', timeout=timeout)
|
||||
|
@ -136,6 +128,30 @@ class ADBAndroid(ADBDevice):
|
|||
raise
|
||||
self._logger.warning('Unable to set power stayon true: %s' % e)
|
||||
|
||||
def reboot(self, timeout=None):
|
||||
"""Reboots the device.
|
||||
|
||||
This method uses the Android only package manager to determine
|
||||
if the device is ready after the reboot.
|
||||
|
||||
:param timeout: optional integer specifying the maximum time in
|
||||
seconds for any spawned adb process to complete before
|
||||
throwing an ADBTimeoutError.
|
||||
This timeout is per adb call. The total time spent
|
||||
may exceed this value. If it is not specified, the value
|
||||
set in the ADB constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
reboot() reboots the device, issues an adb wait-for-device in order to
|
||||
wait for the device to complete rebooting, then calls is_device_ready()
|
||||
to determine if the device has completed booting.
|
||||
|
||||
"""
|
||||
self.command_output(["reboot"], timeout=timeout)
|
||||
self.command_output(["wait-for-device"], timeout=timeout)
|
||||
return self.is_device_ready(timeout=timeout)
|
||||
|
||||
# Application management methods
|
||||
|
||||
def install_app(self, apk_path, timeout=None):
|
||||
|
@ -151,6 +167,7 @@ class ADBAndroid(ADBDevice):
|
|||
set in the ADB constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
data = self.command_output(["install", apk_path], timeout=timeout)
|
||||
if data.find('Success') == -1:
|
||||
|
@ -170,6 +187,7 @@ class ADBAndroid(ADBDevice):
|
|||
set in the ADB constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
pm_error_string = 'Error: Could not access the Package Manager'
|
||||
data = self.shell_output("pm list package %s" % app_name, timeout=timeout)
|
||||
|
@ -201,6 +219,7 @@ class ADBAndroid(ADBDevice):
|
|||
set in the ADB constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
# If fail_if_running is True, we throw an exception here. Only one
|
||||
# instance of an application can be running at once on Android,
|
||||
|
@ -257,6 +276,7 @@ class ADBAndroid(ADBDevice):
|
|||
set in the ADB constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
extras = {}
|
||||
|
||||
|
@ -293,6 +313,7 @@ class ADBAndroid(ADBDevice):
|
|||
set in the ADB constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
version = self.shell_output("getprop ro.build.version.release",
|
||||
timeout=timeout, root=root)
|
||||
|
@ -331,6 +352,7 @@ class ADBAndroid(ADBDevice):
|
|||
set in the ADB constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
if self.is_app_installed(app_name, timeout=timeout):
|
||||
data = self.command_output(["uninstall", app_name], timeout=timeout)
|
||||
|
@ -353,8 +375,27 @@ class ADBAndroid(ADBDevice):
|
|||
set in the ADB constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
"""
|
||||
output = self.command_output(["install", "-r", apk_path],
|
||||
timeout=timeout)
|
||||
self.reboot(timeout=timeout)
|
||||
return output
|
||||
|
||||
|
||||
class ADBAndroid(ADBDevice, ADBAndroidMixin):
|
||||
"""ADBAndroid provides all of the methods of :class:`mozdevice.ADB` with
|
||||
Android specific extensions useful for that platform.
|
||||
|
||||
::
|
||||
|
||||
from mozdevice import ADBAndroid as ADBDevice
|
||||
|
||||
adb = ADBDevice(...)
|
||||
|
||||
if adb.is_device_ready():
|
||||
adb.install_app("/tmp/build.apk")
|
||||
adb.launch_fennec("org.mozilla.fennec")
|
||||
|
||||
"""
|
||||
pass
|
||||
|
|
|
@ -1,122 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import traceback
|
||||
|
||||
import mozfile
|
||||
|
||||
from adb import ADBDevice, ADBError
|
||||
|
||||
|
||||
class ADBB2G(ADBDevice):
|
||||
"""ADBB2G implements :class:`ADBDevice` providing B2G-specific
|
||||
functionality.
|
||||
|
||||
::
|
||||
|
||||
from mozdevice import ADBB2G
|
||||
|
||||
adbdevice = ADBB2G()
|
||||
print adbdevice.list_files("/mnt/sdcard")
|
||||
if adbdevice.process_exist("b2g"):
|
||||
print "B2G is running"
|
||||
"""
|
||||
|
||||
def get_battery_percentage(self, timeout=None):
|
||||
"""Returns the battery charge as a percentage.
|
||||
|
||||
:param timeout: optional integer specifying the maximum time in
|
||||
seconds for any spawned adb process to complete before
|
||||
throwing an ADBTimeoutError.
|
||||
This timeout is per adb call. The total time spent
|
||||
may exceed this value. If it is not specified, the value
|
||||
set in the ADBDevice constructor is used.
|
||||
:returns: battery charge as a percentage.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
"""
|
||||
with mozfile.NamedTemporaryFile() as tf:
|
||||
self.pull('/sys/class/power_supply/battery/capacity', tf.name,
|
||||
timeout=timeout)
|
||||
try:
|
||||
with open(tf.name) as tf2:
|
||||
return tf2.read().splitlines()[0]
|
||||
except Exception as e:
|
||||
raise ADBError(traceback.format_exception_only(
|
||||
type(e), e)[0].strip())
|
||||
|
||||
def get_memory_total(self, timeout=None):
|
||||
"""Returns the total memory available with units.
|
||||
|
||||
:param timeout: optional integer specifying the maximum time in
|
||||
seconds for any spawned adb process to complete before
|
||||
throwing an ADBTimeoutError.
|
||||
This timeout is per adb call. The total time spent
|
||||
may exceed this value. If it is not specified, the value
|
||||
set in the ADBDevice constructor is used.
|
||||
:returns: memory total with units.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
"""
|
||||
meminfo = {}
|
||||
with mozfile.NamedTemporaryFile() as tf:
|
||||
self.pull('/proc/meminfo', tf.name, timeout=timeout)
|
||||
try:
|
||||
with open(tf.name) as tf2:
|
||||
for line in tf2.read().splitlines():
|
||||
key, value = line.split(':')
|
||||
meminfo[key] = value.strip()
|
||||
except Exception as e:
|
||||
raise ADBError(traceback.format_exception_only(
|
||||
type(e), e)[0].strip())
|
||||
return meminfo['MemTotal']
|
||||
|
||||
def get_info(self, directive=None, timeout=None):
|
||||
"""
|
||||
Returns a dictionary of information strings about the device.
|
||||
|
||||
:param directive: information you want to get. Options are:
|
||||
- `battery` - battery charge as a percentage
|
||||
- `disk` - total, free, available bytes on disk
|
||||
- `id` - unique id of the device
|
||||
- `memtotal` - total memory available on the device
|
||||
- `os` - name of the os
|
||||
- `process` - list of running processes (same as ps)
|
||||
- `systime` - system time of the device
|
||||
- `uptime` - uptime of the device
|
||||
|
||||
If `directive` is `None`, will return all available information
|
||||
:param timeout: optional integer specifying the maximum time in
|
||||
seconds for any spawned adb process to complete before
|
||||
throwing an ADBTimeoutError.
|
||||
This timeout is per adb call. The total time spent
|
||||
may exceed this value. If it is not specified, the value
|
||||
set in the ADB constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
"""
|
||||
info = super(ADBB2G, self).get_info(directive=directive,
|
||||
timeout=timeout)
|
||||
|
||||
directives = ['memtotal']
|
||||
if (directive in directives):
|
||||
directives = [directive]
|
||||
|
||||
if 'memtotal' in directives:
|
||||
info['memtotal'] = self.get_memory_total(timeout=timeout)
|
||||
return info
|
||||
|
||||
def is_device_ready(self, timeout=None):
|
||||
"""Returns True if the device is ready.
|
||||
|
||||
:param timeout: optional integer specifying the maximum time in
|
||||
seconds for any spawned adb process to complete before
|
||||
throwing an ADBTimeoutError.
|
||||
This timeout is per adb call. The total time spent
|
||||
may exceed this value. If it is not specified, the value
|
||||
set in the ADB constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
"""
|
||||
return self.shell_bool('ls /sbin', timeout=timeout)
|
Загрузка…
Ссылка в новой задаче