summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKali Kaneko <kali@leap.se>2017-10-25 01:52:11 +0200
committerKali Kaneko <kali@leap.se>2017-11-01 01:40:18 +0100
commitb0e1bd223368f09e49f13b9ecf04fb0570e04dc0 (patch)
treed409be680d4e7ed80080c48d1f80df915e8036a8 /src
parent4e11a6550e11fb2b8682816dfbc98be1581e5402 (diff)
[feature] display vpn status on systray
Diffstat (limited to 'src')
-rw-r--r--src/leap/bitmask/gui/app.py47
-rw-r--r--src/leap/bitmask/vpn/_status.py2
-rw-r--r--src/leap/bitmask/vpn/fw/firewall.py4
-rw-r--r--src/leap/bitmask/vpn/process.py25
-rw-r--r--src/leap/bitmask/vpn/tunnel.py3
5 files changed, 68 insertions, 13 deletions
diff --git a/src/leap/bitmask/gui/app.py b/src/leap/bitmask/gui/app.py
index 91e8c870..8f763579 100644
--- a/src/leap/bitmask/gui/app.py
+++ b/src/leap/bitmask/gui/app.py
@@ -34,6 +34,8 @@ from multiprocessing import Process
from leap.bitmask.core.launcher import run_bitmaskd, pid
from leap.bitmask.gui import app_rc
from leap.common.config import get_path_prefix
+from leap.common.events import client as leap_events
+from leap.common.events import catalog
if platform.system() == 'Windows':
from multiprocessing import freeze_support
@@ -48,6 +50,7 @@ else:
from PyQt5.QtCore import QObject, pyqtSlot
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QIcon
+ from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QMenu
from PyQt5.QtWidgets import QSystemTrayIcon
from PyQt5.QtWidgets import QDialog
@@ -70,10 +73,49 @@ qApp = None
bitmaskd = None
browser = None
+# TODO do switch based on theme
+
+TRAY_ICONS = (
+ ':/black/22/wait.png',
+ ':/black/22/on.png',
+ ':/black/22/off.png')
class WithTrayIcon(QDialog):
- def createTrayIcon(self):
+ def setupSysTray(self):
+ self._createIcons()
+ self._createTrayIcon()
+ self.setVPNStatus('off')
+ self.trayIcon.show()
+ self.setUpEventListener()
+
+ def setVPNStatus(self, status):
+ seticon = self.trayIcon.setIcon
+ if status == 'off':
+ seticon(self.ICON_OFF)
+ elif status == 'on':
+ seticon(self.ICON_ON)
+ elif status == 'starting':
+ seticon(self.ICON_WAIT)
+ elif status == 'stopping':
+ seticon(self.ICON_WAIT)
+
+ def setUpEventListener(self):
+ leap_events.register(catalog.VPN_STATUS_CHANGED, self._handle_vpn_event)
+
+ def _handle_vpn_event(self, *args):
+ print ">>>>>> GOT EVENT", str(args)
+ status = None
+ if len(args) > 1:
+ status = args[1]
+ self.setVPNStatus(status.lower())
+
+ def _createIcons(self):
+ self.ICON_WAIT = QIcon(QPixmap(TRAY_ICONS[0]))
+ self.ICON_ON = QIcon(QPixmap(TRAY_ICONS[1]))
+ self.ICON_OFF = QIcon(QPixmap(TRAY_ICONS[2]))
+
+ def _createTrayIcon(self):
self.trayIcon = QSystemTrayIcon(self)
@@ -227,8 +269,7 @@ def launch_gui():
print('ERROR: ' + e.message)
sys.exit(1)
- browser.createTrayIcon()
- browser.trayIcon.show()
+ browser.setupSysTray()
qApp.setQuitOnLastWindowClosed(True)
qApp.lastWindowClosed.connect(browser.shutdown)
diff --git a/src/leap/bitmask/vpn/_status.py b/src/leap/bitmask/vpn/_status.py
index 5cf0cc77..4bf8d004 100644
--- a/src/leap/bitmask/vpn/_status.py
+++ b/src/leap/bitmask/vpn/_status.py
@@ -80,7 +80,7 @@ class VPNStatus(object):
if self._status != status:
self._status = status
self.errcode = errcode
- emit_async(catalog.VPN_STATUS_CHANGED)
+ emit_async(catalog.VPN_STATUS_CHANGED, status.upper())
def get_traffic_status(self):
down = None
diff --git a/src/leap/bitmask/vpn/fw/firewall.py b/src/leap/bitmask/vpn/fw/firewall.py
index 63aac36e..d5b1f018 100644
--- a/src/leap/bitmask/vpn/fw/firewall.py
+++ b/src/leap/bitmask/vpn/fw/firewall.py
@@ -134,7 +134,7 @@ class _LinuxFirewallManager(object):
raise FirewallError(msg)
finally:
log.debug(result)
- emit_async(catalog.VPN_STATUS_CHANGED)
+ emit_async(catalog.VPN_STATUS_CHANGED, "FW_ON")
return True
def stop(self):
@@ -144,7 +144,7 @@ class _LinuxFirewallManager(object):
cmd = [self.BITMASK_ROOT, "firewall", "stop"]
cmd = check_root(cmd)
exitCode = subprocess.call(cmd)
- emit_async(catalog.VPN_STATUS_CHANGED)
+ emit_async(catalog.VPN_STATUS_CHANGED, "FW_OFF")
if exitCode == 0:
return True
else:
diff --git a/src/leap/bitmask/vpn/process.py b/src/leap/bitmask/vpn/process.py
index 7f33e83a..862215f8 100644
--- a/src/leap/bitmask/vpn/process.py
+++ b/src/leap/bitmask/vpn/process.py
@@ -50,7 +50,7 @@ class VPNStateListener(object):
# and make VPNProcess the implementer itself - or the service.
def change_state(self, state):
- emit_async(catalog.VPN_STATUS_CHANGED)
+ emit_async(catalog.VPN_STATUS_CHANGED, state.simple)
class _VPNProcess(protocol.ProcessProtocol):
@@ -109,6 +109,7 @@ class _VPNProcess(protocol.ProcessProtocol):
self.errmsg = None
self.proto = None
self._remotes = remotes
+ self._listener = VPNStateListener()
# processProtocol methods
@@ -120,8 +121,7 @@ class _VPNProcess(protocol.ProcessProtocol):
@defer.inlineCallbacks
def _got_management_protocol(self, proto):
self.proto = proto
- listener = VPNStateListener()
- proto.addStateListener(listener)
+ proto.addStateListener(self._listener)
try:
yield proto.logOn()
@@ -134,7 +134,7 @@ class _VPNProcess(protocol.ProcessProtocol):
def _connect_to_management(self, retries=30):
if retries == 0:
- self.log.error('Timeout whilte connecting to management')
+ self.log.error('Timeout while connecting to management')
self.failed = True
return
@@ -213,8 +213,23 @@ class _VPNProcess(protocol.ProcessProtocol):
def status(self):
if self.failed:
return {'status': 'failed', 'error': self.errmsg}
+
+ # FIXME - hack, doesn't belong here ----------------------------------
+ # needs to go with implementing the history within the VPNProcess.
+ # this only will work before the UI is pulling the state and therefore
+ # checking this condition as a side-effect of reading the property.
+
+ # TODO trigger off transition when proto dissapears (at processExited)
if not self.proto:
- return {'status': 'off', 'error': None}
+ OFF = 'off'
+ if self._status != OFF:
+ self._status = OFF
+ class _state(object):
+ simple = 'OFF'
+ off = _state()
+ self._listener.change_state(off)
+ return {'status': OFF, 'error': None}
+ # --------------------------------------------------------------------
try:
self._status = self.proto.state.simple.lower()
diff --git a/src/leap/bitmask/vpn/tunnel.py b/src/leap/bitmask/vpn/tunnel.py
index b49135df..f6080b85 100644
--- a/src/leap/bitmask/vpn/tunnel.py
+++ b/src/leap/bitmask/vpn/tunnel.py
@@ -92,8 +92,7 @@ class ConfiguredTunnel(object):
else:
status = self._vpnproc.status
# Currently, there's some UI flickering that needs to be debugged #9049
- # XXX remove this print after that.
- print ">>>STATUS", status
+ print ">>>> STATUS", status
return status
@property