#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2011-2012 Canonical, Ltd.
#
# Authors:
#  Ugo Riboni <ugo.riboni@canonical.com>
#  Olivier Tilloy <olivier.tilloy@canonical.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""
Monitor dock and undock events.
 - On dock check what browser tabs are open on android and open then in ubuntu
 - On undock tell android what browser tabs we have open
"""

# dependencies: python, python-gobject

from gi.repository import GObject, Gio, GLib, Gdk

import sys, subprocess

dockmonitor_proxy = None

def get_browser_proxy():
   bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
   return Gio.DBusProxy.new_sync(bus, 0, None,
                                 'com.canonical.Android.ChromeExtension',
                                 '/',
                                 'com.canonical.Android.ChromeExtension',
                                 None)

def get_applications_proxy():
   bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
   return Gio.DBusProxy.new_sync(bus, 0, None,
                                 'com.canonical.Android',
                                 '/com/canonical/android/applications/Applications',
                                 'com.canonical.android.applications.Applications',
                                 None)

def get_lockmanager_proxy():
   bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
   return Gio.DBusProxy.new_sync(bus, 0, None,
                                 'com.canonical.Android',
                                 '/com/canonical/android/lockmanager/ScreenLockManager',
                                 'com.canonical.android.lockmanager.ScreenLockManager',
                                 None)

def should_launch_browser():
   settings = Gio.Settings.new('com.canonical.Unity2d')
   formfactor = settings.get_string('form-factor')
   print "form-factor setting is %s" % formfactor
   if formfactor == "tv":
      return False

   try:
      foreground = get_applications_proxy().getForegroundApplication()
   except GLib.GError:
      return False
   else:
      return foreground[0] == 'org.zirco'

def on_dock():
   # Acquire wake lock to prevent Android from automatically locking the
   # device’s screen after a period of inactivity. When Ubuntu is running,
   # it takes over the responsibility of locking the screen when idle.
   try:
      get_lockmanager_proxy().keepDeviceAwake()
   except GLib.GError, e:
      print 'Failed to acquire Android wake lock: %s' % e

   # Launch switch script to change to TV or desktop UI.
   try:
      subprocess.call(["/usr/bin/switch.sh"])
   except OSError as ex:
      print "Failed to start switch script: %s" % ex

   # Check if browser is already running and trigger launch or sync
   browser_proxy = get_browser_proxy()
   owner = browser_proxy.props.g_name_owner
   if owner is None or len(owner) == 0:
      # Browser is not running, launch it if we are not in tv mode and if
      # the zirco browser is the foreground app in android
      if should_launch_browser():
         print "Launching browser"
         chrome = Gio.DesktopAppInfo.new('chromium-browser.desktop')
         chrome.launch([], Gdk.Display.get_default().get_app_launch_context())
      else:
         print "TV mode or no browser in foreground on Android. Doing nothing."
   else:
      print "Browser already running"
      browser_proxy.syncFromAndroid()

def on_undock():
   # Release the wake lock; Android is handed back the responsibility of
   # locking the device’s screen when idle.
   try:
      get_lockmanager_proxy().sleep()
   except GLib.GError, e:
      print 'Failed to release Android wake lock: %s' % e

   # When undocked, if chrome is running ask it to send its own tabs to zirco
   browser_proxy = get_browser_proxy()
   owner = browser_proxy.props.g_name_owner
   if owner is not None and len(owner) > 0:
      browser_proxy.syncToAndroid()

def got_dockmonitor_signal(proxy, sender, signal, parameters):
   if signal == 'DockEvent':
      docked = parameters.unpack()[0]
      print 'The device has just been %s' % ('docked' if docked else 'undocked')
      if docked:
         on_dock()
      else:
         on_undock()

if __name__ == '__main__':
   # Ensure only one instance of self is running at any given time.
   # See http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-names
   bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
   proxy = Gio.DBusProxy.new_sync(bus, 0, None,
                                 'org.freedesktop.DBus',
                                 '/org/freedesktop/DBus',
                                 'org.freedesktop.DBus', None)
   name = 'com.canonical.Android.DockMonitor'
   result = proxy.RequestName('(su)', name, 0x4)
   if result != 1 :
      print >> sys.stderr, ("Name '%s' is already owned on the session bus."
                            "Aborting.") % name
      sys.exit(1)

   dockmonitor_proxy = Gio.DBusProxy.new_sync(bus, 0, None,
                                              'com.canonical.Android',
                                              '/com/canonical/android/dockmonitor/DockMonitor',
                                              'com.canonical.android.dockmonitor.DockMonitor',
                                              None)
   dockmonitor_proxy.connect('g-signal', got_dockmonitor_signal)

   GObject.MainLoop().run()

