# -*- coding:utf-8 -*-
import time

from ssat_sdk.ocr_convert import OCRConvert

from ssat_sdk.device_manage.capturecard_manager import CCardManager

from ssat_sdk.uiautomator2.ext import htmlreport
# from uiautomator2.ext import htmlreport

from ssat_sdk import uiautomator2 as u2, LoggingUtil, inspect, FeatureDetect, sat_environment, getSATTmpDIR, ImageCMP

from ssat_sdk.UATree.UAT_tree import UATTree
from ssat_sdk.tv_operator import TvOperator


# import uiautomator2 as u2

import os
import re

from ssat_sdk.utils import LoggingUtil
from ssat_sdk.utils.string_util import getDigitFromString
from ssat_sdk.sat_environment import getAdbDeviceSatatus

pyFileName = os.path.split(__file__)[-1]


def get_current_function_name():
    return inspect.stack()[1][3]


'''
预置条件:保证执行PC和测试电视adb连接
各个API说明的例子中到达self.pyUIAutomator 是PyUIAutomator类的实例
self.pyUIAutomator = PyUIAutomator()

'''


class PyUIAutomator():
    def __init__(self, serial=None):
        try:
            self.u = u2.connect_usb(serial) #得到UIAutomatorServer实例对象
            self.serial = serial
        except Exception,e:
            print e
        # hrp = htmlreport.HTMLReport(self.u, 'report')
        # try:
        #     hrp.patch_click()
        # except Exception, e:
        #     print e
        #     pass
        # self.u.app_stop_all()

    def reConnect_usb(self):
        self.u = u2.connect_usb(self.serial)
        # hrp = htmlreport.HTMLReport(self.u, 'report')
        # try:
        #     hrp.patch_click()
        # except Exception, e:
        #     print e
        #     pass
        # self.u.app_stop_all()
    '''
    废弃,改用sat_environment.getAdbDeviceSatatus()
    '''
    def checkAdbConnected(self):
        return u2.check_adb_connect()

    def listenAdbConnected(self):
        count = 5
        while getAdbDeviceSatatus() is False and count >0:
            count -= 1
            LoggingUtil.printLog("PyUIAutomator","listenAdbConnected,Count %d adb not connected!"%count)
            # self.reConnect_usb()
            time.sleep(1)

    def killAdb(self):
        return u2.killAdb()

    def getAdbType(self):
        return u2.check_adb_connect_type()

    '''
    作用:获取UIAutomator 连接对象  后续可以使用该对象使用原生方法
    '''

    def getPyUIAutomator(self):
        self.listenAdbConnected()
        return self.u

    '''
    作用:Android times次按键  key:常用按键的字符串
    主要的键值字段:home、back、left、right、up、down、center、menu、search、enter、delete ( or del)、
    recent (recent apps)、volume_up、volume_down、volume_mute、camera、power
    times :按键次数         默认为1次
    duration:按键时间间隔  默认为1.0s

    '''

    def pressKeyTimes(self, key, times=1, duration=1.0):
        self.listenAdbConnected()
        self.u.pressKeyTimes(key, times, duration)

    '''
    用uiautomator view属性键作为paramDIct的键,传入的paramDict里的参数,必须有效。
    参考session.Selector里的__fields字典
    '''
    def getUiObject2(self, paramDict):
        # print "getUiObject2,paramDict:",paramDict
        uiObject = None
        if paramDict.__len__>0:
            try:
                uiObject = self.u(**paramDict)
            except Exception,e:
                print "UIAutomator未启动,请确认是否为开机状态"
                uiObject = None
            # print uiObject,uiObject.info
        return uiObject

    '''
    作用:获取UiObject对象
    参数:
    className:控件类型(例如:android.widget.TextView)
    resourceId:控件的Id(例如:lh.oslauncher:id/tv_title)
    text:控件上的文件(例如:'主页')
    description:控件描述
    instance:实例参数

    注意:className、resourceId、text 、description、instance是利用
    UIautomatoview.bat工具查看控件属性看到的
   其中 className对应 UIautomatoview.bat中的 class
       resourceId对应 UIautomatoview.bat中的 resource-id
      description对应 UIautomatoview.bat中的 content-desc
         instance对应 UIautomatoview.bat中的 index


    例子:uiObject =self.pyUIAutomator.getUiObject(resourceId="com.google.android.tvlauncher:id/banner_image", description=u"Play 电影", className = 'android.widget.ImageView')


    '''

    def getUiObject(self, className='', resourceId='', text='', description='', bounds = '',instance=-1):

        if text != "":
            if type(text) is not type([]):
                obj = self.getUiObjectTest(className,resourceId,text,description,bounds,instance)
                return obj
            if type(text) is type([]):
                count = 0
                for t in text:
                    try:
                        obj = self.getUiObjectTest(className,resourceId,t,description,bounds,instance)
                        objInfo = obj.info
                        print "文本%s对应的option已找到"%t
                        return obj
                    except Exception,e:
                        nextText = text[count+1]
                        print"文本%s对应的option未找到,匹配下一个文本%s"%(t,nextText)
                    count += 1
                print "所有文本均已匹配完毕,未找到对应option"
                class object():
                    exists = False
                obj = object()
                return obj
        else:
            obj = self.getUiObjectTest(className,resourceId,text,description,bounds,instance)
            return obj





    def getUiObjectTest(self, className='', resourceId='', text='', description='', bounds = '',instance=-1):
        self.listenAdbConnected()
        # print 'className:', className
        # print 'resourceId:', resourceId
        # print 'text:', text
        # print 'description:', description
        # print 'instance:', instance

        uiObject = None
        try:

            if className == "" and resourceId == "" and text == "" and description == "" and\
                    bounds == "" and instance == -1:
                print "没有参数带入,找不到对象"
                return uiObject

            if className != "" and resourceId != "" and text != "" and description != "" and \
                    bounds != "" and instance != -1:
                uiObject = self.u(className=className, resourceId=resourceId, text=text, description=description,
                                  bounds=bounds,instance=instance)
            # 缺少一个元素的
            #缺instance
            if className != "" and resourceId != "" and text != "" and description != "" and \
                    bounds != "" and instance == -1:
                uiObject = self.u(className=className, resourceId=resourceId, text=text, bounds = bounds,
                                  description=description)
            #缺bounds
            if className != "" and resourceId != "" and text != "" and description != "" and \
                    bounds == "" and instance != -1:
                uiObject = self.u(className=className, resourceId=resourceId, text=text,
                                  description=description,instance = instance)
            #缺description
            if className != "" and resourceId != "" and text != "" and description == "" and\
                    bounds != "" and instance != -1:
                uiObject = self.u(className=className, resourceId=resourceId, text=text,
                                  bounds=bounds,instance=instance)
            #缺text
            if className != "" and resourceId != "" and text == "" and description != "" and\
                    bounds != "" and instance != -1:
                uiObject = self.u(className=className, resourceId=resourceId, description=description,
                                  bounds=bounds,instance=instance)
            #缺resouceId
            if className != "" and resourceId == "" and text != "" and description != "" and \
                    bounds!="" and instance != -1:
                uiObject = self.u(className=className, text=text, description=description,
                                  bounds=bounds,instance=instance)
            # lack of className
            if className == "" and resourceId != "" and text != "" and description != "" and \
                    bounds!="" and instance != -1:
                uiObject = self.u(resourceId=resourceId, text=text, description=description,
                                  bounds=bounds,instance=instance)

            # 缺少两个元素的
            # lack of className and resourceId
            if className == "" and resourceId == "" and text != "" and description != "" and \
                    bounds!="" and instance != -1:
                uiObject = self.u(text=text, description=description,bounds=bounds,
                                  instance=instance)
            # lack of className and text
            if className == "" and resourceId != "" and text == "" and description != "" and \
                    bounds != "" and instance != -1:
                uiObject = self.u(resourceId=resourceId, description=description, bounds=bounds,
                                  instance=instance)
            #lack of className and description
            if className == "" and resourceId != "" and text != "" and description == "" and \
                    bounds!="" and instance != -1:
                uiObject = self.u(resourceId=resourceId, text=text,bounds=bounds,
                                  instance=instance)
            # lack of className and bounds
            if className == "" and resourceId != "" and text != "" and description != "" and \
                    bounds == "" and instance != -1:
                uiObject = self.u(resourceId=resourceId, text=text, description=description,
                                  instance=instance)
            # lack of className and instance
            if className == "" and resourceId != "" and text != "" and description != "" and \
                    bounds != "" and instance == -1:
                uiObject = self.u(resourceId=resourceId, text=text, description=description,
                                  bounds=bounds)
            # lack of resourceId and text
            if className != "" and resourceId == "" and text == "" and description != "" and \
                    bounds!="" and instance != -1:
                uiObject = self.u(className=className, description=description,bounds=bounds,
                                  instance=instance)
            # lack of resourceId and description
            if className != "" and resourceId == "" and text != "" and description == "" and \
                    bounds!="" and instance != -1:
                uiObject = self.u(className=className, text=text,bounds = bounds,
                                  instance=instance)
            # lack of resourceId and bounds
            if className != "" and resourceId != "" and text == "" and description != "" and \
                    bounds == "" and instance != -1:
                uiObject = self.u(className=className, text=text, description=description,
                                  instance=instance)
            # lack of resourceId and instance
            if className != "" and resourceId == "" and text != "" and description != "" and \
                    bounds != "" and instance == -1:
                uiObject = self.u(className=className, text=text, description=description,
                                  bounds=bounds)
            # lack of text and description
            if className != "" and resourceId != "" and text == "" and description == "" and \
                    bounds!="" and instance != -1:
                uiObject = self.u(className=className, resourceId=resourceId, bounds=bounds,
                                  instance=instance)
            # lack of text and bounds
            if className != "" and resourceId != "" and text == "" and description != "" and \
                    bounds=="" and instance != -1:
                uiObject = self.u(className=className, resourceId=resourceId,
                                  description=description,instance=instance)
            # lack of text and instance
            if className != "" and resourceId != "" and text == "" and description != "" and \
                    bounds!="" and instance == -1:
                uiObject = self.u(className=className, resourceId=resourceId,
                                  description=description,bounds=bounds)
            # lack of description and bounds
            if className != "" and resourceId != "" and text != "" and description == "" and \
                    bounds=="" and instance != -1:
                uiObject = self.u(className=className, resourceId=resourceId, text = text,
                                  instance=instance)
            # lack of description and instance
            if className != "" and resourceId != "" and text != "" and description == "" and \
                    bounds!="" and instance == -1:
                uiObject = self.u(className=className, resourceId=resourceId, text = text,
                                  bounds=bounds)
            # lack of bounds and instance
            if className != "" and resourceId != "" and text != "" and description != "" and \
                    bounds=="" and instance == -1:
                uiObject = self.u(className=className, resourceId=resourceId, text = text,
                                  description=description)

            # 缺少3个元素
            # lack of className and resourceId and text
            if className == "" and resourceId == "" and text == "" and description != "" and \
                    bounds!="" and instance != -1:
                uiObject = self.u(description=description, bounds=bounds,instance=instance)
            # lack of className and resourceId and description
            if className == "" and resourceId == "" and text != "" and description == "" and \
                    bounds!="" and instance != -1:
                uiObject = self.u(text = text,bounds=bounds,instance=instance)
            # lack of className and resourceId and bounds
            if className == "" and resourceId == "" and text != "" and description != "" and \
                    bounds =="" and instance != -1:
                uiObject = self.u(text = text,description=description,instance=instance)
            # lack of className and resourceId and instance
            if className == "" and resourceId == "" and text != "" and description != "" and \
                    bounds!="" and instance == -1:
                uiObject = self.u(text = text,description=description,bounds=bounds)
            # lack of className and text and description
            if className == "" and resourceId != "" and text == "" and description == "" and \
                    bounds!="" and instance != -1:
                uiObject = self.u(resourceId=resourceId,bounds=bounds,instance=instance)
            # lack of className and text and bounds
            if className == "" and resourceId != "" and text == "" and description != "" and \
                    bounds=="" and instance != -1:
                uiObject = self.u(resourceId=resourceId,description=description,instance=instance)
             # lack of className and text and instance
            if className == "" and resourceId != "" and text == "" and description != "" and \
                    bounds!="" and instance == -1:
                uiObject = self.u(resourceId=resourceId,description=description,bounds=bounds)
            # lack of className and description and bounds
            if className == "" and resourceId != "" and text != "" and description == "" and \
                    bounds=="" and instance != -1:
                uiObject = self.u(resourceId=resourceId, text = text,instance=instance)
            # lack of className and description and instance
            if className == "" and resourceId != "" and text != "" and description == "" and \
                    bounds!="" and instance == -1:
                uiObject = self.u(resourceId=resourceId, text = text,bounds=bounds)
            # lack of resourceId and text and description
            if className != "" and resourceId == "" and text == "" and description == "" and \
                    bounds!="" and instance != -1:
                uiObject = self.u(className=className,bounds=bounds,instance=instance)
            # lack of resourceId and text and bounds
            if className != "" and resourceId == "" and text == "" and description != "" and \
                    bounds=="" and instance != -1:
                uiObject = self.u(className=className,description=description,instance=instance)
            # lack of resourceId and text and instance
            if className != "" and resourceId == "" and text == "" and description != "" and \
                    bounds!="" and instance == -1:
                uiObject = self.u(className=className,description=description,bounds=bounds)
            # lack of resourceId and description and bounds
            if className != "" and resourceId == "" and text != "" and description == "" and \
                    bounds =="" and instance != -1:
                uiObject = self.u(className=className,text = text,instance=instance)
            # lack of resourceId and description and instance
            if className != "" and resourceId == "" and text != "" and description == "" and \
                    bounds!="" and instance == -1:
                uiObject = self.u(className=className, text = text,bounds=bounds)
            # lack of resourceId and bounds and instance
            if className != "" and resourceId == "" and text != "" and description != "" and \
                    bounds =="" and instance == -1:
                uiObject = self.u(className=className, text = text,description=description)
            # lack of text and description and bounds
            if className != "" and resourceId != "" and text == "" and description == "" and \
                    bounds=="" and instance != -1:
                uiObject = self.u(className=className, resourceId=resourceId,instance=instance)
            # lack of text and description and instance
            if className != "" and resourceId != "" and text == "" and description == "" and \
                    bounds!="" and instance == -1:
                uiObject = self.u(className=className, resourceId=resourceId,bounds=bounds)
            # lack of description and bounds and instance
            if className != "" and resourceId != "" and text != "" and description == "" and \
                    bounds =="" and instance == -1:
                uiObject = self.u(className=className, resourceId=resourceId, text = text)

            # 缺少4个元素
            # lack of className and resourceId and text and description
            if className == "" and resourceId == "" and text == "" and description == "" and \
                    bounds !="" and instance != -1:
                uiObject = self.u(bounds=bounds,instance=instance)
            # lack of className and resourceId and text and bounds
            if className == "" and resourceId == "" and text == "" and description != "" and \
                    bounds =="" and instance != -1:
                uiObject = self.u(description=description,instance=instance)
            # lack of className and resourceId and text and instance
            if className == "" and resourceId == "" and text == "" and description != "" and \
                    bounds !="" and instance == -1:
                uiObject = self.u(description=description,bounds=bounds)
            # lack of className and resourceId and description and bounds
            if className == "" and resourceId == "" and text != "" and description == "" and \
                    bounds =="" and instance != -1:
                uiObject = self.u(text = text,instance=instance)
            # lack of className and resourceId and description and instance
            if className == "" and resourceId == "" and text != "" and description == "" and \
                    bounds !="" and instance == -1:
                uiObject = self.u(text = text,bounds=bounds)
            # lack of resourceid and text and description and bounds
            if className != "" and resourceId == "" and text == "" and description == "" and \
                    bounds =="" and instance != -1:
                uiObject = self.u(className=className,instance=instance)
            # lack of resourceid and text and description and instance
            if className != "" and resourceId == "" and text == "" and description == "" and \
                    bounds !="" and instance == -1:
                uiObject = self.u(className=className,bounds=bounds)
            # lack of text and description and bounds and instance
            if className != "" and resourceId != "" and text == "" and description == "" and \
                    bounds =="" and instance == -1:
                uiObject = self.u(className=className, resourceId=resourceId)

            # 缺少5个元素的
            # only className
            if className != "" and resourceId == "" and text == "" and description == "" and \
                    bounds =="" and instance == -1:
                uiObject = self.u(className=className)
            # only resourceid
            if className == "" and resourceId != "" and text == "" and description == "" and \
                    bounds =="" and instance == -1:
                uiObject = self.u(resourceId=resourceId)
            # only text
            if className == "" and resourceId == "" and text != "" and description == "" and \
                    bounds =="" and instance == -1:
                uiObject = self.u(text = text)
            # only description
            if className == "" and resourceId == "" and text == "" and description != "" and \
                    bounds =="" and instance == -1:
                uiObject = self.u(description=description)
            # only bounds
            if className == "" and resourceId == "" and text == "" and description == "" and \
                    bounds !="" and instance == -1:
                uiObject = self.u(bounds=bounds)
            # only instance
            if className == "" and resourceId == "" and text == "" and description == "" and \
                    bounds =="" and instance == -1:
                uiObject = self.u(instance=instance)
            return uiObject
        except Exception, e:
            print "异常:",e
            return uiObject

    ''' 
    作用:判断当前界面中指定控件是否存在
    参数:
    className:控件类型(例如:android.widget.TextView)
    resourceId:控件的Id(例如:lh.oslauncher:id/tv_title)
    text:控件上的文件(例如:'主页')
    description:控件描述
    instance:实例参数

    注意:className、resourceId、text 是利用WEditor工具查看控件属性看到的

    例子:isExists = self.pyUIAutomator.isElementExist("android.widget.TextView",
                                                     resourceId="com.apps.weather:id/today_tv_city",
                                                     text='鞍山')
    '''

    def isElementExist(self, className='', resourceId='', text='', description='', instance=-1):
        self.listenAdbConnected()
        try:
            uiObject = self.getUiObject(className, resourceId, text, description, instance)
            print 'uiObject:', uiObject
            if uiObject:
                isExists = uiObject.exists()
                print 'isExists:', isExists
            else:
                isExists = False
        except Exception, e:
            print e
            isExists = False
        return isExists

    ''' 
    作用:获取指定控件的文字属性
    参数:
    className:控件类型(例如:android.widget.TextView)
    resourceId:控件的Id(例如:lh.oslauncher:id/tv_title)
    注意:className、resourceId 是利用WEditor工具查看控件属性看到的
    例子: str_play_time = self.pyUIAutomator.getTextById("android.widget.TextView",
                                                       resourceId="com.apps.usbmediaplayer:id/playingTime")
    '''

    def getTextById(self, className, resourceId):
        self.listenAdbConnected()
        try:
            text = self.u(className=className, resourceId=resourceId).get_text()
        except Exception, e:
            print e
            text = ''
        return text

    '''
    作用:执行adb命令
    参数:adbCmd:要被执行的adb命令
    注意:adbCmd不需要输入adb shell
    例子:self.pyUIAutomator.adb_shell('am start -n com.apps.factory.ui/.designmenu.DesignMenuActivity')
    '''

    def adb_shell(self, adbCmd):
        self.listenAdbConnected()
        try:
            self.u.adb_shell(adbCmd)
        except Exception, e:
            print e

    ''' 
    作用:设置android.widget.EditText 的文字内容
    参数:text 要输入到EditText的文字内容
    注意:保证焦点在该EditText,处于可以输入的状态
    例子:self.pyUIAutomator.send_text(u'鞍山')
    '''

    def send_text(self, text):
        self.listenAdbConnected()
        try:
            self.u.set_fastinput_ime(True)  # 切换成FastInputIME输入法
            self.u.clear_text()
            self.u.send_keys(unicode(text))  # adb广播输入
            self.u.set_fastinput_ime(False)  # 切换成正常的输入法
        except Exception, e:
            print e

    ''' 
       作用:向电视机发送action动作
       参数:actin 要执行的动作
       注意:焦点在搜索界面输入框中,在搜索界面输入完搜索内容,执行该搜索动作
       例子:小米谷歌商店搜索应用  搜索 keep应用
           self.pyUIAutomator.send_text("kee")
           self.pyUIAutomator.send_action("search")
       '''

    def send_action(self, action):
        self.listenAdbConnected()
        try:
            self.u.set_fastinput_ime(True)  # 切换成FastInputIME输入法
            self.u.send_action(action)
            self.u.set_fastinput_ime(False)  # 切换成正常的输入法
        except Exception, e:
            print e

    ''' 
     作用:保存界面截图到指定地址
     参数:pngPath 要保存图片的全路径名称
     注意:保证该图片路径所在文件夹存在
     例子:self.pyUIAutomator.screenshot(
            r'E:\svn\SAT\SAT_Runner\btc_runner_se\runner\smoking\report\imgs\testUSB_Desk_Focused.png')
     '''

    def screenshot(self, pngPath):
        self.listenAdbConnected()
        try:
            self.u.screenshot(pngPath)
        except Exception, e:
            print e

    ''' 
       作用:在Android 一个土司提示框  方便在电视机中看到跑到哪里
       参数:
       toastText:土司的内容
       toastTime:土司存留时间
       注意:
       例子:self.pyUIAutomator.makeToast('测试开始', 3)
       '''

    def makeToast(self, toastText, toastTime=1):
        self.listenAdbConnected()
        try:
            self.u.make_toast(toastText, toastTime)
        except Exception, e:
            print e

    ''' 
        作用:启动指定包名的应用的指定Activity
        参数:
        pkg_name:指定的包名
        activity:指定的activity名
        注意:
        例子:self.pyUIAutomator.startApp('com.apps.usbmediaplayer')
              self.pyUIAutomator.startApp('com.apps.usbmediaplayer','com.apps.usbmediaplayer.activity.MainActivity')
        '''

    def startApp(self, pkg_name, activity=None):
        self.listenAdbConnected()
        try:
            if activity:
                self.u.app_start(pkg_name, activity=activity)
            else:
                self.u.app_start(pkg_name)
        except Exception, e:
            print e

    ''' 
        作用:关闭某一指定包名的APP
        参数:
        pkg_name:指定的包名
        注意:
        例子:self.pyUIAutomator.stopApp('com.apps.usbmediaplayer')
     '''

    def stopApp(self, pkg_name):
        self.listenAdbConnected()
        try:
            self.u.app_stop(pkg_name)
        except Exception, e:
            print e

    ''' 
        作用:关闭Android系统中所有的运行程序
        参数:
        注意:
        例子:self.pyUIAutomator.stopAllApps()
     '''

    def stopAllApps(self):
        self.listenAdbConnected()
        try:
            self.u.app_stop_all()
        except Exception, e:
            print e

    ''' 
        作用:停止uiautomator守护程序,允许其他测试框架如 appium 运行
        参数:
        注意:
        例子:self.pyUIAutomator.stopUIAutomatorService()
     '''

    def stopUIAutomatorService(self):
        self.listenAdbConnected()
        try:
            self.u.service("uiautomator").stop()
        except Exception, e:
            print e

    '''
      作用:根据传入的chooseType,获取当前界面聚焦的对象
      参数:
      注意:
      例子:self.pyUIAutomator.getChoosedUIObject("focus")
    '''
    def getChoosedUIObject(self, chooseType, resourceId='', text=''):
        if chooseType.lower() == "focus":
            return self.getFocusedUIObject(resourceId=resourceId, text=text)
        elif chooseType.lower() == "select":
            return self.getSelectedUIObject(resourceId=resourceId, text=text)
        else:
            return None

    ''' 
          作用:获取当前界面的focused的UIObject对象
          参数:
          注意:
          例子:self.pyUIAutomator.getFocusedUIObject()
       '''

    def getFocusedUIObject(self, resourceId='', text=''):
        self.listenAdbConnected()
        focusedUIObject = None
        try:
            if resourceId != "" and text != "":
                focusedUIObject = self.u(resourceId=resourceId, text=text, focused=True)
            elif resourceId == "" and text != "":
                focusedUIObject = self.u(text=text, focused=True)
            elif resourceId != "" and text == "":
                focusedUIObject = self.u(resourceId=resourceId, focused=True)
            else:
                focusedUIObject = self.u(focused=True)
        except Exception, e:
            print "getFocusedUIObject Error:", e
        return focusedUIObject

    ''' 
            作用:获取当前界面的selected的UIObject对象
            参数:
            注意:
            例子:self.pyUIAutomator.getFocusedUIObject()
         '''

    def getSelectedUIObject(self, resourceId='', text=''):
        self.listenAdbConnected()
        try:
            if resourceId != "" and text != "":
                selectedUIObject = self.u(resourceId=resourceId, text=text, selected=True)
            elif resourceId == "" and text != "":
                selectedUIObject = self.u(text=text, selected=True)
            elif resourceId != "" and text == "":
                selectedUIObject = self.u(resourceId=resourceId, selected=True)
            else:
                selectedUIObject = self.u(selected=True)
            return selectedUIObject
        except Exception, e:
            print "getSelectedUIObject Error:", e
            return None

    ''' 
            作用:在脚本运行过程中,监听弹框的出现,如果出现则按按钮使其消失,使得脚本中获取元素控件时不被遮挡报错
            参数:watcherName 监听器名称
                 dialogText 弹框的text
                 buttonText 使弹框消失的按钮text
            注意: 1.这个函数只是创建监听器,这些监听器生效使用u.startWatchers(),监听器失效使用u.stopWatchers();
                   2.一般使用在脚本运行实际执行界面前 声明监听器、调用 u.startWatchers(),在脚本 结束时候调用u.stopWatchers()
            例子:self.pyUIAutomator.getFocusedUIObject()
                u = PyUIAutomator()
                u.createDilogWatcher("Normal Dialog Watcher", "我是一个普通Dialog", "确定")
                u.startWatchers()
                #这30S延时代表脚本执行
                time.sleep(30)
                 u.stopWatchers()
         '''

    def createDilogWatcher(self, watcherName, dialogText, buttonText):
        self.listenAdbConnected()
        self.u.watcher(watcherName).when(text=dialogText).click(text=buttonText)

    ''' 
             作用:使得创建的弹框监听器生效
             参数:
             注意:

          '''

    def startWatchers(self):
        self.listenAdbConnected()
        self.u.watchers.watched = True

    ''' 
             作用:使得创建的弹框监听器失效
             参数:
             注意:

          '''

    def stopWatchers(self):
        self.listenAdbConnected()
        self.u.watchers.watched = False

    def dump_hierarchy(self):
        self.listenAdbConnected()
        return self.u.dump_hierarchy()


