Migrate test_utils from acts to acts_contrib

This change will allow the ACTS framework to be packaged independently
of its test_utils. This facilitates the usage of ACTS within test suites
outside of tools/test/connectivity.

Re-submission of ag/13029169.
This reverts commit a4913cd4087bb09bf192de6ef819657aa6e082bd.

Reason for revert: Submit once references in acts_power are fixed.

Change-Id: I2d60f8ccaf936a80820a7b4387c23bbce1293dcf
diff --git a/acts_tests/acts_contrib/test_utils/instrumentation/device/command/adb_command_types.py b/acts_tests/acts_contrib/test_utils/instrumentation/device/command/adb_command_types.py
new file mode 100644
index 0000000..c65d8a8
--- /dev/null
+++ b/acts_tests/acts_contrib/test_utils/instrumentation/device/command/adb_command_types.py
@@ -0,0 +1,177 @@
+#!/usr/bin/env python3
+#
+#   Copyright 2019 - The Android Open Source Project
+#
+#   Licensed under the Apache License, Version 2.0 (the 'License');
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an 'AS IS' BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+import logging
+from acts import tracelogger
+
+from acts_contrib.test_utils.instrumentation.device.command.intent_builder import IntentBuilder
+
+DESCRIPTION_MISSING_MESSAGE = (
+    'Description for command is mandatory. Provide a brief description on what '
+    'the command "%s" does. Preferably in third person, for example, instead '
+    'of "Turn torch on" you should write "Turns torch on". If a description is '
+    'too long and adding a link would help, adding a link is allowed. Make '
+    'sure that the link is to a specific/fixed version of a document (either '
+    'website or code) so that it doesn\'t lose context over time.')
+
+log = tracelogger.TraceLogger(logging.getLogger())
+
+
+class GenericCommand(object):
+    """Class for generic adb commands."""
+
+    def __init__(self, cmd, desc=None):
+        """ Constructor for GenericCommand.
+
+        Args:
+          cmd: ADB command.
+          desc: Free form string to describe what this command does.
+        """
+        if not cmd:
+            raise ValueError('Command can not be left undefined.')
+
+        if not desc:
+            log.warning(DESCRIPTION_MISSING_MESSAGE % cmd)
+
+        self.cmd = cmd
+        self.desc = desc
+
+
+class DeviceState(object):
+    """Class for adb commands for setting device properties to a value."""
+
+    def __init__(self, base_cmd, on_val='1', off_val='0', desc=None):
+        """Create a DeviceState.
+
+        Args:
+            base_cmd: The base adb command. Needs to accept an argument/value to
+                generate the full command.
+            on_val: Value used for the 'on' state
+            off_val: Value used for the 'off' state
+            desc: Free form string to describes what is this command does.
+        """
+        if not desc:
+            log.warning(DESCRIPTION_MISSING_MESSAGE % base_cmd)
+
+        self._base_cmd = base_cmd
+        self._on_val = on_val
+        self._off_val = off_val
+        self.desc = desc
+
+    def set_value(self, *values):
+        """Returns the adb command with the given arguments/values.
+
+        Args:
+            values: The value(s) to run the command with
+        """
+        try:
+            cmd = self._base_cmd % values
+        except TypeError:
+            cmd = str.strip(' '.join(
+                [self._base_cmd] + [str(value) for value in values]))
+        return GenericCommand(cmd, self.desc)
+
+    def toggle(self, enabled):
+        """Returns the command corresponding to the desired state.
+
+        Args:
+            enabled: True for the 'on' state.
+        """
+        return self.set_value(self._on_val if enabled else self._off_val)
+
+
+class DeviceSetprop(DeviceState):
+    """Class for setprop commands."""
+
+    def __init__(self, prop, on_val='1', off_val='0', desc=None):
+        """Create a DeviceSetprop.
+
+        Args:
+            prop: Property name
+            on_val: Value used for the 'on' state
+            off_val: Value used for the 'off' state
+            desc: Free form string to describes what is this command does.
+        """
+        super().__init__('setprop %s' % prop, on_val=on_val, off_val=off_val,
+                         desc=desc)
+
+
+class DeviceSetting(DeviceState):
+    """Class for commands to set a settings.db entry to a value."""
+
+    # common namespaces
+    GLOBAL = 'global'
+    SYSTEM = 'system'
+    SECURE = 'secure'
+
+    def __init__(self, namespace, setting, on_val='1', off_val='0', desc=None):
+        """Create a DeviceSetting.
+
+        Args:
+            namespace: Namespace of the setting
+            setting: Setting name
+            on_val: Value used for the 'on' state
+            off_val: Value used for the 'off' state
+            desc: Free form string to describes what is this command does.
+        """
+        super().__init__('settings put %s %s' % (namespace, setting),
+                         on_val=on_val, off_val=off_val, desc=desc)
+
+
+class DeviceGServices(DeviceState):
+    """Class for overriding a GServices value."""
+
+    OVERRIDE_GSERVICES_INTENT = ('com.google.gservices.intent.action.'
+                                 'GSERVICES_OVERRIDE')
+
+    def __init__(self, setting, on_val='true', off_val='false', desc=None):
+        """Create a DeviceGServices.
+
+        Args:
+            setting: Name of the GServices setting
+            on_val: Value used for the 'on' state
+            off_val: Value used for the 'off' state
+            desc: Free form string to describes what is this command does.
+        """
+        super().__init__(None, on_val=on_val, off_val=off_val, desc=desc)
+        self._intent_builder = IntentBuilder('am broadcast')
+        self._intent_builder.set_action(self.OVERRIDE_GSERVICES_INTENT)
+        self._setting = setting
+
+    def set_value(self, value):
+        """Returns the adb command with the given value."""
+        self._intent_builder.add_key_value_param(self._setting, value)
+        return GenericCommand(self._intent_builder.build(), desc=self.desc)
+
+
+class DeviceBinaryCommandSeries(object):
+    """Class for toggling multiple settings at once."""
+
+    def __init__(self, binary_commands):
+        """Create a DeviceBinaryCommandSeries.
+
+        Args:
+            binary_commands: List of commands for setting toggleable options
+        """
+        self.cmd_list = binary_commands
+
+    def toggle(self, enabled):
+        """Returns the list of command corresponding to the desired state.
+
+        Args:
+            enabled: True for the 'on' state.
+        """
+        return [cmd.toggle(enabled) for cmd in self.cmd_list]