mediacontrollertest.py | mediacontrollertest.py | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
# SPDX-License-Identifier: GPL-2.0-or-later | # SPDX-License-Identifier: GPL-2.0-or-later | |||
# pylint: disable=too-many-arguments | # pylint: disable=too-many-arguments | |||
import threading | import threading | |||
import unittest | import unittest | |||
from os import getcwd, getpid, path | from os import getcwd, getpid, path | |||
from typing import Any, Final | from typing import Any, Final | |||
from appium import webdriver | from appium import webdriver | |||
from appium.options.common.base import AppiumOptions | ||||
from appium.webdriver.common.appiumby import AppiumBy | from appium.webdriver.common.appiumby import AppiumBy | |||
from gi.repository import Gio, GLib | from gi.repository import Gio, GLib | |||
from selenium.webdriver.support import expected_conditions as EC | from selenium.webdriver.support import expected_conditions as EC | |||
from selenium.webdriver.support.ui import WebDriverWait | from selenium.webdriver.support.ui import WebDriverWait | |||
WIDGET_ID: Final = "org.kde.plasma.mediacontroller" | ||||
class Mpris2: | class Mpris2: | |||
""" | """ | |||
MPRIS2 interface implemented in GDBus, since dbus-python does not suppo rt property | MPRIS2 interface implemented in GDBus, since dbus-python does not suppo rt property | |||
""" | """ | |||
BASE_IFACE: Final = "org.mpris.MediaPlayer2" | BASE_IFACE: Final = "org.mpris.MediaPlayer2" | |||
OBJECT_PATH: Final = "/org/mpris/MediaPlayer2" | OBJECT_PATH: Final = "/org/mpris/MediaPlayer2" | |||
PLAYER_IFACE: Final = GLib.Variant('s', "org.mpris.MediaPlayer2.Player" ) | PLAYER_IFACE: Final = GLib.Variant('s', "org.mpris.MediaPlayer2.Player" ) | |||
APP_INTERFACE: Final = f"org.mpris.MediaPlayer2.appiumtest.instance{str (getpid())}" | APP_INTERFACE: Final = f"org.mpris.MediaPlayer2.appiumtest.instance{str (getpid())}" | |||
skipping to change at line 76 | skipping to change at line 79 | |||
'MaximumRate': GLib.Variant('d', 1.0), | 'MaximumRate': GLib.Variant('d', 1.0), | |||
'Volume': GLib.Variant('d', 1.0), | 'Volume': GLib.Variant('d', 1.0), | |||
'CanGoNext': GLib.Variant('b', True), | 'CanGoNext': GLib.Variant('b', True), | |||
'CanGoPrevious': GLib.Variant('b', True), | 'CanGoPrevious': GLib.Variant('b', True), | |||
'CanPlay': GLib.Variant('b', True), | 'CanPlay': GLib.Variant('b', True), | |||
'CanPause': GLib.Variant('b', True), | 'CanPause': GLib.Variant('b', True), | |||
'CanSeek': GLib.Variant('b', True), | 'CanSeek': GLib.Variant('b', True), | |||
'CanControl': GLib.Variant('b', True), | 'CanControl': GLib.Variant('b', True), | |||
} | } | |||
self.__owner_id: int = Gio.bus_own_name(Gio.BusType.SESSION, self.A | self.__owner_id: int = Gio.bus_own_name(Gio.BusType.SESSION, self.A | |||
PP_INTERFACE, Gio.BusNameOwnerFlags.NONE, self.on_bus_acquired, | PP_INTERFACE, Gio.BusNameOwnerFlags.NONE, self.on_bus_acquired, self.on_nam | |||
self.on_name_acquired, self | e_acquired, self.on_name_lost) | |||
.on_name_lost) | ||||
assert self.__owner_id > 0 | assert self.__owner_id > 0 | |||
def quit(self) -> None: | def quit(self) -> None: | |||
self.stop(self.__connection, self.OBJECT_PATH) | self.stop(self.__connection, self.OBJECT_PATH) | |||
Gio.bus_unown_name(self.__owner_id) | Gio.bus_unown_name(self.__owner_id) | |||
print("Player exit") | print("Player exit") | |||
def on_bus_acquired(self, connection: Gio.DBusConnection, name: str, *a rgs) -> None: | def on_bus_acquired(self, connection: Gio.DBusConnection, name: str, *a rgs) -> None: | |||
""" | """ | |||
Interface is ready, now register objects. | Interface is ready, now register objects. | |||
""" | """ | |||
self.__connection = connection | self.__connection = connection | |||
properties_introspection_xml: str = '\n'.join(open("../dataengines/ mpris2/org.freedesktop.DBus.Properties.xml", encoding="utf-8").readlines()) | properties_introspection_xml: str = '\n'.join(open("../dataengines/ mpris2/org.freedesktop.DBus.Properties.xml", encoding="utf-8").readlines()) | |||
introspection_data = Gio.DBusNodeInfo.new_for_xml(properties_intros pection_xml) | introspection_data = Gio.DBusNodeInfo.new_for_xml(properties_intros pection_xml) | |||
reg_id = connection.register_object(self.OBJECT_PATH, introspection _data.interfaces[0], self.properties_handle_method_call, None, None) | reg_id = connection.register_object(self.OBJECT_PATH, introspection _data.interfaces[0], self.properties_handle_method_call, None, None) | |||
player_introspection_xml: str = '\n'.join(open("../dataengines/mpri s2/org.mpris.MediaPlayer2.Player.xml", encoding="utf-8").readlines()) | player_introspection_xml: str = '\n'.join(open("../dataengines/mpri s2/org.mpris.MediaPlayer2.Player.xml", encoding="utf-8").readlines()) | |||
introspection_data = Gio.DBusNodeInfo.new_for_xml(player_introspect ion_xml) | introspection_data = Gio.DBusNodeInfo.new_for_xml(player_introspect ion_xml) | |||
reg_id = connection.register_object(self.OBJECT_PATH, introspection | reg_id = connection.register_object(self.OBJECT_PATH, introspection | |||
_data.interfaces[0], self.player_handle_method_call, self.player_handle_get | _data.interfaces[0], self.player_handle_method_call, self.player_handle_get | |||
_property, | _property, self.player_handle_set_property) | |||
self.player_handle_set_property | ||||
) | ||||
assert reg_id != 0 | assert reg_id != 0 | |||
interface_introspection_xml: str = '\n'.join(open("../dataengines/m pris2/org.mpris.MediaPlayer2.xml", encoding="utf-8").readlines()) | interface_introspection_xml: str = '\n'.join(open("../dataengines/m pris2/org.mpris.MediaPlayer2.xml", encoding="utf-8").readlines()) | |||
introspection_data = Gio.DBusNodeInfo.new_for_xml(interface_introsp ection_xml) | introspection_data = Gio.DBusNodeInfo.new_for_xml(interface_introsp ection_xml) | |||
reg_id = connection.register_object(self.OBJECT_PATH, introspection | reg_id = connection.register_object(self.OBJECT_PATH, introspection | |||
_data.interfaces[0], self.interface_handle_method_call, | _data.interfaces[0], self.interface_handle_method_call, self.interface_hand | |||
self.interface_handle_get_prope | le_get_property, self.interface_handle_set_property) | |||
rty, self.interface_handle_set_property) | ||||
assert reg_id != 0 | assert reg_id != 0 | |||
def on_name_acquired(self, connection, name, *args) -> None: | def on_name_acquired(self, connection, name, *args) -> None: | |||
pass | pass | |||
def on_name_lost(self, connection, name, *args) -> None: | def on_name_lost(self, connection, name, *args) -> None: | |||
pass | pass | |||
def properties_handle_method_call(self, connection: Gio.DBusConnection, | def properties_handle_method_call(self, connection: Gio.DBusConnection, | |||
sender: str, object_path: str, interface_name: str, method_name: str, | sender: str, object_path: str, interface_name: str, method_name: str, para | |||
parameters: GLib.Variant, invocation: | meters: GLib.Variant, invocation: Gio.DBusMethodInvocation) -> None: | |||
Gio.DBusMethodInvocation) -> None: | ||||
""" | """ | |||
Handles method calls for org.freedesktop.DBus.Properties | Handles method calls for org.freedesktop.DBus.Properties | |||
""" | """ | |||
assert interface_name == "org.freedesktop.DBus.Properties", f"Wrong interface name {interface_name} from {sender}" | assert interface_name == "org.freedesktop.DBus.Properties", f"Wrong interface name {interface_name} from {sender}" | |||
if method_name == "Get": | if method_name == "Get": | |||
ret: Any = None | ret: Any = None | |||
interface: str = parameters[0] | interface: str = parameters[0] | |||
property_name: str = parameters[1] | property_name: str = parameters[1] | |||
if interface == self.BASE_IFACE: | if interface == self.BASE_IFACE: | |||
skipping to change at line 180 | skipping to change at line 179 | |||
invocation.return_value(None) | invocation.return_value(None) | |||
def set_playing(self, playing: bool, connection: Gio.DBusConnection, ob ject_path: str) -> None: | def set_playing(self, playing: bool, connection: Gio.DBusConnection, ob ject_path: str) -> None: | |||
""" | """ | |||
Changes the playing state | Changes the playing state | |||
""" | """ | |||
self.player_properties["PlaybackStatus"] = GLib.Variant('s', "Playi ng" if playing else "Paused") | self.player_properties["PlaybackStatus"] = GLib.Variant('s', "Playi ng" if playing else "Paused") | |||
changed_properties = GLib.Variant('a{sv}', { | changed_properties = GLib.Variant('a{sv}', { | |||
"PlaybackStatus": self.player_properties["PlaybackStatus"], | "PlaybackStatus": self.player_properties["PlaybackStatus"], | |||
}) | }) | |||
Gio.DBusConnection.emit_signal(connection, None, object_path, "org. | Gio.DBusConnection.emit_signal(connection, None, object_path, "org. | |||
freedesktop.DBus.Properties", "PropertiesChanged", | freedesktop.DBus.Properties", "PropertiesChanged", GLib.Variant.new_tuple(s | |||
GLib.Variant.new_tuple(self.PLAYER_I | elf.PLAYER_IFACE, changed_properties, GLib.Variant('as', ()))) | |||
FACE, changed_properties, GLib.Variant('as', ()))) | ||||
def stop(self, connection: Gio.DBusConnection, object_path: str) -> Non e: | def stop(self, connection: Gio.DBusConnection, object_path: str) -> Non e: | |||
""" | """ | |||
Changes the playing state | Changes the playing state | |||
""" | """ | |||
self.player_properties["PlaybackStatus"] = GLib.Variant('s', "Stopp ed") | self.player_properties["PlaybackStatus"] = GLib.Variant('s', "Stopp ed") | |||
self.player_properties["Metadata"] = GLib.Variant('a{sv}', {}) | self.player_properties["Metadata"] = GLib.Variant('a{sv}', {}) | |||
changed_properties = GLib.Variant('a{sv}', { | changed_properties = GLib.Variant('a{sv}', { | |||
"PlaybackStatus": self.player_properties["PlaybackStatus"], | "PlaybackStatus": self.player_properties["PlaybackStatus"], | |||
"Metadata": self.player_properties["Metadata"], | "Metadata": self.player_properties["Metadata"], | |||
}) | }) | |||
Gio.DBusConnection.emit_signal(connection, None, object_path, "org. | Gio.DBusConnection.emit_signal(connection, None, object_path, "org. | |||
freedesktop.DBus.Properties", "PropertiesChanged", | freedesktop.DBus.Properties", "PropertiesChanged", GLib.Variant.new_tuple(s | |||
GLib.Variant.new_tuple(self.PLAYER_I | elf.PLAYER_IFACE, changed_properties, GLib.Variant('as', ()))) | |||
FACE, changed_properties, GLib.Variant('as', ()))) | ||||
def set_rate(self, rate: float, connection: Gio.DBusConnection, object_ path: str) -> None: | def set_rate(self, rate: float, connection: Gio.DBusConnection, object_ path: str) -> None: | |||
""" | """ | |||
Changes the shuffle state | Changes the shuffle state | |||
""" | """ | |||
assert isinstance(rate, float), f"argument is not a float but {type (rate)}" | assert isinstance(rate, float), f"argument is not a float but {type (rate)}" | |||
assert self.player_properties["MinimumRate"].get_double() <= rate < = self.player_properties["MaximumRate"].get_double(), f"Rate {rate} is out of bounds" | assert self.player_properties["MinimumRate"].get_double() <= rate < = self.player_properties["MaximumRate"].get_double(), f"Rate {rate} is out of bounds" | |||
self.player_properties["Rate"] = GLib.Variant('d', rate) | self.player_properties["Rate"] = GLib.Variant('d', rate) | |||
changed_properties = GLib.Variant('a{sv}', { | changed_properties = GLib.Variant('a{sv}', { | |||
"Rate": self.player_properties["Rate"], | "Rate": self.player_properties["Rate"], | |||
}) | }) | |||
Gio.DBusConnection.emit_signal(connection, None, object_path, "org. | Gio.DBusConnection.emit_signal(connection, None, object_path, "org. | |||
freedesktop.DBus.Properties", "PropertiesChanged", | freedesktop.DBus.Properties", "PropertiesChanged", GLib.Variant.new_tuple(s | |||
GLib.Variant.new_tuple(self.PLAYER_I | elf.PLAYER_IFACE, changed_properties, GLib.Variant('as', ()))) | |||
FACE, changed_properties, GLib.Variant('as', ()))) | ||||
def set_shuffle(self, shuffle: bool, connection: Gio.DBusConnection, ob ject_path: str) -> None: | def set_shuffle(self, shuffle: bool, connection: Gio.DBusConnection, ob ject_path: str) -> None: | |||
""" | """ | |||
Changes the shuffle state | Changes the shuffle state | |||
""" | """ | |||
assert isinstance(shuffle, bool), f"argument is not a boolean but { type(shuffle)}" | assert isinstance(shuffle, bool), f"argument is not a boolean but { type(shuffle)}" | |||
self.player_properties["Shuffle"] = GLib.Variant('b', shuffle) | self.player_properties["Shuffle"] = GLib.Variant('b', shuffle) | |||
changed_properties = GLib.Variant('a{sv}', { | changed_properties = GLib.Variant('a{sv}', { | |||
"Shuffle": self.player_properties["Shuffle"], | "Shuffle": self.player_properties["Shuffle"], | |||
}) | }) | |||
Gio.DBusConnection.emit_signal(connection, None, object_path, "org. | Gio.DBusConnection.emit_signal(connection, None, object_path, "org. | |||
freedesktop.DBus.Properties", "PropertiesChanged", | freedesktop.DBus.Properties", "PropertiesChanged", GLib.Variant.new_tuple(s | |||
GLib.Variant.new_tuple(self.PLAYER_I | elf.PLAYER_IFACE, changed_properties, GLib.Variant('as', ()))) | |||
FACE, changed_properties, GLib.Variant('as', ()))) | ||||
def set_repeat(self, repeat: str, connection: Gio.DBusConnection, objec t_path: str) -> None: | def set_repeat(self, repeat: str, connection: Gio.DBusConnection, objec t_path: str) -> None: | |||
""" | """ | |||
Changes the loop state | Changes the loop state | |||
""" | """ | |||
assert isinstance(repeat, str), f"argument is not a string but {typ e(repeat)}" | assert isinstance(repeat, str), f"argument is not a string but {typ e(repeat)}" | |||
self.player_properties["LoopStatus"] = GLib.Variant('s', repeat) | self.player_properties["LoopStatus"] = GLib.Variant('s', repeat) | |||
changed_properties = GLib.Variant('a{sv}', { | changed_properties = GLib.Variant('a{sv}', { | |||
"LoopStatus": self.player_properties["LoopStatus"], | "LoopStatus": self.player_properties["LoopStatus"], | |||
}) | }) | |||
Gio.DBusConnection.emit_signal(connection, None, object_path, "org. | Gio.DBusConnection.emit_signal(connection, None, object_path, "org. | |||
freedesktop.DBus.Properties", "PropertiesChanged", | freedesktop.DBus.Properties", "PropertiesChanged", GLib.Variant.new_tuple(s | |||
GLib.Variant.new_tuple(self.PLAYER_I | elf.PLAYER_IFACE, changed_properties, GLib.Variant('as', ()))) | |||
FACE, changed_properties, GLib.Variant('as', ()))) | ||||
def set_volume(self, volume: float, connection: Gio.DBusConnection, obj ect_path: str) -> None: | def set_volume(self, volume: float, connection: Gio.DBusConnection, obj ect_path: str) -> None: | |||
""" | """ | |||
Adjusts the volume | Adjusts the volume | |||
""" | """ | |||
assert isinstance(volume, float) and 0 <= volume <= 1, f"Invalid vo lume {volume} of type {type(volume)}" | assert isinstance(volume, float) and 0 <= volume <= 1, f"Invalid vo lume {volume} of type {type(volume)}" | |||
self.player_properties["Volume"] = GLib.Variant('d', volume) | self.player_properties["Volume"] = GLib.Variant('d', volume) | |||
changed_properties = GLib.Variant('a{sv}', { | changed_properties = GLib.Variant('a{sv}', { | |||
"Volume": self.player_properties["Volume"], | "Volume": self.player_properties["Volume"], | |||
}) | }) | |||
Gio.DBusConnection.emit_signal(connection, None, object_path, "org. | Gio.DBusConnection.emit_signal(connection, None, object_path, "org. | |||
freedesktop.DBus.Properties", "PropertiesChanged", | freedesktop.DBus.Properties", "PropertiesChanged", GLib.Variant.new_tuple(s | |||
GLib.Variant.new_tuple(self.PLAYER_I | elf.PLAYER_IFACE, changed_properties, GLib.Variant('as', ()))) | |||
FACE, changed_properties, GLib.Variant('as', ()))) | ||||
def player_handle_method_call(self, connection: Gio.DBusConnection, sen | def player_handle_method_call(self, connection: Gio.DBusConnection, sen | |||
der: str, object_path: str, interface_name: str, method_name: str, | der: str, object_path: str, interface_name: str, method_name: str, paramete | |||
parameters: GLib.Variant, invocation: Gio | rs: GLib.Variant, invocation: Gio.DBusMethodInvocation) -> None: | |||
.DBusMethodInvocation) -> None: | ||||
""" | """ | |||
Handles method calls for org.mpris.MediaPlayer2.Player | Handles method calls for org.mpris.MediaPlayer2.Player | |||
""" | """ | |||
assert interface_name == "org.mpris.MediaPlayer2.Player", f"Wrong i nterface name {interface_name} from {sender}" | assert interface_name == "org.mpris.MediaPlayer2.Player", f"Wrong i nterface name {interface_name} from {sender}" | |||
print(f"player_handle_method_call method_name: {method_name}") | print(f"player_handle_method_call method_name: {method_name}") | |||
if method_name == "Next": | if method_name == "Next": | |||
self.metadata = { | self.metadata = { | |||
'mpris:trackid': GLib.Variant('o', "/appiumtest/2"), | 'mpris:trackid': GLib.Variant('o', "/appiumtest/2"), | |||
'xesam:url': GLib.Variant('s', "file://" + path.join(getcwd (), "resources/media2.mp3")), | 'xesam:url': GLib.Variant('s', "file://" + path.join(getcwd (), "resources/media2.mp3")), | |||
'mpris:length': GLib.Variant('x', 90 * 10e6), # ms | 'mpris:length': GLib.Variant('x', 90 * 10e6), # ms | |||
'xesam:title': GLib.Variant('s', "Konqi's Favorite"), | 'xesam:title': GLib.Variant('s', "Konqi's Favorite"), | |||
'xesam:album': GLib.Variant('s', "The Best of Konqi"), | 'xesam:album': GLib.Variant('s', "The Best of Konqi"), | |||
'xesam:artist': GLib.Variant('as', ["KDE Community", "KDE 社 区"]), | 'xesam:artist': GLib.Variant('as', ["KDE Community", "KDE 社 区"]), | |||
"mpris:artUrl": GLib.Variant('s', "file://" + path.join(get cwd(), "resources/mediacontrollertests_art2.png")) | "mpris:artUrl": GLib.Variant('s', "file://" + path.join(get cwd(), "resources/mediacontrollertests_art2.png")) | |||
} | } | |||
self.player_properties["Metadata"] = GLib.Variant('a{sv}', self .metadata) | self.player_properties["Metadata"] = GLib.Variant('a{sv}', self .metadata) | |||
self.player_properties["CanGoPrevious"] = GLib.Variant('b', Tru e) | self.player_properties["CanGoPrevious"] = GLib.Variant('b', Tru e) | |||
self.player_properties["CanGoNext"] = GLib.Variant('b', False) | self.player_properties["CanGoNext"] = GLib.Variant('b', False) | |||
changed_properties = GLib.Variant( | changed_properties = GLib.Variant('a{sv}', { | |||
'a{sv}', { | 'Metadata': self.player_properties["Metadata"], | |||
'Metadata': self.player_properties["Metadata"], | "CanGoPrevious": self.player_properties["CanGoPrevious"], | |||
"CanGoPrevious": self.player_properties["CanGoPrevious" | "CanGoNext": self.player_properties["CanGoNext"], | |||
], | }) | |||
"CanGoNext": self.player_properties["CanGoNext"], | Gio.DBusConnection.emit_signal(connection, None, object_path, " | |||
}) | org.freedesktop.DBus.Properties", "PropertiesChanged", GLib.Variant.new_tup | |||
Gio.DBusConnection.emit_signal(connection, None, object_path, " | le(self.PLAYER_IFACE, changed_properties, GLib.Variant('as', ()))) | |||
org.freedesktop.DBus.Properties", "PropertiesChanged", | ||||
GLib.Variant.new_tuple(self.PLAY | ||||
ER_IFACE, changed_properties, GLib.Variant('as', ()))) | ||||
elif method_name == "Previous": | elif method_name == "Previous": | |||
self.metadata = { | self.metadata = { | |||
'mpris:trackid': GLib.Variant('o', "/appiumtest/2"), | 'mpris:trackid': GLib.Variant('o', "/appiumtest/2"), | |||
'xesam:url': GLib.Variant('s', "file://" + path.join(getcwd (), "resources/media0.mp3")), | 'xesam:url': GLib.Variant('s', "file://" + path.join(getcwd (), "resources/media0.mp3")), | |||
'mpris:length': GLib.Variant('x', 60 * 10e6), # ms | 'mpris:length': GLib.Variant('x', 60 * 10e6), # ms | |||
'xesam:title': GLib.Variant('s', "Katie's Favorite"), | 'xesam:title': GLib.Variant('s', "Katie's Favorite"), | |||
'xesam:album': GLib.Variant('s', "The Best of Konqi"), | 'xesam:album': GLib.Variant('s', "The Best of Konqi"), | |||
'xesam:artist': GLib.Variant('as', ["KDE Community"]), | 'xesam:artist': GLib.Variant('as', ["KDE Community"]), | |||
"mpris:artUrl": GLib.Variant('s', "file://" + path.join(get cwd(), "resources/mediacontrollertests_art0.png")) | "mpris:artUrl": GLib.Variant('s', "file://" + path.join(get cwd(), "resources/mediacontrollertests_art0.png")) | |||
} | } | |||
self.player_properties["Metadata"] = GLib.Variant('a{sv}', self .metadata) | self.player_properties["Metadata"] = GLib.Variant('a{sv}', self .metadata) | |||
self.player_properties["CanGoPrevious"] = GLib.Variant('b', Fal se) | self.player_properties["CanGoPrevious"] = GLib.Variant('b', Fal se) | |||
self.player_properties["CanGoNext"] = GLib.Variant('b', True) | self.player_properties["CanGoNext"] = GLib.Variant('b', True) | |||
changed_properties = GLib.Variant( | changed_properties = GLib.Variant('a{sv}', { | |||
'a{sv}', { | 'Metadata': self.player_properties["Metadata"], | |||
'Metadata': self.player_properties["Metadata"], | "CanGoPrevious": self.player_properties["CanGoPrevious"], | |||
"CanGoPrevious": self.player_properties["CanGoPrevious" | "CanGoNext": self.player_properties["CanGoNext"], | |||
], | }) | |||
"CanGoNext": self.player_properties["CanGoNext"], | Gio.DBusConnection.emit_signal(connection, None, object_path, " | |||
}) | org.freedesktop.DBus.Properties", "PropertiesChanged", GLib.Variant.new_tup | |||
Gio.DBusConnection.emit_signal(connection, None, object_path, " | le(self.PLAYER_IFACE, changed_properties, GLib.Variant('as', ()))) | |||
org.freedesktop.DBus.Properties", "PropertiesChanged", | ||||
GLib.Variant.new_tuple(self.PLAY | ||||
ER_IFACE, changed_properties, GLib.Variant('as', ()))) | ||||
elif method_name == "Pause": | elif method_name == "Pause": | |||
self.set_playing(False, connection, object_path) | self.set_playing(False, connection, object_path) | |||
elif method_name == "PlayPause": | elif method_name == "PlayPause": | |||
self.set_playing(self.player_properties["PlaybackStatus"] != "P laying", connection, object_path) | self.set_playing(self.player_properties["PlaybackStatus"] != "P laying", connection, object_path) | |||
elif method_name == "Stop": | elif method_name == "Stop": | |||
self.stop(connection, object_path) | self.stop(connection, object_path) | |||
skipping to change at line 319 | skipping to change at line 307 | |||
elif method_name == "Seek": | elif method_name == "Seek": | |||
offset: int = parameters[0] | offset: int = parameters[0] | |||
length: int = int(self.metadata["mpris:length"]) | length: int = int(self.metadata["mpris:length"]) | |||
position: int = int(self.player_properties["Position"]) | position: int = int(self.player_properties["Position"]) | |||
assert 0 <= position + offset <= length | assert 0 <= position + offset <= length | |||
self.player_properties["Position"] = GLib.Variant('x', position + offset) | self.player_properties["Position"] = GLib.Variant('x', position + offset) | |||
changed_properties = GLib.Variant('a{sv}', { | changed_properties = GLib.Variant('a{sv}', { | |||
'Position': self.player_properties["Position"], | 'Position': self.player_properties["Position"], | |||
}) | }) | |||
Gio.DBusConnection.emit_signal(connection, None, object_path, s | Gio.DBusConnection.emit_signal(connection, None, object_path, s | |||
elf.PLAYER_IFACE.get_string(), "Seeked", | elf.PLAYER_IFACE.get_string(), "Seeked", GLib.Variant.new_tuple(self.player | |||
GLib.Variant.new_tuple(self.play | _properties["Position"])) | |||
er_properties["Position"])) | Gio.DBusConnection.emit_signal(connection, None, object_path, " | |||
Gio.DBusConnection.emit_signal(connection, None, object_path, " | org.freedesktop.DBus.Properties", "PropertiesChanged", GLib.Variant.new_tup | |||
org.freedesktop.DBus.Properties", "PropertiesChanged", | le(self.PLAYER_IFACE, changed_properties, GLib.Variant('as', ()))) | |||
GLib.Variant.new_tuple(self.PLAY | ||||
ER_IFACE, changed_properties, GLib.Variant('as', ()))) | ||||
elif method_name == "SetPosition": | elif method_name == "SetPosition": | |||
assert parameters[0] == self.metadata["mpris:trackid"].get_stri | assert parameters[0] == self.metadata["mpris:trackid"].get_stri | |||
ng( | ng(), f"expected trackid: {parameters[0]}, actual trackid: {self.metadata[' | |||
), f"expected trackid: {parameters[0]}, actual trackid: {self.m | mpris:trackid'].get_string()}" | |||
etadata['mpris:trackid'].get_string()}" | ||||
self.player_properties["Position"] = GLib.Variant('x', paramete rs[1]) | self.player_properties["Position"] = GLib.Variant('x', paramete rs[1]) | |||
changed_properties = GLib.Variant('a{sv}', { | changed_properties = GLib.Variant('a{sv}', { | |||
'Position': self.player_properties["Position"], | 'Position': self.player_properties["Position"], | |||
}) | }) | |||
Gio.DBusConnection.emit_signal(connection, None, object_path, " | Gio.DBusConnection.emit_signal(connection, None, object_path, " | |||
org.freedesktop.DBus.Properties", "PropertiesChanged", | org.freedesktop.DBus.Properties", "PropertiesChanged", GLib.Variant.new_tup | |||
GLib.Variant.new_tuple(self.PLAY | le(self.PLAYER_IFACE, changed_properties, GLib.Variant('as', ()))) | |||
ER_IFACE, changed_properties, GLib.Variant('as', ()))) | ||||
elif method_name == "OpenUri": | elif method_name == "OpenUri": | |||
print("OpenUri") | print("OpenUri") | |||
else: | else: | |||
# In case the interface adds new methods, fail here for easier discovery | # In case the interface adds new methods, fail here for easier discovery | |||
assert False, f"{method_name} does not exist" | assert False, f"{method_name} does not exist" | |||
def player_handle_get_property(self, connection: Gio.DBusConnection, se nder: str, object_path: str, interface_name: str, value: Any): | def player_handle_get_property(self, connection: Gio.DBusConnection, se nder: str, object_path: str, interface_name: str, value: Any): | |||
""" | """ | |||
skipping to change at line 375 | skipping to change at line 359 | |||
elif key == "Volume": | elif key == "Volume": | |||
self.set_volume(value, connection, object_path) | self.set_volume(value, connection, object_path) | |||
else: | else: | |||
assert False | assert False | |||
# What is the correct thing to return here on success? It appears that | # What is the correct thing to return here on success? It appears that | |||
# we need to return something other than None or what would be eval uated | # we need to return something other than None or what would be eval uated | |||
# to False for this call back to be successful. | # to False for this call back to be successful. | |||
return True | return True | |||
def interface_handle_method_call(self, connection: Gio.DBusConnection, | def interface_handle_method_call(self, connection: Gio.DBusConnection, | |||
sender: str, object_path: str, interface_name: str, method_name: str, | sender: str, object_path: str, interface_name: str, method_name: str, param | |||
parameters: GLib.Variant, invocation: | eters: GLib.Variant, invocation: Gio.DBusMethodInvocation) -> None: | |||
Gio.DBusMethodInvocation) -> None: | ||||
""" | """ | |||
Handles method calls for org.mpris.MediaPlayer2 | Handles method calls for org.mpris.MediaPlayer2 | |||
""" | """ | |||
assert interface_name == "org.mpris.MediaPlayer2", f"Wrong interfac e name {interface_name} from {sender}" | assert interface_name == "org.mpris.MediaPlayer2", f"Wrong interfac e name {interface_name} from {sender}" | |||
if method_name == "Raise": | if method_name == "Raise": | |||
print("Raise") | print("Raise") | |||
elif method_name == "Quit": | elif method_name == "Quit": | |||
print("Quit") | print("Quit") | |||
else: | else: | |||
skipping to change at line 445 | skipping to change at line 428 | |||
driver: webdriver.Remote | driver: webdriver.Remote | |||
mpris_interface: Mpris2 | None | mpris_interface: Mpris2 | None | |||
loopThread: GlibMainloopThread | loopThread: GlibMainloopThread | |||
@classmethod | @classmethod | |||
def setUpClass(cls) -> None: | def setUpClass(cls) -> None: | |||
""" | """ | |||
Opens the widget and initialize the webdriver | Opens the widget and initialize the webdriver | |||
""" | """ | |||
desired_caps: dict[str, Any] = {} | options = AppiumOptions() | |||
desired_caps["app"] = "plasmawindowed -p org.kde.plasma.nano org.kd | options.set_capability("app", f"plasmawindowed -p org.kde.plasma.na | |||
e.plasma.mediacontroller" | no {WIDGET_ID}") | |||
desired_caps["timeouts"] = {'implicit': 5000} | options.set_capability("timeouts", {'implicit': 10000}) | |||
cls.driver = webdriver.Remote(command_executor='http://127.0.0.1:47 | cls.driver = webdriver.Remote(command_executor='http://127.0.0.1:47 | |||
23', desired_capabilities=desired_caps) | 23', options=options) | |||
cls.driver.implicitly_wait = 10 | ||||
cls.loopThread = GlibMainloopThread() | cls.loopThread = GlibMainloopThread() | |||
cls.loopThread.start() | cls.loopThread.start() | |||
@classmethod | @classmethod | |||
def tearDownClass(cls) -> None: | def tearDownClass(cls) -> None: | |||
cls.loopThread.quit() | cls.loopThread.quit() | |||
def setUp(self) -> None: | def setUp(self) -> None: | |||
self.mpris_interface = Mpris2() | self.mpris_interface = Mpris2() | |||
End of changes. 20 change blocks. | ||||
94 lines changed or deleted | 73 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |