1#!/usr/bin/env python3
2#
3#   Copyright 2019 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the 'License');
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an 'AS IS' BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16
17from acts.test_utils.instrumentation.device.command.intent_builder import \
18    IntentBuilder
19
20
21class DeviceState(object):
22    """Class for adb commands for setting device properties to a value."""
23
24    def __init__(self, base_cmd, on_val='1', off_val='0'):
25        """Create a DeviceState.
26
27        Args:
28            base_cmd: The base adb command. Needs to accept an argument/value to
29                generate the full command.
30            on_val: Value used for the 'on' state
31            off_val: Value used for the 'off' state
32        """
33        self._base_cmd = base_cmd
34        self._on_val = on_val
35        self._off_val = off_val
36
37    def set_value(self, *values):
38        """Returns the adb command with the given arguments/values.
39
40        Args:
41            values: The value(s) to run the command with
42        """
43        try:
44            return self._base_cmd % values
45        except TypeError:
46            return str.strip(' '.join(
47                [self._base_cmd] + [str(value) for value in values]))
48
49    def toggle(self, enabled):
50        """Returns the command corresponding to the desired state.
51
52        Args:
53            enabled: True for the 'on' state.
54        """
55        return self.set_value(self._on_val if enabled else self._off_val)
56
57
58class DeviceSetprop(DeviceState):
59    """Class for setprop commands."""
60
61    def __init__(self, prop, on_val='1', off_val='0'):
62        """Create a DeviceSetprop.
63
64        Args:
65            prop: Property name
66            on_val: Value used for the 'on' state
67            off_val: Value used for the 'off' state
68        """
69        super().__init__('setprop %s' % prop, on_val, off_val)
70
71
72class DeviceSetting(DeviceState):
73    """Class for commands to set a settings.db entry to a value."""
74
75    def __init__(self, namespace, setting, on_val='1', off_val='0'):
76        """Create a DeviceSetting.
77
78        Args:
79            namespace: Namespace of the setting
80            setting: Setting name
81            on_val: Value used for the 'on' state
82            off_val: Value used for the 'off' state
83        """
84        super().__init__('settings put %s %s' % (namespace, setting),
85                         on_val, off_val)
86
87
88class DeviceGServices(DeviceState):
89    """Class for overriding a GServices value."""
90
91    OVERRIDE_GSERVICES_INTENT = ('com.google.gservices.intent.action.'
92                                 'GSERVICES_OVERRIDE')
93
94    def __init__(self, setting, on_val='true', off_val='false'):
95        """Create a DeviceGServices.
96
97        Args:
98            setting: Name of the GServices setting
99            on_val: Value used for the 'on' state
100            off_val: Value used for the 'off' state
101        """
102        super().__init__(None, on_val, off_val)
103        self._intent_builder = IntentBuilder('am broadcast')
104        self._intent_builder.set_action(self.OVERRIDE_GSERVICES_INTENT)
105        self._setting = setting
106
107    def set_value(self, value):
108        """Returns the adb command with the given value."""
109        self._intent_builder.add_key_value_param(self._setting, value)
110        return self._intent_builder.build()
111
112
113class DeviceBinaryCommandSeries(object):
114    """Class for toggling multiple settings at once."""
115
116    def __init__(self, binary_commands):
117        """Create a DeviceBinaryCommandSeries.
118
119        Args:
120            binary_commands: List of commands for setting toggleable options
121        """
122        self.cmd_list = binary_commands
123
124    def toggle(self, enabled):
125        """Returns the list of command corresponding to the desired state.
126
127        Args:
128            enabled: True for the 'on' state.
129        """
130        return [cmd.toggle(enabled) for cmd in self.cmd_list]
131