1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 package android.windowanimationjank;
15 
16 import android.app.Instrumentation;
17 import android.app.UiAutomation;
18 import android.content.ComponentName;
19 import android.content.Intent;
20 import android.os.SystemClock;
21 import android.support.test.uiautomator.By;
22 import android.support.test.uiautomator.BySelector;
23 import android.support.test.uiautomator.UiDevice;
24 import android.support.test.uiautomator.UiObject2;
25 import android.support.test.uiautomator.Until;
26 
27 /**
28  * Set of helpers to manipulate test activities.
29  */
30 public class Utils {
31     protected final static String PACKAGE = "android.windowanimationjank";
32     protected final static String ELEMENT_LAYOUT_ACTIVITY = "ElementLayoutActivity";
33     protected final static String ELEMENT_LAYOUT_CLASS = PACKAGE + "." + ELEMENT_LAYOUT_ACTIVITY;
34     protected final static long WAIT_FOR_ACTIVITY_TIMEOUT = 10000;
35     private static final BySelector ROOT_ELEMENT_LAYOUT = By.res(PACKAGE, "root_flow_layout");
36 
37     private final static long ROTATION_ANIMATION_TIME_FULL_SCREEN_MS = 1000;
38 
39     protected final static int ROTATION_MODE_NATURAL = 0;
40     protected final static int ROTATION_MODE_LEFT = 1;
41     protected final static int ROTATION_MODE_RIGHT = 2;
42 
waitForActivity(Instrumentation instrumentation, BySelector selector)43     private static UiObject2 waitForActivity(Instrumentation instrumentation, BySelector selector) {
44         UiDevice device = UiDevice.getInstance(instrumentation);
45         UiObject2 window = device.wait(Until.findObject(selector), WAIT_FOR_ACTIVITY_TIMEOUT);
46         if (window == null) {
47             throw new RuntimeException(selector.toString() + " has not been started.");
48         }
49 
50         // Get root object.
51         while (window.getParent() != null) {
52             window = window.getParent();
53         }
54         return window;
55     }
56 
waitForElementLayout(Instrumentation instrumentation)57     public static UiObject2 waitForElementLayout(Instrumentation instrumentation) {
58         return waitForActivity(instrumentation, ROOT_ELEMENT_LAYOUT);
59     }
60 
61     /**
62      * Start and return activity with requested number of random elements.
63      */
startElementLayout(Instrumentation instrumentation, int numElements)64     public static UiObject2 startElementLayout(Instrumentation instrumentation, int numElements) {
65         Intent intent = new Intent(Intent.ACTION_MAIN);
66         intent.setComponent(new ComponentName(PACKAGE, ELEMENT_LAYOUT_CLASS));
67         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
68         intent.putExtra(ElementLayoutActivity.NUM_ELEMENTS_KEY, numElements);
69         instrumentation.getTargetContext().startActivity(intent);
70         return waitForElementLayout(instrumentation);
71     }
72 
getDeviceRotation(Instrumentation instrumentation)73     public static int getDeviceRotation(Instrumentation instrumentation) {
74         try {
75             UiDevice device = UiDevice.getInstance(instrumentation);
76             switch (device.getDisplayRotation()) {
77             case UiAutomation.ROTATION_FREEZE_90:
78                 return ROTATION_MODE_LEFT;
79             case UiAutomation.ROTATION_FREEZE_270:
80                 return ROTATION_MODE_RIGHT;
81             case UiAutomation.ROTATION_FREEZE_0:
82             case UiAutomation.ROTATION_FREEZE_180:
83                 return ROTATION_MODE_NATURAL;
84             }
85         } catch(Exception e) {
86             throw new RuntimeException();
87         }
88         throw new RuntimeException("Unsupported device rotation.");
89     }
90 
rotateDevice(Instrumentation instrumentation, int rotationMode)91     public static void rotateDevice(Instrumentation instrumentation, int rotationMode) {
92         try {
93             UiDevice device = UiDevice.getInstance(instrumentation);
94             long startTime = System.currentTimeMillis();
95             switch (rotationMode) {
96             case ROTATION_MODE_NATURAL:
97                 device.setOrientationNatural();
98                 break;
99             case ROTATION_MODE_LEFT:
100                 device.setOrientationLeft();
101                 break;
102             case ROTATION_MODE_RIGHT:
103                 device.setOrientationRight();
104                 break;
105             default:
106                 throw new RuntimeException("Unsupported rotation mode: " + rotationMode);
107             }
108 
109             long toSleep = ROTATION_ANIMATION_TIME_FULL_SCREEN_MS -
110                     (System.currentTimeMillis() - startTime);
111             if (toSleep > 0) {
112                 SystemClock.sleep(toSleep);
113             }
114         } catch(Exception e) {
115             throw new RuntimeException(e);
116         }
117     }
118 }
119