Merge pull request #163 from marcbonnici/Derived_Measurements
Add support for AcmeCape and Derived Measurements
diff --git a/devlib/target.py b/devlib/target.py
index 27b1c4b..b96bbdc 100644
--- a/devlib/target.py
+++ b/devlib/target.py
@@ -1061,20 +1061,25 @@
# Android-specific
- def swipe_to_unlock(self, direction="horizontal"):
+ def swipe_to_unlock(self, direction="diagonal"):
width, height = self.screen_resolution
command = 'input swipe {} {} {} {}'
- if direction == "horizontal":
- swipe_heigh = height * 2 // 3
+ if direction == "diagonal":
start = 100
stop = width - start
- self.execute(command.format(start, swipe_heigh, stop, swipe_heigh))
- if direction == "vertical":
- swipe_middle = height / 2
- swipe_heigh = height * 2 // 3
- self.execute(command.format(swipe_middle, swipe_heigh, swipe_middle, 0))
+ swipe_height = height * 2 // 3
+ self.execute(command.format(start, swipe_height, stop, 0))
+ elif direction == "horizontal":
+ swipe_height = height * 2 // 3
+ start = 100
+ stop = width - start
+ self.execute(command.format(start, swipe_height, stop, swipe_height))
+ elif direction == "vertical":
+ swipe_middle = width / 2
+ swipe_height = height * 2 // 3
+ self.execute(command.format(swipe_middle, swipe_height, swipe_middle, 0))
else:
- raise DeviceError("Invalid swipe direction: {}".format(self.swipe_to_unlock))
+ raise TargetError("Invalid swipe direction: {}".format(direction))
def getprop(self, prop=None):
props = AndroidProperties(self.execute('getprop'))
@@ -1186,6 +1191,69 @@
if self.is_screen_on():
self.execute('input keyevent 26')
+ def set_auto_brightness(self, auto_brightness):
+ cmd = 'settings put system screen_brightness_mode {}'
+ self.execute(cmd.format(int(boolean(auto_brightness))))
+
+ def get_auto_brightness(self):
+ cmd = 'settings get system screen_brightness_mode'
+ return boolean(self.execute(cmd).strip())
+
+ def set_brightness(self, value):
+ if not 0 <= value <= 255:
+ msg = 'Invalid brightness "{}"; Must be between 0 and 255'
+ raise ValueError(msg.format(value))
+ self.set_auto_brightness(False)
+ cmd = 'settings put system screen_brightness {}'
+ self.execute(cmd.format(int(value)))
+
+ def get_brightness(self):
+ cmd = 'settings get system screen_brightness'
+ return integer(self.execute(cmd).strip())
+
+ def get_airplane_mode(self):
+ cmd = 'settings get global airplane_mode_on'
+ return boolean(self.execute(cmd).strip())
+
+ def set_airplane_mode(self, mode):
+ root_required = self.get_sdk_version() > 23
+ if root_required and not self.is_rooted:
+ raise TargetError('Root is required to toggle airplane mode on Android 7+')
+ cmd = 'settings put global airplane_mode_on {}'
+ self.execute(cmd.format(int(boolean(mode))))
+ self.execute('am broadcast -a android.intent.action.AIRPLANE_MODE', as_root=root_required)
+
+ def get_auto_rotation(self):
+ cmd = 'settings get system accelerometer_rotation'
+ return boolean(self.execute(cmd).strip())
+
+ def set_auto_rotation(self, autorotate):
+ cmd = 'settings put system accelerometer_rotation {}'
+ self.execute(cmd.format(int(boolean(autorotate))))
+
+ def set_natural_rotation(self):
+ self.set_rotation(0)
+
+ def set_left_rotation(self):
+ self.set_rotation(1)
+
+ def set_inverted_rotation(self):
+ self.set_rotation(2)
+
+ def set_right_rotation(self):
+ self.set_rotation(3)
+
+ def get_rotation(self):
+ cmd = 'settings get system user_rotation'
+ return self.execute(cmd).strip()
+
+ def set_rotation(self, rotation):
+ if not 0 <= rotation <= 3:
+ raise ValueError('Rotation value must be between 0 and 3')
+ self.set_auto_rotation(False)
+ cmd = 'settings put system user_rotation {}'
+ self.execute(cmd.format(rotation))
+
def homescreen(self):
self.execute('am start -a android.intent.action.MAIN -c android.intent.category.HOME')
diff --git a/devlib/utils/types.py b/devlib/utils/types.py
index be30bfc..645328d 100644
--- a/devlib/utils/types.py
+++ b/devlib/utils/types.py
@@ -68,6 +68,15 @@
"""
if isinstance(value, int):
return value
+
+ if isinstance(value, basestring):
+ value = value.strip()
+ if value.endswith('%'):
+ try:
+ return float(value.rstrip('%')) / 100
+ except ValueError:
+ raise ValueError('Not numeric: {}'.format(value))
+
try:
fvalue = float(value)
except ValueError:
diff --git a/doc/target.rst b/doc/target.rst
index b64246a..08472e2 100644
--- a/doc/target.rst
+++ b/doc/target.rst
@@ -2,18 +2,18 @@
======
-.. class:: Target(connection_settings=None, platform=None, working_directory=None, executables_directory=None, connect=True, modules=None, load_default_modules=True, shell_prompt=DEFAULT_SHELL_PROMPT)
-
+.. class:: Target(connection_settings=None, platform=None, working_directory=None, executables_directory=None, connect=True, modules=None, load_default_modules=True, shell_prompt=DEFAULT_SHELL_PROMPT, conn_cls=None)
+
:class:`Target` is the primary interface to the remote device. All interactions
with the device are performed via a :class:`Target` instance, either
directly, or via its modules or a wrapper interface (such as an
:class:`Instrument`).
- :param connection_settings: A ``dict`` that specifies how to connect to the remote
+ :param connection_settings: A ``dict`` that specifies how to connect to the remote
device. Its contents depend on the specific :class:`Target` type (used see
:ref:`connection-types`\ ).
- :param platform: A :class:`Target` defines interactions at Operating System level. A
+ :param platform: A :class:`Target` defines interactions at Operating System level. A
:class:`Platform` describes the underlying hardware (such as CPUs
available). If a :class:`Platform` instance is not specified on
:class:`Target` creation, one will be created automatically and it will
@@ -22,8 +22,8 @@
:param working_directory: This is primary location for on-target file system
interactions performed by ``devlib``. This location *must* be readable and
- writable directly (i.e. without sudo) by the connection's user account.
- It may or may not allow execution. This location will be created,
+ writable directly (i.e. without sudo) by the connection's user account.
+ It may or may not allow execution. This location will be created,
if necessary, during ``setup()``.
If not explicitly specified, this will be set to a default value
@@ -35,7 +35,7 @@
(obviously). It should also be possible to write to this location,
possibly with elevated privileges (i.e. on a rooted Linux target, it
should be possible to write here with sudo, but not necessarily directly
- by the connection's account). This location will be created,
+ by the connection's account). This location will be created,
if necessary, during ``setup()``.
This location does *not* need to be same as the system's executables
@@ -52,7 +52,7 @@
:param modules: a list of additional modules to be installed. Some modules will
try to install by default (if supported by the underlying target).
- Current default modules are ``hotplug``, ``cpufreq``, ``cpuidle``,
+ Current default modules are ``hotplug``, ``cpufreq``, ``cpuidle``,
``cgroups``, and ``hwmon`` (See :ref:`modules`\ ).
See modules documentation for more detail.
@@ -68,6 +68,9 @@
prompted on the target. This may be used by some modules that establish
auxiliary connections to a target over UART.
+ :param conn_cls: This is the type of connection that will be used to communicate
+ with the device.
+
.. attribute:: Target.core_names
This is a list containing names of CPU cores on the target, in the order in
@@ -94,7 +97,7 @@
.. attribute:: Target.is_connected
A boolean value that indicates whether an active connection exists to the
- target device.
+ target device.
.. attribute:: Target.connected_as_root
@@ -146,7 +149,7 @@
thread.
.. method:: Target.connect([timeout])
-
+
Establish a connection to the target. It is usually not necessary to call
this explicitly, as a connection gets automatically established on
instantiation.
@@ -225,7 +228,7 @@
:param timeout: Timeout (in seconds) for the execution of the command. If
specified, an exception will be raised if execution does not complete
with the specified period.
- :param check_exit_code: If ``True`` (the default) the exit code (on target)
+ :param check_exit_code: If ``True`` (the default) the exit code (on target)
from execution of the command will be checked, and an exception will be
raised if it is not ``0``.
:param as_root: The command will be executed as root. This will fail on
@@ -262,7 +265,7 @@
will be interpreted as a comma-separated list of cpu ranges, e.g.
``"0,4-7"``.
:param as_root: Specify whether the command should be run as root
- :param timeout: If this is specified and invocation does not terminate within this number
+ :param timeout: If this is specified and invocation does not terminate within this number
of seconds, an exception will be raised.
.. method:: Target.background_invoke(binary [, args [, in_directory [, on_cpus [, as_root ]]]])
@@ -314,13 +317,13 @@
.. method:: Target.write_value(path, value [, verify])
- Write the value to the specified path on the target. This is primarily
+ Write the value to the specified path on the target. This is primarily
intended for sysfs/procfs/debugfs etc.
:param path: file to write into
:param value: value to be written
:param verify: If ``True`` (the default) the value will be read back after
- it is written to make sure it has been written successfully. This due to
+ it is written to make sure it has been written successfully. This due to
some sysfs entries silently failing to set the written value without
returning an error code.
@@ -450,3 +453,110 @@
Returns the path to the extracted contents. In case of files (gzip and
bzip2), the path to the decompressed file is returned; for archives, the
path to the directory with the archive's contents is returned.
+
+
+Android Target
+---------------
+
+.. class:: AndroidTarget(connection_settings=None, platform=None, working_directory=None, executables_directory=None, connect=True, modules=None, load_default_modules=True, shell_prompt=DEFAULT_SHELL_PROMPT, conn_cls=AdbConnection, package_data_directory="/data/data")
+
+ :class:`AndroidTarget` is a subclass of :class:`Target` with additional features specific to a device running Android.
+
+ :param package_data_directory: This is the location of the data stored
+ for installed Android packages on the device.
+
+.. method:: AndroidTarget.set_rotation(rotation)
+
+ Specify an integer representing the desired screen rotation with the
+ following mappings: Natural: ``0``, Rotated Left: ``1``, Inverted : ``2``
+ and Rotated Right : ``3``.
+
+.. method:: AndroidTarget.get_rotation(rotation)
+
+ Returns an integer value representing the orientation of the devices
+ screen. ``0`` : Natural, ``1`` : Rotated Left, ``2`` : Inverted
+ and ``3`` : Rotated Right.
+
+.. method:: AndroidTarget.set_natural_rotation()
+
+ Sets the screen orientation of the device to its natural (0 degrees)
+ orientation.
+
+.. method:: AndroidTarget.set_left_rotation()
+
+ Sets the screen orientation of the device to 90 degrees.
+
+.. method:: AndroidTarget.set_inverted_rotation()
+
+ Sets the screen orientation of the device to its inverted (180 degrees)
+ orientation.
+
+.. method:: AndroidTarget.set_right_rotation()
+
+ Sets the screen orientation of the device to 270 degrees.
+
+.. method:: AndroidTarget.set_auto_rotation(autorotate)
+
+ Specify a boolean value for whether the devices auto-rotation should
+ be enabled.
+
+.. method:: AndroidTarget.get_auto_rotation()
+
+ Returns ``True`` if the targets auto rotation is currently enabled and
+ ``False`` otherwise.
+
+.. method:: AndroidTarget.set_airplane_mode(mode)
+
+ Specify a boolean value for whether the device should be in airplane mode.
+
+ .. note:: Requires the device to be rooted if the device is running Android 7+.
+
+.. method:: AndroidTarget.get_airplane_mode()
+
+ Returns ``True`` if the target is currently in airplane mode and
+ ``False`` otherwise.
+
+.. method:: AndroidTarget.set_brightness(value)
+
+ Sets the devices screen brightness to a specified integer between ``0`` and
+ ``255``.
+
+.. method:: AndroidTarget.get_brightness()
+
+ Returns an integer between ``0`` and ``255`` representing the devices
+ current screen brightness.
+
+.. method:: AndroidTarget.set_auto_brightness(auto_brightness)
+
+ Specify a boolean value for whether the devices auto brightness
+ should be enabled.
+
+.. method:: AndroidTarget.get_auto_brightness()
+
+ Returns ``True`` if the targets auto brightness is currently
+ enabled and ``False`` otherwise.
+
+.. method:: AndroidTarget.ensure_screen_is_off()
+
+ Checks if the devices screen is on and if so turns it off.
+
+.. method:: AndroidTarget.ensure_screen_is_on()
+
+ Checks if the devices screen is off and if so turns it on.
+
+.. method:: AndroidTarget.is_screen_on()
+
+ Returns ``True`` if the targets screen is currently on and ``False``
+ otherwise.
+
+.. method:: AndroidTarget.homescreen()
+
+ Returns the device to its home screen.
+
+.. method:: AndroidTarget.swipe_to_unlock(direction="diagonal")
+
+ Performs a swipe input on the device to try and unlock the device.
+ A direction of ``"horizontal"``, ``"vertical"`` or ``"diagonal"``
+ can be supplied to specify in which direction the swipe should be
+ performed. By default ``"diagonal"`` will be used to try and
+ support the majority of newer devices.