class DirectionManageAndroid():
    def __init__(self):

        self.className = self.__class__.__name__

        self.grid = None
        self.remote = TvOperator()

    def goOneStep(self, pyUIAutomator, direction, keyType = UATTree.Key_Event):
        # keyDict = {'U': "up", "D": "down", "L": "left", "R": "right"}
        print "goOneStep,direction:", direction
        directionArr = direction.split("-")
        for direct in directionArr:
            LoggingUtil.getDebugLogger().info(pyFileName, self.className, get_current_function_name(),
                                              u"script:sendKey 执行按键:%s" % (direct))
            # self.custSendKey(keyDict[direct])
            if keyType == UATTree.Key_Event:
                pyUIAutomator.pressKeyTimes(direct)
            elif keyType == UATTree.Key_IR:
                self.remote.sendKey(direct)

    # def custSendKey(self, keyEvent):
    #     if type(keyEvent) == type('') or type(keyEvent) == type(u""):
    #         self.operator.sendKey(keyEvent)
    #     if type(keyEvent) == type([]):
    #         try:
    #             self.operator.sendKey(keyEvent[0], keyEvent[1], keyEvent[2])
    #         except Exception:
    #             LoggingUtil.getDebugLogger().info(pyFileName, self.className, get_current_function_name(),
    #                                               u'script:sendKey  ERROR 双击按键数组%s格式出错,请按照格式:[按键字符,按键次数,按键间隔]' % (
    #                                                   keyEvent))

    '''
    计算目标区域在当前焦点区域的方位.
            |               |
    左上角  |      上       |   右上角
            |               |
    -----------------------------------
            |               |
            |               |
     左     |    焦点区域   |    右
            |               |
    -----------------------------------
            |               |
     左下角 |      下       |   右下角
            |               |

    区域的方位,按上图,分成4面位方向和4角位方向。
    4面位方向:上、下、左、右。只要目标区域,和4面位方向区域有交集,就属于面位方向。
    4角位方向:左上角、右上角、左下角、右下角。目标区域全部在4角位方向区域,才是角位方向。
    方位定义:up、down、left、right、left-up、left-down、right-up、right-down
    :param areaL:当前焦点所在区域
    :param areaT:目标区域
    :return direction。字符串类型,方位:up、down、left、right、left-up、left-down、right-up、right-down
    '''
    ImgRectLimit = 10000

    def getTargetDirection(self, focusedBounds, destBounds, moveKey=["down","up"]):
        areaL = (focusedBounds['left'], focusedBounds['top'], focusedBounds['right'], focusedBounds['bottom'])
        areaT = (destBounds['left'], destBounds['top'], destBounds['right'], destBounds['bottom'])
        print "getTargetDirection:", areaL, areaT
        LoggingUtil.getDebugLogger().info(pyFileName, self.className,
                                          get_current_function_name(),
                                          u'script:focusMatch 当前聚焦区域坐标:%s  目标聚焦区域坐标:%s' % (str(areaL), str(areaT)))
        if self.hasSameArea(areaL,areaT):
            focusCP = [(areaL[2] + areaL[0])/2,(areaL[3]+areaL[1])/2]
            destCP = [(areaT[2] + areaT[0])/2,(areaT[3]+areaT[1])/2]
            return self.getPointDirection(focusCP,destCP)
        # 确定4个面位方位的区域的x,y轴范围
        up = [areaL[0], 0, areaL[2], areaL[1]]
        down = [areaL[0], areaL[3], areaL[2], DirectionManageAndroid.ImgRectLimit]
        left = [0, areaL[1], areaL[0], areaL[3]]
        right = [areaL[2], areaL[1], DirectionManageAndroid.ImgRectLimit, areaL[3]]
        # 检测目标区域是否和4个面位方向区域有重叠部分
        up_direct = self.hasSameArea(up, areaT)
        if up_direct:
            return "up"
        down_direct = self.hasSameArea(down, areaT)
        if down_direct:
            return "down"
        left_direct = self.hasSameArea(left, areaT)
        if left_direct:
            return "left"
        right_direct = self.hasSameArea(right, areaT)
        if right_direct:
            return "right"

        # 计算目标区域坐上角点的方位,x,y差值确定角位方向
        dL_Ux = areaT[0] - areaL[0]
        dL_Uy = areaT[1] - areaL[1]
        if (dL_Ux > 0) and (dL_Uy > 0):
            if "down" in moveKey:
                return "down-right"
            else:
                return "right-down"
        if (dL_Ux < 0) and (dL_Uy > 0):
            if "down" in moveKey:
                return "down-left"
            else:
                return "left-down"
        if (dL_Ux > 0) and (dL_Uy < 0):
            if "down" in moveKey:
                return "up-right"
            else:
                return "right-up"
        if (dL_Ux < 0) and (dL_Uy < 0):
            if "down" in moveKey:
                return "up-left"
            else:
                return "left-up"

    '''
    计算点p2相对p1的方位。按p1 45°斜线划分上下左右。
    '''
    def getPointDirection(self,p1,p2):
        print "getPointDirection,p1,p2:",p1,p2
        dx = p2[0] - p1[0]
        dy = p2[1] - p1[1]
        if dx >= 0 and abs(dy) < abs(dx):
            return "right"
        if dx <= 0 and abs(dy) < abs(dx):
            return "left"
        if dy >= 0 and abs(dy) >= abs(dx):
            return "down"
        if dy <= 0 and abs(dy) >= abs(dx):
            return "up"
        return "center"


    '''
    检测两个区域是否有重叠部分
    '''

    def hasSameArea(self, area1, area2):
        # 计算各区域宽、高
        area1_W = area1[2] - area1[0]
        area1_H = area1[3] - area1[1]
        area2_W = area2[2] - area2[0]
        area2_H = area2[3] - area2[1]

        # 计算目标区域坐上角点的方位
        dL_Ux = area1[0] - area2[0]
        dL_Uy = area1[1] - area2[1]
        # 计算x坐标,判断是否有重叠可能。
        x_enable = False
        if dL_Ux > 0:
            if (abs(dL_Ux) - area2_W) >= 0:
                x_enable = False
            else:
                x_enable = True
        else:
            if (abs(dL_Ux) - area1_W) >= 0:
                x_enable = False
            else:
                x_enable = True

        # 计算y坐标,判断是否有重叠可能。
        y_enable = False
        if dL_Uy > 0:
            if (abs(dL_Uy) - area2_H) >= 0:
                y_enable = False
            else:
                y_enable = True
        else:
            if (abs(dL_Uy) - area1_H) >= 0:
                y_enable = False
            else:
                y_enable = True

        # 如果x坐标、y坐标都有可能重叠,则一定重叠。反之,没有重叠。
        return x_enable and y_enable

    def isSameBounds(self, BoundA, BoundB):
        areaA = (BoundA['left'], BoundA['top'], BoundA['right'], BoundA['bottom'])
        areaB = (BoundB['left'], BoundB['top'], BoundB['right'], BoundB['bottom'])
        if areaA[0] == areaB[0] \
                and areaA[1] == areaB[1] \
                and areaA[2] == areaB[2] \
                and areaA[3] == areaB[3]:
            return True
        else:
            return False

    def isHasAnotherBounds(self, BoundA, BoundB):
        areaA = (BoundA['left'], BoundA['top'], BoundA['right'], BoundA['bottom'])
        areaB = (BoundB['left'], BoundB['top'], BoundB['right'], BoundB['bottom'])

        if areaA[0] <= areaB[0] and areaA[1] <= areaB[1] and areaA[2] >= areaB[2] and areaA[3] >= areaB[3]:
            return True
        else:
            return False

    def isRelativePositionBounds(self, initFocusedArea, initDestTextArea, BoundA, BoundB):
        # initFocusedArea = (
        #     initFocusedBound['left'], initFocusedBound['top'], initFocusedBound['right'], initFocusedBound['bottom'])
        # initDestTextArea = (
        #     initFocusedBound['left'], initDestTextBound['top'], initDestTextBound['right'], initDestTextBound['bottom'])

        areaA = (BoundA['left'], BoundA['top'], BoundA['right'], BoundA['bottom'])
        areaB = (BoundB['left'], BoundB['top'], BoundB['right'], BoundB['bottom'])

        # if areaA[0] < areaB[0] and areaA[1] < areaB[1] and areaA[2] > areaB[2] and areaA[3] >areaB[3]:
        #     return True
        # else:
        #     return False
        if initFocusedArea[0] - initDestTextArea[0] == areaA[0] - areaB[0] and initFocusedArea[1] - initDestTextArea[
            1] == areaA[1] - areaB[1] and initFocusedArea[2] - initDestTextArea[2] == areaA[2] - areaB[2] and \
                initFocusedArea[3] - initDestTextArea[3] == areaA[3] - areaB[3]:
            return True
        else:
            return False
        # 比较两个Bound面积大小

    def isBiggerBound(self, boundA, boundB):
        # print 'boundA:',boundA
        # print 'boundB:',boundB
        if ((boundA["bottom"] - boundA["top"]) * (boundA["right"] - boundA["left"])) >= ((
                                                                                                 boundB["bottom"] -
                                                                                                 boundB["top"]) * (
                                                                                                 boundB["right"] -
                                                                                                 boundB["left"])):
            return True
        else:
            return False

    def getRelativeBounds(self, standBounds_view1, standBounds_view2, currentBound_view1):
        currentBound_view2 = {}
        currentBound_view2["top"] = standBounds_view2["top"] - standBounds_view1["top"] + currentBound_view1["top"]
        currentBound_view2["left"] = standBounds_view2["left"] - standBounds_view1["left"] + currentBound_view1["left"]
        currentBound_view2["right"] = standBounds_view2["right"] - standBounds_view1["right"] + currentBound_view1[
            "right"]
        currentBound_view2["bottom"] = standBounds_view2["bottom"] - standBounds_view1["bottom"] + currentBound_view1[
            "bottom"]

        return currentBound_view2


