5454 and touches it at M{(x+OFFSET, y+OFFSET)} '''
5555
5656USE_MONKEYRUNNER_TO_GET_BUILD_PROPERTIES = True
57-
58- USE_UI_AUTOMATOR = False
57+ ''' Use monkeyrunner (C{MonkeyDevice.getProperty()}) to obtain the needed properties. If this is
58+ C{ False} then C{adb shell getprop} is used '''
5959
6060SKIP_CERTAIN_CLASSES_IN_GET_XY_ENABLED = False
6161''' Skips some classes related with the Action Bar and the PhoneWindow$DecorView in the
6767
6868# some constants for the attributes
6969ID_PROPERTY = 'mID'
70+ ID_PROPERTY_UI_AUTOMATOR = 'uniqueId'
7071TEXT_PROPERTY = 'text:mText'
7172TEXT_PROPERTY_API_10 = 'mText'
73+ TEXT_PROPERTY_UI_AUTOMATOR = 'text'
7274WS = "\xfe " # the whitespace replacement char for TEXT_PROPERTY
7375GET_VISIBILITY_PROPERTY = 'getVisibility()'
7476LAYOUT_TOP_MARGIN_PROPERTY = 'layout:layout_topMargin'
@@ -214,7 +216,29 @@ def __init__(self, map, device, version=-1):
214216 self .build [VERSION_SDK_PROPERTY ] = int (device .shell ('getprop ro.build.' + VERSION_SDK_PROPERTY )[:- 2 ])
215217 except :
216218 self .build [VERSION_SDK_PROPERTY ] = - 1
217-
219+
220+ version = self .build [VERSION_SDK_PROPERTY ]
221+ self .useUiAutomator = (version >= 16 )
222+ ''' Whether to use UIAutomator or ViewServer '''
223+ self .idProperty = None
224+ ''' The id property depending on the View attribute format '''
225+ self .textProperty = None
226+ ''' The text property depending on the View attribute format '''
227+ if version >= 16 :
228+ self .idProperty = ID_PROPERTY_UI_AUTOMATOR
229+ self .textProperty = TEXT_PROPERTY_UI_AUTOMATOR
230+ elif version > 10 and version < 16 :
231+ self .idProperty = ID_PROPERTY
232+ self .textProperty = TEXT_PROPERTY
233+ elif version > 0 and version <= 10 :
234+ self .idProperty = ID_PROPERTY
235+ self .textProperty = TEXT_PROPERTY_API_10
236+ elif version == - 1 :
237+ self .idProperty = ID_PROPERTY
238+ self .textProperty = TEXT_PROPERTY
239+ else :
240+ self .idProperty = ID_PROPERTY
241+ self .textProperty = TEXT_PROPERTY
218242
219243 def __getitem__ (self , key ):
220244 return self .map [key ]
@@ -287,7 +311,7 @@ def getId(self):
287311 '''
288312
289313 try :
290- return self .map [ID_PROPERTY ]
314+ return self .map [self . idProperty ]
291315 except :
292316 return None
293317
@@ -312,12 +336,12 @@ def getText(self):
312336 '''
313337
314338 try :
315- return self .map [TEXT_PROPERTY ]
339+ return self .map [self . textProperty ]
316340 except Exception :
317341 return None
318342
319343 def getHeight (self ):
320- if USE_UI_AUTOMATOR :
344+ if self . useUiAutomator :
321345 return self .map ['bounds' ][1 ][1 ] - self .map ['bounds' ][0 ][1 ]
322346 else :
323347 try :
@@ -326,7 +350,7 @@ def getHeight(self):
326350 return 0
327351
328352 def getWidth (self ):
329- if USE_UI_AUTOMATOR :
353+ if self . useUiAutomator :
330354 return self .map ['bounds' ][1 ][0 ] - self .map ['bounds' ][0 ][0 ]
331355 else :
332356 try :
@@ -372,7 +396,7 @@ def getX(self):
372396 print >> sys .stderr , "getX(%s %s ## %s)" % (self .getClass (), self .getId (), self .getUniqueId ())
373397 x = 0
374398
375- if USE_UI_AUTOMATOR :
399+ if self . useUiAutomator :
376400 x = self .map ['bounds' ][0 ][0 ]
377401 else :
378402 try :
@@ -394,7 +418,7 @@ def getY(self):
394418 print >> sys .stderr , "getY(%s %s ## %s)" % (self .getClass (), self .getId (), self .getUniqueId ())
395419 y = 0
396420
397- if USE_UI_AUTOMATOR :
421+ if self . useUiAutomator :
398422 y = self .map ['bounds' ][0 ][1 ]
399423 else :
400424 try :
@@ -424,7 +448,7 @@ def getXY(self):
424448 hx = 0
425449 hy = 0
426450
427- if not USE_UI_AUTOMATOR :
451+ if not self . useUiAutomator :
428452 while parent != None :
429453 if DEBUG_COORDS : print >> sys .stderr , " getXY: parent: %s %s <<<<" % (parent .getClass (), parent .getId ())
430454 if SKIP_CERTAIN_CLASSES_IN_GET_XY_ENABLED :
@@ -879,18 +903,10 @@ def __init__(self, device, serialno, adb=None, autodump=True, localport=VIEW_SER
879903 # we expect it to be an int
880904 self .build [prop ] = int (self .build [prop ] if self .build [prop ] else - 1 )
881905
882- if self .build [VERSION_SDK_PROPERTY ] > 0 and self .build [VERSION_SDK_PROPERTY ] <= 10 : # gingerbread 2.3.3
883- global TEXT_PROPERTY
884- TEXT_PROPERTY = TEXT_PROPERTY_API_10
885- elif self .build [VERSION_SDK_PROPERTY ] >= 16 : # jelly bean 4.1 & 4.2
886- global USE_UI_AUTOMATOR
887- global TEXT_PROPERTY
888- global ID_PROPERTY
889- USE_UI_AUTOMATOR = True
890- TEXT_PROPERTY = 'text'
891- ID_PROPERTY = 'uniqueId'
892-
893- if not USE_UI_AUTOMATOR :
906+ self .useUiAutomator = (self .build [VERSION_SDK_PROPERTY ] >= 16 ) # jelly bean 4.1 & 4.2
907+ ''' If UIAutomator is supported by the device it will be used '''
908+
909+ if not self .useUiAutomator :
894910 if startviewserver :
895911 if not self .serviceResponse (device .shell ('service call window 3' )):
896912 try :
@@ -1217,6 +1233,8 @@ def __splitAttrs(self, strArgs, addViewToViewsById=False):
12171233 @return: Returns the attributes map.
12181234 '''
12191235
1236+ if self .useUiAutomator :
1237+ raise RuntimeError ("This method is not compatible with UIAutomator" )
12201238 # replace the spaces in text:mText to preserve them in later split
12211239 # they are translated back after the attribute matches
12221240 textRE = re .compile ('%s=%s,' % (TEXT_PROPERTY , __nd ('len' )))
@@ -1398,12 +1416,15 @@ def dump(self, windowId=-1, sleep=1):
13981416 if sleep > 0 :
13991417 MonkeyRunner .sleep (sleep )
14001418
1401- if USE_UI_AUTOMATOR :
1402- if not re .search ('dumped' , self .device .shell ('uiautomator dump /mnt/sdcard/window_dump.xml' )):
1419+ if self .useUiAutomator :
1420+ windowDump = '/mnt/sdcard/window_dump.xml'
1421+ if not re .search ('dumped' , self .device .shell ('uiautomator dump %s' % windowDump )):
14031422 raise RuntimeError ('ERROR: Getting UIAutomator dump' )
1404- received = self .device .shell ('cat /mnt/sdcard/window_dump.xml' )
1423+ received = self .device .shell ('cat %s 2>/dev/null' % windowDump )
14051424 if received :
14061425 received = received .encode ('ascii' , 'ignore' )
1426+ else :
1427+ raise RuntimeError ("ERROR: Received empty UIAutomator dump" )
14071428 if DEBUG :
14081429 self .received = received
14091430 if DEBUG_RECEIVED :
0 commit comments