Newer
Older
Import / projects / LGN-IP3870 / t / new / elbrowser.py
from setting import setting
from basemodel import EntryStage,ListStage
from roxiadebug import roxia_trace
import runtime, config, os, os.path, uiconfig, time, signal, keysender
from basemodel import NotifyStage, SymbolSelectionStage, Stage
from baseui import WebLoadingUI

#message queue 방식으로 browser와 통신

def killall(name, sig):
	for pid in os.listdir('/proc'):
		cmdline_path = '/proc/%s/cmdline' % pid
		if os.path.exists(cmdline_path):
			try:
				pid = int(pid)
			except ValueError:
				continue

			if open(cmdline_path).read().startswith(name):
				os.kill(pid, sig)


class BrowserApp:
	def __init__(self):
		roxia_trace('BrowserApp.__init__()')
		self.pid = 0
		self.is_activate = False

	def run_web(self, url = ''):
		import status
		status.supervision_not_allowed = 1
		
		print '===================== unload EPT==================='
		runtime.vdci_send_mesg(code1=config.MESG_SET_PARAMS, code2='t', mesg1=0)

		time.sleep(2)
		runtime.dspg.hal_close()
		os.system('/sbin/rmmod ept')		

		#os.system('web_start')
		roxia_trace('******* starting WEB *******')
		keysender.create_msgqueue()

		try:
			self.pid = os.fork()
		except:
			keysender.delete_msgqueue()
			if config.elbrowser_debug:
				print '***********************************************************'
				print 'browser fork() failed.'
				print '***********************************************************'
			return False

		if self.pid == 0: # child process
			url = url.strip()
			roxia_trace('>>> url:', url)

			try:
				if url == '':
					os.execlp('/usr/local/bin/fresco', 'fresco')
				else:
					os.execlp('/usr/local/bin/fresco', 'fresco', '--url', url)
			except:
				os.system('web_stop')
				os._exit(1)


		else: # parent, check web
			time.sleep(1)
			if self.is_running() == True:
				if config.elbrowser_debug:
					print '***********************************************************'
					print 'browser exec success. :-)'
					print '***********************************************************'
				return True
			else:
				if config.elbrowser_debug:
					print '***********************************************************'
					print 'browser exec failed. :-('
					print '***********************************************************'
				keysender.delete_msgqueue()
				return False


	def kill_web(self):
		if self.pid:
			try:
				os.kill(self.pid, signal.SIGTERM)
				runtime.browserapp = None
				os.waitpid(self.pid, 0)
			except:
				pass

			killall('fresco', signal.SIGTERM)

			def hdl_sigchld(signum, frame):  # clean a zombie
				try:
				    	while 1:
    						print 'os wait pid 2'
					        if os.waitpid(0, os.WNOHANG): raise OSError
					        if config.elbrowser_debug:
						        print 'Some child is dying.. T_T byebye~'
				except OSError:
				   	pass

			signal.signal(signal.SIGCHLD, hdl_sigchld)


	def destroy(self):
		roxia_trace('********** BrowserApp.destroy(), pid=', self.pid)

		try_kill = 0
		success_kill = False

		while try_kill < 3:
			try_kill += 1

			self.kill_web()

			if self.is_running() == False: # killed
				success_kill = True
				break

		if success_kill == False:
			if config.elbrowser_debug:
				print '********* web destroy failed. **********'

		keysender.delete_msgqueue()
		active_web(False)
		os.system('web_stop')
		import status
		status.supervision_not_allowed = 0

		print '===================== load EPT==================='
		os.system('insmod /lib/modules/BROADCOM/ept.ko isVideoSupported=1')		
		runtime.dspg.hal_open()

		dspg = runtime.dspg
		dspg.default_set_volume()

		runtime.vdci_send_mesg(code1=config.MESG_SET_PARAMS, code2='t', mesg1=1)	
		time.sleep(2)
		
	def is_running(self):
		import status
		status.supervision_not_allowed = 1

		for pid in os.listdir('/proc'):
			cmdline_path = '/proc/%s/cmdline' % pid
			if os.path.exists(cmdline_path):
				try:
					pid = int(pid)
				except ValueError:
					continue

				if open(cmdline_path).read().startswith('fresco'):
					return True
		return False

	# use is_running() instead of is_alive()
	def is_alive(self):
		import status
		status.supervision_not_allowed = 1

		run_proc = 0

		try:
			p = os.popen('ps -ae|grep fresco')
			t=p.read()
			p.close()

			t = t.replace(' ','')
			t = t.replace('\n','')
			run_proc = t.count('fresco')
		except:
			if config.elbrowser_debug:
				print '*************** [E] is_alive ERROR *************'

		if config.elbrowser_debug:
			print 'is_alive(), run_proc count:', run_proc
		if run_proc >= 3:
			return True
		else:
			return False

	def send_mesg(self, mesg_type, mesg = None):
		if mesg != None:
			if type(mesg).__name__  == 'int':
				message = '%s|%d|'%(mesg_type, mesg)
			elif type(mesg).__name__  == 'str':
				message = '%s|%s|'%(mesg_type, mesg)
			message = '%d|%s'%(len(message),message)
		else:
			message = '3|' + mesg_type + '||'

		keysender.key_send(message)

	def getPhoneKeyValue(self, key_name):
		if key_name == config.Menu1:
			return 63
		elif key_name == config.Menu2:
			return 64
		elif key_name == config.Green:
			return 65
		elif key_name == config.Red:	# END
			return 66
		elif key_name == config.Video:
			return 67

		elif key_name == config.OnHook:
			pass
		elif key_name == config.OffHook:
			pass
		elif key_name == config.VideoPrivacy:
			pass
		elif key_name == config.Snapshot:
			pass
		elif key_name == config.VideoSize:
			pass

		elif key_name == '*':	# _ASTERISK
			return 55
		elif key_name == '#':	# _SHARP
			return 74
		elif key_name == '0':	#NUM0
			return 82
		elif key_name == '1':	#NUM1
			return 79
		elif key_name == '2':	#NUM2
			return 80
		elif key_name == '3':	#NUM3
			return 81
		elif key_name == '4':	#NUM4
			return 75
		elif key_name == '5':	#NUM5
			return 76
		elif key_name == '6':	#NUM6
			return 77
		elif key_name == '7':	#NUM7
			return 71
		elif key_name == '8':	#NUM8
			return 72
		elif key_name == '9':	#NUM9
			return 73
		elif key_name == 'Up':	# _UP
			return 103
		elif key_name == 'Down':
			return 108
		elif key_name == 'Left':
			return 105
		elif key_name == 'Right':
			return 106
		elif key_name == config.key_favorite:
			return 59
		elif key_name == config.key_soft3:
			return 61
		elif key_name == config.key_soft4:
			return 62
		else:
			if config.elbrowser_debug:
				print '*********** [E] Unknown key:', key_name

	def send_act_Exit(self):
		if config.elbrowser_debug:
			print '******** [FATAL] Don''t use EXIT message!*********'

	def send_act_writeURL(self):
		roxia_trace('--->> Write URL')
		self.send_mesg(config.BRW_ACT_WRITE)

	def send_msg_keys(self, key):
		tmp_key = self.getPhoneKeyValue(key)
		roxia_trace('--->> Send Key:', key)
		self.send_mesg(config.BRW_MSG_KEYS, tmp_key)

	def send_act_previous(self):
		roxia_trace('--->> PREVIOUS')
		self.send_mesg(config.BRW_ACT_PREV)

	def send_act_forward(self):
		roxia_trace('--->> FORWARD')
		self.send_mesg(config.BRW_ACT_FWD )

	def send_act_URLsend(self,url):
		#url이 없을 경우 start page로 이동한다
		if url == '':
			url = 'about:/start.htm'
		roxia_trace('--->> Send URL:', url)

		try:
			fp = open('/tmp/temp.url', 'w')
			fp.write(url)
			fp.close()
		except:
			if config.elbrowser_debug:
				print '*** url write failed. (/tmp/temp.url) ***'

		self.send_mesg(config.BRW_MSG_URL)