class FocusManageAndroid():
    # u是PyUIAutomator对象
    # focusManage 是DirectionManageAndroid对象
    def __init__(self, u, directionManageAndroid):
        self.className = self.__class__.__name__
        self.u = u
        self.directionManageAndroid = directionManageAndroid
        self.ReverseDirctionDict = {"up": "down", "down": "up", "left": "right", "right": "left"}
        self.featureDetect = FeatureDetect()
        self.ccard = CCardManager()
        self.imgCMP = ImageCMP()
        self.ocr = OCRConvert()
        self.remote = TvOperator()

    '''
                     作用:在RecyclerView 中 focused控件包含文字控件  用于聚焦目标焦点
                     参数:
                     text:目标文字的文字内容
                     className:目标文字的className
                     findDirection: 目标文字控件被隐藏时寻找的方向
                     Max_Try:最多查找次数
                     注意:
                     例子:
                     小米信源设置界面  聚焦到Device Settings/Sound mode
                     className = "android.widget.TextView"
                     focusManageAndroid.toDestFocusByText_className_for_RecyclerView("News", className)
                  '''

    # 在RecyclerView 中 focused控件包含文字控件
    def toDestFocusByText_className_for_RecyclerView(self, text, className, findDirection="down", Max_Try=10, keyType = UATTree.Key_Event):
        # 按照传入的方向寻找Max_Try次,如果仍未聚焦到选中area,则按照传入方向的反方向 反向寻找 2*Max_Try 次
        count = 0
        Max_Try = Max_Try
        Reversecount = 0
        Reverse_Max_Try = Max_Try * 2
        while (True):
            if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                break
            # 等待聚焦效果刷新完成,稳定之后再获取相关的属性
            time.sleep(0.5)
            focusedUIObject = self.u.getFocusedUIObject()
            focusedBounds = focusedUIObject.info['bounds']
            # print "focusedBounds:",focusedBounds
            destUIObject = self.u.getUiObject(text=text, className=className)
            if destUIObject:
                try:
                    destBounds = destUIObject.info['bounds']
                    # print "destBounds:", destBounds
                    if self.directionManageAndroid.isHasAnotherBounds(focusedBounds, destBounds):
                        print '成功聚焦到目标焦点:', text
                        return True
                    else:
                        count = count + 1
                    direction = self.directionManageAndroid.getTargetDirection(focusedBounds, destBounds)
                    self.directionManageAndroid.goOneStep(self.u, direction, keyType)
                except Exception:
                    # 出现控件出现一半的时候,获取控件信息会报错
                    if count < Max_Try:
                        count = count + 1
                        self.pressKeyByType(findDirection, keyType)
                    else:
                        Reversecount = Reversecount + 1
                        self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)
            # 如果界面中没有目标文字的控件出现,则按照传入的方向寻找Max_Try次;仍然未找到 则反方向寻找2*Max_Try次
            else:
                if count < Max_Try:
                    count = count + 1
                    self.pressKeyByType(findDirection, keyType)
                else:
                    Reversecount = Reversecount + 1
                    self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)

        print "执行%s 次查找,仍未找到目标焦点!!" % (str(Max_Try))
        return False

    ''' 
            作用:在RecyclerView 中 focused控件包含文字控件  用于聚焦目标焦点
            参数:
            text:目标文字的文字内容
            textResourceId:目标文字的resourceId
            findDirection: 目标文字控件被隐藏时寻找的方向
            Max_Try:最多查找次数
            注意:
            例子:
            小米信源设置界面  聚焦到Device Settings
            focusManageAndroid.toDestFocusByText_for_RecyclerView("Device Settings","com.android.tv:id/title")
         '''

    # 在RecyclerView 中 focused控件包含文字控件
    def toDestFocusByText_for_RecyclerView(self, text, textResourceId="", findDirection="down", Max_Try=10, keyType = UATTree.Key_Event, hb_keyDict={}):
        # 按照传入的方向寻找Max_Try次,如果仍未聚焦到选中area,则按照传入方向的反方向 反向寻找 2*Max_Try 次
        count = 0
        Max_Try = Max_Try
        Reversecount = 0
        Reverse_Max_Try = Max_Try * 2
        while (True):
            if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                break
            # 等待聚焦效果刷新完成,稳定之后再获取相关的属性
            time.sleep(0.5)
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            focusedUIObject = self.u.getFocusedUIObject()
            try:
                focusedBounds = focusedUIObject.info['bounds']
            except Exception, e:
                print "未能获取到当前聚焦焦点,聚焦框丢失,判断聚焦失败!!"
                return False
            print "focusedBounds:",focusedBounds
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            destUIObject = self.u.getUiObject(text=text, resourceId=textResourceId)

            if destUIObject:
                try:
                    destBounds = destUIObject.info['bounds']
                    print "destBounds:", destBounds
                    if self.directionManageAndroid.isHasAnotherBounds(focusedBounds, destBounds):
                        print '成功聚焦到目标焦点:', text
                        return True
                    else:
                        count = count + 1
                    direction = self.directionManageAndroid.getTargetDirection(focusedBounds, destBounds)
                    self.directionManageAndroid.goOneStep(self.u, direction, keyType)
                except Exception:
                    # 出现控件出现一半的时候,获取控件信息会报错
                    if count < Max_Try:
                        count = count + 1
                        self.pressKeyByType(findDirection, keyType)
                    else:
                        Reversecount = Reversecount + 1
                        self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)
            # 如果界面中没有目标文字的控件出现,则按照传入的方向寻找Max_Try次;仍然未找到 则反方向寻找2*Max_Try次
            else:
                if count < Max_Try:
                    count = count + 1
                    self.pressKeyByType(findDirection, keyType)
                else:
                    Reversecount = Reversecount + 1
                    self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)

        print "执行%s 次查找,仍未找到目标焦点!!" % (str(Max_Try))
        return False


    '''
            作用:在RecyclerView 中 focused控件包含文字控件  用于聚焦目标焦点,传入的resourceId为聚焦焦点的resId时的处理函数
            参数:
            text:目标文字的文字内容
            focuseResId:整个聚焦焦点的resourceId
            findDirection: 目标文字控件被隐藏时寻找的方向
            Max_Try:最多查找次数
            注意:
            例子:
            小米俄罗斯设置界面 存在复数个聚焦焦点时,使用此函数,可以规避复数焦点的问题
    '''
    def toDestFocusByText_with_FocuseResourceId(self, text, focuseResId, findDirection="down", Max_Try=10, keyType = UATTree.Key_Event, hb_keyDict = {}):
        # 按照传入的方向寻找Max_Try次,如果仍未聚焦到选中area,则按照传入方向的反方向 反向寻找 2*Max_Try 次
        count = 0
        Max_Try = Max_Try
        Reversecount = 0
        Reverse_Max_Try = Max_Try * 2
        while (True):
            if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                break
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            # 等待聚焦效果刷新完成,稳定之后再获取相关的属性
            time.sleep(0.5)
            focusedUIObject = self.u.getFocusedUIObject(resourceId=focuseResId)
            try:
                focusedBounds = focusedUIObject.info['bounds']
            except Exception, e:
                print "未能获取到当前聚焦焦点,聚焦框丢失,判断聚焦失败!!"
                return False
            print "focusedBounds:",focusedBounds
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            destUIObject = self.u.getUiObject(text=text)
            if destUIObject:
                try:
                    destBounds = destUIObject.info['bounds']
                    print "destBounds:", destBounds
                    if self.directionManageAndroid.isHasAnotherBounds(focusedBounds, destBounds):
                        print '成功聚焦到目标焦点:', text
                        return True
                    else:
                        count = count + 1
                    direction = self.directionManageAndroid.getTargetDirection(focusedBounds, destBounds)
                    self.directionManageAndroid.goOneStep(self.u, direction, keyType)
                except Exception:
                    # 出现控件出现一半的时候,获取控件信息会报错
                    if count < Max_Try:
                        count = count + 1
                        self.pressKeyByType(findDirection, keyType)
                    else:
                        Reversecount = Reversecount + 1
                        self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)
            # 如果界面中没有目标文字的控件出现,则按照传入的方向寻找Max_Try次;仍然未找到 则反方向寻找2*Max_Try次
            else:
                if count < Max_Try:
                    count = count + 1
                    self.pressKeyByType(findDirection, keyType)
                else:
                    Reversecount = Reversecount + 1
                    self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)

        print "执行%s 次查找,仍未找到目标焦点!!" % (str(Max_Try))
        return False



    ''' 
             作用:在RecyclerVi或listView 中 selected控件包含文字控件  用于聚焦目标焦点
             参数:
             text:目标文字的文字内容
             textResourceId:目标文字的resourceId
             listViewResourceId:RecyclerVi或listView的resourceId
             findDirection: 目标文字控件被隐藏时寻找的方向
             Max_Try:最多查找次数
             注意:
             例子:
             2841项目信源列表聚焦  聚焦到HDMI1
             focusManageAndroid.toDestSelectByText_for_RecyclerView("HDMI1","com.android.tv:id/title","com.android.tv:id/scene_transition_common")
          '''

    def toDestSelectByText_for_RecyclerView(self, text, textResourceId='', optionViewResoucreId='', listViewResourceId='', findDirection="down",
                                            Max_Try=10, keyType = UATTree.Key_Event, hb_keyDict={}):
        # 按照传入的方向寻找Max_Try次,如果仍未聚焦到选中area,则按照传入方向的反方向 反向寻找 2*Max_Try 次
        count = 0
        Max_Try = Max_Try
        Reversecount = 0
        Reverse_Max_Try = Max_Try * 2
        while (True):
            if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                break
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            listViewUIObject = self.u.getUiObject(resourceId=listViewResourceId)
            print "listViewUIObject.info:", listViewUIObject.info
            if optionViewResoucreId != '':
                selectedUIObject = listViewUIObject.child(selected=True, resourceId=optionViewResoucreId)
            else:
                selectedUIObject = listViewUIObject.child(selected=True)
            print "selectedUIObject.info:", selectedUIObject.info
            selectedBounds = selectedUIObject.info['bounds']
            # print "focusedBounds:",focusedBounds
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            destUIObject = self.u.getUiObject(text=text, resourceId=textResourceId)
            if destUIObject:
                destBounds = destUIObject.info['bounds']
                # print "destBounds:", destBounds
                if self.directionManageAndroid.isHasAnotherBounds(selectedBounds, destBounds):
                    print '成功聚焦到目标焦点:', text
                    return True
                else:
                    count = count + 1
                direction = self.directionManageAndroid.getTargetDirection(selectedBounds, destBounds)
                self.directionManageAndroid.goOneStep(self.u, direction, keyType)
            # 如果界面中没有目标文字的控件出现,则按照传入的方向寻找Max_Try次;仍然未找到 则反方向寻找2*Max_Try次
            else:
                if count < Max_Try:
                    count = count + 1
                    self.pressKeyByType(findDirection, keyType)
                else:
                    Reversecount = Reversecount + 1
                    self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)

        print "执行%s 次查找,仍未找到目标焦点!!" % (str(Max_Try))
        return False

    ''' 
                 作用:在界面中 中 focused控件包含content-des控件  用于聚焦目标焦点
                 参数:
                 description:目标描述的文字内容
                 descriptionResourceId:目标描述的resourceId
                 findDirection: 目标文字控件被隐藏时寻找的方向
                 Max_Try:最多查找次数
                 注意:
                 例子:
                 小米APP  聚焦到YouTube
                 descriptionResourceId = "com.google.android.tvlauncher:id/banner_image"
                 focusManageAndroid.toDestFocusByDescription_for_RecyclerView("YouTube",descriptionResourceId=descriptionResourceId)
              '''

    # 在RecyclerView 中 focused控件包含文字控件
    def toDestFocusByDescription_for_RecyclerView(self, description, descriptionResourceId="", findDirection="down",
                                                  Max_Try=10 ,keyType = UATTree.Key_Event, hb_keyDict = {}):
        # 按照传入的方向寻找Max_Try次,如果仍未聚焦到选中area,则按照传入方向的反方向 反向寻找 2*Max_Try 次
        count = 0
        Max_Try = Max_Try
        Reversecount = 0
        Reverse_Max_Try = Max_Try * 2
        while (True):
            print "count:", count
            if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                break
            # 等待聚焦效果刷新完成,稳定之后再获取相关的属性
            time.sleep(0.5)
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            focusedUIObject = self.u.getFocusedUIObject()
            focusedBounds = focusedUIObject.info['bounds']
            # print "focusedBounds:",focusedBounds
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            destUIObject = self.u.getUiObject(description=description, resourceId=descriptionResourceId)
            if destUIObject:
                try:
                    destBounds = destUIObject.info['bounds']
                    # print "destBounds:", destBounds
                    if self.directionManageAndroid.isHasAnotherBounds(focusedBounds, destBounds):
                        print '成功聚焦到目标焦点:', description
                        return True
                    else:
                        count = count + 1
                    direction = self.directionManageAndroid.getTargetDirection(focusedBounds, destBounds)
                    self.directionManageAndroid.goOneStep(self.u, direction, keyType)
                except Exception, e:
                    # 出现控件出现一半的时候,获取控件信息会报错
                    if count < Max_Try:
                        count = count + 1
                        self.pressKeyByType(findDirection, keyType)
                    else:
                        Reversecount = Reversecount + 1
                        self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)
            # 如果界面中没有目标文字的控件出现,则按照传入的方向寻找Max_Try次;仍然未找到 则反方向寻找2*Max_Try次
            else:
                if count < Max_Try:
                    count = count + 1
                    self.pressKeyByType(findDirection, keyType)
                else:
                    Reversecount = Reversecount + 1
                    self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)

        print "执行%s 次查找,仍未找到目标焦点!!" % (str(Max_Try))
        return False


        # 在RecyclerView 中 focused控件包含bounds控件
    def toDestFocusByBounds_for_RecyclerView(self, bounds, boundsResourceId="", findDirection="down",
                                             Max_Try=10, keyType=UATTree.Key_Event, hb_keyDict={}):
        # 按照传入的方向寻找Max_Try次,如果仍未聚焦到选中area,则按照传入方向的反方向 反向寻找 2*Max_Try 次
        count = 0
        Max_Try = Max_Try
        Reversecount = 0
        Reverse_Max_Try = Max_Try * 2
        while (True):
            print "count:", count
            if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                break
            # 等待聚焦效果刷新完成,稳定之后再获取相关的属性
            time.sleep(0.5)
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            focusedUIObject = self.u.getFocusedUIObject()
            focusedBounds = focusedUIObject.info['bounds']
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            try:
                destBounds = bounds
                if self.directionManageAndroid.isHasAnotherBounds(focusedBounds,destBounds):
                    print "success to focus the target:",bounds
                    return True
                else:
                    count = count + 1
                    direction = self.directionManageAndroid.getTargetDirection(focusedBounds,destBounds)
                    self.directionManageAndroid.goOneStep(self.u,direction,keyType)
            except Exception,e:
                # 出现控件出现一半的时候,获取控件信息会报错
                if count < Max_Try:
                    count = count + 1
                    self.pressKeyByType(findDirection, keyType)
                else:
                    Reversecount = Reversecount + 1
                    self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)
                # 如果界面中没有目标文字的控件出现,则按照传入的方向寻找Max_Try次;仍然未找到 则反方向寻找2*Max_Try次
            else:
                if count < Max_Try:
                    count = count + 1
                    self.pressKeyByType(findDirection, keyType)
                else:
                    Reversecount = Reversecount + 1
                    self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)

            print "执行%s 次查找,仍未找到目标焦点!!" % (str(Max_Try))
            return False

    # class&Bounds
    def toDestFocusByClassBounds_for_RecyclerView(self, className, bounds,classResourceId="", findDirection="down",
                                             Max_Try=10, keyType=UATTree.Key_Event, hb_keyDict={}):
        # 按照传入的方向寻找Max_Try次,如果仍未聚焦到选中area,则按照传入方向的反方向 反向寻找 2*Max_Try 次
        count = 0
        Max_Try = Max_Try
        Reversecount = 0
        Reverse_Max_Try = Max_Try * 2
        while (True):
            print "count:", count
            if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                break
            # 等待聚焦效果刷新完成,稳定之后再获取相关的属性
            time.sleep(0.5)
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            focusedUIObject = self.u.getFocusedUIObject()
            print "zhouyifocusedUIObject",focusedUIObject
            print "zhouyifocusedUIObject.info", focusedUIObject.info
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            destUIObject = self.u.getUiObject(className=className, bounds = bounds,resourceId=classResourceId)
            print "destUIObject",destUIObject
            try:
                destUIObjectInfo = destUIObject.info
                print "destUIObjectInfo",destUIObjectInfo
            except Exception,e:
                print "异常:",e
                # print "destUIObject.info",destUIObjectInfo
            try:
                # destBounds = destUIObject.info['bounds']
                destBounds = bounds
                print "destBounds:", destBounds
                if self.directionManageAndroid.isHasAnotherBounds(focusedBounds,destBounds):
                    print "c&b success to focus the target:",bounds
                    return True
                else:
                    count = count + 1
                    direction = self.directionManageAndroid.getTargetDirection(focusedBounds,destBounds)
                    self.directionManageAndroid.goOneStep(self.u,direction,keyType)
            except Exception,e:
                # 出现控件出现一半的时候,获取控件信息会报错
                if count < Max_Try:
                    count = count + 1
                    self.pressKeyByType(findDirection, keyType)
                else:
                    Reversecount = Reversecount + 1
                    self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)
                # 如果界面中没有目标文字的控件出现,则按照传入的方向寻找Max_Try次;仍然未找到 则反方向寻找2*Max_Try次
            else:
                if count < Max_Try:
                    count = count + 1
                    self.pressKeyByType(findDirection, keyType)
                else:
                    Reversecount = Reversecount + 1
                    self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)

            print "执行%s 次查找,仍未找到目标焦点!!" % (str(Max_Try))
            return False

        # class
        def toDestFocusByClass_for_RecyclerView(self, className, classResourceId="", findDirection="down",
                                                Max_Try=10, keyType=UATTree.Key_Event, hb_keyDict={}):
            # 按照传入的方向寻找Max_Try次,如果仍未聚焦到选中area,则按照传入方向的反方向 反向寻找 2*Max_Try 次
            count = 0
            Max_Try = Max_Try
            Reversecount = 0
            Reverse_Max_Try = Max_Try * 2
            while (True):
                print "count:", count
                if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                    break
                # 等待聚焦效果刷新完成,稳定之后再获取相关的属性
                time.sleep(0.5)
                if hb_keyDict != {}:
                    # 执行心跳按键
                    self.executeHeartBeatKey(hb_keyDict)
                focusedUIObject = self.u.getFocusedUIObject()
                print "zhouyifocusedUIObject", focusedUIObject
                print "zhouyifocusedUIObject.info", focusedUIObject.info
                if hb_keyDict != {}:
                    # 执行心跳按键
                    self.executeHeartBeatKey(hb_keyDict)
                destUIObject = self.u.getUiObject(className=className, resourceId=classResourceId)
                print "destUIObject", destUIObject
                try:
                    destUIObjectInfo = destUIObject.info
                    print "destUIObjectInfo", destUIObjectInfo
                except Exception, e:
                    print "异常:", e
                    # print "destUIObject.info",destUIObjectInfo
                try:
                    destBounds = destUIObject.info['bounds']
                    print "destBounds:", destBounds
                    if self.directionManageAndroid.isHasAnotherBounds(focusedBounds, destBounds):
                        print '成功聚焦到目标焦点:', bounds
                        return True
                    else:
                        count = count + 1
                        direction = self.directionManageAndroid.getTargetDirection(focusedBounds, destBounds)
                        self.directionManageAndroid.goOneStep(self.u, direction, keyType)
                except Exception, e:
                    # 出现控件出现一半的时候,获取控件信息会报错
                    if count < Max_Try:
                        count = count + 1
                        self.pressKeyByType(findDirection, keyType)
                    else:
                        Reversecount = Reversecount + 1
                        self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)
                    # 如果界面中没有目标文字的控件出现,则按照传入的方向寻找Max_Try次;仍然未找到 则反方向寻找2*Max_Try次
                else:
                    if count < Max_Try:
                        count = count + 1
                        self.pressKeyByType(findDirection, keyType)
                    else:
                        Reversecount = Reversecount + 1
                        self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)

                print "执行%s 次查找,仍未找到目标焦点!!" % (str(Max_Try))
                return False



    # zhouyi
    def toDestTargetByBounds_for_RecyclerView(self, bounds, chooseType, Max_Try=20,
                                              keyType=UATTree.Key_Event, findFocusCount=0, hb_keyDict={}):
        count = 0
        while (True):
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            # targetUIObject = self.u.getUiObject(bounds=bounds)
            # print "targetUIObject",targetUIObject
            # print "zhouyibounds",bounds
            # print "targetUIObject.info:", targetUIObject.info
            # destBounds = targetUIObject.info['bounds']
            destBounds = bounds
            print "目标坐标:", destBounds
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            try:
                if chooseType.lower() == "focus":
                    choosingUIObject = self.u.getFocusedUIObject()
                    objBounds = choosingUIObject.info['bounds']
                elif chooseType.lower() == "select":
                    choosingUIObject = self.u.getSelectedUIObject()
                    objBounds = choosingUIObject.info['bounds']
                print "当前坐标:", objBounds
            except Exception, e:
                print "获取焦点失败!Error:", e
                if findFocusCount < 3:
                    self.u.pressKeyTimes("down")
                    return self.toDestTargetByBounds_for_RecyclerView(bounds, chooseType,
                                                                      findFocusCount=findFocusCount + 1)
                else:
                    print "尝试%s次操作!!!仍未能找到聚焦点!!!无法聚焦到目标" % findFocusCount
                    return False
            if self.directionManageAndroid.isHasAnotherBounds(objBounds, destBounds):
                print "已聚焦至目标组件!!!"
                return True
            else:
                if count >= Max_Try:
                    print "已尝试至最大次数%s次,仍未能聚焦至目标组件!!!" % Max_Try
                    return False
                direction = self.directionManageAndroid.getTargetDirection(objBounds, destBounds)
                print "目标方位:", direction
                self.directionManageAndroid.goOneStep(self.u, direction, keyType)
                count += 1

    ''' 
                 作用:在界面中 中 focused控件中既没有包含content-des控件属性,也没有text控件属性,
                       采用单张图片模板匹配  用于聚焦目标焦点
                 参数:
                 singleImagePath:目标聚焦的单张小图片的地址
                 findDirection: 目标文字控件被隐藏时寻找的方向
                 Max_Try:最多查找次数
                 注意:
                 例子:
                 小米内销APP(既没有文字text属性也没有描述属性content-des)  聚焦到ATX APP
                 singleImagePath = "D:\\ATX_APP.jpg"
                 focusManageAndroid.toDestFocusBySingleImage_for_RecyclerView(singleImagePath)
              '''

    # 在RecyclerView 中 focused控件包含文字控件
    def toDestFocusBySingleImage_for_RecyclerView(self, singleImagePath, findDirection="down",
                                                  Max_Try=10 ,keyType = UATTree.Key_Event):
        # 按照传入的方向寻找Max_Try次,如果仍未聚焦到选中area,则按照传入方向的反方向 反向寻找 2*Max_Try 次
        count = 0
        Max_Try = Max_Try
        Reversecount = 0
        Reverse_Max_Try = Max_Try * 2
        while (True):
            print "count:", count
            if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                break
            # 等待聚焦效果刷新完成,稳定之后再获取相关的属性
            time.sleep(0.5)
            focusedUIObject = self.u.getFocusedUIObject()
            focusedBounds = focusedUIObject.info['bounds']

            srceenImgPath = os.path.join(sat_environment.getSATTmpDIR(), "SingleImage_runpath.png")
            self.ccard.takePicture(srceenImgPath)
            resultDict = self.featureDetect.matchSingleImage(srceenImgPath, [0, 0, 1920, 1080], singleImagePath)

            # destUIObject = self.u.getUiObject(description=description, resourceId=descriptionResourceId)
            if resultDict:
                try:
                    destBounds_coordinate = resultDict['coordinate']
                    # areaA = (BoundA['left'], BoundA['top'], BoundA['right'], BoundA['bottom'])
                    destBounds = {"left": destBounds_coordinate[0], "top": destBounds_coordinate[1],
                                  "right": destBounds_coordinate[2], "bottom": destBounds_coordinate[3]}
                    # print "destBounds:", destBounds
                    if self.directionManageAndroid.isHasAnotherBounds(focusedBounds, destBounds):
                        print '成功聚焦到目标焦点:', singleImagePath
                        return True
                    else:
                        count = count + 1
                    direction = self.directionManageAndroid.getTargetDirection(focusedBounds, destBounds)
                    self.directionManageAndroid.goOneStep(self.u, direction, keyType)
                except Exception, e:
                    # 出现控件出现一半的时候,获取控件信息会报错
                    if count < Max_Try:
                        count = count + 1
                        self.pressKeyByType(findDirection, keyType)
                    else:
                        Reversecount = Reversecount + 1
                        self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)
            # 如果界面中没有目标文字的控件出现,则按照传入的方向寻找Max_Try次;仍然未找到 则反方向寻找2*Max_Try次
            else:
                if count < Max_Try:
                    count = count + 1
                    self.pressKeyByType(findDirection, keyType)
                else:
                    Reversecount = Reversecount + 1
                    self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)

        print "执行%s 次查找,仍未找到目标焦点!!" % (str(Max_Try))
        return False

    ''' 
                 作用:在界面中 中 focused控件中既没有包含content-des控件属性,也没有text控件属性,
                       采用OCR识别文字  用于聚焦目标焦点
                 参数:

                 text:需要OCR识别的文字
                 textResourceId:文字区域的resourceId
                 recyclerViewResourceId:列表recyclerView的resourceId
                 ocrTextBorder:为OCR识别更准确,文字识别坐标需要扩充的边界的值(默认为10)
                 OCRDict:OCR识别文字的属性 默认为百度中英文识别
                 findDirection: 目标文字控件被隐藏时寻找的方向
                 Max_Try:最多查找次数
                 注意:
                 例子:

              '''

    # 在RecyclerView 中 focused控件包含文字控件
    def toDestFocusByOCRText_for_RecyclerView(self, text, textResourceId, recyclerViewResourceId, ocrTextBorder=10,
                                              OCRDict={"OCR_lan": "CHN_ENG", "OCR_type": 10000},
                                              findDirection="down",
                                              Max_Try=10,
                                              keyType = UATTree.Key_Event):
        # 按照传入的方向寻找Max_Try次,如果仍未聚焦到选中area,则按照传入方向的反方向 反向寻找 2*Max_Try 次
        count = 0
        Max_Try = Max_Try
        Reversecount = 0
        Reverse_Max_Try = Max_Try * 2
        while (True):
            print "count:", count
            if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                break
            # 等待聚焦效果刷新完成,稳定之后再获取相关的属性
            time.sleep(0.5)
            focusedUIObject = self.u.getFocusedUIObject()
            focusedBounds = focusedUIObject.info['bounds']
            # 寻找目标焦点坐标
            childbound = None
            recyclerViewUIObject = self.u.getUiObject(resourceId=recyclerViewResourceId)
            for i in range(recyclerViewUIObject.info["childCount"]):
                childUIObject = recyclerViewUIObject.child_by_instance(i, resourceId=textResourceId)
                try:
                    childbound = childUIObject.info["bounds"]
                    # 对扩大后的图片坐标进行边界判断
                    childbound_Area_left = childbound["left"] - 10
                    if childbound_Area_left < 0: childbound_Area_left = 0

                    childbound_Area_top = childbound["top"] - 10
                    if childbound_Area_top < 0: childbound_Area_top = 0

                    childbound_Area_right = childbound["right"] + 10
                    if childbound_Area_right > 1920: childbound_Area_right = 1920

                    childbound_Area_bottom = childbound["bottom"] - 10
                    if childbound_Area_bottom > 1080: childbound_Area_bottom = 1080

                    childbound_Area = (childbound_Area_left, childbound_Area_top,
                                       childbound_Area_right, childbound_Area_bottom)
                    # 小图保存地址
                    tmpPic = os.path.join(getSATTmpDIR(), "uiautomator_text_ocr.png")
                    # 整个界面图片保存地址
                    srceenImgPath = os.path.join(sat_environment.getSATTmpDIR(), "uiautomator_OCR_runpath.png")
                    self.u.screenshot(srceenImgPath)
                    # self.ccard.takePicture(srceenImgPath)
                    # 切割小图片
                    self.imgCMP.saveCropPic(srceenImgPath, tmpPic, (
                        childbound_Area[0], childbound_Area[1], childbound_Area[2], childbound_Area[3]))
                    # ocr 识别
                    textValueCUR = self.ocr.getStr(tmpPic, OCRDict["OCR_lan"], OCRDict["OCR_type"])
                    print "textValueCUR:", textValueCUR
                    print "destText:", text
                    if self.ocr.cmpOcrStr(textValueCUR, text):
                        break
                    else:
                        childbound = None
                except Exception:
                    childbound = None
                    pass

            if childbound:
                try:
                    destBounds = childbound
                    if self.directionManageAndroid.isHasAnotherBounds(focusedBounds, destBounds):
                        print '成功聚焦到目标焦点:', text
                        return True
                    else:
                        count = count + 1
                    direction = self.directionManageAndroid.getTargetDirection(focusedBounds, destBounds)
                    self.directionManageAndroid.goOneStep(self.u, direction, keyType)
                except Exception, e:
                    # 出现控件出现一半的时候,获取控件信息会报错
                    if count < Max_Try:
                        count = count + 1
                        self.pressKeyByType(findDirection, keyType)
                    else:
                        Reversecount = Reversecount + 1
                        self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)
            # 如果界面中没有目标文字的控件出现,则按照传入的方向寻找Max_Try次;仍然未找到 则反方向寻找2*Max_Try次
            else:
                if count < Max_Try:
                    count = count + 1
                    self.pressKeyByType(findDirection, keyType)
                else:
                    Reversecount = Reversecount + 1
                    self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)

        print "执行%s 次查找,仍未找到目标焦点!!" % (str(Max_Try))
        return False

    ''' 
                 作用:在界面中 中 focused控件中既没有包含content-des控件属性,也没有text控件属性,
                       一般这种控件是自定义控件 class类型是android.view.View
                       采用OCR识别文字  用于聚焦目标焦点
                 参数:

                 text:需要OCR识别的文字
                 visableViewResourceId:可以通过UIAutomator框架获取到的控件的id
                 initTextArea: 确定的一个区域下的文字坐标
                 initVisableViewArea:确定的一个区域下的可获取控件的坐标
                 ocrTextBorder:为OCR识别更准确,文字识别坐标需要扩充的边界的值(默认为10)
                 OCRDict:OCR识别文字的属性 默认为百度中英文识别
                 findDirection: 目标文字控件被隐藏时寻找的方向
                 Max_Try:最多查找次数
                 注意:
                 例子:小米内销APP测试
                 #文字内容
                   text = "应用商店"
                 #图标的resourceId
                   visableViewResourceId = "com.mitv.tvhome:id/di_img"
                 #非聚焦的app文字坐标
                   initTextArea = [90, 392, 229, 424]
                #非聚焦的app图片坐标
                   initVisableViewArea = [90, 257, 227, 382]

                   focusManageAndroid.toDestFocusRelativeOCRText__for_RecyclerView(text=text,
                                                                    visableViewResourceId=visableViewResourceId,
                                                                    initTextArea=initTextArea,
                                                                    initVisableViewArea=initVisableViewArea)

              '''

    # 在RecyclerView 中 focused控件包含文字控件
    def toDestFocusRelativeOCRText__for_RecyclerView(self, text, visableViewResourceId, initTextArea,
                                                     initVisableViewArea, ocrTextBorder=5,
                                                     OCRDict={"OCR_lan": "CHN_ENG", "OCR_type": 10000},
                                                     findDirection="down",
                                                     Max_Try=10,
                                                     keyType = UATTree.Key_Event):
        # 按照传入的方向寻找Max_Try次,如果仍未聚焦到选中area,则按照传入方向的反方向 反向寻找 2*Max_Try 次
        count = 0
        Max_Try = Max_Try
        Reversecount = 0
        Reverse_Max_Try = Max_Try * 2

        initTextBounds = {"left": initTextArea[0], "top": initTextArea[1], "right": initTextArea[2],
                          "bottom": initTextArea[3]}
        initvisableViewBounds = {"left": initVisableViewArea[0], "top": initVisableViewArea[1],
                                 "right": initVisableViewArea[2], "bottom": initVisableViewArea[3]}
        while (True):
            print "count:", count
            if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                break
            # 等待聚焦效果刷新完成,稳定之后再获取相关的属性
            time.sleep(0.5)
            focusedUIObject = self.u.getFocusedUIObject()
            focusedBounds = focusedUIObject.info['bounds']
            # 寻找目标焦点坐标
            childbound = None
            childCountUIObject = self.u.getUiObject(resourceId=visableViewResourceId)
            print "childCountUIObject.info", childCountUIObject.info
            childCount = childCountUIObject.count
            print "列表包含的子控件数量:", childCount
            for i in range(childCount):
                print "第%s次查找目标bounds" % (str(i))
                visableViewObject = self.u.getUiObject(instance=i, resourceId=visableViewResourceId)
                try:
                    visableViewBound = visableViewObject.info["bounds"]
                    print "initvisableViewBounds:", initvisableViewBounds
                    print "initTextBounds:", initTextBounds
                    print "visableViewBound:", visableViewBound
                    childbound = self.directionManageAndroid.getRelativeBounds(initvisableViewBounds, initTextBounds,
                                                                               visableViewBound)
                    print "childbound:", childbound
                    # return False
                    # childbound = childUIObject.info["bounds"]
                    # 对扩大后的图片坐标进行边界判断
                    childbound_Area_left = childbound["left"] - 10
                    if childbound_Area_left < 0: childbound_Area_left = 0

                    childbound_Area_top = childbound["top"] - 10
                    if childbound_Area_top < 0: childbound_Area_top = 0

                    childbound_Area_right = childbound["right"] + 10
                    if childbound_Area_right > 1920: childbound_Area_right = 1920

                    childbound_Area_bottom = childbound["bottom"] + 10
                    if childbound_Area_bottom > 1080: childbound_Area_bottom = 1080

                    childbound_Area = [childbound_Area_left, childbound_Area_top,
                                       childbound_Area_right, childbound_Area_bottom]
                    print "childbound_Area:", childbound_Area
                    # 小图保存地址
                    tmpPic = os.path.join(getSATTmpDIR(), "uiautomator_text_ocr.png")
                    # 整个界面图片保存地址
                    srceenImgPath = os.path.join(sat_environment.getSATTmpDIR(), "uiautomator_OCR_runpath.png")
                    self.u.screenshot(srceenImgPath)
                    # self.ccard.takePicture(srceenImgPath)
                    # 切割小图片
                    self.imgCMP.saveCropPic(srceenImgPath, tmpPic, (
                        childbound_Area[0], childbound_Area[1], childbound_Area[2], childbound_Area[3]))
                    # ocr 识别
                    textValueCUR = self.ocr.getStr(tmpPic, OCRDict["OCR_lan"], OCRDict["OCR_type"])
                    print "textValueCUR:", textValueCUR
                    print "destText:", text
                    if self.ocr.cmpOcrStr(textValueCUR, text):
                        break
                    else:
                        childbound = None
                except Exception, e:
                    print e
                    childbound = None
                    pass
            print "childbound:", childbound
            # return False
            if childbound:
                try:
                    destBounds = childbound
                    if self.directionManageAndroid.isHasAnotherBounds(focusedBounds, destBounds):
                        print '成功聚焦到目标焦点:', text
                        return True
                    else:
                        count = count + 1
                    direction = self.directionManageAndroid.getTargetDirection(focusedBounds, destBounds)
                    self.directionManageAndroid.goOneStep(self.u, direction, keyType)
                except Exception, e:
                    # 出现控件出现一半的时候,获取控件信息会报错
                    if count < Max_Try:
                        count = count + 1
                        self.pressKeyByType(findDirection, keyType)
                    else:
                        Reversecount = Reversecount + 1
                        self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)
            # 如果界面中没有目标文字的控件出现,则按照传入的方向寻找Max_Try次;仍然未找到 则反方向寻找2*Max_Try次
            else:
                if count < Max_Try:
                    count = count + 1
                    self.pressKeyByType(findDirection, keyType)
                else:
                    Reversecount = Reversecount + 1
                    self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)

        print "执行%s 次查找,仍未找到目标焦点!!" % (str(Max_Try))
        return False

    ''' 
            作用:在RecyclerView 中 focused控件和文字控件同级 相对位置固定  用于聚焦目标焦点
            参数:
            text:目标文字的文字内容
            textResourceId:目标文字的resourceId
            initFocusedArea:聚焦情况下的focused控件的坐标区域(x1,y1,x2,y2)
            initDestTextArea:聚焦情况下的text控件的坐标区域(x1,y1,x2,y2)
            findDirection: 目标文字控件被隐藏时寻找的方向
            Max_Try:最多查找次数
            注意:

            例子:  
            小米信源设置 的声音自定义界面 Device /Settings Sound mode /Custom/

             initFocusedArea = (822, 180, 1259, 221)
             initDestTextArea = (822, 116, 1259, 180)

            focusManageAndroid.toDestFocusRelativeText_for_RecyclerView("3500Hz: 0dB", "com.android.tv:id/title",
                                                                initFocusedArea, initDestTextArea)
         '''

    # 在RecyclerView 中 focused控件和文字控件同级
    def toDestFocusRelativeText_for_RecyclerView(self, text, textResourceId, initFocusedArea, initDestTextArea,
                                                 findDirection="down", Max_Try=10, keyType = UATTree.Key_Event):
        # 按照传入的方向寻找Max_Try次,如果仍未聚焦到选中area,则按照传入方向的反方向 反向寻找 2*Max_Try 次
        count = 0
        Max_Try = Max_Try
        Reversecount = 0
        Reverse_Max_Try = Max_Try * 2
        while (True):
            if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                break
            # 等待聚焦效果刷新完成,稳定之后再获取相关的属性
            time.sleep(0.5)
            focusedUIObject = self.u.getFocusedUIObject()
            focusedBounds = focusedUIObject.info['bounds']
            # print "focusedBounds:",focusedBounds

            destUIObject = self.u.getUiObject(text=text, resourceId=textResourceId)
            if destUIObject:
                try:
                    destBounds = destUIObject.info['bounds']
                    # print "destBounds:", destBounds
                    if self.directionManageAndroid.isRelativePositionBounds(initFocusedArea, initDestTextArea,
                                                                            focusedBounds,
                                                                            destBounds):
                        print '成功聚焦到目标焦点:', text
                        return True
                    else:
                        count = count + 1
                    direction = self.directionManageAndroid.getTargetDirection(focusedBounds, destBounds)
                    self.directionManageAndroid.goOneStep(self.u, direction, keyType)
                except Exception:
                    # 出现控件出现一半的时候,获取控件信息会报错
                    if count < Max_Try:
                        count = count + 1
                        self.pressKeyByType(findDirection, keyType)
                    else:
                        Reversecount = Reversecount + 1
                        self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)
            # 如果界面中没有目标文字的控件出现,则按照传入的方向寻找Max_Try次;仍然未找到 则反方向寻找2*Max_Try次
            else:
                if count < Max_Try:
                    count = count + 1
                    self.pressKeyByType(findDirection, keyType)
                else:
                    Reversecount = Reversecount + 1
                    self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)

        print "执行%s 次查找,仍未找到目标焦点!!" % (str(Max_Try))
        return False

    ''' 
            作用:聚焦效果View控件 包含 目标文本控件  用于聚焦目标焦点
            参数:
            text:目标文字的文字内容
            textResourceId:目标文字的resourceId
            FocusViewResourceId:聚焦效果View的resourceId
            findDirection: 目标文字控件被隐藏时寻找的方向
            Max_Try:最多查找次数
            注意:
            例子:
            小米USB界面上方Tab聚焦方法
            focusManageAndroid.toDestFocusByText_for_FocusView("Devices", "com.xiaomi.mitv.mediaexplorer:id/dev",
                                                           "com.xiaomi.mitv.mediaexplorer:id/tab_cursor",
                                                           findDirection="right",
                                                           Max_Try=5)
         '''

    # 聚焦效果View控件 包含 目标文本控件
    def toDestFocusByText_for_FocusView(self, text, FocusViewResourceId='', FocusViewClass='',FocusViewDesc='',findDirection="down",
                                        Max_Try=10, keyType = UATTree.Key_Event, hb_keyDict={}):
        # 按照传入的方向寻找Max_Try次,如果仍未聚焦到选中area,则按照传入方向的反方向 反向寻找 2*Max_Try 次
        count = 0
        Max_Try = Max_Try
        Reversecount = 0
        Reverse_Max_Try = Max_Try * 2
        while (True):
            if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                break
            # 等待聚焦效果刷新完成,稳定之后再获取相关的属性
            time.sleep(0.5)
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            if FocusViewResourceId is not '':
                focusedUIObject = self.u.getUiObject(resourceId=FocusViewResourceId)
            else:
                focusedUIObject = self.u.getUiObject(description=FocusViewDesc,className=FocusViewClass)

            focusedBounds = focusedUIObject.info['bounds']
            print "focusedBounds:", focusedBounds
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            destUIObject = self.u.getUiObject(text=text)
            if destUIObject:
                try:
                    destBounds = destUIObject.info['bounds']
                    print "destBounds:", destBounds
                    if self.directionManageAndroid.isHasAnotherBounds(focusedBounds, destBounds):
                        print '成功聚焦到目标焦点:', text
                        return True
                    else:
                        count = count + 1
                    direction = self.directionManageAndroid.getTargetDirection(focusedBounds, destBounds)
                    self.directionManageAndroid.goOneStep(self.u, direction, keyType)
                except Exception:
                    # 出现控件出现一半的时候,获取控件信息会报错
                    if count < Max_Try:
                        count = count + 1
                        self.pressKeyByType(findDirection, keyType)
                    else:
                        Reversecount = Reversecount + 1
                        self.pressKeyByType(self.ReverseDirctionDict[findDirection] ,keyType)
            # 如果界面中没有目标文字的控件出现,则按照传入的方向寻找Max_Try次;仍然未找到 则反方向寻找2*Max_Try次
            else:
                if count < Max_Try:
                    count = count + 1
                    self.pressKeyByType(findDirection, keyType)
                else:
                    Reversecount = Reversecount + 1
                    self.pressKeyByType(self.ReverseDirctionDict[findDirection] ,keyType)

        print "执行%s 次查找,仍未找到目标焦点!!" % (str(Max_Try))
        return False

    '''
                   作用:RecyclerView 中焦点没有focused属性  只是子项中的View有放大效果
                   参数:
                   text:目标文字的文字内容
                   textResourceId:目标文字的resourceId
                   zoomViewResourceId:f放大效果View的resourceId
                   recyclerViewResourceId:列表recyclerView 的resourceId
                   findDirection: 目标文字控件被隐藏时寻找的方向
                   Max_Try:最多查找次数
                   注意:
                   例子:
                   小米USB Images 浏览界面
                   focusManageAndroid.toDestZoomByText_for_RecyclerView("Pattern", "com.xiaomi.mitv.mediaexplorer:id/album_item_name",
                                                              "com.xiaomi.mitv.mediaexplorer:id/album_item_bg",
                                                              "com.xiaomi.mitv.mediaexplorer:id/all_albums_view")
                '''

    # RecyclerView 中焦点没有focused属性  只是子项中的View有放大效果
    def toDestZoomByText_for_RecyclerView(self, text, textResourceId, zoomViewResourceId, recyclerViewResourceId,
                                          findDirection="down",
                                          Max_Try=20,
                                          keyType=UATTree.Key_Event):
        # 按照传入的方向寻找Max_Try次,如果仍未聚焦到选中area,则按照传入方向的反方向 反向寻找 2*Max_Try 次
        count = 0
        Max_Try = Max_Try
        Reversecount = 0
        Reverse_Max_Try = Max_Try * 2

        while (True):
            if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                break
            # 等待聚焦效果刷新完成,稳定之后再获取相关的属性
            time.sleep(0.5)
            # focusedUIObject = self.u.getUiObject(resourceId=FocusViewResourceId)
            # focusedBounds = focusedUIObject.info['bounds']
            # print "focusedBounds:", focusedBounds
            destUIObject = self.u.getUiObject(text=text, resourceId=textResourceId)
            if destUIObject:
                try:
                    # 获取目标文本的bounds
                    destBounds = destUIObject.info['bounds']
                    # print "destBounds:", destBounds

                    zoomUiObject = self.u.getUiObject(resourceId=recyclerViewResourceId)
                    # print "uiObject.info: ", uiObject.info
                    childCount = zoomUiObject.info['childCount']

                    zoomBound = {u'top': 0, u'left': 0, u'right': 0, u'bottom': 0}
                    zoomIndex = -1

                    for i in range(childCount):
                        childObject = zoomUiObject.child_by_instance(i, resourceId=zoomViewResourceId)
                        # print "childObject.info:", childObject.info
                        childounds = childObject.info['bounds']
                        # print "child:", str(i), "bounds:", childounds
                        if self.directionManageAndroid.isBiggerBound(childounds, zoomBound):
                            zoomBound = childounds
                            zoomIndex = i
                            zoomTextBound = zoomUiObject.child_by_instance(i, resourceId=textResourceId).info[
                                "bounds"]
                            zoomText = zoomUiObject.child_by_instance(i, resourceId=textResourceId).info["text"]

                    # print zoomBound, zoomIndex, zoomTextBound, zoomText
                    print "toDestZoomByText_for_RecyclerView 当前聚焦文字:", zoomText
                    if str(zoomText) == str(text):
                        print '成功聚焦到目标焦点:', text
                        return True
                    # if self.directionManageAndroid.isHasAnotherBounds(focusedBounds, destBounds):
                    #     print '成功聚焦到目标焦点:', text
                    #     return True
                    else:
                        count = count + 1
                    direction = self.directionManageAndroid.getTargetDirection(zoomTextBound, destBounds)
                    self.directionManageAndroid.goOneStep(self.u, direction, keyType)
                except Exception:
                    # 出现控件出现一半的时候,获取控件信息会报错
                    if count < Max_Try:
                        count = count + 1
                        self.pressKeyByType(findDirection, keyType)
                    else:
                        Reversecount = Reversecount + 1
                        self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)
            # 如果界面中没有目标文字的控件出现,则按照传入的方向寻找Max_Try次;仍然未找到 则反方向寻找2*Max_Try次
            else:
                if count < Max_Try:
                    count = count + 1
                    self.pressKeyByType(findDirection, keyType)
                else:
                    Reversecount = Reversecount + 1
                    self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)

        print "执行%s 次查找,仍未找到目标焦点!!" % (str(Max_Try))
        return False

    ''' 
                   作用:获取RecyclerView 中所有文字名称的列表
                   参数:

                   recyclerViewResourceId:列表recyclerView 的resourceId
                   textResourceId:item中文本区域的的resourceId
                   findDirection: 目标文字控件被隐藏时寻找的方向
                   Max_Try:最多查看次数,执行Max_Try 次findDirection 后 仍无新控件被刷出 则返回所有文件的列表
                   name_list:最终返回的列表
                   注意:
                   例子:
                   小米USB Music 浏览界面 获取所有的音乐文件
                    recyclerViewResourceId = "com.xiaomi.mitv.mediaexplorer:id/all_music_view"
                    textResourceId = "com.xiaomi.mitv.mediaexplorer:id/item_title"
                    recyclerViewItemNameList = focusManageAndroid.getRecyclerViewItemNameList(recyclerViewResourceId,textResourceId)
                    print "recyclerViewItemNameList:", recyclerViewItemNameList

                '''

    def getRecyclerViewItemNameList(self, recyclerViewResourceId, textResourceId, findDirection="down",
                                    Max_Try=10, name_list=[], keyType = UATTree.Key_Event):
        count = 0
        isNOTChange = False
        old_name_list = name_list

        while (True):
            if count > Max_Try and isNOTChange:
                return name_list
                break
            # 等待聚焦效果刷新完成,稳定之后再获取相关的属性
            time.sleep(0.5)
            recyclerViewUIObject = self.u.getUiObject(resourceId=recyclerViewResourceId)
            for i in range(recyclerViewUIObject.info["childCount"]):
                childUIObject = recyclerViewUIObject.child_by_instance(i, resourceId=textResourceId)
                try:
                    childText = childUIObject.info["text"]
                    if childText not in name_list:
                        name_list.append(childUIObject.info["text"])
                except Exception:
                    pass
            if old_name_list == name_list:
                isNOTChange = True
                count = count + 1
                self.pressKeyByType(findDirection, keyType)

            else:
                isNOTChange = False
                self.pressKeyByType(findDirection, keyType)
                self.getRecyclerViewItemNameList(recyclerViewResourceId, textResourceId, findDirection,
                                                 Max_Try, name_list)

    '''
                      作用:获取RecyclerView 中所有文字名称的列表
                      参数:
                      keyText:寻找目标Text的key的Text
                      keyResourceId:寻找目标Text的key的resourceId
                      recyclerViewResourceId:列表recyclerView 的resourceId
                      textResourceId:目标text的中文本区域的的resourceId
                      findDirection: 目标文字控件被隐藏时寻找的方向
                      Max_Try:最多查看次数,执行Max_Try 次findDirection 后 仍无新控件被刷出 则返回""
                      注意:
                      例子:
                      小米USB Music 音乐播放界面 通过音乐名称获取音乐时长
                       keyResourceId = "com.xiaomi.mimusic2:id/item_textview"
                       recyclerViewResourceId = "com.xiaomi.mimusic2:id/music_list_view"
                       textResourceId = "com.xiaomi.mimusic2:id/music_list_item_duration"
                       findText = focusManageAndroid.getRecyclerViewItemTextByKeyText("鸭子", keyResourceId,
                                                                                   recyclerViewResourceId,
                                                                                   textResourceId)
                       print "findText:", findText

                   '''

    def getRecyclerViewItemTextByKeyText(self, keyText, keyResourceId, recyclerViewResourceId, textResourceId,
                                         findDirection="down",
                                         Max_Try=20,
                                         keyType = UATTree.Key_Event):
        count = 0
        Reversecount = 0
        Reverse_Max_Try = Max_Try * 2

        while (True):
            if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                break
            # 等待聚焦效果刷新完成,稳定之后再获取相关的属性
            time.sleep(0.5)
            recyclerViewUIObject = self.u.getUiObject(resourceId=recyclerViewResourceId)
            iCounnt = -1
            findText = ""
            print "recyclerViewUIObject.info:", recyclerViewUIObject.info
            for i in range(recyclerViewUIObject.info["childCount"]):
                print "i:", i
                try:
                    childUIObject = recyclerViewUIObject.child_by_instance(i, resourceId=keyResourceId)
                    if str(childUIObject.info["text"]) == str(keyText):
                        iCounnt = i
                        findUIObject = recyclerViewUIObject.child_by_instance(i, resourceId=textResourceId)
                        findText = findUIObject.info["text"]
                        return str(findText)
                except Exception:
                    iCounnt = -1
                    pass
            if iCounnt == -1:
                if count < Max_Try:
                    count = count + 1
                    self.pressKeyByType(findDirection, keyType)
                else:
                    Reversecount = Reversecount + 1
                    self.pressKeyByType(self.ReverseDirctionDict[findDirection], keyType)
        print "执行%s 次查找,仍未找到keyText:%s!!" % (str(Max_Try), str(keyText))
        return ""


    def focusFirstItemFromRecyclerView(self, recyclerView_resId, child_class, Max_Try=20, keyType = UATTree.Key_Event):
        return self.focusItemByIndexFromRecyclerView(recyclerView_resId, child_class, 0, Max_Try, keyType)

    def focusItemByIndexFromRecyclerView(self, recyclerView_resId, child_class, target_index, Max_Try=20,
                                         keyType = UATTree.Key_Event, hb_keyDict={}):
        count = 0
        recyclerView = self.u.getUiObject(resourceId=recyclerView_resId)
        while(True):
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            firstItemUIObject = recyclerView.child_by_instance(target_index, className = child_class)
            print "firstItemUIObject.info:", firstItemUIObject.info
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            destBounds = firstItemUIObject.info['bounds']
            print "目标坐标:", destBounds
            focusedUIObject = self.u.getFocusedUIObject()
            focusedBounds = focusedUIObject.info['bounds']
            print "当前坐标:",focusedBounds
            if self.directionManageAndroid.isHasAnotherBounds(focusedBounds, destBounds):
                print "已将焦点归位至第一位!!!"
                return True
            else:
                if count >= Max_Try:
                    print "已尝试至最大次数%s次,仍未能使焦点归位至第一位!!!"%Max_Try
                    return False
                direction = self.directionManageAndroid.getTargetDirection(focusedBounds, destBounds)
                print "目标方位:",direction
                self.directionManageAndroid.goOneStep(self.u, direction, keyType)
                count += 1

    def focusTargetSeekBar(self, target_resId, chooseType, Max_Try=20, keyType = UATTree.Key_Event, findFocusCount = 0):
        count = 0
        while(True):
            targetUIObject = self.u.getUiObject(resourceId=target_resId)
            print "targetUIObject.info:", targetUIObject.info
            destBounds = targetUIObject.info['bounds']
            print "目标坐标:", destBounds
            try:
                if chooseType.lower() == "focus":
                    choosingUIObject = self.u.getFocusedUIObject()
                    objBounds = choosingUIObject.info['bounds']
                elif chooseType.lower() == "select":
                    choosingUIObject = self.u.getSelectedUIObject()
                    objBounds = choosingUIObject.info['bounds']
                print "当前坐标:",objBounds
            except Exception,e:
                print "获取焦点失败!Error:",e
                if findFocusCount < 3:
                    self.u.pressKeyTimes("down")
                    return self.focusTargetSeekBar(target_resId, chooseType, findFocusCount = findFocusCount + 1)
                else:
                    print "尝试%s次操作!!!仍未能找到聚焦点!!!无法聚焦到目标"%findFocusCount
                    return False
            if self.directionManageAndroid.isHasAnotherBounds(objBounds, destBounds):
                print "已聚焦至目标seekbar!!!"
                return True
            else:
                if count >= Max_Try:
                    print "已尝试至最大次数%s次,仍未能聚焦至目标seekbar!!!"%Max_Try
                    return False
                direction = self.directionManageAndroid.getTargetDirection(objBounds, destBounds)
                print "目标方位:",direction
                self.directionManageAndroid.goOneStep(self.u, direction, keyType)
                count += 1

    def toDestTargetByResourceId_for_RecyclerView(self, resourceId, chooseType, Max_Try=20,
                                                  keyType = UATTree.Key_Event, findFocusCount = 0, hb_keyDict={}):
        count = 0
        while(True):
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            targetUIObject = self.u.getUiObject(resourceId=resourceId)
            print "targetUIObject.info:", targetUIObject.info
            destBounds = targetUIObject.info['bounds']
            print "目标坐标:", destBounds
            if hb_keyDict != {}:
                # 执行心跳按键
                self.executeHeartBeatKey(hb_keyDict)
            try:
                if chooseType.lower() == "focus":
                    choosingUIObject = self.u.getFocusedUIObject()
                    objBounds = choosingUIObject.info['bounds']
                elif chooseType.lower() == "select":
                    choosingUIObject = self.u.getSelectedUIObject()
                    objBounds = choosingUIObject.info['bounds']
                print "当前坐标:",objBounds
            except Exception,e:
                print "获取焦点失败!Error:",e
                if findFocusCount < 3:
                    self.u.pressKeyTimes("down")
                    return self.toDestTargetByResourceId_for_RecyclerView(resourceId, chooseType, findFocusCount = findFocusCount + 1)
                else:
                    print "尝试%s次操作!!!仍未能找到聚焦点!!!无法聚焦到目标"%findFocusCount
                    return False
            if self.directionManageAndroid.isHasAnotherBounds(objBounds, destBounds):
                print "已聚焦至目标组件!!!"
                return True
            else:
                if count >= Max_Try:
                    print "已尝试至最大次数%s次,仍未能聚焦至目标组件!!!"%Max_Try
                    return False
                direction = self.directionManageAndroid.getTargetDirection(objBounds, destBounds)
                print "目标方位:",direction
                self.directionManageAndroid.goOneStep(self.u, direction, keyType)
                count += 1


    def pressKeyByType(self, keyName, keyType = UATTree.Key_Event, times = 1, duration = 1.0):
        print "pressKeyByType:",keyName,keyType
        if keyType == UATTree.Key_Event:
            return self.u.pressKeyTimes(keyName, times, duration)
        elif keyType == UATTree.Key_IR:
            return self.remote.sendKey(keyName, times, duration)
        else:
            return False

    '''
    执行心跳按键的函数。传入UATree里parent['others']['heartbeat_key']中的参数,会根据参数的配置执行心跳按键
    '''
    def executeHeartBeatKey(self, hb_keyDict):
        try:
            eventList = hb_keyDict["event"]
            irList = hb_keyDict["ir"]
            if eventList.__len__() > 0:
                LoggingUtil.printLog("Executing heartbeat_key by EventKey!!!KeyList:%s" % eventList)
                for key in eventList:
                    self.u.pressKeyTimes(key)
            elif irList.__len__() > 0:
                LoggingUtil.printLog("Executing heartbeat_key by irKey!!!KeyList:%s" % irList)
                for key in irList:
                    self.remote.sendKey(key)
        except Exception,e:
            LoggingUtil.printLog(u"[executeHeartBeatKey]: 心跳按键配置异常,无法正常执行心跳按键。\n %s"%e)


