blob: c65d8a8b1790671f98ef6ae2d3acc6bf2c88eb6d [file] [log] [blame]
Xianyuan Jiabff38082019-07-12 14:14:12 -07001#!/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
Hectord4bfca62020-03-06 02:17:16 -080017import logging
18from acts import tracelogger
19
Xianyuan Jia63751fb2020-11-17 00:07:40 +000020from acts_contrib.test_utils.instrumentation.device.command.intent_builder import IntentBuilder
Hectord4bfca62020-03-06 02:17:16 -080021
22DESCRIPTION_MISSING_MESSAGE = (
23 'Description for command is mandatory. Provide a brief description on what '
24 'the command "%s" does. Preferably in third person, for example, instead '
25 'of "Turn torch on" you should write "Turns torch on". If a description is '
26 'too long and adding a link would help, adding a link is allowed. Make '
27 'sure that the link is to a specific/fixed version of a document (either '
28 'website or code) so that it doesn\'t lose context over time.')
29
30log = tracelogger.TraceLogger(logging.getLogger())
Xianyuan Jia9915f642019-07-25 16:28:40 -070031
Xianyuan Jiabff38082019-07-12 14:14:12 -070032
Hector6048d232020-03-05 18:54:19 -080033class GenericCommand(object):
34 """Class for generic adb commands."""
35
36 def __init__(self, cmd, desc=None):
37 """ Constructor for GenericCommand.
38
39 Args:
40 cmd: ADB command.
41 desc: Free form string to describe what this command does.
42 """
Hectord4bfca62020-03-06 02:17:16 -080043 if not cmd:
44 raise ValueError('Command can not be left undefined.')
45
46 if not desc:
47 log.warning(DESCRIPTION_MISSING_MESSAGE % cmd)
48
Hector6048d232020-03-05 18:54:19 -080049 self.cmd = cmd
50 self.desc = desc
51
52
Xianyuan Jiabff38082019-07-12 14:14:12 -070053class DeviceState(object):
54 """Class for adb commands for setting device properties to a value."""
55
Hector6048d232020-03-05 18:54:19 -080056 def __init__(self, base_cmd, on_val='1', off_val='0', desc=None):
Xianyuan Jiabff38082019-07-12 14:14:12 -070057 """Create a DeviceState.
58
59 Args:
60 base_cmd: The base adb command. Needs to accept an argument/value to
61 generate the full command.
62 on_val: Value used for the 'on' state
63 off_val: Value used for the 'off' state
Hector6048d232020-03-05 18:54:19 -080064 desc: Free form string to describes what is this command does.
Xianyuan Jiabff38082019-07-12 14:14:12 -070065 """
Hectord4bfca62020-03-06 02:17:16 -080066 if not desc:
67 log.warning(DESCRIPTION_MISSING_MESSAGE % base_cmd)
68
Xianyuan Jiabff38082019-07-12 14:14:12 -070069 self._base_cmd = base_cmd
70 self._on_val = on_val
71 self._off_val = off_val
Hector6048d232020-03-05 18:54:19 -080072 self.desc = desc
Xianyuan Jiabff38082019-07-12 14:14:12 -070073
Xianyuan Jiaf7248ea2019-07-15 14:18:36 -070074 def set_value(self, *values):
75 """Returns the adb command with the given arguments/values.
Xianyuan Jiabff38082019-07-12 14:14:12 -070076
77 Args:
Xianyuan Jiaf7248ea2019-07-15 14:18:36 -070078 values: The value(s) to run the command with
Xianyuan Jiabff38082019-07-12 14:14:12 -070079 """
Xianyuan Jia2fc56312019-08-05 12:05:31 -070080 try:
Hector6048d232020-03-05 18:54:19 -080081 cmd = self._base_cmd % values
Xianyuan Jia2fc56312019-08-05 12:05:31 -070082 except TypeError:
Hector6048d232020-03-05 18:54:19 -080083 cmd = str.strip(' '.join(
Xianyuan Jia2fc56312019-08-05 12:05:31 -070084 [self._base_cmd] + [str(value) for value in values]))
Hector6048d232020-03-05 18:54:19 -080085 return GenericCommand(cmd, self.desc)
Xianyuan Jiabff38082019-07-12 14:14:12 -070086
87 def toggle(self, enabled):
88 """Returns the command corresponding to the desired state.
89
90 Args:
91 enabled: True for the 'on' state.
92 """
93 return self.set_value(self._on_val if enabled else self._off_val)
94
95
96class DeviceSetprop(DeviceState):
97 """Class for setprop commands."""
98
Hector6048d232020-03-05 18:54:19 -080099 def __init__(self, prop, on_val='1', off_val='0', desc=None):
Xianyuan Jiabff38082019-07-12 14:14:12 -0700100 """Create a DeviceSetprop.
101
102 Args:
103 prop: Property name
104 on_val: Value used for the 'on' state
105 off_val: Value used for the 'off' state
Hector6048d232020-03-05 18:54:19 -0800106 desc: Free form string to describes what is this command does.
Xianyuan Jiabff38082019-07-12 14:14:12 -0700107 """
Hector6048d232020-03-05 18:54:19 -0800108 super().__init__('setprop %s' % prop, on_val=on_val, off_val=off_val,
109 desc=desc)
Xianyuan Jiabff38082019-07-12 14:14:12 -0700110
111
112class DeviceSetting(DeviceState):
113 """Class for commands to set a settings.db entry to a value."""
114
Hectora13edf42020-03-06 13:34:48 -0800115 # common namespaces
116 GLOBAL = 'global'
117 SYSTEM = 'system'
118 SECURE = 'secure'
119
Hector6048d232020-03-05 18:54:19 -0800120 def __init__(self, namespace, setting, on_val='1', off_val='0', desc=None):
Xianyuan Jiabff38082019-07-12 14:14:12 -0700121 """Create a DeviceSetting.
122
123 Args:
124 namespace: Namespace of the setting
125 setting: Setting name
126 on_val: Value used for the 'on' state
127 off_val: Value used for the 'off' state
Hector6048d232020-03-05 18:54:19 -0800128 desc: Free form string to describes what is this command does.
Xianyuan Jiabff38082019-07-12 14:14:12 -0700129 """
130 super().__init__('settings put %s %s' % (namespace, setting),
Hector6048d232020-03-05 18:54:19 -0800131 on_val=on_val, off_val=off_val, desc=desc)
Xianyuan Jiabff38082019-07-12 14:14:12 -0700132
133
Xianyuan Jia9915f642019-07-25 16:28:40 -0700134class DeviceGServices(DeviceState):
135 """Class for overriding a GServices value."""
136
137 OVERRIDE_GSERVICES_INTENT = ('com.google.gservices.intent.action.'
138 'GSERVICES_OVERRIDE')
139
Hector6048d232020-03-05 18:54:19 -0800140 def __init__(self, setting, on_val='true', off_val='false', desc=None):
Xianyuan Jia9915f642019-07-25 16:28:40 -0700141 """Create a DeviceGServices.
142
143 Args:
144 setting: Name of the GServices setting
145 on_val: Value used for the 'on' state
146 off_val: Value used for the 'off' state
Hector6048d232020-03-05 18:54:19 -0800147 desc: Free form string to describes what is this command does.
Xianyuan Jia9915f642019-07-25 16:28:40 -0700148 """
Hector6048d232020-03-05 18:54:19 -0800149 super().__init__(None, on_val=on_val, off_val=off_val, desc=desc)
Xianyuan Jia9915f642019-07-25 16:28:40 -0700150 self._intent_builder = IntentBuilder('am broadcast')
151 self._intent_builder.set_action(self.OVERRIDE_GSERVICES_INTENT)
152 self._setting = setting
153
154 def set_value(self, value):
155 """Returns the adb command with the given value."""
156 self._intent_builder.add_key_value_param(self._setting, value)
Hector6048d232020-03-05 18:54:19 -0800157 return GenericCommand(self._intent_builder.build(), desc=self.desc)
Xianyuan Jia9915f642019-07-25 16:28:40 -0700158
159
Xianyuan Jiabff38082019-07-12 14:14:12 -0700160class DeviceBinaryCommandSeries(object):
161 """Class for toggling multiple settings at once."""
162
163 def __init__(self, binary_commands):
164 """Create a DeviceBinaryCommandSeries.
165
166 Args:
167 binary_commands: List of commands for setting toggleable options
168 """
169 self.cmd_list = binary_commands
170
171 def toggle(self, enabled):
172 """Returns the list of command corresponding to the desired state.
173
174 Args:
175 enabled: True for the 'on' state.
176 """
177 return [cmd.toggle(enabled) for cmd in self.cmd_list]