class WriteURLEditStage(EntryStage):
	name = 'writeurledit'

	def __init__(self):
		import status
		status.supervision_not_allowed = 1

		EntryStage.__init__(self, _('URL'), _('Write URL'))
		self.ui.set_automata('multitap', 'lower')
		self.mode = 0
		self.ui.set_max(100)

	def activate_menu1(self):
		url = self.ui.get_text()
		runtime.manager.back_stage('webloading')
		runtime.evas.render_now()

		if runtime.browserapp:
			## send URL
			runtime.browserapp.send_act_URLsend(url)

			time.sleep(2)
			if runtime.browserapp.is_running() == False:
				success_run = runtime.browserapp.run_web(self.web[index])
				if success_run == True:
					if config.elbrowser_debug:
						print '****************************'
						print 're-run OK'
						print '****************************'
				if success_run == False:
					if config.elbrowser_debug:
						print '****************************'
						print 're-run failed.'
						print '****************************'
					return True

			active_web()

	def handle_key(self, key):
		roxia_trace('>>>>> WriteURLEditStage.handle_key(), key=',key)
		if key == '#':
			if self.mode == 0:
				self.ui.set_automata('123', False)
				self.mode = 1
			else:
				self.ui.set_automata('multitap', 'lower')
				self.mode = 0
			return True

		return EntryStage.handle_key(self, key)

