123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768 |
- # -*- coding:utf-8 -*-
- import time,sys,os
- from UAT_tree import UATTree
- from UAT_log import error,info,debug
- from UAT_PathManage import UATPathManage
- from UIParamUtil import UIParamUtil
- # from UAT_runnerCommand import UATRunnerCommand
- from ssat_sdk.python_uiautomator import PyUIAutomator,DirectionManageAndroid,FocusManageAndroid
- import math
- import traceback
- import copy
- ERROR = True
- INFO = True
- DEBUG = True # 上传SVN版本此参数关闭
- '''
- 采用uiautomator技术,处理界面定位问题,用于移动焦点到目标组件上
- '''
- class FocusCommand():
- cls = "FocusCommand"
- UIObjParam = UIParamUtil.UIObjParam
- UATParamMap = UIParamUtil.UATParamMap
- def __init__(self, runnerCommand):
- self.runnerCommand = runnerCommand
- self.pyU = PyUIAutomator()
- self.dm = DirectionManageAndroid()
- self.fm = FocusManageAndroid(self.pyU, self.dm)
- self.inLayout= False
- '''
- 解析option的焦点组件参数,返回focusView或者focus-select组件参数
- :param option: option字典
- :return 返回 focus焦点参数字典,采用setObjParam可以转换成UIObject识别需要的参数。
- 如果为None,则表示不需要焦点选中。
- '''
- def getFPFromOption(self, option):
- focusParam = None
- fsParam = option[UATTree.TAB_FOCUS_SELECT]
- fvParam = option[UATTree.TAB_FOCUSE_VIEW]
- if fsParam[UATTree.FS_Type].__len__() > 1:
- if fsParam[UATTree.FS_Type].lower() == "focus":
- fsParam["focus"] = True
- focusParam = fsParam
- elif fsParam[UATTree.FS_Type].lower() == "select":
- fsParam["select"] = True
- focusParam = fsParam
- elif fsParam[UATTree.FS_Type].lower() == "no":
- focusParam = None
- else:
- error(self.cls, "getFPFromOption", "Option %s focus-select参数异常。" % option[UATTree.TAB_NAME], ERROR)
- else:
- focusParam = fvParam
- return focusParam
- '''
- 解析option的焦点组件参数,返回focusView或者focus-select组件参数.
- 在getFPFromOption返回值上,采用setObjParam转换成UIObject识别需要的参数。
- :param option: option字典
- :return 返回 focus焦点UIObject参数字典.
- '''
- def getFPObjParam(self, option):
- focusParam = self.getFPFromOption(option)
- fpObjParam = UIParamUtil.setObjParam(focusParam)
- return fpObjParam
- '''
- 解析存储在UATree里的moveKey字典,得到按键类型、键值数组、最大尝试次数
- :param moveKey, parent字典中moveKey字典
- :param optionCount: moveKey对应的parent的option个数
- :return keyType, keyCodeList, Max_Trye
- '''
- def parseMoveKey(self,moveKey, optionCount):
- if moveKey[UATTree.Max_Try] != "":
- Max_Try = int(moveKey[UATTree.Max_Try])
- else:
- Max_Try = optionCount
- findDirection = ["down","up"]
- keyType = UATTree.Key_Event
- if moveKey[UATTree.Key_Event].__len__() > 1:
- findDirection = moveKey[UATTree.Key_Event]
- keyType = UATTree.Key_Event
- elif moveKey[UATTree.Key_IR].__len__() > 1:
- findDirection = moveKey[UATTree.Key_IR]
- keyType = UATTree.Key_IR
- elif moveKey[UATTree.Key_Input].__len__() > 1:
- inputCmd = moveKey[UATTree.Key_Input]
- #TODO input情况的处理
- return None,None,None
- else:
- return None,None,None
- return keyType, findDirection, Max_Try
- '''
- 在parent界面,将焦点移动到目标option上。
- 焦点定位:根据layout是不是限制焦点范围,进行焦点组件寻找,焦点组件类型:focus、select、focusView、long-click
- 目标定位:纯粹是根据optionView配置组建坐标定位
- :param parent:当前电视界面的parent字典
- :param option:目标option字典
- :return True/False
- '''
- def focusOptionView(self, parent, option,chooseType):
- #是否采用layout限制焦点判断范围
- layout = parent[UATTree.TAB_LAYOUT]
- print "focusOptionView,layout:",layout
- self.inLayout = layout[UATTree.Layout_Limit]
- # 找到目标optionView参数
- layoutUIObj = {}
- optionUIObjParam = UIParamUtil.setObjParam(option[UATTree.TAB_OPTION_VIEW])
- if self.inLayout == 1:
- layoutUIObjParam = UIParamUtil.setObjParam(layout)
- else:
- layoutUIObjParam = {}
- # 获取move key按键
- moveKey = parent[UATTree.TAB_MOVE_KEY]
- keyType, findDirection,Max_Try = self.parseMoveKey(moveKey, parent[UATTree.TAB_OPTION].__len__())
- if keyType is None:
- error(self.cls, "focusTargetOption", option[UATTree.TAB_NAME] + " option 读取 move_key失败", ERROR)
- return False
- #获取optionview的View_sambounds参数
- osamBounds = option[UATTree.TAB_OPTION_VIEW][UATTree.View_sambounds]
- #获取焦点view参数
- focusParam = self.getFPFromOption(option)
- focusUIParam = UIParamUtil.setObjParam(focusParam)
- if focusParam is None:
- fsamBounds = []
- else:
- fsamBounds = focusParam[UATTree.View_sambounds]
- if chooseType.lower()== 'no':
- return self.getNoFocusedObj(option, Max_Try, findDirection, keyType, layoutUIObjParam)
- else:
- return self.toDestObj(parent, option, Max_Try, findDirection, keyType, layoutUIObjParam,fsamBounds,osamBounds)
- '''
- 传入uiautomator需要的目标组件参数,获取无聚焦属性的option对象
- '''
- def getNoFocusedObj(self,option, Max_Try, findDirection, keyType, layoutUIObjParam):
- count = 0
- directIndex = 0
- while(True):
- if count >= Max_Try and directIndex >= findDirection.__len__()-1:
- break
- time.sleep(0.1)
- destUIObject = self.getOptionUIObj(option, layoutUIObjParam)
- if destUIObject and destUIObject.exists():
- info(self.cls,"getNoFocusedObj","找到目标option %s"%option[UATTree.TAB_NAME],INFO)
- return True
- else:
- if count < Max_Try:
- count = count + 1
- elif count >= Max_Try and directIndex<findDirection.__len__() -1:
- count=0
- Max_Try *= 2
- directIndex = directIndex + 1
- self.fm.pressKeyByType(findDirection[directIndex], keyType)
- error(self.cls, "getNoFocusedObj", "执行%s 次查找,仍未找到目标焦点!!" % (str(Max_Try)), ERROR)
- return False
- '''
- 传入uiautomator需要的目标组件参数和焦点框参数,用于寻找目标。
- '''
- def toDestObj(self, parent, option, Max_Try=10, findDirections=["down","up"], keyType=UATTree.Key_Event,
- layoutUIParam={}, fsamBounds=[],osamBounds=[]):
- # 按照传入的方向寻找Max_Try次,如果仍未聚焦到选中area,则按照传入方向的反方向 反向寻找 2*Max_Try 次
- print "toDestObj,enter:",Max_Try,findDirections,keyType,fsamBounds,osamBounds
- count = 0
- Max_Try = Max_Try
- directIndex = 0
- focusCount = 0 # 当目标和聚焦点在一个页面同时存在时,从当前聚焦点到目标的移动次数
- focusedBoundsPre = {u'top': 0, u'left': 0, u'right': 0, u'bottom': 0} # 上一轮聚焦点的坐标
- destBoundsPre = {u'top': 0, u'left': 0, u'right': 0, u'bottom': 0} # 上一轮目标的坐标
- hb_keyDict = parent[UATTree.TAB_OTHERS][UATTree.Key_HeartBeat]
- # print "##########", hb_keyDict
- # print "##########", parent[UATTree.TAB_OTHERS]
- if hb_keyDict != {}:
- # 执行心跳按键
- info(self.cls, "toDestObj", "executeHeartBeatKey:%s"%hb_keyDict, INFO)
- self.fm.executeHeartBeatKey(hb_keyDict)
- while (True):
- if count >= Max_Try and directIndex >= findDirections.__len__()-1:
- break
- # 等待聚焦效果刷新完成,稳定之后再获取相关的属性
- time.sleep(0.1)
- destUIObject = self.getOptionUIObj(option,layoutUIParam)
- focusParam = self.getFPFromOption(option)
- #option是否需要聚焦
- needFocus = True
- if focusParam.has_key(UATTree.FS_Type) and \
- focusParam[UATTree.FS_Type] == "no":
- needFocus = False
- if destUIObject and destUIObject.exists(): # 有聚焦属性的option存在不代表已聚焦,无聚焦属性的option存在即当作已聚焦
- try:
- retCode, focusedUIObject = self.getChooseUIObjP(parent, layoutUIParam,needFocus=needFocus)
- debug(self.cls, "toDestObj", "Parent %s 当前聚焦框retCode:%d" % (parent[UATTree.TAB_NAME],retCode), DEBUG)
- #如果焦点不存在,只需要判断optionView存在即可算是聚焦成功
- if retCode == self.Focus_Need_Not:
- return True
- #根据已获取到destUIObject和focusedUIObject,进行是否选中目标option判断,
- #未选中,则继续利用moveKey查找
- focusedBounds = focusedUIObject.info['bounds']
- info(self.cls,"toDestObj","当前聚焦框所在坐标:%s"%focusedBounds,INFO)
- destBounds = destUIObject.info['bounds']
- info(self.cls, "toDestObj", "已寻找%s次" % focusCount, INFO)
- info(self.cls,"toDestObj","目标Option %s坐标:%s"%(option[UATTree.TAB_NAME], destBounds),INFO)
- if self.hasFocusDest(focusedBounds, destBounds, fsamBounds=fsamBounds, osamBounds=osamBounds):
- info(self.cls,"toDestObj","成功聚焦到目标焦点:%s"%option[UATTree.TAB_NAME],INFO)
- return True
- # 如果往同一个方向跑了5次,聚焦坐标和目标坐标的位置都没变化,则说明目标可能为非聚焦,跑不动了
- if focusCount<5:
- direction = self.dm.getTargetDirection(focusedBounds, destBounds, findDirections)
- self.dm.goOneStep(self.pyU, direction, keyType)
- isSameFocused = self.dm.isSameBounds(focusedBoundsPre,focusedBounds) # 前一次聚焦点与当前聚焦点坐标对比
- isSameDest = self.dm.isSameBounds(destBoundsPre,destBounds)
- info(self.cls,"toDestObj","focusedBoundsPre:%s"%focusedBoundsPre,INFO)
- info(self.cls, "toDestObj", "focusedBounds:%s" % focusedBounds, INFO)
- if isSameFocused == True and isSameDest == True:
- focusCount += 1
- focusedBoundsPre = focusedBounds
- destBoundsPre = destBounds
- info(self.cls,"toDestObj.focusCount","focusCount:%s"%focusCount,INFO)
- continue
- if focusCount == 0:
- focusCount += 1 # 如果focusCount=0,则将当前聚焦点和目标坐标赋值给前一次
- focusedBoundsPre = focusedBounds
- destBoundsPre = destBounds
- info(self.cls,"toDestObj.focusCount.countStart", "focusCount:%s"%focusCount,INFO)
- continue
- else:
- error(self.cls, "toDestObj", "未找到目标焦点!!!", ERROR)
- return False
- except Exception,e:
- info(self.cls,"toDestObj","未获取到目标/焦点对象坐标:count:%d,Max_Try:%d,directIndex:%d"%(count,Max_Try,directIndex),INFO)
- traceback.print_exc()
- # 出现控件出现一半的时候,获取控件信息会报错
- if count < Max_Try:
- count = count + 1
- elif count >= Max_Try and directIndex < findDirections.__len__() -1:
- count=0
- Max_Try *= 2
- directIndex = directIndex + 1
- self.fm.pressKeyByType(findDirections[directIndex], keyType)
- # 如果界面中没有目标文字的控件出现,则按照传入的方向寻找Max_Try次;仍然未找到 则反方向寻找2*Max_Try次
- else:
- if count < Max_Try:
- count = count + 1
- elif count >= Max_Try and directIndex<findDirections.__len__() -1:
- count=0
- Max_Try *= 2
- directIndex = directIndex + 1
- self.fm.pressKeyByType(findDirections[directIndex], keyType)
- error(self.cls, "toDestObj", "执行%s 次查找,仍未找到目标焦点!!" % (str(Max_Try)), ERROR)
- return False
- '''
- 根据配置的样本焦点框和OptionView 区域坐标,计算是否聚焦
- :param focusedBounds 当前电视焦点框坐标
- :param destBounds 当前电视目标坐标
- :param fsamBounds 取样时的焦点框坐标
- :param osamBounds 取样时的目标坐标
- :return True/False True:焦点在目标上;False:焦点不在目标上
- '''
- def hasFocusDest(self,focusedBounds, destBounds, fsamBounds=[],osamBounds=[]):
- # print "hasFocusDest,focusedBounds,destBounds,fsamBounds,osamBounds:",focusedBounds, destBounds,fsamBounds,osamBounds
- if fsamBounds.__len__() < 1 or osamBounds.__len__()<1:
- return self.dm.isHasAnotherBounds(focusedBounds, destBounds)
- else:#在焦点框bounds特别大时,同时包含多个目标optionView时,用此方法判断是否选中。
- focusBounds = UIParamUtil.atxBounds2UATBounds(focusedBounds)
- destBounds = UIParamUtil.atxBounds2UATBounds(destBounds)
- print "fsamBounds,osamBounds"
- sdrate = self.calPointAngle(fsamBounds[0], osamBounds[0])
- sdLine = self.calPointLine(fsamBounds[0], osamBounds[0])
- print "focusBounds,destBounds"
- drate = self.calPointAngle(focusBounds[0],destBounds[0])
- dLine = self.calPointLine(focusBounds[0],destBounds[0])
- if abs(drate - sdrate) < 5 and abs(dLine - sdLine) < 30:
- return True
- else:
- return False
- '''
- 计算点p2相对点p1的角度
- '''
- def calPointAngle(self, p1, p2):
- angle = 0.0
- print "calPointAngle,p1,p2:", p1,p2
- dx = float(p2[0])-float(p1[0])
- dy = float(p2[1])-float(p1[1])
- print "calPointAngle,dx,dy:",dx,dy
- if dx == 0 and dy >= 0:
- return 90
- elif dx == 0 and dy < 0:
- return 180
- radian = math.atan(dy/dx) #计算出弧度值
- angle = 180 * radian/math.pi
- print "calPointAngle,angle,radian:",angle,radian
- return angle
- def calPointLine(self, p1,p2):
- print "calPointLine,p1,p2:", p1,p2
- dx = float(p2[0])-float(p1[0])
- dy = float(p2[1])-float(p1[1])
- line = round(math.sqrt(dx*dx + dy*dy),1)
- print "calPointLine,line:", line
- return line
- '''
- 检测option组件,在电视上是否被选中了
- :param option 数据字典
- :param layoutUIParam, parent的layout组件定位字典
- :param focusUIObj, 焦点组件
- :return -1:未进入option的页面,找不到option UIObject;0:进入了option的页面,未选中option;1 已经选中option
- -2:代表未找到焦点
- '''
- def checkOptionChoose(self, option, layoutUIParam, focusUIObj):
- optionUIObj = self.getOptionUIObj(option, layoutUIParam)
- if optionUIObj is None or optionUIObj.exists() is False:
- return -1
- if focusUIObj is None or focusUIObj.exists() is False:
- return -2
- focusParam = self.getFPFromOption(option)
- if focusParam is None:
- return 1
- try:
- focusedBounds = focusUIObj.info()["bounds"]
- destBounds = optionUIObj.info()['bounds']
- except Exception,e:
- return 0
- fsamBounds = focusParam[UATTree.View_sambounds]
- osamBounds = option[UATTree.TAB_OPTION_VIEW][UATTree.View_sambounds]
- if self.hasFocusDest(focusedBounds, destBounds,fsamBounds, osamBounds):
- return 1
- else:
- return 0
- def checkOptionExist(self, option, parent):
- # print "checkOptionExist,option:",option
- moveKey = parent[UATTree.TAB_MOVE_KEY]
- hb_keyDict = parent[UATTree.TAB_OTHERS][UATTree.Key_HeartBeat]
- if hb_keyDict != {}:
- # 执行心跳按键
- info(self.cls, "checkOptionExist", "executeHeartBeatKey:%s"%hb_keyDict, INFO)
- self.fm.executeHeartBeatKey(hb_keyDict)
- optionName = option['name']
- print "checkOptionExist,moveKey:", moveKey
- Max_Try = moveKey[UATTree.Max_Try]
- if Max_Try == "":
- Max_Try = 1
- else:
- Max_Try = int(Max_Try)
- Reverse_Max_Try = Max_Try * 2
- print "Max_Try:", Max_Try
- count = 0
- Reversecount = 0
- lastObj = ""
- opUIParam = UIParamUtil.setObjParam(option["optionView"])
- # 为了兼容多文本,逐个遍历文本,针对text属性做特殊处理
- if "text" in opUIParam and type(opUIParam['text']) == type([]):
- for text in opUIParam['text']:
- uiParam = copy.deepcopy(opUIParam)
- uiParam['text'] = text
- while (True):
- if count >= Max_Try and Reversecount >= Reverse_Max_Try:
- break
- # 如果找到目标直接返回
- debug(self.cls,"checkOptionExist","optionView:%s"%option,DEBUG)
- ###
- try:
- opOBJ = self.pyU.getUiObject2(uiParam)
- opOBJInfo = opOBJ.info
- debug(self.cls,"checkOptionExist","opOBJInfo: %s"%opOBJInfo,DEBUG)
- break
- except Exception,e:
- opOBJ = None
- if count < Max_Try:
- flag = 1
- count += 1
- print "now count:", count
- else:
- flag = 0
- Reversecount += 1
- print "now Reversecount:", Reversecount
- self.runnerCommand.executeMoveKey(moveKey, flag)
- # print "###",type(opOBJ),opOBJ
- if opOBJ is not None:
- if opOBJ.exists:
- info(self.cls, "checkOptionExist", "当前页面已找到option: %s" % optionName, INFO)
- return True
- else:
- while (True):
- if count >= Max_Try and Reversecount >= Reverse_Max_Try:
- break
- # 如果找到目标直接返回
- debug(self.cls, "checkOptionExist", "optionView:%s" % option, DEBUG)
- ###
- try:
- opOBJ = self.pyU.getUiObject2(opUIParam)
- opOBJInfo = opOBJ.info
- debug(self.cls, "checkOptionExist", "opOBJInfo: %s" % opOBJInfo, DEBUG)
- break
- except Exception, e:
- opOBJ = None
- if count < Max_Try:
- flag = 1
- count += 1
- print "now count:", count
- else:
- flag = 0
- Reversecount += 1
- print "now Reversecount:", Reversecount
- self.runnerCommand.executeMoveKey(moveKey, flag)
- # print "###", type(opOBJ), opOBJ
- if opOBJ is not None:
- if opOBJ.exists:
- info(self.cls, "checkOptionExist", "当前页面已找到option: %s" % optionName, INFO)
- return True
- info(self.cls, "checkOptionExist", "注意!!!当前页面未找到option: %s" % optionName, INFO)
- return False
- '''
- 根据option配置的焦点方式,返回当前页面焦点组件
- :param option: option字典
- :param layoutUIObj : option对应组件的根组件
- :return retCode,UIObject对象:reCode=0表示默认为不需要选中状态,retCode=1表示option默认为需要选中状态
- '''
- Focus_Need = 1
- Focus_Need_Not = 0
- def getChooseUIObj(self, option, layoutUIObj = None):
- debug(self.cls, "getChooseUIObj", "option name:"+option[UATTree.TAB_NAME],DEBUG)
- focusObjParam = self.getFPObjParam(option)
- debug(self.cls, "getChooseUIObj", "focusObjParam:"+str(focusObjParam)+"; layoutUIObj:"+str(layoutUIObj),DEBUG)
- if focusObjParam.__len__() <= 0:
- return self.Focus_Need_Not,None
- if layoutUIObj is None:
- return self.Focus_Need,self.pyU.getUiObject2(focusObjParam)
- else:
- return self.Focus_Need,layoutUIObj.child(**focusObjParam)
- '''
- 根据parent字典,检索parent是否有一个option被选中,任何一个备选中,返回option的UIObject
- :param parent: parent 字典
- :param needFocus: 目标option需要聚焦,则优先找焦点,再处理select type为no情况
- :return retCode,UIObject对象:reCode=0表示默认为不需要选中状态,retCode=1表示option默认为需要选中状态
- '''
- def getChooseUIObjP(self, parent, layoutUIParam, needFocus = True):
- if layoutUIParam.__len__() > 0:
- layoutUIObj = self.pyU.getUiObject2(layoutUIParam)
- else:
- layoutUIObj = None
- # 筛选焦点定位类型,减少重复判断
- focusOptionDict = self.reMuFocusOption(parent[UATTree.TAB_OPTION])
- debug(self.cls,"getChooseUIObjP","focusOptionDict:"+str(focusOptionDict.keys()),DEBUG)
- for optionName in focusOptionDict:
- option = focusOptionDict[optionName]
- retCode, uiObj = self.getChooseUIObj(option, layoutUIObj)
- if retCode == self.Focus_Need_Not and needFocus is False:
- return self.Focus_Need_Not, None
- elif retCode == self.Focus_Need and uiObj is not None and uiObj.exists():
- return retCode, uiObj
- return self.Focus_Need,None
- '''
- 根据parent字典,检索parent是否有一个option被选中,任何一个备选中,返回option的字典信息
- :param parent: parent 字典
- :param needFocus: 目标option需要聚焦,则优先找焦点,再处理select type为no情况
- :return retCode,UIObject对象:reCode=0表示默认为不需要选中状态,retCode=1表示option默认为需要选中状态
- '''
- def getChooseOptionP(self, parent, layoutUIParam, needFocus = True):
- if layoutUIParam.__len__() > 0:
- layoutUIObj = self.pyU.getUiObject2(layoutUIParam)
- else:
- layoutUIObj = None
- optionDict = parent[UATTree.TAB_OPTION]
- # 筛选焦点定位类型,减少重复判断
- focusOptionDict = self.reMuFocusOption(parent[UATTree.TAB_OPTION])
- debug(self.cls,"getChooseUIObjP","focusOptionDict:"+str(focusOptionDict.keys()),DEBUG)
- # 是否确认当前聚焦optionName的标识
- # 用任意一option,获取当前聚焦的uiobj
- optionName = focusOptionDict.keys()[0]
- option = focusOptionDict[optionName]
- retCode, choosedObj = self.getChooseUIObj(option, layoutUIObj)
- if retCode == self.Focus_Need_Not and needFocus is False:
- return self.Focus_Need_Not, None
- elif retCode == self.Focus_Need and choosedObj is not None and choosedObj.exists():
- for optionName in optionDict:
- option = optionDict[optionName]
- destUIParam = UIParamUtil.setObjParam(option[UATTree.TAB_OPTION_VIEW])
- destObj = self.pyU.getUiObject2(destUIParam)
- if destObj.exists():
- choosedBound = choosedObj.info['bounds']
- destBound = destObj.info['bounds']
- if self.dm.isHasAnotherBounds(choosedBound, destBound):
- return self.Focus_Need, option
- return self.Focus_Need,None
- def reMuFocusOption(self, optionDict):
- retDict = {}
- for optionName in optionDict:
- option = optionDict[optionName]
- focusObjParam = self.getFPObjParam(option)
- if retDict.__len__() == 0:
- retDict[optionName] = option
- continue
- isSame = False
- for retName in retDict:
- retOption = optionDict[retName]
- retFocusObjParam = self.getFPObjParam(retOption)
- if UIParamUtil.cmpObjParam(focusObjParam, retFocusObjParam):
- isSame = True
- break
- if isSame is False:
- retDict[optionName] = option
- return retDict
- '''
- 根据option和layoutUIParam参数,获取option UIObject对象
- layoutUIParam参数有效,则在layout里查找子组件option,否则全界面查找子组件。
- '''
- def getOptionUIObj(self, option, layoutUIParam):
- debug(self.cls, "getOptionUIObj","OptionView:"+str(option[UATTree.TAB_OPTION_VIEW]),DEBUG)
- destUIParam = UIParamUtil.setObjParam(option[UATTree.TAB_OPTION_VIEW])
- debug(self.cls, "getOptionUIObj", "destUIParam:" + str(destUIParam), DEBUG)
- destUITextExist = False
- destUIObject = None
- try:
- destUIText = destUIParam['text']
- destUITextExist = True
- except Exception, e:
- info(self.cls, "getOptionUIObj", "目标对象%s的optionView无text属性"%option[UATTree.TAB_NAME], INFO)
- if destUITextExist is True:
- #####################
- if type(destUIParam['text']) is type([]):
- destUIObjectExist = False
- tempTextList = destUIParam['text']
- txtCount = 0
- for txt in tempTextList:
- destUIParam['text'] = txt
- uix = self.pyU.dump_hierarchy()
- if txt not in uix:
- continue
- if layoutUIParam.__len__() > 0:
- layoutUIObj = self.pyU.getUiObject2(layoutUIParam)
- try:
- destUIObject = layoutUIObj.child(**destUIParam)
- destUIObjectInfo = destUIObject.info
- destUIObjectExist = True
- info(self.cls, "getOptionUIObj", "文本%s对应的option对象已找到" % txt, INFO)
- except Exception, e:
- nextText = tempTextList[txtCount + 1]
- error(self.cls, "getOptionUIObj", "文本%s对应的option对象未找到,匹配下一个文本%s" % (txt, nextText), ERROR)
- if destUIObjectExist is True:
- break
- else:
- try:
- destUIObject = self.pyU.getUiObject2(destUIParam)
- destUIObjectInfo = destUIObject.info
- destUIObjectExist = True
- info(self.cls, "getOptionUIObj", "文本%s对应的option对象已找到" % txt, INFO)
- except Exception, e:
- nextText = tempTextList[txtCount + 1]
- error(self.cls, "getOptionUIObj", "文本%s对应的option对象未找到,匹配下一个文本%s" % (txt, nextText), ERROR)
- if destUIObjectExist is True:
- break
- txtCount += 1
- else:
- if layoutUIParam.__len__() > 0:
- layoutUIObj = self.pyU.getUiObject2(layoutUIParam)
- destUIObject = layoutUIObj.child(**destUIParam)
- else:
- destUIObject = self.pyU.getUiObject2(destUIParam)
- #########################
- else:
- if layoutUIParam.__len__() > 0:
- layoutUIObj = self.pyU.getUiObject2(layoutUIParam)
- destUIObject = layoutUIObj.child(**destUIParam)
- else:
- destUIObject = self.pyU.getUiObject2(destUIParam)
- return destUIObject
- '''
- 检测parent,在电视上是否被选中了。一个option被选中,表示选中
- :param option 数据字典
- :return
- -3:代表UIView判断未通过;
- -2:代表选中了parent,但未找到焦点;
- -1:未进入parent的页面,找不到parent layout;
- 0:进入了parent的页面,未选中parent;
- 1:已经选中parent
- '''
- def checkParentChoose(self, parent):
- debug(self.cls, "checkParentChoose", "parent:" + parent[UATTree.TAB_NAME], DEBUG)
- chooseTypeDict = {}
- layoutParam = parent[UATTree.TAB_LAYOUT]
- layoutUIParam = UIParamUtil.setObjParam(layoutParam)
- layoutResId = layoutParam[UATTree.View_ID]
- uiView = parent[UATTree.TAB_UI_VIEW]
- uiViewResId = uiView[UATTree.View_ID]
- uiViewText = uiView[UATTree.View_Text]
- uiViewDesc = uiView[UATTree.View_Desc]
- # print "checkParentChoose,layoutUIParam:",layoutUIParam
- if layoutResId == "" and uiViewResId == "" and uiViewText == "" and uiViewDesc == "":
- debug(self.cls, "checkParentChoose",
- "Warning:Parent %s的Layout resId和UIView信息获取失败!!请注意检查UATree文件!!!" % parent[UATTree.TAB_NAME], DEBUG)
- return -1
- elif layoutUIParam.__len__() > 0:
- # 如果存在UIView信息,则先判断UIView
- isExist = self.checkUIViewExist(uiView)
- if isExist is False:
- info(self.cls, "checkParentChoose", "当前页面不存在Parent:%s的UIView组件,判断该界面非此parent" % parent[UATTree.TAB_NAME],
- INFO)
- return -3
- else:
- debug(self.cls, "checkParentChoose", "已识别出Parent:%s的UIView组件" % parent[UATTree.TAB_NAME], DEBUG)
- # debug(self.cls, "checkParentChoose", "UIView组件内容:%s" % uiView, DEBUG)
- # 判断Layout是否存在
- layoutUIObj = self.pyU.getUiObject2(layoutUIParam)
- if layoutUIObj is None or layoutUIObj.exists() is False:
- info(self.cls, "checkParentChoose", "parent %s layout 不存在 "%parent[UATTree.TAB_NAME], INFO)
- return -1
- debug(self.cls, "checkParentChoose", "parent %s layout 存在"%parent[UATTree.TAB_NAME], DEBUG)
- # 获取焦点组件,判断是否在layout中
- retCode, focusObj = self.getChooseUIObjP(parent, layoutUIParam, needFocus=False)
- if retCode == self.Focus_Need_Not:
- debug(self.cls, "checkParentChoose",
- "已找到目标parent %s,不需要选中。" % (parent['name']), DEBUG)
- elif focusObj is not None and focusObj.exists():
- debug(self.cls, "checkParentChoose",
- "已找到目标parent %s,焦点在Layout中。" % (parent['name']), DEBUG)
- else:
- info(self.cls, "checkParentChoose",
- "已找到目标parent %s,但是焦点不在Layout中。" % (parent['name']), INFO)
- return -2
- # 判断parent中存在一个option,则标识parent被选中。注意:为了快速消失界面相应
- if layoutParam[UATTree.Layout_Limit] <> 1:
- layoutUIParam = {}
- optionUIObj = None
- optionExist = False
- for optionName in parent["option"]:
- option = parent["option"][optionName]
- ret = self.checkOptionExist(option,parent)
- if ret is True:
- info(self.cls, "checkParentChoose",
- "已找到目标parent %s,识别出该parent下的option %s。" % (parent['name'], option['name']),
- INFO)
- return 1
- info(self.cls, "checkParentChoose",
- "已找到目标parent %s,但是parent下的option未被发现。" % (parent['name']), INFO)
- return 0
- else:
- isExist = self.checkUIViewExist(uiView)
- if not isExist:
- return -3
- else:
- info(self.cls, "checkParentChoose",
- "识别出parent %s的UIView参数,判断处于该界面中" % (parent['name']), INFO)
- return 1
- '''
- 检测某个弹窗是否存在。
- 弹窗相关的参数放在UIView中配置。
- 当存在resId参数时,使用resId获取对象并获取文本,再与text做比较;
- 当不存在resId参数时,使用text直接获取对象,判断对象是否存在。
- 与checkParentChoose判断不一致,做特殊处理。
- :return 整型:0代表不存在,1代表存在
- '''
- def checkDialogExist(self, dialog):
- debug(self.cls, "checkDialogExist", "dialog:" + dialog["name"], DEBUG)
- dialogText = dialog[UATTree.TAB_UI_VIEW][UATTree.View_Text]
- dialogResId = dialog[UATTree.TAB_UI_VIEW][UATTree.View_ID]
- # print "checkDialogExist.dialogText:", dialogText
- # print "checkDialogExist.dialogResId:", dialogResId
- if dialogResId != "":
- textObj = self.pyU.getUiObject(resourceId=dialogResId)
- if textObj.exists:
- objText = textObj.info['text']
- # print "checkDialogExist.objText:", objText
- if dialogText in objText:
- return 1
- else:
- return 0
- else:
- return 0
- else:
- textObj = self.pyU.getUiObject(text=dialogText)
- if textObj.exists:
- return 1
- else:
- return 0
- def checkUIViewExist(self, uiView):
- #uiview未配置默认为检测通过
- if uiView.__len__() == 0:
- return True
- uiviewObjParam = UIParamUtil.setObjParam(uiView)
- uiViewObj = self.pyU.getUiObject2(uiviewObjParam)
- if uiViewObj is None:
- return False
- elif uiViewObj.exists:
- return True
- else:
- return False
- def moveToCheckedRedioButton(self, fsParam, findDirection="down", keyType=UATTree.Key_Event, maxTry=20):
- count = 0
- Reversecount = 0
- tryCount = 0
- while(True):
- param={"checked":"true"}
- checkedObj = self.pyU.getUiObject2(param)
- if not checkedObj.exists():
- if count < maxTry:
- self.fm.pressKeyByType(findDirection[1], keyType)
- count += 1
- continue
- else:
- Reversecount = Reversecount + 1
- self.fm.pressKeyByType(self.fm.ReverseDirctionDict[findDirection], keyType)
- continue
- choosedObj = self.pyU.getUiObject2(fsParam)
- if not choosedObj.exists():
- count += 1
- continue
- choosedBounds = choosedObj.info['bounds']
- checkedBounds = checkedObj.info['bounds']
- if self.dm.isHasAnotherBounds(choosedBounds, checkedBounds):
- info(self.cls, "moveToCheckedRedioButton", "已聚焦至目标组件!!!", INFO)
- return True, choosedObj
- else:
- direction = self.dm.getTargetDirection(choosedBounds, checkedBounds)
- print "目标方位:",direction
- self.dm.goOneStep(self.pyU, direction, keyType)
- tryCount += 1
- if tryCount >= maxTry:
- error(self.cls, "moveToCheckedRedioButton", "已尝试至最大次数%s次,仍未能聚焦至目标组件!!!"%maxTry, error)
- return False, choosedObj
- if Reversecount >= maxTry:
- error(self.cls, "moveToCheckedRedioButton", "已尝试至最大次数%s次,仍未能找到目标组件!!!"%maxTry, error)
- return False, choosedObj
- if __name__ == "__main__":
- uatPathManage = UATPathManage()
- pyU = PyUIAutomator()
- dm = DirectionManageAndroid()
- fm = FocusManageAndroid(pyU, dm)
- # runnerCmd = UATRunnerCommand(uatPathManage, pyU, dm, fm)
- # focusCmd = FocusCommand(runnerCmd)
- # ret = focusCmd.calPointAngle([0,0],[244,151])
- # ret = focusCmd.calPointAngle([244,151],[107,641])
- # focusCmd.strToBounds('[801,116][1280,180]')
- # option = focusCmd.runnerCommand.uatPathManage.uatData.getOption("av_devices_settings")
- # parent = focusCmd.runnerCommand.uatPathManage.uatData.getParentByOption(option)
- # focusCmd.focusOptionView(parent, option)
- # print "dump_hierarchy 0:",time.time()
- # print focusCmd.pyU.dump_hierarchy()
- # print "dump_hierarchy 1:",time.time()
- # uiobjg = focusCmd.pyU.getUiObject()
|