Support gles animation.
[vuplus_dvbapp] / lib / python / Plugins / Extensions / HbbTV / plugin.py
1 from Plugins.Plugin import PluginDescriptor
2 from Screens.Screen import Screen
3 from Screens.InfoBar import InfoBar
4 from Screens.ChoiceBox import ChoiceBox
5 from Screens.HelpMenu import HelpableScreen
6 from Screens.MessageBox import MessageBox
7 from Screens.VirtualKeyBoard import VirtualKeyBoard
8 from Components.config import config
9 from Components.ActionMap import ActionMap
10 from Components.Language import language
11 from Components.ServiceEventTracker import ServiceEventTracker
12 from Components.VolumeControl import VolumeControl
13
14 from enigma import eTimer, fbClass, eRCInput, iServiceInformation, iPlayableService
15
16 import os, struct, vbcfg
17
18 from __init__ import _
19 from hbbtv import HbbTVWindow
20 from browser import Browser
21 from youtube import YoutubeTVWindow, YoutubeTVSettings
22 from vbipc import VBController, VBServerThread, VBHandlers
23
24 strIsEmpty = lambda x: x is None or len(x) == 0
25
26 vbcfg.SOCKETFILE = '/tmp/.browser.support'
27 vbcfg.CONTROLFILE = '/tmp/.browser.controller'
28 _OPCODE_LIST = [
29                 'CONTROL_BACK',
30                 'CONTROL_FORWARD',
31                 'CONTROL_STOP',
32                 'CONTROL_RELOAD',
33                 'CONTROL_OPENURL',
34                 'CONTROL_EXIT',
35                 'CONTROL_TITLE',
36                 'CONTROL_OK',
37                 'CONTROL_OUT_OF_MEMORY',
38                 'CONTROL_INVALIDATE',
39                 'CONTROL_GET_FBSIZE',
40                 'CONTROL_GET_VOLUME',
41                 'CONTROL_SET_VOLUME',
42                 'CONTROL_VOLUME_UP',
43                 'CONTROL_VOLUME_DOWN',
44                 'HBBTV_LOADAIT',
45                 'HBBTV_OPENURL',
46                 'YOUTUBETV_OPENURL',
47                 'BROWSER_OPENURL',
48                 'BROWSER_MENU_OPEN',
49                 'BROWSER_MENU_CLOSE',
50                 'BROWSER_VKB_OPEN',
51                 'BROWSER_VKB_CLOSE',
52                 'OOIF_GET_CURRENT_CHANNEL',
53                 'OOIF_BROADCAST_PLAY',
54                 'OOIF_BROADCAST_STOP',
55                 'OOIF_BROADCAST_CHECK',
56                 'OPCODE_END'
57                 ]
58
59 class VBHandler(VBHandlers):
60         def __init__(self, session):
61                 self._session = session
62                 self.current_title = None
63                 self.max_volume = -1
64                 self.soft_volume = -1
65                 self.videobackend_activate = False
66                 self.onSetTitleCB = []
67                 self.onCloseCB = []
68                 VBHandlers.__init__(self, _OPCODE_LIST, '_CB_')
69
70         def set_volume(self, volume):
71                 if self.max_volume < 0:
72                         self.max_volume = VolumeControl.instance.volctrl.getVolume()
73
74                 self.max_volume += volume
75                 if self.max_volume > 100:
76                         self.max_volume = 100
77                 elif self.max_volume < 0:
78                         self.max_volume = 0
79
80                 if self.soft_volume > 0:
81                         v = int((self.max_volume * self.soft_volume) / 100)
82                         VolumeControl.instance.volctrl.setVolume(v, v)
83                 else:
84                         VolumeControl.instance.volctrl.setVolume(self.max_volume, self.max_volume)
85
86         def close_vkb(self, data=""):
87                 fbClass.getInstance().lock()
88                 eRCInput.getInstance().lock()
89
90                 if strIsEmpty(data):
91                         data = ""
92                 VBController.command("BROWSER_VKB_CLOSE", data)
93
94         def _CB_CONTROL_EXIT(self, result, packet):
95                 if self.onCloseCB:
96                         for x in self.onCloseCB:
97                                 try:
98                                         x()
99                                 except Exception:
100                                         if x in self.onCloseCB:
101                                                 self.onCloseCB.remove(x)
102                 if self.videobackend_activate is False:
103                         if vbcfg.g_service is not None:
104                                 self._session.nav.playService(vbcfg.g_service)
105                 return (True, None)
106
107         def _CB_CONTROL_TITLE(self, result, packet):
108                 if packet.startswith('file://') or packet.startswith('http://'):
109                         return (True, None)
110                 for x in self.onSetTitleCB:
111                         try:
112                                 x(packet)
113                                 self.current_title = packet
114                         except Exception:
115                                 if x in self.onSetTitleCB:
116                                         self.onSetTitleCB.remove(x)
117                 return (True, None)
118
119         def _CB_CONTROL_OK(self, result, packet):
120                 if vbcfg.g_browser and packet.startswith('stop'):
121                         vbcfg.g_browser.keyOK()
122                 return (True, None)
123
124         def _CB_CONTROL_OUT_OF_MEMORY(self, result, packet):
125                 vbcfg.need_restart = True;
126                 return (True, None)
127
128         def _CB_CONTROL_INVALIDATE(self, result, packet):
129                 # redraw enigma
130                 from enigma import getDesktop
131                 getDesktop(0).paint()
132                 return (True, None)
133
134         def _CB_CONTROL_GET_FBSIZE(self, result, packet):
135                 from enigma import getDesktop
136                 desktop_size = getDesktop(0).size()
137                 data = "%dx%d" % (desktop_size.width(), desktop_size.height())
138                 return (True, data)
139
140         def _CB_CONTROL_SET_VOLUME(self, result, packet):
141                 if self.max_volume < 0:
142                         self.max_volume = VolumeControl.instance.volctrl.getVolume()
143                 self.soft_volume = int(packet)
144
145                 v = 0
146                 if self.soft_volume > 0 and self.max_volume > 0:
147                         v = int((self.max_volume * self.soft_volume) / 100)
148                 VolumeControl.instance.volctrl.setVolume(v, v)
149                 return (True, None)
150
151         def _CB_CONTROL_VOLUME_UP(self, result, packet):
152                 self.set_volume(5)
153                 return (True, None)
154
155         def _CB_CONTROL_VOLUME_DOWN(self, result, packet):
156                 self.set_volume(-5)
157                 return (True, None)
158
159         def _CB_BROWSER_MENU_OPEN(self, result, packet):
160                 if vbcfg.g_browser and vbcfg.g_browser.is_browser_opened:
161                         vbcfg.setPosition(vbcfg.g_position)
162                         fbClass.getInstance().unlock()
163                         eRCInput.getInstance().unlock()
164
165                         vbcfg.g_browser.toggle_browser(packet, self.current_title)
166                 return (True, None)
167
168         def _CB_BROWSER_VKB_OPEN(self, result, packet):
169                 if vbcfg.g_browser and vbcfg.g_browser.is_browser_opened:
170                         vbcfg.setPosition(vbcfg.g_position)
171                         fbClass.getInstance().unlock()
172                         eRCInput.getInstance().unlock()
173
174                         if strIsEmpty(packet):
175                                 packet = ""
176                         self._session.openWithCallback(self.close_vkb, VirtualKeyBoard, title=("Please enter URL here"), text=str(packet))
177                 return (True, None)
178
179         def _CB_OOIF_GET_CURRENT_CHANNEL(self, result, packet):
180                 if (vbcfg.g_channel_info):
181                         try:
182                                 data = struct.pack('iiii', vbcfg.g_channel_info[0], vbcfg.g_channel_info[1], vbcfg.g_channel_info[2], len(vbcfg.g_channel_info[3])) + vbcfg.g_channel_info[3]
183                         except Exception, err:
184                                 vbcfg.ERR(err)
185                                 return (False, None)
186                 else:
187                         return (False, None)
188                 return (True, data)
189
190         def _CB_OOIF_BROADCAST_PLAY(self, result, packet):
191                 if vbcfg.g_service is not None:
192                         self._session.nav.playService(vbcfg.g_service)
193                 self.videobackend_activate = False
194                 return (True, None)
195
196         def _CB_OOIF_BROADCAST_STOP(self, result, packet):
197                 vbcfg.g_service = self._session.nav.getCurrentlyPlayingServiceReference()
198                 self._session.nav.stopService()
199                 self.videobackend_activate = True
200                 return (True, None)
201
202         def _CB_OOIF_BROADCAST_CHECK(self, result, packet):
203                 if self._session.nav.getCurrentService() is None:
204                         return (False, None)
205                 return (True, None)
206
207 class VBMain(Screen):
208         skin = """<screen name="VBMAIN" position="0,0" size="0,0" backgroundColor="transparent" flags="wfNoBorder" title=" "></screen>"""
209         def __init__(self, session):
210                 Screen.__init__(self, session)
211
212                 self.vbcallback = None
213                 self.vbhandler = VBHandler(session)
214                 self.vbserver = VBServerThread()
215                 self.vbserver.open(1)
216                 self.vbserver.start()
217
218                 # comment for dev
219                 self.restart_browser()
220                 vbcfg.LOG("browser start")
221
222                 self._timer_infobar = eTimer()
223                 self._timer_infobar.callback.append(self._cb_register_infobar)
224                 self._timer_infobar.start(1000)
225
226                 self._event = ServiceEventTracker(screen=self, eventmap={
227                                 iPlayableService.evHBBTVInfo: self._cb_ait_detected,
228                                 iPlayableService.evUpdatedInfo: self._cb_info_updated
229                         })
230                 self._applicationList = None
231                 self._app_info = None
232
233                 try:
234                         from Screens.InfoBarGenerics import gHbbtvApplication
235                         self.m_vuplus = gHbbtvApplication.getUseAit()
236                 except:
237                         self.m_vuplus = False
238
239         def _cb_register_infobar(self):
240                 if InfoBar.instance:
241                         self._timer_infobar.stop()
242                         if self._cb_hbbtv_activated not in InfoBar.instance.onHBBTVActivation:
243                                 InfoBar.instance.onHBBTVActivation.append(self._cb_hbbtv_activated)
244                 vbcfg.DEBUG("registred HbbTV in InfoBar")
245
246         def _cb_hbbtv_activated(self, url=None, app_info=None):
247                 if not self.check_browser():
248                         message = _("HbbTV Browser was not running.\nPlease running browser before start HbbTV Application.")
249                         self.session.open(MessageBox, message, MessageBox.TYPE_INFO)
250                         return
251                 self.start_hbbtv_application(url, app_info)
252
253         def _cb_ait_detected(self):
254                 vbcfg.g_channel_info = None
255                 self._applicationList = None
256                 self._app_info = self.get_autostart_application()
257                 vbcfg.DEBUG("detected AIT")
258
259         def _cb_info_updated(self):
260                 vbcfg.g_service = self.session.nav.getCurrentlyPlayingServiceReference()
261                 vbcfg.DEBUG("updated channel info")
262
263         def start_hbbtv_application(self, url, app_info):
264                 if vbcfg.need_restart:
265                         self.restart_browser()
266                         os.time.sleep(2)
267                         vbcfg.need_restart = False
268
269                 if not app_info:
270                         app_info = self._app_info
271                 self.session.open(HbbTVWindow, url, app_info)
272
273         def menu_toggle_browser(self, callback=None):
274                 mode = []
275                 self.vbcallback = callback
276                 if self.check_browser():
277                         mode.append((_('Stop'), 'Stop'))
278                 else:
279                         mode.append((_('Start'), 'Start'))
280                 self.session.openWithCallback(self.toggle_browser, ChoiceBox, title=_("Please choose one."), list=mode)
281
282         def toggle_browser(self, selected):
283                 if selected is not None:
284                         if self.vbcallback:
285                                 self.vbcallback()
286                         try:
287                                 mode = selected[1]
288                                 if mode == 'Start':
289                                         if not self.check_browser():
290                                                 self.start_browser()
291                                 elif mode == 'Stop':
292                                         self.stop_browser()
293
294                         except Exception, ErrMsg:
295                                 vbcfg.ERR("toggle browser: %s" % ErrMsg)
296
297         def menu_hbbtv_applications(self):
298                 applications = []
299                 if self._applicationList is not None:
300                         for x in self._applicationList:
301                                 applications.append((x["name"], x))
302                 else:
303                         applications.append((_("No detected HbbTV applications."), None))
304                 self.session.openWithCallback(self.start_application_selected, ChoiceBox, title=_("Please choose an HbbTV application."), list=applications)
305
306         def start_application_selected(self, selected):
307                 vbcfg.DEBUG(selected)
308                 try:
309                         if selected[1] is not None:
310                                 self._cb_hbbtv_activated(selected[1]["url"], selected[1])
311                 except Exception, ErrMsg:
312                         vbcfg.ERR(ErrMsg)
313
314         def get_autostart_application(self):
315                 if self._applicationList is None:
316                         service = self.session.nav.getCurrentService()
317                         info = service and service.info()
318                         if info is not None:
319                                 sid = info.getInfo(iServiceInformation.sSID)
320                                 onid = info.getInfo(iServiceInformation.sONID)
321                                 tsid = info.getInfo(iServiceInformation.sTSID)
322                                 name = info.getName()
323                                 vbcfg.g_channel_info = (sid, onid, tsid, name)
324
325                                 pmtid = info.getInfo(iServiceInformation.sPMTPID)
326                                 demux = info.getInfoString(iServiceInformation.sLiveStreamDemuxId)
327                                 vbcfg.DEBUG("demux = %s, pmtid = 0x%x, sid = 0x%x" % (demux, pmtid, sid))
328
329                                 from aitreader import eAITSectionReader
330                                 reader = eAITSectionReader(demux, pmtid, sid)
331                                 if reader.doOpen(info, self.m_vuplus):
332                                         reader.doParseApplications()
333                                         reader.doDump()
334                                 else:
335                                         vbcfg.ERR("no AIT")
336
337                                 try:
338                                         self._applicationList = reader.getApplicationList()
339                                 except:
340                                         pass
341
342                 if self._applicationList is not None:
343                         for app in self._applicationList:
344                                 if app["control"] in (1, -1):
345                                         return app
346                 return None
347
348         def start_browser(self):
349                 if not self.check_browser():
350                         os.system("%s/%s start"%(vbcfg.APPROOT, vbcfg.APP_RUN))
351                 return True
352
353         def stop_browser(self):
354                 VBController.command('CONTROL_EXIT')
355                 return True
356                 try:
357                         os.system("%s/%s stop"%(vbcfg.APPROOT, vbcfg.APP_RUN))
358                 except:
359                         pass
360                 return True
361
362         def check_browser(self):
363                 try:
364                         ret = os.popen('%s/%s check'%(vbcfg.APPROOT, vbcfg.APP_RUN)).read()
365                         return ret.strip() != "0"
366                 except Exception, ErrMsg:
367                         vbcfg.ERR("check browser running: %s" % ErrMsg)
368                 return False
369
370         def restart_browser(self):
371                 try:
372                         os.system("%s/%s restart"%(vbcfg.APPROOT, vbcfg.APP_RUN))
373                 except:
374                         pass
375                 return True
376
377 def HelpableScreen__init__(self):
378         if isinstance(self, HelpableScreen):
379                 HelpableScreen.showManual = showManual
380
381                 self["helpActions"] = ActionMap(["HelpbuttonActions"], {
382                         "help_b" : self.showHelp,
383                         "help_l" : self.showManual,
384                 }, -2)
385
386 def showManual(self):
387         if not os.path.exists(vbcfg.MANUALROOT):
388                 return
389
390         url = 'file://' + vbcfg.MANUALROOT + '/main.html'
391         lang = language.getLanguage()
392         if os.path.exists(vbcfg.MANUALROOT + '/' + lang):
393                 url = 'file://' + vbcfg.MANUALROOT + '/' + lang + '/main.html'
394
395         vbcfg.g_browser = self.session.open(Browser, url)
396
397 def auto_start_main(reason, **kwargs):
398         if reason:
399                 try:
400                         if vbcfg.g_main.vbserver is not None:
401                                 vbcfg.g_main.vbserver.kill()
402                 except: pass
403
404 def session_start_main(session, reason, **kwargs):
405         vbcfg.g_main = session.open(VBMain)
406         HelpableScreen.__init__ = HelpableScreen__init__
407         HelpableScreen.session = session
408
409 def start_youtubetv_main(session, **kwargs):
410         def _cb_youtubetv_close(ret):
411                 if ret:
412                         vbcfg.g_service = session.nav.getCurrentlyPlayingServiceReference()
413                         if vbcfg.g_service is not None:
414                                 session.nav.stopService()
415                         vbcfg.g_browser = session.open(Browser, vbcfg.g_youtubetv_cfg.uri.value, True)
416
417         if config.plugins.youtubetv.showhelp.value == True:
418                 _cb_youtubetv_close(True)
419         else:
420                 session.openWithCallback(_cb_youtubetv_close, YoutubeTVWindow)
421
422
423 def menu_start_youtube(menuid, **kwargs):
424         if menuid == "mainmenu":
425                 return [(_("YouTube TV"), start_youtubetv_main, "youtube_tv", 46)]
426         return []
427
428 def plugin_setting_youtube(session, **kwargs):
429         session.open(YoutubeTVSettings)
430
431 def plugin_start_browser(session, **kwargs):
432         vbcfg.g_browser = session.open(Browser)
433
434 def extension_toggle_browser(session, **kwargs):
435         if vbcfg.g_main is not None:
436                 vbcfg.g_main.menu_toggle_browser()
437
438 def extension_start_application(session, **kwargs):
439         if vbcfg.g_main is not None:
440                 vbcfg.g_main.menu_hbbtv_applications()
441
442 def Plugins(**kwargs):
443         l = []
444         l.append(PluginDescriptor(where=PluginDescriptor.WHERE_AUTOSTART, fnc=auto_start_main))
445         l.append(PluginDescriptor(where=PluginDescriptor.WHERE_SESSIONSTART, needsRestart=True, fnc=session_start_main, weight=-10))
446         l.append(PluginDescriptor(name=_("YouTube TV"), where=PluginDescriptor.WHERE_MENU, fnc=menu_start_youtube))
447         l.append(PluginDescriptor(name=_("YouTube TV Settings"), where=PluginDescriptor.WHERE_PLUGINMENU, fnc=plugin_setting_youtube))
448         l.append(PluginDescriptor(name=_("Browser Start/Stop"), where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=extension_toggle_browser))
449         l.append(PluginDescriptor(name=_("HbbTV Applications"), where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=extension_start_application))
450         l.append(PluginDescriptor(name=_("Opera Web Browser"), description=_("start opera web browser"), where=PluginDescriptor.WHERE_PLUGINMENU, needsRestart=True, fnc=plugin_start_browser))
451         return l