class WebBrowserStage(ListStage):
	name = 'favorites'

	def __init__(self):
		import status
		self.title = _('WEB BROWSER')

		status.supervision_not_allowed = 1

		self.web = []
		self.old_edit_index = 0
		self.web, self.favorite_name = self.get_favorite_name()
		ListStage.__init__(self, self.favorite_name, self.title, uiconfig.TdE_web_icon, None, _('OK'), _('EDIT'), True)

# eicho add 06.11.10 according to LVP-2850.
	def destroy(self):
		import status
		status.supervision_not_allowed = 0
		ListStage.destroy(self)
# eicho end.

	def get_favorite_name(self):
		fa_setting = setting.favorites
		web_name = []
		fa_name = []

		for i, f in enumerate(fa_setting):
			if f == '':
				index_name = '%d' % (i + 1)
				fa_name.append(_('Favorite') + index_name)
			else:
				fa_name.append(f)
			web_name.append(f)

		return web_name, fa_name

	def show(self):
		self.web, self.favorite_name = self.get_favorite_name()
		ListStage.change_choice(self, self.favorite_name)
		ListStage.show(self)
		self.ui.set_focus(self.old_edit_index)

	def activate(self, index):
		roxia_trace('WebBrowserStage.activate()')

		runtime.manager.stack_stage(WebLoadingStage)
		runtime.evas.render_now()

		# create instance
		if not runtime.browserapp:
			runtime.browserapp = BrowserApp()

		# check running
		alive = runtime.browserapp.is_running()

		if alive == True:
			roxia_trace('******* WEB already running... *******')
			runtime.browserapp.send_act_URLsend(self.web[index])
		else:
			try_count = 0
			success_run = False

			while try_count < 5: # retry 5 times
				try_count += 1
				success_run = runtime.browserapp.run_web(self.web[index]) # with URL
				if success_run == True:
					break
				else:
					if config.elbrowser_debug:
						print '************************************************'
						print 'browser exec failed. retry', try_count
						print '************************************************'

			# 더이상 실행할 수 없음
			if success_run == False:
				stage = NotifyStage(_('Web browser not available'), uiconfig.baloon_web_icon, None, 3000)
				runtime.manager.change_stage(stage)
				return True

		# web page가 loading되기를 기다림
		time.sleep(2)

		if runtime.browserapp.is_running() == False:
			success_run = runtime.browserapp.run_web(self.web[index])
			if success_run == True:
				if config.elbrowser_debug:
					print '****************************'
					print 're-run OK'
					print '****************************'
			if success_run == False:
				if config.elbrowser_debug:
					print '****************************'
					print 're-run failed.'
					print '****************************'
				return True

		active_web()

		return True

	def activate2(self, index):
		roxia_trace('WebBrowserStage.activate2()')
		self.old_edit_index = index
		runtime.manager.stack_stage(FavoriteEditStage('', self.web[index], index))

	def handle_key(self, key):
		if key == config.Red: # END key
			if runtime.browserapp:
				roxia_trace('** press END key. destroy WEB **')
				runtime.browserapp.destroy()
				runtime.browserapp = None

			runtime.manager.back_stage()
			runtime.evas.render_now()

			active_web(False)
			return True
		else:
			return ListStage.handle_key(self, key)

class FavoriteEditStage(EntryStage):
	def __init__(self, name, web, index):
		import status
		status.supervision_not_allowed = 1

		EntryStage.__init__(self, name, _('FAVORITES'))
		self.ca = 1 # 0:123, 1:abc, 2:Abc, 3:ABC (default:abc)
		self.ui.set_fixed_automata('multitap', 'lower')
		# KA: [20070831] hangul lvp-2000
		self.automata_idx = 3
		self.ui.set_max(100)
		self.index = index
		self.name = name
		if web != '':
			self.ui.set_text(web)

	def activate_menu1(self):
		str_domain = self.ui.get_text()
		setting.set_favorite(str_domain, self.index)
		runtime.manager.back_stage()

	def insert_symbol(self, s):
		before_text = self.ui.get_text()
		self.ui.insert_text(s)
		after_text = self.ui.get_text()
		if before_text == after_text:
			runtime.manager.change_stage(NotifyStage(_('Max length exceeded'), uiconfig.baloon_message_icon))
		else:
			runtime.manager.back_stage()

	def handle_key(self, key):
		# KA: [20070831] hangul lvp-2000
		# vpark 2007.08.28 automata
		if key =='SOFT4':
			self.automata_idx = (self.automata_idx + 1) % len(config.automata_list)	
			self.ui.automata = config.automata_list[self.automata_idx]					
			self.ui.set_automata(*self.ui.automata)		
			return True	
		elif key == '*' or key == '#':
			return True
		'''	
		if key == '#':
			# 0:123, 1:abc, 2:Abc, 3:ABC (default:abc)
			self.ca = (self.ca + 1) % 4

			if self.ca == 0: # 0:abc, 1:123, 2:Abc, 3:ABC
				self.ui.set_automata('123',False)
			elif self.ca == 1:
				self.ui.set_automata('multitap', 'lower')
			elif self.ca == 2:
				self.ui.set_automata('multitap', 'first capital')
			elif self.ca == 3:
				self.ui.set_automata('multitap', 'upper')
		elif key == '*':
			if self.ca == 0: # 123mode에서 *은 "."으로...
				self.ui.set_text(self.ui.get_text() + '.')
			else:
				self.ui.reset_automata()
				runtime.manager.stack_stage(SymbolSelectionStage(self, True))
				return True
		else:
			return EntryStage.handle_key(self, key)
		'''
		return EntryStage.handle_key(self, key)
		# KA: [20070831] hangul lvp-2000 ==
		