if __name__ == "__main__":
    u = PyUIAutomator()
    dm = DirectionManageAndroid()
    fm = FocusManageAndroid(u, dm)
    fm.toDestFocusByText_with_FocuseResourceId(text="Picture", focuseResId="com.mediatek.wwtv.tvcenter:id/menu_item_frame")
    # directionMange = DirectionManageAndroid()
    # focusManage = FocusManageAndroid(u, directionMange)
    # focusObj = focusManage.u.getFocusedUIObject()
    # print "focusObj.info:",focusObj.info
    # childCount = focusObj.info["childCount"]
    # for i in range(childCount):
    #     childUI = focusObj.child_by_instance(i, className = "android.widget.TextView")
    #     print childUI.info["text"]

        # focusManage.toDestFocusByText_for_RecyclerView(text="Picture mode",textResourceId="",
    #                                                findDirection="down")
    # focusManage.focusTargetSeekBar("com.android.tv.settings:id/seekbar_freq_300")
    # recyclerViewUIObject = u.getUiObject(resourceId="com.xiaomi.mitv.mediaexplorer:id/photo_list")
    # print "recyclerViewUIObject.info", recyclerViewUIObject.info
    # for i in range(recyclerViewUIObject.info["childCount"]):
    #     childUI = recyclerViewUIObject.child_by_instance(i)
    #     print "cound %s child.info:"%i, childUI.info

    # focusManage.focusFirstItemFromRecyclerView(recyclerViewUIObject, child_class="android.widget.LinearLayout")

    # focusedUIObject = pyui.getFocusedUIObject()
    # print 'focusedUIObject:', focusedUIObject
    # if focusedUIObject:
    #     print focusedUIObject.info