wacom: throw the exception (if any) to the "done" handler

Attach an errno to all exceptions, so we can bubble that up to the client
and display a message.

Fixes #24
pull/34/head
Peter Hutterer 2018-01-24 21:06:16 +10:00
parent bf3842c150
commit 3d516530c6
5 changed files with 52 additions and 11 deletions

View File

@ -227,6 +227,22 @@ org.freedesktop.tuhi1.Device
on behalf of another client. In this case, this client should wait for on behalf of another client. In this case, this client should wait for
the Listening property to change and StartListening() once the the Listening property to change and StartListening() once the
property is set to False. property is set to False.
If the error is -EBADE, the device is not in pairing/listening mode
and pairing/listening was requested. In this case, the client should
indicate to the user that the device needs to be paired first or
switched to listening mode.
If the error is -EACCES, the device is not paired with the daemon or
incorrectly paired. This may happen when the device was paired with
another host since the last connection.
The following other errnos may be sent by the daemon:
-EPROTO: the daemon has encountered a protocol error with the device.
-ETIME: timeout while communicating with the device.
These errnos indicate a bug in the daemon, and the client should
display a message to that effect.
``` ```
JSON File Format JSON File Format

View File

@ -14,6 +14,7 @@
from gi.repository import GObject, Gio, GLib from gi.repository import GObject, Gio, GLib
import sys import sys
import argparse import argparse
import os
import json import json
import logging import logging
import select import select
@ -133,6 +134,9 @@ class TuhiKeteDevice(_DBusObject):
if signal == 'ButtonPressRequired': if signal == 'ButtonPressRequired':
print("{}: Press button on device now".format(self)) print("{}: Press button on device now".format(self))
elif signal == 'ListeningStopped': elif signal == 'ListeningStopped':
err = parameters[0]
if err < 0:
print("{}: an error occured: {}".format(self, os.strerror(err)))
self.notify('listening') self.notify('listening')
def _on_properties_changed(self, proxy, changed_props, invalidated_props): def _on_properties_changed(self, proxy, changed_props, invalidated_props):

View File

@ -76,6 +76,12 @@ class TuhiDevice(GObject.Object):
real device) with the frontend DBusServer object that exports the device real device) with the frontend DBusServer object that exports the device
over Tuhi's DBus interface over Tuhi's DBus interface
""" """
__gsignals__ = {
# Signal sent when an error occurs on the device itself.
# Argument is a Wacom*Exception
'device-error':
(GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)),
}
def __init__(self, bluez_device, config, uuid=None, paired=True): def __init__(self, bluez_device, config, uuid=None, paired=True):
GObject.Object.__init__(self) GObject.Object.__init__(self)
@ -177,8 +183,11 @@ class TuhiDevice(GObject.Object):
self._tuhi_dbus_device.add_drawing(d) self._tuhi_dbus_device.add_drawing(d)
def _on_fetching_finished(self, device, bluez_device): def _on_fetching_finished(self, device, exception, bluez_device):
bluez_device.disconnect_device() bluez_device.disconnect_device()
if exception is not None:
logger.info(exception)
self.emit('device-error', exception)
def _on_button_press_required(self, device): def _on_button_press_required(self, device):
self._tuhi_dbus_device.notify_button_press_required() self._tuhi_dbus_device.notify_button_press_required()

View File

@ -147,6 +147,7 @@ class TuhiDBusDevice(_TuhiDBus):
self._listening_client = None self._listening_client = None
self._dbusid = self._register_object(connection) self._dbusid = self._register_object(connection)
device.connect('notify::paired', self._on_device_paired) device.connect('notify::paired', self._on_device_paired)
device.connect('device-error', self._on_device_error)
@GObject.Property @GObject.Property
def listening(self): def listening(self):
@ -231,6 +232,12 @@ class TuhiDBusDevice(_TuhiDBus):
return return
self.paired = device.paired self.paired = device.paired
def _on_device_error(self, device, exception):
logger.info('An error occured while synching the device')
if self.listening:
self._stop_listening(self.connection, self._listening_client[0],
-exception.errno)
def _start_listening(self, connection, sender): def _start_listening(self, connection, sender):
if self.listening: if self.listening:
logger.debug("{} - already listening".format(self)) logger.debug("{} - already listening".format(self))
@ -265,7 +272,7 @@ class TuhiDBusDevice(_TuhiDBus):
self._stop_listening(connection, user_data) self._stop_listening(connection, user_data)
def _stop_listening(self, connection, sender): def _stop_listening(self, connection, sender, errno=0):
if not self.listening or sender != self._listening_client[0]: if not self.listening or sender != self._listening_client[0]:
return return
@ -275,7 +282,7 @@ class TuhiDBusDevice(_TuhiDBus):
self.notify('listening') self.notify('listening')
status = GLib.Variant.new_int32(0) status = GLib.Variant.new_int32(errno)
self.signal('ListeningStopped', status, dest=sender) self.signal('ListeningStopped', status, dest=sender)
self.listening = False self.listening = False
self.notify('listening') self.notify('listening')

View File

@ -17,6 +17,7 @@ import logging
import threading import threading
import time import time
import uuid import uuid
import errno
from gi.repository import GObject from gi.repository import GObject
logger = logging.getLogger('tuhi.wacom') logger = logging.getLogger('tuhi.wacom')
@ -86,27 +87,27 @@ class Drawing(list):
class WacomException(Exception): class WacomException(Exception):
pass errno = errno.ENOSYS
class WacomEEAGAINException(WacomException): class WacomEEAGAINException(WacomException):
pass errno = errno.EAGAIN
class WacomWrongModeException(WacomException): class WacomWrongModeException(WacomException):
pass errno = errno.EBADE
class WacomNotPairedException(WacomException): class WacomNotPairedException(WacomException):
pass errno = errno.EACCES
class WacomTimeoutException(WacomException): class WacomTimeoutException(WacomException):
pass errno = errno.ETIME
class WacomCorruptDataException(WacomException): class WacomCorruptDataException(WacomException):
pass errno = errno.EPROTO
class WacomDevice(GObject.Object): class WacomDevice(GObject.Object):
@ -121,7 +122,7 @@ class WacomDevice(GObject.Object):
"drawing": "drawing":
(GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)), (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)),
"done": "done":
(GObject.SIGNAL_RUN_FIRST, None, ()), (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT, )),
"button-press-required": "button-press-required":
(GObject.SIGNAL_RUN_FIRST, None, ()), (GObject.SIGNAL_RUN_FIRST, None, ()),
} }
@ -643,15 +644,19 @@ class WacomDevice(GObject.Object):
logger.debug('{}: starting'.format(self.device.address)) logger.debug('{}: starting'.format(self.device.address))
self._is_running = True self._is_running = True
exception = None
try: try:
if self._pairing_mode: if self._pairing_mode:
self.pair_device() self.pair_device()
else: else:
self.retrieve_data() self.retrieve_data()
except WacomException as e:
logger.error(f'**** Exception: {e} ****')
exception = e
finally: finally:
self._pairing_mode = False self._pairing_mode = False
self._is_running = False self._is_running = False
self.emit("done") self.emit("done", exception)
def start(self, pairing_mode): def start(self, pairing_mode):
self._pairing_mode = pairing_mode self._pairing_mode = pairing_mode