focus_web = False

def active_web(active = True):
	global focus_web
	focus_web = active

	if active:
		os.system('fb0top 0')
	else:
		os.system('fb0top 1')

def is_active_web():
	global focus_web

	if focus_web:
		return True
	else:
		return False


class WebLoadingStage(Stage):
	name = 'webloading'

	def __init__(self):
		import status
		status.supervision_not_allowed = 1
		self.ui = WebLoadingUI()

	def handle_key(self, key):
		roxia_trace('>>>>> WebLoadingStage.handle_key(), key=',key)

		# process END key
		if key == config.Red:
			if runtime.browserapp:
				roxia_trace('** press END key. destroy WEB **')
				runtime.browserapp.destroy()
				runtime.browserapp = None

			runtime.manager.back_stage()
			runtime.evas.render_now()

			active_web(False)
			return True

		# process Green, Video, HangOff
		elif key == config.Green or key == config.Video or key == config.OffHook:
			if runtime.browserapp:
				runtime.browserapp.destroy()
				runtime.browserapp = None

			runtime.manager.back_stage('idle')
			runtime.evas.render_now()

			active_web(False)
			return

		elif key == config.key_favorite:
			runtime.manager.back_stage('favorites')
			runtime.evas.render_now()
			active_web(False)
			return

		if not runtime.browserapp:
			roxia_trace('******* [E] browserapp instance NONE. *******')
			return

		if runtime.browserapp.is_running() == False:
			# What shall I do? exec web browser?
			roxia_trace('******* [E] WEB NOT running. *******')
			return

		# command ui
		if key == config.key_soft4:
			runtime.manager.stack_stage(WebBrowserSelectStage)
			runtime.evas.render_now()
			active_web(False)
			return

		################ current Activate WEB #################
		if is_active_web() == True:
			roxia_trace('** status: WEB activate **')

			if key == config.Menu1:
				runtime.browserapp.send_msg_keys(config.key_soft3)

			elif key == config.key_soft4:
				runtime.manager.stack_stage(WebBrowserSelectStage)
				runtime.evas.render_now()
				active_web(False)

			else:
				runtime.browserapp.send_msg_keys(key)

			return


class WebBrowserSelectStage(ListStage):
	name = 'webbrowserselect'

	def __init__(self):
		import status
		self.title = _('WEB BROWSER')
		self.choice = _('Back page'), _('Write URL'), _('Fwd page'), _('Exit')

		status.supervision_not_allowed = 1
		ListStage.__init__(self, self.choice, self.title, uiconfig.TdE_web_icon)

	def activate(self, index):
		if runtime.browserapp:
			if index == 0 :#previous
				runtime.browserapp.send_act_previous()

			elif index == 1:#write url
				runtime.manager.stack_stage(WriteURLEditStage)
				return

			elif index == 2:#forward
				runtime.browserapp.send_act_forward()

			elif index == 3:#exit
				if runtime.browserapp:
					runtime.browserapp.destroy()
					runtime.browserapp = None

				active_web(False)
				runtime.manager.back_stage('favorites')

				return True

			active_web()

		runtime.manager.back_stage()

	def handle_key(self, key):
		if key in (config.Menu2, config.key_soft4, config.Red):
			runtime.manager.back_stage()
			active_web()
			if key == config.Red:
				return True

		elif key == config.key_soft3: # emulate softkey[OK].
			return self.activate(self.ui.get_focus())

		else:
			return ListStage.handle_key(self, key)


class CallForwardingStage(ListStage):

	def __init__(self):
		self.title = _('WEB BROWSER')
		self.choice = (_('Condition'), _('Address to forward'), _('No answer time'))

		ListStage.__init__(self, choice=self.choice, title=self.title)
	def activate(self, index):
		pass

class WebNotAvailableNotifyStage(NotifyStage):
	def __init__(self):
		icon = uiconfig.baloon_web_icon
		message = _('Web browser not available in PSTN profile')
		NotifyStage.__init__(self, message, icon, None, 3000)