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 */
14package android.windowanimationjank;
15
16import android.app.Instrumentation;
17import android.app.UiAutomation;
18import android.content.ComponentName;
19import android.content.Intent;
20import android.os.SystemClock;
21import android.support.test.uiautomator.By;
22import android.support.test.uiautomator.BySelector;
23import android.support.test.uiautomator.UiDevice;
24import android.support.test.uiautomator.UiObject2;
25import android.support.test.uiautomator.Until;
26
27/**
28 * Set of helpers to manipulate test activities.
29 */
30public 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
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
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     */
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
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
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