From 2138c40ae4685375a299f0f60c5a3e42137c898e Mon Sep 17 00:00:00 2001 From: Dawn <33214307+Xiaojun0822@users.noreply.github.com> Date: Mon, 13 May 2024 10:47:21 +0800 Subject: [PATCH] feat(shell): add brightness_value and brightness_mode (#115) * feat(shell): add brightness_value and brightness_mode --------- Co-authored-by: codeskyblue --- README.md | 17 +++++++-- adbutils/_proto.py | 13 ++++--- adbutils/shell.py | 62 +++++++++++++++++++++++++++++---- test_real_device/test_device.py | 20 +++++++++-- 4 files changed, 97 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 5cbe1c2..f1e4277 100644 --- a/README.md +++ b/README.md @@ -284,9 +284,12 @@ d.app_info("com.github.uiautomator") # example output: {"version_name": "1.1.7", "version_code": "1007"} d.keyevent("HOME") + d.volume_up() d.volume_down() -d.volume_mute() +# default times=1, If you want to adjust the volume multiple times, you can use:d.volume_up(times=xxx) + +d.volume_mute() # device mute d.send_keys("hello world$%^&*") # simulate: adb shell input text "hello%sworld\%\^\&\*" @@ -302,8 +305,18 @@ d.root() # adb tcpip d.tcpip(5555) -print(d.battery()) +print(d.battery()) # get battery info BatteryInfo(ac_powered=False, usb_powered=False, wireless_powered=False, dock_powered=False, max_charging_current=0, max_charging_voltage=0, charge_counter=10000, status=4, health=2, present=True, level=100, scale=100, voltage=5000, temperature=25.0, technology='Li-ion') + +print(d.brightness_value) # get brightness value, return int value in 0-255 +d.brightness_value = 100 # set brightness value + +# you can also set brightness mode +from adbutils import BrightnessMode +print(d.brightness_mode) # output BrightnessMode.AUTO or BrightnessMode.MANUAL +d.brightness_mode = BrightnessMode.MANUAL # set brightness mode is manual +d.brightness_mode = BrightnessMode.AUTO # set brightness mode is auto + ``` Screenrecord (mp4) diff --git a/adbutils/_proto.py b/adbutils/_proto.py index 06baab8..97ad859 100644 --- a/adbutils/_proto.py +++ b/adbutils/_proto.py @@ -5,8 +5,8 @@ from __future__ import annotations __all__ = [ - "Network", "DeviceEvent", "ForwardItem", "ReverseItem", "FileInfo", - "WindowSize", "RunningAppInfo", "ShellReturn", "AdbDeviceInfo", "AppInfo" + "Network", "BrightnessMode", "DeviceEvent", "ForwardItem", "ReverseItem", "FileInfo", + "WindowSize", "RunningAppInfo", "ShellReturn", "AdbDeviceInfo", "AppInfo", "BatteryInfo" ] import enum @@ -27,6 +27,11 @@ class Network(str, enum.Enum): LOCAL_ABSTRACT = "localabstract" # same as UNIX +class BrightnessMode(int, enum.Enum): + AUTO = 1 + MANUAL = 0 + + @dataclass(frozen=True) class DeviceEvent: present: bool @@ -82,8 +87,8 @@ class BatteryInfo: present: Optional[bool] level: Optional[int] scale: Optional[int] - voltage: Optional[int] # mV - temperature: Optional[float] # e.g. 25.0 + voltage: Optional[int] # mV + temperature: Optional[float] # e.g. 25.0 technology: Optional[str] diff --git a/adbutils/shell.py b/adbutils/shell.py index e3a1ae5..8832378 100644 --- a/adbutils/shell.py +++ b/adbutils/shell.py @@ -10,7 +10,7 @@ import re import time from typing import List, Optional, Union -from adbutils._proto import WindowSize, AppInfo, RunningAppInfo, BatteryInfo +from adbutils._proto import WindowSize, AppInfo, RunningAppInfo, BatteryInfo, BrightnessMode from adbutils.errors import AdbError, AdbInstallError from adbutils._utils import escape_special_characters from retry import retry @@ -75,6 +75,55 @@ def switch_screen(self, enable: bool): """turn screen on/off""" return self.keyevent(224 if enable else 223) + @property + def brightness_value(self) -> int: + """ + Return screen brightness value, [0, 255] + + Examples: + print(d.brightness_value) output:128 + """ + value = self.shell('settings get system screen_brightness') + return int(value.strip()) + + @brightness_value.setter + def brightness_value(self, value: int): + """ + Set screen brightness values + :param value: brightness value + eg: d.brightness_value = 128 + """ + if not isinstance(value, int): + raise ValueError("Brightness value must be an integer") + if not 0 <= value <= 255: + raise ValueError("Brightness value must be between 0 and 255") + self.shell(f"settings put system screen_brightness {value}") + + @property + def brightness_mode(self) -> BrightnessMode: + """ + Return screen brightness mode + :return: BrightnessMode.AUTO or BrightnessMode.MANUAL + """ + value = int(self.shell('settings get system screen_brightness_mode')) + return BrightnessMode(value) + + @brightness_mode.setter + def brightness_mode(self, mode: BrightnessMode): + """ + Set screen brightness mode + + Args: + mode: BrightnessMode.AUTO or BrightnessMode.MANUAL + + Example: + d.brightness_mode = BrightnessMode.AUTO + """ + if isinstance(mode, BrightnessMode): + self.shell(f"settings put system screen_brightness_mode {mode.value}") + else: + raise ValueError("Brightness mode must be an instance of BrightnessMode") + def switch_airplane(self, enable: bool): """turn airplane-mode on/off""" base_setting_cmd = ["settings", "put", "global", "airplane_mode_on"] @@ -447,7 +496,7 @@ def battery(self) -> BatteryInfo: Returns: BatteryInfo - + Details: AC powered - Indicates that the device is currently not powered by AC power. If true, it indicates that the device is connected to an AC power adapter. USB powered - Indicates that the device is currently being powered or charged through the USB interface. @@ -464,21 +513,22 @@ def battery(self) -> BatteryInfo: Temperature - Battery temperature, usually measured in degrees Celsius (° C) Technology - Battery type, like (Li-ion) battery """ + def to_bool(v: str) -> bool: return v == "true" - + output = self.shell(["dumpsys", "battery"]) shell_kvs = {} for line in output.splitlines(): key, val = line.strip().split(':', 1) shell_kvs[key.strip()] = val.strip() - + def get_key(k: str, map_function): v = shell_kvs.get(k) if v is not None: return map_function(v) return None - + ac_powered = get_key("AC powered", to_bool) usb_powered = get_key("USB powered", to_bool) wireless_powered = get_key("Wireless powered", to_bool) @@ -510,4 +560,4 @@ def get_key(k: str, map_function): voltage=voltage, temperature=temperature, technology=technology, - ) \ No newline at end of file + ) diff --git a/test_real_device/test_device.py b/test_real_device/test_device.py index afe74a0..978ae4d 100644 --- a/test_real_device/test_device.py +++ b/test_real_device/test_device.py @@ -15,7 +15,7 @@ import pytest import adbutils -from adbutils import AdbDevice, Network +from adbutils import AdbDevice, Network, BrightnessMode from adbutils.errors import AdbSyncError @@ -74,6 +74,22 @@ def test_keyevent(device: AdbDevice): device.volume_mute() +def test_brightness(device: AdbDevice): + current_brightness = device.brightness_value + device.brightness_value = 100 + assert device.brightness_value == 100 + device.brightness_value = current_brightness + + current_mode = device.brightness_mode + if current_mode == BrightnessMode.AUTO: + device.brightness_mode = BrightnessMode.MANUAL + assert device.brightness_mode == BrightnessMode.MANUAL + elif current_mode == BrightnessMode.MANUAL: + device.brightness_mode = BrightnessMode.AUTO + assert device.brightness_mode == BrightnessMode.AUTO + device.brightness_mode = current_mode + + def test_switch_screen(device: AdbDevice): device.switch_screen(False) device.switch_screen(True) @@ -240,8 +256,6 @@ def test_logcat(device: AdbDevice, tmp_path: pathlib.Path): assert re.compile(r"I/TAG.*hello").search(logcat_path.read_text(encoding="utf-8")) - - # todo: make independent of already present stuff on the phone def test_pull_push_dirs( device: AdbDevice,