correctly handle out-of-process pairing and unpairing
This commit is contained in:
parent
3319feeb73
commit
bd3198f6f0
|
@ -124,6 +124,8 @@ def _process_hidpp10_notification(device, status, n):
|
|||
status.clear()
|
||||
device.wpid = None
|
||||
device.status = None
|
||||
if device.number in device.receiver:
|
||||
del device.receiver[device.number]
|
||||
status.changed(active=False, alert=_ALERT.ALL, reason='unpaired')
|
||||
else:
|
||||
_log.warn("%s: disconnection with unknown type %02X: %s", device, n.address, n)
|
||||
|
|
|
@ -60,6 +60,8 @@ class PairedDevice(object):
|
|||
self._polling_rate = None
|
||||
self._power_switch = None
|
||||
|
||||
# _log.debug("new PairedDevice(%s, %s, %s)", receiver, number, link_notification)
|
||||
|
||||
if link_notification is not None:
|
||||
self.online = bool(ord(link_notification.data[0:1]) & 0x40)
|
||||
self.wpid = _strhex(link_notification.data[2:3] + link_notification.data[1:2])
|
||||
|
@ -81,7 +83,7 @@ class PairedDevice(object):
|
|||
device_info = self.receiver.read_register(_R.receiver_info, 0x04)
|
||||
if device_info is None:
|
||||
_log.error("failed to read Nano wpid for device %d of %s", number, receiver)
|
||||
raise _base.NoSuchDevice(nuber=number, receiver=receiver, error="read Nano wpid")
|
||||
raise _base.NoSuchDevice(number=number, receiver=receiver, error="read Nano wpid")
|
||||
|
||||
self.wpid = _strhex(device_info[3:5])
|
||||
self._polling_rate = 0
|
||||
|
@ -437,16 +439,24 @@ class Receiver(object):
|
|||
return self.register_new_device(key)
|
||||
|
||||
def __delitem__(self, key):
|
||||
key = int(key)
|
||||
|
||||
if self._devices.get(key) is None:
|
||||
raise IndexError(key)
|
||||
|
||||
dev = self._devices[key]
|
||||
if not dev:
|
||||
if key in self._devices:
|
||||
del self._devices[key]
|
||||
return
|
||||
|
||||
action = 0x03
|
||||
reply = self.write_register(_R.receiver_pairing, action, int(key))
|
||||
reply = self.write_register(_R.receiver_pairing, action, key)
|
||||
if reply:
|
||||
# invalidate the device
|
||||
dev.online = False
|
||||
dev.wpid = None
|
||||
if key in self._devices:
|
||||
del self._devices[key]
|
||||
_log.warn("%s unpaired device %s", self, dev)
|
||||
else:
|
||||
|
|
|
@ -223,7 +223,12 @@ def pair_device(receiver, args):
|
|||
receiver.set_lock(False, timeout=timeout)
|
||||
print ("Pairing: turn your new device on (timing out in", timeout, "seconds).")
|
||||
|
||||
while receiver.status.lock_open:
|
||||
# the lock-open notification may come slightly later, wait for it a bit
|
||||
from time import time as timestamp
|
||||
pairing_start = timestamp()
|
||||
patience = 5 # seconds
|
||||
|
||||
while receiver.status.lock_open or timestamp() - pairing_start < patience:
|
||||
n = base.read(receiver.handle)
|
||||
if n:
|
||||
n = base.make_notification(*n)
|
||||
|
@ -239,7 +244,8 @@ def pair_device(receiver, args):
|
|||
dev = receiver.status.new_device
|
||||
print ("Paired device %d: %s [%s:%s:%s]" % (dev.number, dev.name, dev.wpid, dev.codename, dev.serial))
|
||||
else:
|
||||
_fail(receiver.status[status.KEYS.ERROR])
|
||||
error = receiver.status[status.KEYS.ERROR] or 'no device detected?'
|
||||
_fail(error)
|
||||
|
||||
|
||||
def unpair_device(receiver, args):
|
||||
|
|
|
@ -139,8 +139,9 @@ class ReceiverListener(_listener.EventsListener):
|
|||
|
||||
assert device.receiver == self.receiver
|
||||
if not device:
|
||||
# device was unpaired, and since the object is weakref'ed
|
||||
# it won't be valid for much longer
|
||||
# Device was unpaired, and isn't valid anymore.
|
||||
# We replace it with a ghost so that the UI has something to work
|
||||
# with while cleaning up.
|
||||
_log.warn("device %s was unpaired, ghosting", device)
|
||||
device = _ghost(device)
|
||||
|
||||
|
@ -190,7 +191,7 @@ class ReceiverListener(_listener.EventsListener):
|
|||
if _log.isEnabledFor(_INFO):
|
||||
_log.info("%s: pairing detected new device", self.receiver)
|
||||
self.receiver.status.new_device = dev
|
||||
else:
|
||||
elif dev:
|
||||
if dev.online is None:
|
||||
dev.ping()
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ GLib.threads_init()
|
|||
|
||||
|
||||
def _error_dialog(reason, object):
|
||||
_log.error("%s: %s", reason, object)
|
||||
_log.error("error: %s %s", reason, object)
|
||||
|
||||
if reason == 'permissions':
|
||||
title = 'Permissions error'
|
||||
|
|
|
@ -6,6 +6,13 @@ from __future__ import absolute_import, division, print_function, unicode_litera
|
|||
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
from logging import getLogger
|
||||
_log = getLogger(__name__)
|
||||
del getLogger
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
def make(name, label, function, *args):
|
||||
action = Gtk.Action(name, label, label, None)
|
||||
|
@ -77,4 +84,5 @@ def unpair(window, device):
|
|||
try:
|
||||
del receiver[device_number]
|
||||
except:
|
||||
_log.exception("unpairing %s", device)
|
||||
error_dialog('unpair', device)
|
||||
|
|
Loading…
Reference in New Issue