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
This commit is contained in:
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
the Listening property to change and StartListening() once the
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

View File

@ -14,6 +14,7 @@
from gi.repository import GObject, Gio, GLib
import sys
import argparse
import os
import json
import logging
import select
@ -133,6 +134,9 @@ class TuhiKeteDevice(_DBusObject):
if signal == 'ButtonPressRequired':
print("{}: Press button on device now".format(self))
elif signal == 'ListeningStopped':
err = parameters[0]
if err < 0:
print("{}: an error occured: {}".format(self, os.strerror(err)))
self.notify('listening')
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
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):
GObject.Object.__init__(self)
@ -177,8 +183,11 @@ class TuhiDevice(GObject.Object):
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()
if exception is not None:
logger.info(exception)
self.emit('device-error', exception)
def _on_button_press_required(self, device):
self._tuhi_dbus_device.notify_button_press_required()

View File

@ -147,6 +147,7 @@ class TuhiDBusDevice(_TuhiDBus):
self._listening_client = None
self._dbusid = self._register_object(connection)
device.connect('notify::paired', self._on_device_paired)
device.connect('device-error', self._on_device_error)
@GObject.Property
def listening(self):
@ -231,6 +232,12 @@ class TuhiDBusDevice(_TuhiDBus):
return
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):
if self.listening:
logger.debug("{} - already listening".format(self))
@ -265,7 +272,7 @@ class TuhiDBusDevice(_TuhiDBus):
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]:
return
@ -275,7 +282,7 @@ class TuhiDBusDevice(_TuhiDBus):
self.notify('listening')
status = GLib.Variant.new_int32(0)
status = GLib.Variant.new_int32(errno)
self.signal('ListeningStopped', status, dest=sender)
self.listening = False
self.notify('listening')

View File

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