[hbbtv] update.
[vuplus_dvbapp] / lib / python / Plugins / Extensions / HbbTV / plugin.py
1 from Plugins.Plugin import PluginDescriptor
2
3 from Screens.Screen import Screen
4 from Screens.InfoBar import InfoBar
5 from Screens.ChoiceBox import ChoiceBox
6 from Screens.MessageBox import MessageBox
7 from Screens.InfoBarGenerics import InfoBarNotifications
8 from Screens.VirtualKeyBoard import VirtualKeyBoard
9
10 from Components.PluginComponent import plugins
11 from Components.Button import Button
12 from Components.Label import Label
13 from Components.Sources.StaticText import StaticText
14 from Components.ActionMap import NumberActionMap, ActionMap
15 from Components.ServiceEventTracker import ServiceEventTracker
16 from Components.MenuList import MenuList
17 from Components.Label import Label, MultiColorLabel
18 from Components.ConfigList import ConfigListScreen
19 from Components.VolumeControl import VolumeControl
20 from Components.config import config, ConfigSubsection, ConfigPosition, getConfigListEntry, ConfigBoolean, ConfigInteger, ConfigText, ConfigSelection, configfile, getCharValue
21
22 from enigma import eTimer, eConsoleAppContainer, getDesktop, eServiceReference, iPlayableService, iServiceInformation, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_HALIGN_CENTER, RT_VALIGN_CENTER, getPrevAsciiCode, eRCInput, fbClass
23
24 import os, struct, threading, stat, select, time, socket, select
25
26 strIsEmpty = lambda x: x is None or len(x) == 0
27
28 HBBTVAPP_PATH = "/usr/local/hbb-browser"
29 COMMAND_PATH = '/tmp/.sock.hbbtv.cmd'
30
31 class GlobalValues:
32         command_util   = None
33         command_server = None
34
35         before_service = None
36
37         channel_info_sid   = None
38         channel_info_onid  = None
39         channel_info_tsid  = None
40         channel_info_name  = None
41         channel_info_orgid = None
42
43         hbbtv_handelr = None
44
45         packet_m  = 0xBBADBEE
46         packet_h  = '!IIII'
47         packet_hl = struct.calcsize(packet_h)
48
49         need_restart = False
50 __gval__ = GlobalValues()
51
52 def getPacketHeaders():
53         global __gval__
54         return (__gval__.packet_m, __gval__.packet_h, __gval__.packet_hl)
55
56 def setChannelInfo(sid, onid, tsid, name, orgid):
57         if sid is None:   sid   = 0;
58         if onid is None:  onid  = 0;
59         if tsid is None:  tsid  = 0;
60         if name is None:  name  = "";
61         if orgid is None: orgid = 0;
62         global __gval__
63         __gval__.channel_info_sid   = sid
64         __gval__.channel_info_onid  = onid
65         __gval__.channel_info_tsid  = tsid
66         __gval__.channel_info_name  = name
67         __gval__.channel_info_orgid = orgid
68         print "Set Channel Info >> sid : %X, onid : %X, tsid : %X, name : %s, orgid : %d " % (sid, onid, tsid, name, orgid)
69 def getChannelInfos():
70         global __gval__
71         print "Get Channel Info >> sid : %X, onid : %X, tsid : %X, name : %s, orgid : %d " % (__gval__.channel_info_sid, 
72                 __gval__.channel_info_onid, __gval__.channel_info_tsid, __gval__.channel_info_name, __gval__.channel_info_orgid)
73         return (__gval__.channel_info_sid, 
74                 __gval__.channel_info_onid, 
75                 __gval__.channel_info_tsid, 
76                 __gval__.channel_info_name, 
77                 __gval__.channel_info_orgid)
78
79 def isNeedRestart():
80         global __gval__
81         print "Need Restart(GET) : ", __gval__.need_restart
82         return __gval__.need_restart
83 def setNeedRestart(n):
84         global __gval__
85         __gval__.need_restart = n
86         print "Need Restart(SET) : ", __gval__.need_restart
87
88 def getCommandUtil():
89         global __gval__
90         return __gval__.command_util
91 def getCommandServer():
92         global __gval__
93         return __gval__.command_server
94
95 def setBeforeService(s):
96         global __gval__
97         __gval__.before_service = s
98 def getBeforeService():
99         global __gval__
100         return __gval__.before_service
101
102 def _unpack(packed_data):
103         (mg, h, hlen) = getPacketHeaders()
104
105         if strIsEmpty(packed_data):
106                 return None
107         (m, o, l, s) = struct.unpack(h, packed_data[:hlen])
108         if m != mg:
109                 return None
110         d = 0
111         if l > 0:
112                 d = packed_data[hlen:hlen+l]
113         return (o,d,s)
114
115 def _pack(opcode, params=None, reserved=0):
116         (m, h, hlen) = getPacketHeaders()
117         if strIsEmpty(params):
118                 params = ''
119         packed_data = struct.pack(h, m, opcode, len(params), reserved)
120         return packed_data + params
121
122 class MMSStreamURL:
123         headers = [
124                    'GET %s HTTP/1.0'
125                   ,'Accept: */* '
126                   ,'User-Agent: NSPlayer/7.10.0.3059 '
127                   ,'Host: %s '
128                   ,'Connection: Close '
129                   ]
130
131         def __init__(self):
132                 self.sendmsg = ''
133                 for m in self.headers:
134                         self.sendmsg += m + '\n'
135                 self.sendmsg += '\n\n'
136
137         def request(self, host, port=80, location='/'):
138                 sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
139                 sock.connect((host, port))
140                 sock.send(self.sendmsg%(location, host))
141                 print "Request."
142                 print self.sendmsg%(location, host)
143                 fullydata = ''
144                 while 1:
145                         res = sock.recv(1024)
146                         if res == '': break
147                         fullydata += res
148                 sock.close()
149                 return fullydata
150
151         def parse(self, data):
152                 for d in data.splitlines():
153                         if d.startswith('Location: '):
154                                 return d[9:]
155                 return None
156
157         def getLocationData(self, url):
158                 url_list,host,location = None,None,None
159                 try:
160                         url = url[url.find(':')+3:]
161                         url_list = url.split('/')
162                         host = url_list[0]
163                         location = url[len(url_list[0]):]
164                 except Exception, err_msg:
165                         print err_msg
166                         return None
167                 html = self.request(host=host, location=location)
168                 return self.parse(html)
169
170 class OpCodeSet:
171         def __init__(self):
172                 self._opcode_ = {
173                          "OP_UNKNOWN"                   : 0x0000
174                         ,"OP_HBBTV_EXIT"                : 0x0001
175                         ,"OP_HBBTV_OPEN_URL"            : 0x0002
176                         ,"OP_HBBTV_LOAD_AIT"            : 0x0003
177                         ,"OP_HBBTV_UNLOAD_AIT"          : 0x0004
178                         ,"OP_HBBTV_FULLSCREEN"          : 0x0005
179                         ,"OP_HBBTV_TITLE"               : 0x0006
180                         ,"OP_HBBTV_RETRY_OPEN_URL"      : 0x0009
181                         ,"OP_OIPF_GET_CHANNEL_INFO_URL" : 0x0101
182                         ,"OP_OIPF_GET_CHANNEL_INFO_AIT" : 0x0102
183                         ,"OP_OIPF_GET_CHANNEL_INFO_LIST": 0x0103
184                         ,"OP_VOD_URI"                   : 0x0201
185                         ,"OP_VOD_PLAY"                  : 0x0202
186                         ,"OP_VOD_STOP"                  : 0x0203
187                         ,"OP_VOD_PAUSE"                 : 0x0204
188                         ,"OP_VOD_STATUS"                : 0x0205
189                         ,"OP_VOD_FORBIDDEN"             : 0x0206
190                         ,"OP_VOD_STOPED"                : 0x0207
191                         ,"OP_BROWSER_OPEN_URL"          : 0x0301
192                         ,"OP_DVBAPP_VOL_UP"             : 0x0401
193                         ,"OP_DVBAPP_VOL_DOWN"           : 0x0402
194                         ,"OP_SYSTEM_OUT_OF_MEMORY"      : 0x0501
195                         ,"OP_SYSTEM_NOTIFY_MY_PID"      : 0x0502
196                 }
197                 self._opstr_ = {
198                          0x0000 : "OP_UNKNOWN"
199                         ,0x0001 : "OP_HBBTV_EXIT"
200                         ,0x0002 : "OP_HBBTV_OPEN_URL"
201                         ,0x0003 : "OP_HBBTV_LOAD_AIT"
202                         ,0x0004 : "OP_HBBTV_UNLOAD_AIT"
203                         ,0x0005 : "OP_HBBTV_FULLSCREEN"
204                         ,0x0006 : "OP_HBBTV_TITLE"
205                         ,0x0009 : "OP_HBBTV_RETRY_OPEN_URL"
206                         ,0x0101 : "OP_OIPF_GET_CHANNEL_INFO_URL"
207                         ,0x0102 : "OP_OIPF_GET_CHANNEL_INFO_AIT"
208                         ,0x0103 : "OP_OIPF_GET_CHANNEL_INFO_LIST"
209                         ,0x0201 : "OP_VOD_URI"
210                         ,0x0202 : "OP_VOD_PLAY"
211                         ,0x0203 : "OP_VOD_STOP"
212                         ,0x0204 : "OP_VOD_PAUSE"
213                         ,0x0205 : "OP_VOD_STATUS"
214                         ,0x0206 : "OP_VOD_FORBIDDEN"
215                         ,0x0207 : "OP_VOD_STOPED"
216                         ,0x0301 : "OP_BROWSER_OPEN_URL"
217                         ,0x0401 : "OP_DVBAPP_VOL_UP"
218                         ,0x0402 : "OP_DVBAPP_VOL_DOWN"
219                         ,0x0501 : "OP_SYSTEM_OUT_OF_MEMORY"
220                         ,0x0502 : "OP_SYSTEM_NOTIFY_MY_PID"
221                 }
222
223         def get(self, opstr):
224                 try:
225                         return self._opcode_[opstr]
226                 except: pass
227                 return self._opcode_["OP_UNKNOWN"]
228
229         def what(self, opcode):
230                 try:
231                         return self._opstr_[opcode]
232                 except: pass
233                 return self._opstr_["0x0000"]
234
235 class SocketParams:
236         def __init__(self):
237                 self.protocol = None
238                 self.type     = None
239                 self.addr     = None
240                 self.buf_size = 4096
241                 self.handler  = None
242                 self.timeout  = 5
243                 self.destroy  = None
244
245 class StreamServer:
246         def __init__(self, params):
247                 self._protocol = params.protocol
248                 self._type     = params.type
249                 self._addr     = params.addr
250                 self._buf_size = params.buf_size
251                 self._handler  = params.handler
252                 self._timeout  = params.timeout
253                 self._destroy  = params.destroy
254
255                 self._terminated = False
256                 self._server_thread = None
257
258                 self.onHbbTVCloseCB = []
259                 self.onSetPageTitleCB = []
260
261         def __del__(self):
262                 if self._destroy is not None:
263                         self._destroy(self._addr)
264
265         def stop(self):
266                 self._terminated = True
267                 if self._server_thread is not None:
268                         self._server_thread.join()
269                         self._server_thread = None
270
271         def start(self):
272                 self._socket = socket.socket(self._protocol, self._type)
273                 self._socket.settimeout(self._timeout)
274                 self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
275                 self._socket.bind(self._addr)
276                 self._socket.listen(True)
277
278                 self._server_thread = threading.Thread(target=self._listen)
279                 self._server_thread.start()
280
281         def _listen(self):
282                 select_list = [self._socket]
283                 def _accept():
284                         try:
285                                 conn, addr = self._socket.accept()
286                                 self._client(conn, addr)
287                         except Exception, ErrMsg:
288                                 print "ServerSocket Error >>", ErrMsg
289                                 pass
290
291                 while not self._terminated:
292                         readable, writable, errored = select.select(select_list, [], [], self._timeout)
293                         for s in readable:
294                                 if s is self._socket:
295                                         _accept()
296
297         def _client(self, conn, addr):
298                 try:
299                         send_data     = ''
300                         received_data = conn.recv(self._buf_size)
301                         if self._handler is not None and not strIsEmpty(received_data):
302                                 send_data = self._handler.doHandle(received_data, self.onHbbTVCloseCB, self.onSetPageTitleCB)
303                         self._send(conn, send_data)
304                 except Exception, ErrMsg: 
305                         try: conn.close()
306                         except:pass
307                         if self._handler is not None:
308                                 self._handler.printError(ErrMsg)
309         def _send(self, conn, data) :
310                 conn.send(data)
311                 conn.close()
312
313 class ServerFactory:
314         def doListenUnixTCP(self, name, handler):
315                 def destroy(name):
316                         if os.path.exists(name):
317                                 os.unlink(name)
318                                 print "Removed ", name
319                 destroy(name)
320
321                 params = SocketParams()
322                 params.protocol = socket.AF_UNIX
323                 params.type     = socket.SOCK_STREAM
324                 params.addr     = name
325                 params.handler  = handler
326                 params.destroy  = destroy
327
328                 streamServer = StreamServer(params)
329                 streamServer.start()
330                 return streamServer
331
332         def doListenInetTCP(self, ip, port, handler):
333                 print "Not implemented yet!!"
334         def doListenUnixDGRAM(self, name, handler):
335                 print "Not implemented yet!!"
336         def doListenInetDGRAM(self, ip, port, handler):
337                 print "Not implemented yet!!"
338
339 class Handler:
340         def doUnpack(self, data):
341                 return _unpack(data)
342
343         def doPack(self, opcode, params, reserved=0):
344                 return _pack(opcode, params, reserved)
345
346         def doHandle(self, data, onCloseCB):
347                 opcode, params = 0x0, 'Invalid Request!!'
348                 return _pack(opcode, params)
349
350         def printError(self, reason):
351                 print reason
352
353 class BrowserCommandUtil(OpCodeSet):
354         def __init__(self):
355                 self._fd = None
356                 OpCodeSet.__init__(self)
357
358         def isConnected(self):
359                 if self._fd is None:
360                         return False
361                 return True
362
363         def doConnect(self, filename):
364                 if not os.path.exists(filename):
365                         print "File not exists :", filename
366                         return False
367                 try:
368                         self._fd = os.open(filename, os.O_WRONLY|os.O_NONBLOCK)
369                         if self._fd is None:
370                                 print "Fail to open file :", filename
371                                 return False
372                 except Exception, ErrMsg:
373                         print ErrMsg
374                         self._fd = None
375                         return False
376                 return True
377
378         def doDisconnect(self):
379                 if self._fd is None:
380                         return
381                 os.close(self._fd)
382                 self._fd = None
383
384         def doSend(self, command, params=None, reserved=0):
385                 if self._fd is None:
386                         print "Pipe was not exists!!"
387                         return False
388                 data = ''
389                 try:
390                         data = _pack(self.get(command), params, reserved)
391                         if data is None:
392                                 return False
393                         os.write(self._fd, data)
394                         print "Send OK!! :", command
395                 except: return False
396                 return True
397
398         def sendCommand(self, command, params=None, reserved=0):
399                 if not self.isConnected():
400                         global COMMAND_PATH
401                         self.doConnect(COMMAND_PATH)
402                 result = self.doSend(command, params, reserved)
403                 self.doDisconnect()
404                 return result
405
406 class HandlerHbbTV(Handler):
407         _vod_service = None
408         def __init__(self, session):
409                 self._session = session
410                 self.opcode = OpCodeSet()
411                 self.handle_map = {
412                          0x0001 : self._cb_handleCloseHbbTVBrowser
413                         ,0x0006 : self._cb_handleSetPageTitle
414                         ,0x0009 : self._cb_handleHbbTVRetryOpen
415                         ,0x0101 : self._cb_handleGetChannelInfoForUrl
416                         ,0x0102 : self._cb_handleGetChannelInfoForAIT
417                         ,0x0103 : self._cb_handleGetChannelInfoList
418                         ,0x0201 : self._cb_handleVODPlayerURI
419                         ,0x0202 : self._cb_handleVODPlayerPlay
420                         ,0x0203 : self._cb_handleVODPlayerStop
421                         ,0x0204 : self._cb_handleVODPlayerPlayPause
422                         ,0x0401 : self._cb_handleDVBAppVolUp
423                         ,0x0402 : self._cb_handleDVBAppVolDown
424                         ,0x0501 : self._cb_handleSystemOutOfMemory
425                         ,0x0502 : self._cb_handleSystemNotufyMyPID
426                 }
427                 self._on_close_cb = None
428                 self._on_set_title_cb = None
429
430                 self._vod_uri = None
431
432                 self._retry_open_url = None
433                 self._timer_retry_open = eTimer()
434                 
435
436         def _handle_dump(self, handle, opcode, data=None):
437                 if True: return
438                 print str(handle)
439                 try:
440                         print "    - opcode : ", self.opcode.what(opcode)
441                 except: pass
442                 print "    - data   : ", data
443
444         def doHandle(self, data, onCloseCB, onSetPageTitleCB):
445                 opcode, params, reserved = None, None, 0
446                 self._on_close_cb = onCloseCB
447                 self._on_set_title_cb = onSetPageTitleCB
448                 try:
449                         datas  = self.doUnpack(data)
450                 except Exception, ErrMsg:
451                         print "Unpacking packet ERR :", ErrMsg
452                         params = 'fail to unpack packet!!'
453                         opcode = self.opcode.get("OP_UNKNOWN")
454                         return self.doPack(opcode, params)
455                 else:
456                         opcode = datas[0]
457                         params = datas[1]
458                 self.opcode.what(opcode)
459
460                 try:
461                         #print self.handle_map[opcode]
462                         (reserved, params) = self.handle_map[opcode](opcode, params)
463                 except Exception, ErrMsg:
464                         print "Handling packet ERR :", ErrMsg
465                         params = 'fail to handle packet!!'
466                         opcode = self.opcode.get("OP_UNKNOWN")
467                         return self.doPack(opcode, params)
468                 self._on_close_cb = None
469                 self._on_set_title_cb = None
470                 return self.doPack(opcode, params, reserved)
471
472         def _cb_handleHbbTVRetryOpen(self, opcode, data):
473                 def _cb_HbbTVRetryOpenURL():
474                         self._timer_retry_open.stop()
475                         if self._retry_open_url is not None:
476                                 command_util = getCommandUtil()
477                                 command_util.sendCommand('OP_HBBTV_RETRY_OPEN_URL', params=self._retry_open_url)
478                         self._retry_open_url = None
479                 self._handle_dump(self._cb_handleHbbTVRetryOpen, opcode, data)
480                 headLen = struct.calcsize('!I')
481                 unpackedData = struct.unpack('!I', data[:headLen])
482                 delayTime = unpackedData[0]
483                 restartUrl = data[headLen:]
484
485                 self._retry_open_url = restartUrl.strip()
486                 self._timer_retry_open.callback.append(_cb_HbbTVRetryOpenURL)
487                 self._timer_retry_open.start(delayTime*1000)
488                 return (0, "OK")
489
490         def _cb_handleSystemNotufyMyPID(self, opcode, data):
491                 self._handle_dump(self._cb_handleSystemNotufyMyPID, opcode, data)
492                 return (0, "OK")
493
494         def _cb_handleSystemOutOfMemory(self, opcode, data):
495                 self._handle_dump(self._cb_handleSystemOutOfMemory, opcode, data)
496                 setNeedRestart(True)
497                 return (0, "OK")
498
499         def _cb_handleDVBAppVolUp(self, opcode, data):
500                 self._handle_dump(self._cb_handleDVBAppVolUp, opcode, data)
501                 vcm = VolumeControl.instance
502                 vcm.volUp()
503                 return (0, "OK")
504
505         def _cb_handleDVBAppVolDown(self, opcode, data):
506                 self._handle_dump(self._cb_handleDVBAppVolDown, opcode, data)
507                 vcm = VolumeControl.instance
508                 vcm.volDown()
509                 return (0, "OK")
510
511         def _cb_handleGetChannelInfoForUrl(self, opcode, data):
512                 self._handle_dump(self._cb_handleGetChannelInfoForUrl, opcode, data)
513                 (sid, onid, tsid, name, orgid) = getChannelInfos()
514                 namelen = len(name)
515                 return (0, struct.pack('!IIII', sid, onid, tsid, namelen) + name)
516
517         def _cb_handleGetChannelInfoForAIT(self, opcode, data):
518                 self._handle_dump(self._cb_handleGetChannelInfoForAIT, opcode, data)
519                 (sid, onid, tsid, name, orgid) = getChannelInfos()
520                 namelen = len(name)
521                 return (0, struct.pack('!IIIII', orgid, sid, onid, tsid, namelen) + name)
522
523         def _cb_handleGetChannelInfoList(self, opcode, data):
524                 self._handle_dump(self._cb_handleGetChannelInfoList, opcode, data)
525                 (sid, onid, tsid, name, orgid) = getChannelInfos()
526                 namelen = len(name)
527                 channel_list_size = 1
528                 return (channel_list_size, struct.pack('!IIII', sid, onid, tsid, namelen) + name)
529
530         def _cb_handleSetPageTitle(self, opcode, data):
531                 self._handle_dump(self._cb_handleCloseHbbTVBrowser, opcode, data)
532                 if data.startswith('file://') or data.startswith('http://'):
533                         return "OK"
534                 if self._on_set_title_cb is not None:
535                         for x in self._on_set_title_cb:
536                                 try:
537                                         x(data)
538                                 except Exception, ErrMsg:
539                                         if x in self._on_set_title_cb:
540                                                 self._on_set_title_cb.remove(x)
541                 return (0, "OK")
542
543         def _cb_handleCloseHbbTVBrowser(self, opcode, data):
544                 self._timer_retry_open.stop()
545                 self._handle_dump(self._cb_handleCloseHbbTVBrowser, opcode, data)
546
547                 if self._on_close_cb:
548                         for x in self._on_close_cb:
549                                 try:
550                                         x()
551                                 except Exception, ErrMsg:
552                                         if x in self._on_close_cb:
553                                                 self._on_close_cb.remove(x)
554
555                 command_util = getCommandUtil()
556                 command_util.sendCommand('OP_HBBTV_FULLSCREEN', None)
557
558                 before_service = getBeforeService()
559                 if before_service is not None:
560                         self._session.nav.playService(before_service)
561                         self._vod_uri = None
562                 return (0, "OK")
563
564         def _cb_handleVODPlayerURI(self, opcode, data):
565                 self._vod_uri = None
566                 hl = struct.calcsize('!II')
567                 datas = struct.unpack('!II', data[:hl])
568                 uriLength = datas[1]
569                 vodUri = data[hl:hl+uriLength]
570                 self._handle_dump(self._cb_handleVODPlayerURI, opcode, vodUri)
571                 self._vod_uri = vodUri
572                 return (0, "OK")
573
574         def doStop(self, restoreBeforeService=True, needStop=True):
575                 if needStop == True:
576                         self._session.nav.stopService()
577                 if self._vod_service is not None and restoreBeforeService:
578                         before_service = getBeforeService()
579                         self._session.nav.playService(before_service)
580                         self._vod_uri = None
581                 self._vod_service = None
582
583         def getUrl(self):
584                 return self._vod_uri
585
586         def doRetryOpen(self, url):
587                 if url is None:
588                         return False
589                 for ii in range(5):
590                         self._vod_service = None
591                         try:
592                                 print "Try to open vod [%d] : %s" % (ii, url)
593                                 self._vod_service = eServiceReference(4097, 0, url)
594                                 self._session.nav.playService(self._vod_service)
595                                 if self._vod_service is not None:
596                                         return True
597                         except Exception, ErrMsg: 
598                                 print "OpenVOD ERR :", ErrMsg
599                         time.sleep(1)
600                 return False
601
602         def _cb_handleVODPlayerPlay(self, opcode, data):
603                 self._handle_dump(self._cb_handleVODPlayerPlay, opcode, data)
604                 self.doStop(restoreBeforeService=False)
605                 if self.doRetryOpen(url=self._vod_uri) == False:
606                         self.doStop()
607                 return (0, "OK")
608
609         def _cb_handleVODPlayerStop(self, opcode, data):
610                 self._handle_dump(self._cb_handleVODPlayerStop, opcode, data)
611                 self.doStop()   
612                 return (0, "OK")
613
614         def _cb_handleVODPlayerPlayPause(self, opcode, data):
615                 self._handle_dump(self._cb_handleVODPlayerPlayPause, opcode, data)
616                 service = self._session.nav.getCurrentService()
617                 try:
618                         pauseFlag = data[0]
619                         servicePause = service.pause()
620                         if pauseFlag == 'U':
621                                 servicePause.unpause()
622                         elif pauseFlag == 'P':
623                                 servicePause.pause()
624                 except Exception, ErrMsg:
625                         print "onPause ERR :", ErrMsg
626                 return (0, "OK")
627
628 from libshm import SimpleSharedMemory
629 _g_ssm_ = None
630 class HbbTVWindow(Screen, InfoBarNotifications):
631         skin =  """
632                 <screen name="HbbTVWindow" position="0,0" size="1280,720" backgroundColor="transparent" flags="wfNoBorder" title="HbbTV Plugin">
633                 </screen>
634                 """
635         def __init__(self, session, url=None, cbf=None, useAIT=False, profile=0):
636                 self._session = session
637                 eRCInput.getInstance().lock()
638
639                 Screen.__init__(self, session)
640                 InfoBarNotifications.__init__(self)
641                 self.__event_tracker = ServiceEventTracker(screen = self, eventmap = {
642                         iPlayableService.evUser+20: self._serviceForbiden,
643                         iPlayableService.evStart: self._serviceStarted,
644                         iPlayableService.evEOF: self._serviceEOF,
645                 })
646
647                 self._url = url
648                 self._use_ait = useAIT
649                 self._profile = profile
650                 self._cb_closed_func = cbf
651                 self.onLayoutFinish.append(self._layoutFinished)
652
653                 command_server = getCommandServer()
654                 if self._cb_set_page_title not in command_server.onSetPageTitleCB:
655                         command_server.onSetPageTitleCB.append(self._cb_set_page_title)
656
657                 if self._cb_close_window not in command_server.onHbbTVCloseCB:
658                         command_server.onHbbTVCloseCB.append(self._cb_close_window)
659
660                 self._closeTimer = eTimer()
661                 self._closeTimer.callback.append(self._do_close)
662
663                 self._currentServicePositionTimer = eTimer()
664                 self._currentServicePositionTimer.callback.append(self._cb_currentServicePosition)
665                 self._vodLength = 0
666
667                 global _g_ssm_
668                 self._ssm = _g_ssm_
669                 self._vod_length = 0
670
671         def getVodPlayTime(self):
672                 try:
673                         service = self._session.nav.getCurrentService()
674                         seek = service and service.seek()
675                         l = seek.getLength()
676                         p = seek.getPlayPosition()
677                         #return (p[1]/90000, l[1]/90000)
678                         return (p[1], l[1])
679                 except: pass
680                 return (-1,-1)
681
682         def _cb_currentServicePosition(self):
683                 def getTimeString(t):
684                         t = time.localtime(t/90000)
685                         return "%2d:%02d:%02d" % (t.tm_hour, t.tm_min, t.tm_sec)
686                 position,length = 0,0
687                 try:
688                         (position,length) = self.getVodPlayTime()
689                         self._vod_length = length
690                         if position == -1 and length == -1:
691                                 raise Exception("Can't get play status")
692                         #print getTimeString(position), "/", getTimeString(length)
693                         self._ssm.setStatus(position, length, 1)
694                 except Exception, ErrMsg:
695                         print ErrMsg
696                         self._serviceEOF()
697
698         def _serviceStarted(self):
699                 try:
700                         self._ssm.setStatus(0, 0, 0)
701                         self._currentServicePositionTimer.start(1000)
702                 except Exception, ErrMsg:
703                         print ErrMsg
704
705         def _serviceEOF(self):
706                 self._currentServicePositionTimer.stop()
707
708         def _layoutFinished(self):
709                 command_util = getCommandUtil()
710                 profile = self._profile
711                 (sid, onid, tsid, name, orgid) = getChannelInfos()
712                 params  = struct.pack('!IIIIII', orgid, profile, sid, onid, tsid, len(name)) + name
713                 if self._use_ait:
714                         command_util.sendCommand('OP_HBBTV_UNLOAD_AIT')
715                         time.sleep(1)
716                         command_util.sendCommand('OP_HBBTV_LOAD_AIT', params, 1)
717                         return
718                 command_util.sendCommand('OP_HBBTV_LOAD_AIT', params)
719                 time.sleep(1)
720                 command_util.sendCommand('OP_HBBTV_OPEN_URL', self._url)
721
722         def _cb_close_window(self):
723                 self._closeTimer.start(1000)
724
725         def _do_close(self):
726                 self._closeTimer.stop()
727                 command_server = getCommandServer()
728                 try:
729                         if self._cb_set_page_title in command_server.onSetPageTitleCB:
730                                 command_server.onSetPageTitleCB.remove(self._cb_set_page_title)
731                 except Exception, ErrMsg: pass
732                 try:
733                         if self._cb_close_window in command_server.onHbbTVCloseCB:
734                                         command_server.onHbbTVCloseCB.remove(self._cb_close_window)
735                 except Exception, ErrMsg: pass
736                 try:
737                         if self._cb_closed_func is not None:
738                                 self._cb_closed_func()
739                 except: pass
740                 eRCInput.getInstance().unlock()
741                 self.close()
742
743         def _serviceForbiden(self):
744                 global __gval__
745                 real_url = MMSStreamURL().getLocationData(__gval__.hbbtv_handelr.getUrl())
746                 print "Received URI :\n", real_url
747
748                 if real_url is not None:
749                         __gval__.hbbtv_handelr.doRetryOpen(real_url.strip())
750
751         def _cb_set_page_title(self, title=None):
752                 print "page title :",title
753                 if title is None:
754                         return
755                 self.setTitle(title)
756
757 class HbbTVHelper(Screen):
758         skin =  """<screen name="HbbTVHelper" position="0,0" size="0,0" backgroundColor="transparent" flags="wfNoBorder" title=" "></screen>"""
759         def __init__(self, session):
760                 global __gval__
761                 __gval__.hbbtv_handelr = HandlerHbbTV(session)
762                 __gval__.command_server = ServerFactory().doListenUnixTCP('/tmp/.sock.hbbtv.url', __gval__.hbbtv_handelr)
763
764                 self._urls = None
765                 #self._stop_opera()
766                 #self._start_opera()
767                 self._restart_opera()
768
769                 Screen.__init__(self, session)
770                 self._session = session
771                 self._timer_infobar = eTimer()
772                 self._timer_infobar.callback.append(self._cb_registrate_infobar)
773                 self._timer_infobar.start(1000)
774
775                 self._excuted_browser = False
776                 self._profile = 0
777
778                 __gval__.command_util = BrowserCommandUtil()
779
780                 global _g_ssm_
781                 if _g_ssm_ is None:
782                         _g_ssm_ = SimpleSharedMemory()
783                         _g_ssm_.doConnect()
784
785         def _cb_registrate_infobar(self):
786                 if InfoBar.instance:
787                         self._timer_infobar.stop()
788                         if self._cb_ready_for_ait not in InfoBar.instance.onReadyForAIT:
789                                 InfoBar.instance.onReadyForAIT.append(self._cb_ready_for_ait)
790                         if self._cb_hbbtv_activated not in InfoBar.instance.onHBBTVActivation:
791                                 InfoBar.instance.onHBBTVActivation.append(self._cb_hbbtv_activated)
792
793         def _cb_ready_for_ait(self, orgId=0):
794                 if orgId == 0:
795                         if not self._excuted_browser:
796                                 command_util = getCommandUtil()
797                                 command_util.sendCommand('OP_HBBTV_UNLOAD_AIT')
798                         return
799                 setChannelInfo(None, None, None, None, None)
800
801                 service = self._session.nav.getCurrentService()
802                 info = service and service.info()
803                 if info is not None:
804                         sid  = info.getInfo(iServiceInformation.sSID)
805                         onid = info.getInfo(iServiceInformation.sONID)
806                         tsid = info.getInfo(iServiceInformation.sTSID)
807                         name = info.getName()
808                         if name is None:
809                                 name = ""
810                         orgid   = 0
811                         namelen = len(name)
812                         for x in info.getInfoObject(iServiceInformation.sHBBTVUrl):
813                                 if x[0] in (1, -1) :
814                                         orgid = x[3]
815                                         break
816                         setChannelInfo(sid, onid, tsid, name, orgid)
817
818         def _cb_hbbtv_activated(self, title=None, url=None):
819                 if not self._is_browser_running():
820                         message = "HbbTV Browser was not running.\nPlease running browser before start HbbTV Application."
821                         self.session.open(MessageBox, message, MessageBox.TYPE_INFO)
822                         return
823                 service = self._session.nav.getCurrentlyPlayingServiceReference()
824                 setBeforeService(service)
825                 self._start_hbbtv_application(title, url)
826
827         def _start_hbbtv_application(self, title, url):
828                 use_ait = False
829                 tmp_url = self.getStartHbbTVUrl()
830                 if url is None:
831                         url = tmp_url
832                 if strIsEmpty(url):
833                         print "can't get url of hbbtv!!"
834                         return
835                 print "success to get url of hbbtv!! >>", url
836                 if self._excuted_browser:
837                         print "already excuted opera browser!!"
838                         return
839
840                 if isNeedRestart():
841                         self._restart_opera()
842                         time.sleep(2)
843                         setNeedRestart(False)
844
845                 for x in self._urls:
846                         control_code = x[0]
847                         tmp_url = x[2]
848                         if tmp_url == url and control_code == 1:
849                                 use_ait = True
850                 self._excuted_browser = True
851                 self._session.open(HbbTVWindow, url, self._cb_closed_browser, use_ait, self._profile)
852
853         def _cb_closed_browser(self):
854                 self._excuted_browser = False
855
856         def _start_opera(self):
857                 if not self._is_browser_running():
858                         global HBBTVAPP_PATH
859                         start_command = '%s/launcher start'%(HBBTVAPP_PATH)
860                         os.system(start_command)
861
862         def _stop_opera(self):
863                 global HBBTVAPP_PATH
864                 try:    os.system('%s/launcher stop'%(HBBTVAPP_PATH))
865                 except: pass
866
867         def _restart_opera(self):
868                 global HBBTVAPP_PATH
869                 try:    os.system('%s/launcher restart'%(HBBTVAPP_PATH))
870                 except: pass
871
872         def getStartHbbTVUrl(self):
873                 url, self._urls, self._profile = None, None, 0
874                 service = self._session.nav.getCurrentService()
875                 info = service and service.info()
876                 if not info: return None
877                 self._urls = info.getInfoObject(iServiceInformation.sHBBTVUrl)
878                 for u in self._urls:
879                         if u[0] in (1, -1): # 0:control code, 1:name, 2:url, 3:orgid, 4:appid, 5:profile code
880                                 url = u[2]
881                                 self._profile = u[5]
882                 if url is None:
883                         url = info.getInfoString(iServiceInformation.sHBBTVUrl)
884                 return url
885
886         def showApplicationSelectionBox(self):
887                 applications = []
888
889                 if self.getStartHbbTVUrl():
890                         for x in self._urls:
891                                 applications.append((x[1], x))
892                 else: applications.append(("No detected HbbTV applications.", None))
893                 self._session.openWithCallback(self._application_selected, ChoiceBox, title=_("Please choose an HbbTV application."), list=applications)
894
895         def _application_selected(self, selected):
896                 try:
897                         if selected[1] is None: return
898                         self._cb_hbbtv_activated(selected[1][1], selected[1][2])
899                 except Exception, ErrMsg: print ErrMsg
900
901         def showBrowserConfigBox(self):
902                 start_stop_mode = []
903                 if self._is_browser_running():
904                         start_stop_mode.append(('Stop',None))
905                 else:   start_stop_mode.append(('Start',None))
906                 self._session.openWithCallback(self._browser_config_selected, ChoiceBox, title=_("Please choose one."), list=start_stop_mode)
907
908         def _browser_config_selected(self, selected):
909                 if selected is None:
910                         return
911                 try:
912                         mode = selected[0]
913                         if mode == 'Start':
914                                 if not self._is_browser_running():
915                                         self._start_opera()
916                         elif mode == 'Stop':
917                                 self._stop_opera()
918                 except Exception, ErrMsg: print "Config ERR :", ErrMsg
919
920         def _is_browser_running(self):
921                 try:
922                         global HBBTVAPP_PATH
923                         ret = os.popen('%s/launcher check'%(HBBTVAPP_PATH)).read()
924                         return ret.strip() != "0"
925                 except Exception, ErrMsg:
926                         print "Check Browser Running ERR :", ErrMsg
927                 return False
928
929 _g_helper = None
930 class OperaBrowser(Screen):
931         MENUBAR_ITEM_WIDTH  = 150
932         MENUBAR_ITEM_HEIGHT = 30
933         SUBMENULIST_WIDTH   = 200
934         SUBMENULIST_HEIGHT  = 25
935         SUBMENULIST_NEXT    = 2
936
937         skin =  """
938                 <screen name="Opera Browser" position="0,0" size="1280,720" backgroundColor="transparent" flags="wfNoBorder" title="Opera Browser">
939                         <widget name="topArea" zPosition="-1" position="0,0" size="1280,60" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" />
940                         <widget name="menuitemFile" position="30,20" size="150,30" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" foregroundColors="#9f1313,#a08500" />
941                         <widget name="menuitemHelp" position="180,20" size="150,30" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" foregroundColors="#9f1313,#a08500" />
942                         <widget name="menulist" position="50,%d" size="%d,150" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />
943                         <widget name="submenulist" position="%d,%d" size="%d,150" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />
944                         <widget name="bottomArea" position="0,640" size="1280,80" font="Regular;20" valign="center" halign="center" backgroundColor="#000000" />
945                 </screen>
946                 """ % (MENUBAR_ITEM_HEIGHT+30, SUBMENULIST_WIDTH, SUBMENULIST_WIDTH+50+SUBMENULIST_NEXT, MENUBAR_ITEM_HEIGHT+30, SUBMENULIST_WIDTH)
947
948         MENUITEMS_LIST =[[('Open Location', None), ('Start/Stop',None), ('Exit', None)],
949                          [('About', None)]]
950         def __init__(self, session):
951                 Screen.__init__(self, session)
952
953                 self["actions"] = ActionMap(["MinuteInputActions", "ColorActions", "InputActions", "InfobarChannelSelection", "EPGSelectActions", "KeyboardInputActions"], {
954                          "cancel"      : self.keyCancel
955                         ,"ok"          : self.keyOK
956                         ,"left"        : self.keyLeft
957                         ,"right"       : self.keyRight
958                         ,"up"          : self.keyUp
959                         ,"down"        : self.keyDown
960                         ,"menu"        : self.keyCancel
961                 }, -2)
962
963                 self.menubarCurrentIndex = 0
964                 self.lvMenuItems = []
965                 self.lvSubMenuItems = []
966
967                 self["topArea"]    = Label()
968                 self["bottomArea"] = Label()
969
970                 self["menuitemFile"] = MultiColorLabel()
971                 self["menuitemHelp"] = MultiColorLabel()
972
973                 self["menulist"] = MenuList(self.setListOnView())
974                 self["submenulist"] = MenuList(self.setSubListOnView())
975
976                 self.toggleMainScreenFlag = True
977                 self.toggleListViewFlag = False
978                 self.toggleSubListViewFlag = False
979                 self.currentListView = self["menulist"]
980
981                 self.onLayoutFinish.append(self.layoutFinished)
982
983                 self._onCloseTimer = eTimer()
984                 self._onCloseTimer.callback.append(self._cb_onClose)
985
986         def enableRCMouse(self, mode): #mode=[0|1]|[False|True]
987                 rcmouse_path = "/proc/stb/fp/mouse"
988                 if os.path.exists(rcmouse_path):
989                         os.system("echo %d > %s" % (mode, rcmouse_path))
990
991         def layoutFinished(self):
992                 self["menuitemFile"].setText("File")
993                 self["menuitemHelp"].setText("Help")
994
995                 self["menulist"].hide()
996                 self["submenulist"].hide()
997
998                 self["bottomArea"].setText("Opera Web Browser Plugin v0.1")
999                 self.setTitle("BrowserMain")
1000                 self.selectMenuitem()
1001
1002         def selectMenuitem(self):
1003                 tmp = [self["menuitemFile"], self["menuitemHelp"]]
1004                 self["menuitemFile"].setForegroundColorNum(0)
1005                 self["menuitemHelp"].setForegroundColorNum(0)
1006                 tmp[self.menubarCurrentIndex].setForegroundColorNum(1)
1007
1008         def popupCloseAll(self):
1009                 self.keyLeft()
1010                 self.keyLeft()
1011                 self.keyUp()
1012                 self.keyCancel()
1013
1014         def setListOnView(self):
1015                 self.lvMenuItems = self.MENUITEMS_LIST[self.menubarCurrentIndex]        
1016                 return self.lvMenuItems
1017
1018         def setSubListOnView(self):
1019                 self.lvSubMenuItems = []
1020                 xl = self["menulist"].getCurrent()[1]
1021                 if xl is None: return []
1022                 for x in xl:
1023                         self.lvSubMenuItems.append((x,None))
1024                 return self.lvSubMenuItems
1025
1026         def toggleMainScreen(self):
1027                 if not self.toggleMainScreenFlag:
1028                         self.show()
1029                 else:   self.hide()
1030                 self.toggleMainScreenFlag = not self.toggleMainScreenFlag
1031
1032         def toggleListView(self):
1033                 if not self.toggleListViewFlag:
1034                         self["menulist"].show()
1035                 else:   self["menulist"].hide()
1036                 self.toggleListViewFlag = not self.toggleListViewFlag
1037
1038         def toggleSubListView(self):
1039                 if not self.toggleSubListViewFlag:
1040                         self["submenulist"].show()
1041                 else:   self["submenulist"].hide()
1042                 self.toggleSubListViewFlag = not self.toggleSubListViewFlag
1043
1044         def setCurrentListView(self, listViewIdx):
1045                 if listViewIdx == 0:
1046                         self.currentListView = None
1047                 elif listViewIdx == 1:
1048                         self.currentListView = self["menulist"]
1049                 elif listViewIdx == 2:
1050                         self.currentListView = self["submenulist"]
1051
1052         def _cb_onClose(self):
1053                 self._onCloseTimer.stop()
1054                 command_server = getCommandServer()
1055                 try:
1056                         if self._on_close_window in command_server.onHbbTVCloseCB:
1057                                         command_server.onHbbTVCloseCB.remove(self._on_close_window)
1058                 except Exception, ErrMsg: pass
1059                 try:
1060                         if self._on_setPageTitle in command_server.onSetPageTitleCB:
1061                                 command_server.onSetPageTitleCB.remove(self._on_setPageTitle)
1062                 except Exception, ErrMsg: pass
1063                 self._on_setPageTitle('Opera Browser')
1064                 self.enableRCMouse(False)
1065                 self.toggleMainScreen()
1066                 eRCInput.getInstance().unlock()
1067
1068         def _on_setPageTitle(self, title=None):
1069                 print "Title :",title
1070                 if title is None:
1071                         return
1072                 self.setTitle(title)
1073
1074         def cbUrlText(self, data=None):
1075                 print "Inputed Url :", data
1076                 if strIsEmpty(data):
1077                         return
1078                 command_server = getCommandServer()
1079                 if self._on_setPageTitle not in command_server.onSetPageTitleCB:
1080                                 command_server.onSetPageTitleCB.append(self._on_setPageTitle)
1081                 if self._on_close_window not in command_server.onHbbTVCloseCB:
1082                         command_server.onHbbTVCloseCB.append(self._on_close_window)
1083                 self.toggleMainScreen()
1084                 self.enableRCMouse(True)
1085                 eRCInput.getInstance().lock()
1086                 command_util = getCommandUtil()
1087                 command_util.sendCommand('OP_BROWSER_OPEN_URL', data)
1088
1089         def _on_close_window(self):
1090                 self._onCloseTimer.start(1000)
1091
1092         def _cmd_on_OpenLocation(self):
1093                 global _g_helper
1094                 if not _g_helper._is_browser_running():
1095                         message = "Opera Browser was not running.\nPlease running browser using [File]>[Start/Stop] menu."
1096                         self.session.open(MessageBox, message, MessageBox.TYPE_INFO)
1097                         return
1098                 self.session.openWithCallback(self.cbUrlText, VirtualKeyBoard, title=("Please enter URL here"), text='http://')
1099         def _cmd_on_About(self):
1100                 self.session.open(MessageBox, 'Opera Web Browser Plugin v0.1(beta)', type = MessageBox.TYPE_INFO)
1101         def _cmd_on_Exit(self):
1102                 self.close()
1103         def _cmd_on_StartStop(self):
1104                 global _g_helper
1105                 if _g_helper is None: 
1106                         return
1107                 _g_helper.showBrowserConfigBox()
1108         def doCommand(self, command):
1109                 cmd_map = {
1110                          'Exit'          :self._cmd_on_Exit
1111                         ,'About'         :self._cmd_on_About
1112                         ,'Open Location' :self._cmd_on_OpenLocation
1113                         ,'Start/Stop'    :self._cmd_on_StartStop
1114                 }
1115                 try:
1116                         cmd_map[command]()
1117                 except: pass
1118
1119         def keyOK(self):
1120                 if not self.toggleListViewFlag:
1121                         self.keyDown()
1122                         return
1123                 if self.currentListView.getCurrent()[1] is None:
1124                         self.doCommand(self.currentListView.getCurrent()[0])
1125                         #self.session.open(MessageBox, _(self.currentListView.getCurrent()[0]), type = MessageBox.TYPE_INFO)
1126                         return
1127                 self.keyRight()
1128
1129         def updateSelectedMenuitem(self, status):
1130                 if self.menubarCurrentIndex == 0 and status < 0:
1131                         self.menubarCurrentIndex = 1
1132                 elif self.menubarCurrentIndex == 1 and status > 0:
1133                         self.menubarCurrentIndex = 0
1134                 else:   self.menubarCurrentIndex += status
1135                 self.selectMenuitem()
1136
1137         def keyLeft(self):
1138                 if not self.toggleMainScreenFlag:
1139                         return
1140                 if not self.toggleListViewFlag:
1141                         self.updateSelectedMenuitem(-1)
1142                         return
1143                 if self.toggleSubListViewFlag:
1144                         self.setCurrentListView(1)
1145                         self.toggleSubListView()
1146                         return
1147                 if self.currentListView.getSelectedIndex():
1148                         self.currentListView.pageUp()
1149
1150         def keyRight(self):
1151                 if not self.toggleMainScreenFlag:
1152                         return
1153                 if not self.toggleListViewFlag:
1154                         self.updateSelectedMenuitem(1)
1155                         return
1156                 if self.currentListView is None:
1157                         return
1158                 if self.currentListView.getCurrent()[1] is not None:
1159                         parentSelectedIndex = self.currentListView.getSelectedIndex()
1160                         self.setCurrentListView(2)
1161                         self.currentListView.setList(self.setSubListOnView())
1162                         self.currentListView.resize(self.SUBMENULIST_WIDTH, self.SUBMENULIST_HEIGHT*len(self.lvSubMenuItems)+5)
1163                         self.currentListView.move(self.MENUBAR_ITEM_WIDTH*self.menubarCurrentIndex + self.SUBMENULIST_WIDTH+self.SUBMENULIST_NEXT + 50,self.MENUBAR_ITEM_HEIGHT+30+(parentSelectedIndex*self.SUBMENULIST_HEIGHT))
1164                         self.toggleSubListView()
1165
1166         def keyDown(self):
1167                 if not self.toggleMainScreenFlag:
1168                         return
1169                 if self.currentListView is None:
1170                         return
1171                 if not self.toggleListViewFlag:
1172                         self.currentListView.setList(self.setListOnView())
1173                         self.currentListView.resize(self.SUBMENULIST_WIDTH, self.SUBMENULIST_HEIGHT*len(self.lvMenuItems)+5)
1174                         self.currentListView.move(self.MENUBAR_ITEM_WIDTH*self.menubarCurrentIndex+1+ 50,self.MENUBAR_ITEM_HEIGHT+30)
1175                         self.toggleListView()
1176                         return
1177                 self.currentListView.down()
1178
1179         def keyUp(self):
1180                 if not self.toggleMainScreenFlag:
1181                         return
1182                 if self.currentListView is None:
1183                         return
1184                 if self.currentListView == self["menulist"]:
1185                         if self.currentListView.getSelectedIndex() == 0:
1186                                 self.toggleListView()
1187                                 return
1188                 self.currentListView.up()
1189
1190         def keyCancel(self):
1191                 self.toggleMainScreen()
1192
1193 def auto_start_main(reason, **kwargs):
1194         if reason:
1195                 command_server = getCommandServer()
1196                 command_server.stop()
1197
1198 def session_start_main(session, reason, **kwargs):
1199         eRCInput.getInstance().unlock()
1200         global _g_helper
1201         _g_helper = session.open(HbbTVHelper)
1202
1203 def plugin_start_main(session, **kwargs):
1204         session.open(OperaBrowser)
1205
1206 def plugin_extension_start_application(session, **kwargs):
1207         global _g_helper
1208         if _g_helper is None: 
1209                 return
1210         _g_helper.showApplicationSelectionBox()
1211
1212 def plugin_extension_browser_config(session, **kwargs):
1213         global _g_helper
1214         if _g_helper is None: 
1215                 return
1216         _g_helper.showBrowserConfigBox()
1217
1218 def Plugins(path, **kwargs):
1219         return  [
1220                 PluginDescriptor(where=PluginDescriptor.WHERE_AUTOSTART, fnc=auto_start_main),
1221                 PluginDescriptor(where=PluginDescriptor.WHERE_SESSIONSTART, needsRestart=True, fnc=session_start_main, weight=-10),
1222                 PluginDescriptor(name="HbbTV Applications", where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=plugin_extension_start_application),
1223                 PluginDescriptor(name="Browser Start/Stop", where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=plugin_extension_browser_config),
1224                 PluginDescriptor(name="Opera Web Browser", description="start opera web browser", where=PluginDescriptor.WHERE_PLUGINMENU, needsRestart=True, fnc=plugin_start_main),
1225                 ]
1226