From d01f338a1d995c70527b189a7c3597aaf370b5e0 Mon Sep 17 00:00:00 2001 From: James Hartley Date: Thu, 28 Apr 2016 13:00:02 +0100 Subject: [PATCH] Add UxPerfUiAutomation class This extends on BaseUiAutomation to include Ux performance instrumentation and UiAutomation convenience classes. Todo - extend the create workload infrastructure to allow you to create a new UxPerfUiAutomation workload. --- .../common/android/UxPerfUiAutomation$1.class | Bin 0 -> 917 bytes .../UxPerfUiAutomation$Direction.class | Bin 0 -> 1345 bytes .../UxPerfUiAutomation$GestureType.class | Bin 0 -> 1287 bytes .../UxPerfUiAutomation$PinchType.class | Bin 0 -> 1249 bytes .../android/UxPerfUiAutomation$Timer.class | Bin 0 -> 1118 bytes .../common/android/UxPerfUiAutomation.class | Bin 0 -> 7329 bytes .../arm/wlauto/uiauto/UxPerfUiAutomation.java | 212 ++++++++++++++++++ 7 files changed, 212 insertions(+) create mode 100644 wlauto/common/android/UxPerfUiAutomation$1.class create mode 100644 wlauto/common/android/UxPerfUiAutomation$Direction.class create mode 100644 wlauto/common/android/UxPerfUiAutomation$GestureType.class create mode 100644 wlauto/common/android/UxPerfUiAutomation$PinchType.class create mode 100644 wlauto/common/android/UxPerfUiAutomation$Timer.class create mode 100644 wlauto/common/android/UxPerfUiAutomation.class create mode 100644 wlauto/external/uiauto/src/com/arm/wlauto/uiauto/UxPerfUiAutomation.java diff --git a/wlauto/common/android/UxPerfUiAutomation$1.class b/wlauto/common/android/UxPerfUiAutomation$1.class new file mode 100644 index 0000000000000000000000000000000000000000..30a97eb30059b5f6db3ceb092e8f0bd180bd0c40 GIT binary patch literal 917 zcmbVKO>fgc5Ph3CaS{v-p|olFD%7+|fSOc%9QY7bn?Qt{M5HN)o;HqYwsO2^6Sw>o z4xBjy5<&>|2k@g1vo2C9^-?N%-^dYhKGMCa!96 zO~Z8!H#97mxM^aM;hEhz5Myt!$=}@L?8*C9_V_-hXtmG_Rp7no?3(xToD#G&maWqry<3;vFj9IV#>cD&9Gnj9q208e!Sl$;VK6pYZ<|DJt-i&OdeeCMir8p&T{pi#vw4nYmF0`NW7sY2qrY6!PnV!fDNpm8zBr~!6f)uitrs+?ih(#QRqe?~jc*F$`(W7#oF^#LS?;T zSq$35_JUPewi#w$bw;lqa4!<_<}%q1DU`+FwZqV3xxTX=HFlhEi|=@}qDk(JU53?+ zwZ{*5-s65fZ#P5NuNSkO2~Jr-jeFZXbVZSqN{Y`LR4{e13WHj5eYZK!F!&b{YuRmT zX7i0p9Z1@4-RI3HB&K*q1oTqPJK4O_M!oDujZ!D-=jlETJBY%Xv*L;l4PCtaDbXks zSHwJynkeC^1`aOvz`#Ib0?YF^-zw1G^v z?Z_KDdo4(3-qE=^gPvaTF3?nNx4K4FOl?1q$2>m zBcfZhLqQT(aSaUD$-6-)KBEQp39)0uKaj^TMpl)vNy;CWc_M!XF}Z4_l-y?|j-iPB z*tz_hv||3w!US%~IQ5sZ1VaIF`T;FBIeG;3qYRIc{ZsC2yM~OAj;zedLB}L=L@a3D z(?P^n{|cp=(&9(Z50R9Pp-87oI%YyT-O{?i+)H3o*jxf*!roW$fMKXsdQz;H3dNV^^HQbAF!0Q32cd6O-@maK^pfjZe!=1G zw$)}>E;qfF!Tpx;*5P5`8KEsr?Onz4_iFYA?X`Gddv3ZXOZ3q ze83O6;c$1~FazIq_w(6)MW@PMlRI_p+k&RcrMSFBl&SMP4DnUlwSzT=@qfrDW$O$| z@Y<#>Bu#tY<>C$*q8SlLtTvtQ;mw}ZMK^4%_NRZ1?o>0q&~I8#ZPBHP^CPeznx*5S zn8|S+i&#>z%&^$c2UlkF*XXZOHr z1|&Q4zx)hKy`7eiAm5Ym?*yC`kYCTy>l&h`sjN>5u>e`pD=kR|My5np1OiD+;1U=n z$-6;Td|C(W6Cx*wejtxwiq^P{%@ckaGhO^5B63$tDYKsuJAoqbku&(qw4?t<;R>$G zICYUwf-#3E{eU_DPuXH40 zG#Wnpqm1WX7ubRybZv4^&N}D0~JLbbC}nV)3Bgp1dHM@(-_ss zX$r)%G{%K2r7~iDpk?x~Wxn%x z90g|VN>P8m?}UeScY|y#9=U;^zYJ1lQ1G>sthZy2Md=viq2wVC9?y*ToH=`TI@@B7rLb)y0I4|pt9 zJ!%?C9D}J;#|+MkFck5w&yz$@yFK&hh9)50rnZEk*i>SQWC%m~P^3NOlx~wx6>4;7 zf5{QU9Oci(X4$>2WJ3*`hIwzLnkYC=vf(R$HSVko+yp=H%-}Yz&vj z9M56uZ}ptRaNQHqctUsKADQzs3V29_kBDS@g0wy+y@HjIFptJ7VWuMbLP>%4nVSUc qOn}WX`07-!aTfe^D)`z|uz42TnF220y4H7t90wgK{T9$f9qbRQY0psr literal 0 HcmV?d00001 diff --git a/wlauto/common/android/UxPerfUiAutomation.class b/wlauto/common/android/UxPerfUiAutomation.class new file mode 100644 index 0000000000000000000000000000000000000000..ccd5d115010d2109b8ad40226b9be8d7af68f284 GIT binary patch literal 7329 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 CICJ^{ literal 0 HcmV?d00001 diff --git a/wlauto/external/uiauto/src/com/arm/wlauto/uiauto/UxPerfUiAutomation.java b/wlauto/external/uiauto/src/com/arm/wlauto/uiauto/UxPerfUiAutomation.java new file mode 100644 index 00000000..756d0ea0 --- /dev/null +++ b/wlauto/external/uiauto/src/com/arm/wlauto/uiauto/UxPerfUiAutomation.java @@ -0,0 +1,212 @@ +/* Copyright 2013-2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package com.arm.wlauto.uiauto; + +import android.os.Build; +import android.os.SystemClock; + +import com.android.uiautomator.core.UiObject; +import com.android.uiautomator.core.UiObjectNotFoundException; +import com.android.uiautomator.core.UiScrollable; +import com.android.uiautomator.core.UiSelector; + +import com.arm.wlauto.uiauto.BaseUiAutomation; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileWriter; +import java.io.InputStreamReader; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.Arrays; +import java.util.List; + +public class UxPerfUiAutomation extends BaseUiAutomation { + + private Logger logger = Logger.getLogger(UxPerfUiAutomation.class.getName()); + public long timeout = TimeUnit.SECONDS.toMillis(4); + + public enum Direction { UP, DOWN, LEFT, RIGHT, NULL }; + public enum GestureType { UIDEVICE_SWIPE, UIOBJECT_SWIPE, PINCH }; + public enum PinchType { IN, OUT, NULL }; + + public class Timer { + private long startTime = 0; + private long endTime = 0; + private long duration = 0; + + public void start(){ + this.startTime = System.currentTimeMillis(); + } + + public void end() { + this.endTime = System.currentTimeMillis(); + this.duration = this.endTime - this.startTime; + } + + public long getStart() { + return this.startTime; + } + + public long getFinish() { + return this.endTime; + } + + public long getDuration() { + return this.duration; + } + } + + public void initDumpsysSurfaceFlinger(String appPackage, String view) { + String packageView = String.format(appPackage + "/" + view); + List command = Arrays.asList("dumpsys", "SurfaceFlinger", "--latency-clear" + , packageView); + initDumpsys(command); + } + + public void exitDumpsysSurfaceFlinger(String appPackage, String view, File filename) { + String packageView = String.format(appPackage + "/" + view); + List command = Arrays.asList("dumpsys", "SurfaceFlinger", "--latency", packageView); + exitDumpsys(command, filename); + } + + public void initDumpsysGfxInfo(String appPackage) { + List command; + if (Build.VERSION.SDK_INT >= 22) { + command = Arrays.asList("dumpsys", "gfxinfo", appPackage, "framestats", "reset"); + } else { + command = Arrays.asList("dumpsys", "gfxinfo", appPackage, "reset"); + } + initDumpsys(command); + } + + public void exitDumpsysGfxInfo(String appPackage, File filename) { + List command; + if (Build.VERSION.SDK_INT >= 22) { + command = Arrays.asList("dumpsys", "gfxinfo", appPackage, "framestats"); + } else { + command = Arrays.asList("dumpsys", "gfxinfo", appPackage); + } + exitDumpsys(command, filename); + } + + public void initDumpsys(List command) { + try { + ProcessBuilder builder = new ProcessBuilder(); + builder.command(command); + Process process = builder.start(); + process.waitFor(); + } catch (Exception exception) { + logger.log(Level.SEVERE, "Unable to reset dumpsys", exception); + } + } + + public void exitDumpsys(List command, File filename) { + FileWriter fileWriter = null; + BufferedReader bufferedReader = null; + try { + ProcessBuilder processBuilder = new ProcessBuilder(); + processBuilder.command(command); + Process process = processBuilder.start(); + fileWriter = new FileWriter(filename); + bufferedReader = new BufferedReader( + new InputStreamReader(process.getInputStream())); + String line; + while ((line = bufferedReader.readLine()) != null) { + fileWriter.append(line); + fileWriter.append(System.getProperty("line.separator")); + } + process.waitFor(); + if (process.exitValue() != 0) { + throw new Exception("Error while taking dumpsys, exitCode=" + + process.exitValue()); + } + } catch (Exception exception) { + logger.log(Level.SEVERE, "Unable to take a dumpsys", exception); + } finally { + if (fileWriter != null) { + try { fileWriter.close(); } catch (Exception e) { e.printStackTrace(); } + } + if (bufferedReader != null) { + try { bufferedReader.close(); } catch (Exception e) { e.printStackTrace(); } + } + } + } + + public Timer uiDeviceSwipeTest(Direction direction, int steps) throws Exception { + Timer results = new Timer(); + results.start(); + switch (direction) { + case UP: + uiDeviceSwipeUp(steps); + break; + case DOWN: + uiDeviceSwipeDown(steps); + break; + case LEFT: + uiDeviceSwipeLeft(steps); + break; + case RIGHT: + uiDeviceSwipeRight(steps); + break; + case NULL: + throw new Exception("No direction specified"); + default: + break; + } + results.end(); + return results; + } + + public Timer uiObjectSwipeTest(UiObject view, Direction direction, int steps) throws Exception { + Timer results = new Timer(); + results.start(); + switch (direction) { + case UP: + view.swipeUp(steps); + break; + case DOWN: + view.swipeDown(steps); + break; + case LEFT: + view.swipeLeft(steps); + break; + case RIGHT: + view.swipeRight(steps); + break; + case NULL: + throw new Exception("No direction specified"); + default: + break; + } + results.end(); + return results; + } + + public Timer uiObjectPinchTest(UiObject view, PinchType direction, int steps, + int percent) throws Exception { + Timer results = new Timer(); + results.start(); + if (direction.equals(PinchType.IN)) { + view.pinchIn(percent, steps); + } else if (direction.equals(PinchType.OUT)) { + view.pinchOut(percent, steps); + } + results.end(); + return results; + } +}