1#
2# Copyright (C) 2018 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the 'License');
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an 'AS IS' BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17import logging
18
19from host_controller import common
20from host_controller.command_processor import base_command_processor
21
22from vts.utils.python.common import cmd_utils
23from vts.utils.python.controllers import adb
24from vts.utils.python.controllers import android_device
25
26# Default index of setStreamVolume() from IAudioService.aidl (1 based)
27SETSTREAMVOLUME_INDEX_DEFAULT = 3
28
29# Indices of each stream type (can be checked with "adb shell dumpsys audio" on the command line)
30STREAM_TYPE_CALL = 0
31STREAM_TYPE_RINGTONE = 2
32STREAM_TYPE_MEDIA = 3
33STREAM_TYPE_ALARM = 4
34
35STREAM_TYPE_LIST = [
36    STREAM_TYPE_CALL,
37    STREAM_TYPE_RINGTONE,
38    STREAM_TYPE_MEDIA,
39    STREAM_TYPE_ALARM,
40]
41
42
43class CommandDUT(base_command_processor.BaseCommandProcessor):
44    """Command processor for DUT command.
45
46    Attributes:
47        arg_parser: ConsoleArgumentParser object, argument parser.
48        console: cmd.Cmd console object.
49        command: string, command name which this processor will handle.
50        command_detail: string, detailed explanation for the command.
51    """
52
53    command = "dut"
54    command_detail = "Performs certain operations on DUT (Device Under Test)."
55
56    # @Override
57    def SetUp(self):
58        """Initializes the parser for dut command."""
59        self.arg_parser.add_argument(
60            "--operation",
61            choices=("wifi_on", "wifi_off", 'volume_mute', 'volume_max'),
62            default="",
63            required=True,
64            help="Operation to perform.")
65        self.arg_parser.add_argument(
66            "--serial", default="", required=True, help="The device serial.")
67        self.arg_parser.add_argument(
68            "--ap",
69            default="",  # Required only for wifi_on
70            help="Access point (AP) name for 'wifi_on' operation.")
71        self.arg_parser.add_argument(
72            "--volume_levels",
73            type=int,
74            default=30,  # Required only for volume_mute and volume_max
75            help="The number of volume control levels.")
76        self.arg_parser.add_argument(
77            "--version",
78            type=float,
79            default=8.0,
80            help="System version information of the device on which "
81            "the test will run.")
82
83    # @Override
84    def Run(self, arg_line):
85        """Performs the requested operation on the selected DUT."""
86        args = self.arg_parser.ParseLine(arg_line)
87        device = android_device.AndroidDevice(
88            args.serial, device_callback_port=-1)
89        boot_complete = device.waitForBootCompletion()
90        if not boot_complete:
91            logging.error("Device %s failed to bootup.", args.serial)
92            self.console.device_status[
93                args.serial] = common._DEVICE_STATUS_DICT["error"]
94            self.console.vti_endpoint_client.SetJobStatusFromLeasedTo(
95                "bootup-err")
96            return False
97
98        adb_proxy = adb.AdbProxy(serial=args.serial)
99        adb_proxy.root()
100        try:
101            if args.operation == "wifi_on":
102                adb_proxy.shell("svc wifi enable")
103                if args.ap:
104                    adb_proxy.install(
105                        "../testcases/DATA/app/WifiUtil/WifiUtil.apk")
106                    adb_proxy.shell(
107                        "am instrument -e method \"connectToNetwork\" "
108                        "-e ssid %s "
109                        "-w com.android.tradefed.utils.wifi/.WifiUtil" %
110                        args.ap)
111            elif args.operation == "wifi_off":
112                adb_proxy.shell("svc wifi disable")
113            elif args.operation == "volume_mute":
114                for _ in range(args.volume_levels):
115                    adb_proxy.shell("input keyevent 25")
116                self.SetOtherVolumes(adb_proxy, 0, args.version)
117            elif args.operation == "volume_max":
118                for _ in range(args.volume_levels):
119                    adb_proxy.shell("input keyevent 24")
120                self.SetOtherVolumes(adb_proxy, args.volume_levels,
121                                     args.version)
122        except adb.AdbError as e:
123            logging.exception(e)
124            return False
125
126    def SetOtherVolumes(self, adb_proxy, volume_level, version=None):
127        """Sets device's call/media/alarm volumes a certain level.
128
129        Args:
130            adb_proxy: AdbProxy, used for interacting with the device via adb.
131            volume_level: int, volume level value.
132            version: float, Android system version value. The index of
133                     setStreamVolume() depends on the Android version.
134        """
135        setStreamVolume_index = SETSTREAMVOLUME_INDEX_DEFAULT
136        if version and version >= 9.0:
137            setStreamVolume_index = 7
138        for stream_type in STREAM_TYPE_LIST:
139            adb_volume_command = "service call audio %s i32 %s i32 %s i32 1" % (
140                setStreamVolume_index, stream_type, volume_level)
141            adb_proxy.shell(adb_volume_command)
142