URI: 
       tTrezor: add session timeout to preferences - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 43fd684d979307c68b2270456bfe024fceb6232f
   DIR parent 87363c8301acc0689c0e0a4c59219fdd40b16a07
  HTML Author: Neil Booth <kyuupichan@gmail.com>
       Date:   Sun,  3 Jan 2016 17:25:47 +0900
       
       Trezor: add session timeout to preferences
       
       Fixes #803
       
       Diffstat:
         M plugins/trezor/plugin.py            |      30 +++++++++++++++++++++++++++---
         M plugins/trezor/qt_generic.py        |      27 ++++++++++++++++++++++++++-
       
       2 files changed, 53 insertions(+), 4 deletions(-)
       ---
   DIR diff --git a/plugins/trezor/plugin.py b/plugins/trezor/plugin.py
       t@@ -29,11 +29,18 @@ class TrezorCompatibleWallet(BIP44_Wallet):
                # This is set when paired with a device, and used to re-pair
                # a device that is disconnected and re-connected
                self.device_id = None
       +        # After timeout seconds we clear the device session
       +        self.session_timeout = storage.get('session_timeout', 180)
                # Errors and other user interaction is done through the wallet's
                # handler.  The handler is per-window and preserved across
                # device reconnects
                self.handler = None
        
       +    def set_session_timeout(self, seconds):
       +        self.print_error("setting session timeout to %d seconds" % seconds)
       +        self.session_timeout = seconds
       +        self.storage.put('session_timeout', seconds)
       +
            def disconnected(self):
                self.print_error("disconnected")
                self.handler.watching_only_changed()
       t@@ -46,9 +53,8 @@ class TrezorCompatibleWallet(BIP44_Wallet):
                self.print_error("wiped")
                self.handler.watching_only_changed()
        
       -    def initialized(self):
       -        self.print_error("initialized")
       -        self.handler.watching_only_changed()
       +    def timeout(self):
       +        self.print_error("timed out")
        
            def get_action(self):
                pass
       t@@ -155,6 +161,7 @@ class TrezorCompatiblePlugin(BasePlugin):
                BasePlugin.__init__(self, parent, config, name)
                self.device = self.wallet_class.device
                self.wallet_class.plugin = self
       +        self.prevent_timeout = time.time() + 3600 * 24 * 365
                # A set of client instances to USB paths
                self.clients = set()
                # The device wallets we have seen to inform on reconnection
       t@@ -173,6 +180,13 @@ class TrezorCompatiblePlugin(BasePlugin):
                    if now > self.last_scan + 1:
                        self.last_scan = now
                        self.scan_devices()
       +            for wallet in self.paired_wallets:
       +                if now > wallet.last_operation + wallet.session_timeout:
       +                    client = self.lookup_client(wallet)
       +                    if client:
       +                        wallet.last_operation = self.prevent_timeout
       +                        self.clear_session(client)
       +                        wallet.timeout()
        
            def scan_devices(self):
                paths = self.HidTransport.enumerate()
       t@@ -221,6 +235,9 @@ class TrezorCompatiblePlugin(BasePlugin):
                client.clear_session()
        
            def initialize_device(self, wallet, wizard):
       +        # Prevent timeouts during initialization
       +        wallet.last_operation = self.prevent_timeout
       +
                (strength, label, pin_protection, passphrase_protection) \
                    = wizard.request_trezor_reset_settings(self.device)
        
       t@@ -247,10 +264,16 @@ class TrezorCompatiblePlugin(BasePlugin):
                if not client.is_initialized():
                    self.initialize_device(wallet, wizard)
        
       +    def operated_on(self, wallet):
       +        self.print_error("set last_operation")
       +        wallet.last_operation = time.time()
       +
            def pair_wallet(self, wallet, client):
                self.print_error("pairing wallet %s to device %s" % (wallet, client))
       +        self.operated_on(wallet)
                self.paired_wallets.add(wallet)
                wallet.device_id = client.features.device_id
       +        wallet.last_operation = time.time()
                client.wallet = wallet
                wallet.connected()
        
       t@@ -301,6 +324,7 @@ class TrezorCompatiblePlugin(BasePlugin):
                assert isinstance(wallet, self.wallet_class)
                assert wallet.handler != None
        
       +        self.operated_on(wallet)
                if wallet.device_id is None:
                    client = self.try_to_pair_wallet(wallet)
                else:
   DIR diff --git a/plugins/trezor/qt_generic.py b/plugins/trezor/qt_generic.py
       t@@ -1,6 +1,7 @@
        from functools import partial
        import threading
        
       +from PyQt4.Qt import Qt
        from PyQt4.Qt import QGridLayout, QInputDialog, QPushButton
        from PyQt4.Qt import QVBoxLayout, QLabel, SIGNAL
        from electrum_gui.qt.main_window import StatusBarButton
       t@@ -217,12 +218,17 @@ def qt_plugin_class(base_plugin_class):
                    client().wipe_device()
                    refresh()
        
       +        def slider_moved():
       +            mins = timeout_slider.sliderPosition()
       +            timeout_label.setText(_("%2d minutes") % mins)
       +
                wallet = window.wallet
                handler = wallet.handler
                device = self.device
        
                info_tab = QWidget()
       -        info_layout = QGridLayout(info_tab)
       +        tab_layout = QVBoxLayout(info_tab)
       +        info_layout = QGridLayout()
                noyes = [_("No"), _("Yes")]
                bl_hash_label = QLabel()
                device_label = QLabel()
       t@@ -249,6 +255,22 @@ def qt_plugin_class(base_plugin_class):
                    (_("Firmware Version"), version_label),
                    (_("Language"), language_label),
                ])
       +        tab_layout.addLayout(info_layout)
       +
       +        timeout_layout = QHBoxLayout()
       +        timeout_label = QLabel()
       +        timeout_slider = QSlider(Qt.Horizontal)
       +        timeout_slider.setRange(1, 60)
       +        timeout_slider.setSingleStep(1)
       +        timeout_slider.setSliderPosition(wallet.session_timeout // 60)
       +        timeout_slider.setTickInterval(5)
       +        timeout_slider.setTickPosition(QSlider.TicksBelow)
       +        timeout_slider.setTracking(True)
       +        timeout_slider.valueChanged.connect(slider_moved)
       +        timeout_layout.addWidget(QLabel(_("Session Timeout")))
       +        timeout_layout.addWidget(timeout_slider)
       +        timeout_layout.addWidget(timeout_label)
       +        tab_layout.addLayout(timeout_layout)
        
                advanced_tab = QWidget()
                advanced_layout = QGridLayout(advanced_tab)
       t@@ -267,8 +289,11 @@ def qt_plugin_class(base_plugin_class):
                vbox.addStretch(1)
                vbox.addLayout(Buttons(CloseButton(dialog)))
        
       +        # Show values
       +        slider_moved()
                refresh()
                dialog.setLayout(vbox)
                handler.exec_dialog(dialog)
       +        wallet.set_session_timeout(timeout_slider.sliderPosition() * 60)
        
          return QtPlugin