3 # version 2.2 by steven676 and xiojason
5 # simple python-dbus service that proxies osso_browser events to Tear
6 # based on code from http://paste.lisp.org/display/45824
8 # Copyright (C) 2009 Jason Simpson
9 # Copyright (C) 2009 Steven Luo
11 # This program is free software; you can redistribute it and/or
12 # modify it under the terms of the GNU General Public License
13 # as published by the Free Software Foundation; either version 2
14 # of the License, or (at your option) any later version.
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
21 # You should have received a copy of the GNU General Public License
22 # along with this program; if not, write to the Free Software
23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 # On Maemo systems, a copy of the GPL can be found in
26 # /usr/share/common-licenses/GPL .
35 # Set default configuration values
36 # These can be overriden by the config file $HOME/.config/browser-switchboard
37 def setconfigdefaults():
38 global continuous_mode, default_browser, other_browser_cmd
40 # continuous_mode: 0 -- close after handling a request; 1 -- run
41 # continuously in the background
43 # default_browser: "tear", "microb", "fennec", "midori", or "other"
44 # empty string is handled specially -- see below
46 # If default browser is "other", what program to run (%s will be replaced
48 other_browser_cmd = ""
50 class BrowserLauncher:
51 def LaunchTear(self, uri):
52 # We should be able to just call the D-Bus service to open Tear ...
53 # but if Tear's not open, that causes D-Bus to start Tear and then
54 # pass it the OpenAddress call, which results in two browser windows.
55 # Properly fixing this probably requires Tear to provide a D-Bus method
56 # that opens an address in an existing window, but for now work around
57 # by just opening Tear via the command line if it's not running.
58 if os.system("pidof tear > /dev/null") == 0:
59 dbus.SessionBus().get_object('com.nokia.tear', '/com/nokia/tear').OpenAddress(uri, dbus_interface='com.nokia.Tear')
60 if continuous_mode == 0:
65 # parent process doesn't need to do anything
69 os.execl('/usr/bin/tear', '/usr/bin/tear', uri)
71 def LaunchMicroB(self, uri):
72 if os.system("pidof /usr/sbin/browserd > /dev/null") != 0:
74 os.system("/usr/sbin/browserd -d")
77 dbus.SessionBus().release_name("com.nokia.osso_browser")
78 if uri == "new_window":
79 # exec maemo-invoker directly instead of relying on the
80 # /usr/bin/browser symlink, since /usr/bin/browser may have been
81 # replaced with a shell script calling us via D-Bus
82 os.spawnl(os.P_WAIT, '/usr/bin/maemo-invoker', '/usr/bin/browser')
84 os.spawnl(os.P_WAIT, '/usr/bin/maemo-invoker', '/usr/bin/browser', '--url', uri)
86 os.system("kill `pidof /usr/sbin/browserd`")
88 dbus.SessionBus().request_name("com.nokia.osso_browser")
92 def LaunchOtherBrowser(self, uri):
93 if uri == "new_window":
96 # URI must be quoted and quotes in the URI must be URL-escaped
97 # to prevent the shell from interpreting any part of the URI
98 command = other_browser_cmd % "'%s'" % uri.replace("'", "%27")
100 # Couldn't substitute URI in, just launch the browser
101 print "other_browser_cmd should have a %s placeholder for the URI"
102 command = other_browser_cmd
104 subprocess.Popen(command, shell=True)
105 if continuous_mode == 0:
108 def UpdateDefaultBrowser(self):
109 global other_browser_cmd
110 if default_browser == "tear":
111 self.LaunchBrowser = self.LaunchTear
112 elif default_browser == "microb":
113 self.LaunchBrowser = self.LaunchMicroB
114 elif default_browser == "fennec":
115 # Cheat and reuse LaunchOtherBrowser, since we don't appear to
116 # need to do anything special
117 # TODO: does Fennec have a D-Bus API or signaling mechanism?
118 # Invoking the fennec binary appears to be somewhat expensive
119 other_browser_cmd = "fennec '%s'"
120 self.LaunchBrowser = self.LaunchOtherBrowser
121 elif default_browser == "midori":
122 other_browser_cmd = "midori '%s'"
123 self.LaunchBrowser = self.LaunchOtherBrowser
124 elif default_browser == "other":
125 if other_browser_cmd != "":
126 self.LaunchBrowser = self.LaunchOtherBrowser
128 print "default_browser is 'other', but no other_browser_cmd set -- using default"
129 self.LaunchBrowser = self.LaunchTear
130 elif default_browser == "":
131 # If default_browser is empty, use Tear as the default if
132 # installed, otherwise use MicroB
133 if os.access("/usr/bin/tear", os.X_OK):
134 self.LaunchBrowser = self.LaunchTear
136 self.LaunchBrowser = self.LaunchMicroB
138 print "Unknown default_browser %s, using default" % default_browser
139 self.LaunchBrowser = self.LaunchTear
142 self.UpdateDefaultBrowser()
144 class ProxyBrowserService(dbus.service.Object):
146 bus_name = dbus.service.BusName('com.nokia.osso_browser', bus=dbus.SessionBus())
147 dbus.service.Object.__init__(self, bus_name, '/com/nokia/osso_browser')
148 dbus.service.Object.__init__(self, bus_name, '/com/nokia/osso_browser/request')
150 def OpenAddress(self, uri):
154 print "prefixing apparent local path with file://"
155 uri = "file://" + uri
157 launcher.LaunchBrowser(uri)
159 @dbus.service.method(dbus_interface='com.nokia.osso_browser', in_signature='s')
160 def load_url(self, uri):
162 self.OpenAddress(uri)
164 @dbus.service.method(dbus_interface='com.nokia.osso_browser', in_signature='s')
165 def mime_open(self, uri):
167 self.OpenAddress(uri)
169 @dbus.service.method(dbus_interface='com.nokia.osso_browser', in_signature='s')
170 def open_new_window(self, uri):
171 print "open_new_window"
172 self.OpenAddress(uri)
174 @dbus.service.method(dbus_interface='com.nokia.osso_browser')
175 def top_application(self):
176 print "top_application"
177 launcher.LaunchMicroB("new_window")
179 # This method is an "undocumented", non-standard extension to the
180 # osso_browser D-Bus API, intended solely to allow a wrapper script
181 # replacing /usr/bin/browser to implement --url
182 @dbus.service.method(dbus_interface='com.nokia.osso_browser')
183 def switchboard_launch_microb(self, uri="new_window"):
184 print "switchboard_launch_microb"
185 launcher.LaunchMicroB(uri)
187 def readconfigfile(signalnum=None, frame=None):
188 # reset configuration to defaults
191 # read configuration from the config file, if available
193 execfile(os.getenv("HOME", "/home/user") + "/.config/browser-switchboard", globals())
195 # Try the legacy config file location
197 execfile(os.getenv("HOME", "/home/user") + "/.config/browser-proxy", globals())
199 # No valid config file available
201 launcher.UpdateDefaultBrowser()
205 launcher = BrowserLauncher()
206 pbrowser = ProxyBrowserService()
212 def waitforzombies(signalnum, frame):
214 while os.waitpid(-1, os.WNOHANG) != (0, 0):
218 signal.signal(signal.SIGCHLD, waitforzombies)
219 signal.signal(signal.SIGHUP, readconfigfile)
221 loop = gobject.MainLoop()