1#!/usr/bin/env python3
2#
3#   Copyright 2017 Google, Inc.
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
17import logging
18import time
19import acts.test_utils.bt.BleEnum as bleenum
20import acts.test_utils.instrumentation.device.command.instrumentation_command_builder as icb
21
22BLE_LOCATION_SCAN_ENABLE = 'settings put global ble_scan_always_enabled 1'
23BLE_LOCATION_SCAN_DISABLE = 'settings put global ble_scan_always_enabled 0'
24SCREEN_WAIT_TIME = 1
25
26
27class MediaControl(object):
28    """Media control using adb shell for power testing.
29
30    Object to control media play status using adb.
31    """
32
33    def __init__(self, android_device, music_file):
34        """Initialize the media_control class.
35
36        Args:
37            android_dut: android_device object
38            music_file: location of the music file
39        """
40        self.android_device = android_device
41        self.music_file = music_file
42
43    def player_on_foreground(self):
44        """Turn on screen and make sure media play is on foreground
45
46        All media control keycode only works when screen is on and media player
47        is on the foreground. Turn off screen first and turn it on to make sure
48        all operation is based on the same screen status. Otherwise, 'MENU' key
49        would block command to be sent.
50        """
51        self.android_device.droid.goToSleepNow()
52        time.sleep(SCREEN_WAIT_TIME)
53        self.android_device.droid.wakeUpNow()
54        time.sleep(SCREEN_WAIT_TIME)
55        self.android_device.send_keycode('MENU')
56        time.sleep(SCREEN_WAIT_TIME)
57
58    def play(self):
59        """Start playing music.
60
61        """
62        self.player_on_foreground()
63        PLAY = 'am start -a android.intent.action.VIEW -d file://{} -t audio/wav'.format(
64            self.music_file)
65        self.android_device.adb.shell(PLAY)
66
67    def pause(self):
68        """Pause music.
69
70        """
71        self.player_on_foreground()
72        self.android_device.send_keycode('MEDIA_PAUSE')
73
74    def resume(self):
75        """Pause music.
76
77        """
78        self.player_on_foreground()
79        self.android_device.send_keycode('MEDIA_PLAY')
80
81    def stop(self):
82        """Stop music and close media play.
83
84        """
85        self.player_on_foreground()
86        self.android_device.send_keycode('MEDIA_STOP')
87
88
89def start_apk_ble_adv(dut, adv_mode, adv_power_level, adv_duration):
90    """Trigger BLE advertisement from power-test.apk.
91
92    Args:
93        dut: Android device under test, type AndroidDevice obj
94        adv_mode: The BLE advertisement mode.
95            {0: 'LowPower', 1: 'Balanced', 2: 'LowLatency'}
96        adv_power_leve: The BLE advertisement TX power level.
97            {0: 'UltraLowTXPower', 1: 'LowTXPower', 2: 'MediumTXPower,
98            3: HighTXPower}
99        adv_duration: duration of advertisement in seconds, type int
100    """
101
102    adv_duration = str(adv_duration) + 's'
103    builder = icb.InstrumentationTestCommandBuilder.default()
104    builder.add_test_class(
105        "com.google.android.device.power.tests.ble.BleAdvertise")
106    builder.set_manifest_package("com.google.android.device.power")
107    builder.set_runner("androidx.test.runner.AndroidJUnitRunner")
108    builder.add_key_value_param("cool-off-duration", "0s")
109    builder.add_key_value_param("idle-duration", "0s")
110    builder.add_key_value_param(
111        "com.android.test.power.receiver.ADVERTISE_MODE", adv_mode)
112    builder.add_key_value_param("com.android.test.power.receiver.POWER_LEVEL",
113                                adv_power_level)
114    builder.add_key_value_param(
115        "com.android.test.power.receiver.ADVERTISING_DURATION", adv_duration)
116
117    adv_command = builder.build() + ' &'
118    logging.info('Start BLE {} at {} for {} seconds'.format(
119        bleenum.AdvertiseSettingsAdvertiseMode(adv_mode).name,
120        bleenum.AdvertiseSettingsAdvertiseTxPower(adv_power_level).name,
121        adv_duration))
122    dut.adb.shell_nb(adv_command)
123
124
125def start_apk_ble_scan(dut, scan_mode, scan_duration):
126    """Build the command to trigger BLE scan from power-test.apk.
127
128    Args:
129        dut: Android device under test, type AndroidDevice obj
130        scan_mode: The BLE scan mode.
131            {0: 'LowPower', 1: 'Balanced', 2: 'LowLatency', -1: 'Opportunistic'}
132        scan_duration: duration of scan in seconds, type int
133    Returns:
134        adv_command: the command for BLE scan
135    """
136    scan_duration = str(scan_duration) + 's'
137    builder = icb.InstrumentationTestCommandBuilder.default()
138    builder.add_test_class("com.google.android.device.power.tests.ble.BleScan")
139    builder.set_manifest_package("com.google.android.device.power")
140    builder.set_runner("androidx.test.runner.AndroidJUnitRunner")
141    builder.add_key_value_param("cool-off-duration", "0s")
142    builder.add_key_value_param("idle-duration", "0s")
143    builder.add_key_value_param("com.android.test.power.receiver.SCAN_MODE",
144                                scan_mode)
145    builder.add_key_value_param("com.android.test.power.receiver.MATCH_MODE",
146                                2)
147    builder.add_key_value_param(
148        "com.android.test.power.receiver.SCAN_DURATION", scan_duration)
149    builder.add_key_value_param(
150        "com.android.test.power.receiver.CALLBACK_TYPE", 1)
151    builder.add_key_value_param("com.android.test.power.receiver.FILTER",
152                                'true')
153
154    scan_command = builder.build() + ' &'
155    logging.info('Start BLE {} scans for {} seconds'.format(
156        bleenum.ScanSettingsScanMode(scan_mode).name, scan_duration))
157    dut.adb.shell_nb(scan_command)
158