Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new device API #139

Merged
merged 6 commits into from
Jun 15, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 40 additions & 30 deletions qubesguidaemon/mic.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,46 +18,55 @@
# You should have received a copy of the GNU General Public License along
# with this program; if not, see <http://www.gnu.org/licenses/>.

'''Microphone control extension'''
"""Microphone control extension"""

import asyncio
import subprocess

import qubes.devices
import qubes.device_protocol
import qubes.ext
import qubes.vm.adminvm

class MicDevice(qubes.devices.DeviceInfo):
'''Microphone device info class'''
pass

class MicDeviceExtension(qubes.ext.Extension):
'''Extension to control microphone access
class MicDevice(qubes.device_protocol.DeviceInfo):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing qubes.device_protocol import

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it should be qubes.devices.DeviceInfo... device_protocol is in qubesadmin

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You were right, I didn't update core-admin, but it should be OK now: QubesOS/qubes-core-admin/pull/579/commits/1004c670b76019ff83d0d1587d2a23c514c2cd4b

"""Microphone device info class"""

def __init__(self, backend_domain, product, manufacturer):
super().__init__(
backend_domain=backend_domain,
ident="mic", devclass="mic",
product=product, manufacturer=manufacturer)
self._interfaces = [
qubes.device_protocol.DeviceInterface("******", devclass="mic")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mic device needs some more info, to avoid confusing "unknown mic device" description:
https://openqa.qubes-os.org/tests/96797#step/qui_widgets_devices/4

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed it to "microphone (build-in)"


'''

class MicDeviceExtension(qubes.ext.Extension):
"""
Extension to control microphone access
"""

def __init__(self):
super(MicDeviceExtension, self).__init__()

def get_device(self, app):
return MicDevice(app.domains[0], 'mic', 'Microphone')
return MicDevice(
app.domains[0], product="microphone", manufacturer="build-in")

@qubes.ext.handler('device-list:mic')
def on_device_list_mic(self, vm, event):
'''List microphone device
"""List microphone device

Currently this assume audio being handled in dom0. When adding support
Currently, this assumes audio being handled in dom0. When adding support
for GUI domain, this needs to be changed
'''
"""
return self.on_device_get_mic(vm, event, 'mic')

@qubes.ext.handler('device-get:mic')
def on_device_get_mic(self, vm, event, ident):
'''Get microphone device
"""Get microphone device

Currently this assume audio being handled in dom0. When adding support
Currently, this assumes audio being handled in dom0. When adding support
for GUI domain, this needs to be changed
'''
"""
# pylint: disable=unused-argument,no-self-use

if not isinstance(vm, qubes.vm.adminvm.AdminVM):
Expand All @@ -70,7 +79,7 @@ def on_device_get_mic(self, vm, event, ident):

@qubes.ext.handler('device-list-attached:mic')
def on_device_list_attached_mic(self, vm, event, persistent=None):
'''List attached microphone to the VM'''
"""List attached microphone to the VM"""

if persistent is True:
return
Expand All @@ -88,7 +97,7 @@ def on_device_list_attached_mic(self, vm, event, persistent=None):

@qubes.ext.handler('device-pre-attach:mic')
async def on_device_pre_attach_mic(self, vm, event, device, options):
'''Attach microphone to the VM'''
"""Attach microphone to the VM"""

# there is only one microphone
assert device == self.get_device(vm.app)
Expand All @@ -101,21 +110,22 @@ async def on_device_pre_attach_mic(self, vm, event, device, options):
if audiovm is None:
raise qubes.exc.QubesException(
"VM {} has no AudioVM set".format(vm))

if not audiovm.is_running():
raise qubes.exc.QubesVMNotRunningError(audiovm,
"Audio VM {} isn't running".format(audiovm))
raise qubes.exc.QubesVMNotRunningError(
audiovm, "Audio VM {} isn't running".format(audiovm))
try:
await audiovm.run_service_for_stdio(
'qubes.AudioInputEnable+{}'.format(vm.name))
except subprocess.CalledProcessError as e:
raise qubes.exc.QubesVMError(vm,
'Failed to attach audio input from {!s} to {!s}: '
except subprocess.CalledProcessError:
raise qubes.exc.QubesVMError(
vm, 'Failed to attach audio input from {!s} to {!s}: '
'pulseaudio agent not running'.format(audiovm, vm))

# pylint: disable=unused-argument
@qubes.ext.handler('device-pre-detach:mic')
async def on_device_pre_detach_mic(self, vm, event, device):
'''Detach microphone from the VM'''
"""Detach microphone from the VM"""

# there is only one microphone
assert device == self.get_device(vm.app)
Expand All @@ -127,12 +137,12 @@ async def on_device_pre_detach_mic(self, vm, event, device):
"VM {} has no AudioVM set".format(vm))

if not audiovm.is_running():
raise qubes.exc.QubesVMNotRunningError(audiovm,
"Audio VM {} isn't running".format(audiovm))
raise qubes.exc.QubesVMNotRunningError(
audiovm, "Audio VM {} isn't running".format(audiovm))
try:
await audiovm.run_service_for_stdio(
'qubes.AudioInputDisable+{}'.format(vm.name))
except subprocess.CalledProcessError as e:
raise qubes.exc.QubesVMError(vm,
'Failed to detach audio input from {!s} to {!s}: '
except subprocess.CalledProcessError:
raise qubes.exc.QubesVMError(
vm, 'Failed to detach audio input from {!s} to {!s}: '
'pulseaudio agent not running'.format(audiovm, vm))