14f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel/*
24f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel * Copyright (C) 2015 The Android Open Source Project
34f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel *
44f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
54f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel * in compliance with the License. You may obtain a copy of the License at
64f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel *
74f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel * http://www.apache.org/licenses/LICENSE-2.0
84f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel *
94f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel * Unless required by applicable law or agreed to in writing, software distributed under the License
104f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
114f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel * or implied. See the License for the specific language governing permissions and limitations under
124f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel * the License.
134f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel */
144f26c041ad0429710d135d8e179eec8f44077ebeYury Khmelpackage android.windowanimationjank;
154f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel
164f26c041ad0429710d135d8e179eec8f44077ebeYury Khmelimport android.app.Instrumentation;
174f26c041ad0429710d135d8e179eec8f44077ebeYury Khmelimport android.app.UiAutomation;
184f26c041ad0429710d135d8e179eec8f44077ebeYury Khmelimport android.content.ComponentName;
194f26c041ad0429710d135d8e179eec8f44077ebeYury Khmelimport android.content.Intent;
204f26c041ad0429710d135d8e179eec8f44077ebeYury Khmelimport android.os.SystemClock;
214f26c041ad0429710d135d8e179eec8f44077ebeYury Khmelimport android.support.test.uiautomator.By;
224f26c041ad0429710d135d8e179eec8f44077ebeYury Khmelimport android.support.test.uiautomator.BySelector;
234f26c041ad0429710d135d8e179eec8f44077ebeYury Khmelimport android.support.test.uiautomator.UiDevice;
244f26c041ad0429710d135d8e179eec8f44077ebeYury Khmelimport android.support.test.uiautomator.UiObject2;
254f26c041ad0429710d135d8e179eec8f44077ebeYury Khmelimport android.support.test.uiautomator.Until;
264f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel
274f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel/**
284f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel * Set of helpers to manipulate test activities.
294f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel */
304f26c041ad0429710d135d8e179eec8f44077ebeYury Khmelpublic class Utils {
314f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    protected final static String PACKAGE = "android.windowanimationjank";
324f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    protected final static String ELEMENT_LAYOUT_ACTIVITY = "ElementLayoutActivity";
334f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    protected final static String ELEMENT_LAYOUT_CLASS = PACKAGE + "." + ELEMENT_LAYOUT_ACTIVITY;
344f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    protected final static long WAIT_FOR_ACTIVITY_TIMEOUT = 10000;
354f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    private static final BySelector ROOT_ELEMENT_LAYOUT = By.res(PACKAGE, "root_flow_layout");
364f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel
374f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    private final static long ROTATION_ANIMATION_TIME_FULL_SCREEN_MS = 1000;
384f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel
394f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    protected final static int ROTATION_MODE_NATURAL = 0;
404f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    protected final static int ROTATION_MODE_LEFT = 1;
414f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    protected final static int ROTATION_MODE_RIGHT = 2;
424f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel
434f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    private static UiObject2 waitForActivity(Instrumentation instrumentation, BySelector selector) {
444f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        UiDevice device = UiDevice.getInstance(instrumentation);
454f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        UiObject2 window = device.wait(Until.findObject(selector), WAIT_FOR_ACTIVITY_TIMEOUT);
464f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        if (window == null) {
474f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            throw new RuntimeException(selector.toString() + " has not been started.");
484f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        }
494f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel
504f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        // Get root object.
514f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        while (window.getParent() != null) {
524f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            window = window.getParent();
534f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        }
544f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        return window;
554f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    }
564f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel
574f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    public static UiObject2 waitForElementLayout(Instrumentation instrumentation) {
584f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        return waitForActivity(instrumentation, ROOT_ELEMENT_LAYOUT);
594f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    }
604f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel
614f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    /**
624f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel     * Start and return activity with requested number of random elements.
634f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel     */
644f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    public static UiObject2 startElementLayout(Instrumentation instrumentation, int numElements) {
654f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        Intent intent = new Intent(Intent.ACTION_MAIN);
664f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        intent.setComponent(new ComponentName(PACKAGE, ELEMENT_LAYOUT_CLASS));
674f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
684f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        intent.putExtra(ElementLayoutActivity.NUM_ELEMENTS_KEY, numElements);
694f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        instrumentation.getTargetContext().startActivity(intent);
704f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        return waitForElementLayout(instrumentation);
714f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    }
724f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel
734f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    public static int getDeviceRotation(Instrumentation instrumentation) {
744f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        try {
754f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            UiDevice device = UiDevice.getInstance(instrumentation);
764f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            switch (device.getDisplayRotation()) {
774f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            case UiAutomation.ROTATION_FREEZE_90:
784f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel                return ROTATION_MODE_LEFT;
794f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            case UiAutomation.ROTATION_FREEZE_270:
804f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel                return ROTATION_MODE_RIGHT;
814f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            case UiAutomation.ROTATION_FREEZE_0:
824f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            case UiAutomation.ROTATION_FREEZE_180:
834f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel                return ROTATION_MODE_NATURAL;
844f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            }
854f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        } catch(Exception e) {
864f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            throw new RuntimeException();
874f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        }
884f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        throw new RuntimeException("Unsupported device rotation.");
894f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    }
904f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel
914f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    public static void rotateDevice(Instrumentation instrumentation, int rotationMode) {
924f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        try {
934f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            UiDevice device = UiDevice.getInstance(instrumentation);
944f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            long startTime = System.currentTimeMillis();
954f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            switch (rotationMode) {
964f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            case ROTATION_MODE_NATURAL:
974f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel                device.setOrientationNatural();
984f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel                break;
994f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            case ROTATION_MODE_LEFT:
1004f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel                device.setOrientationLeft();
1014f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel                break;
1024f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            case ROTATION_MODE_RIGHT:
1034f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel                device.setOrientationRight();
1044f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel                break;
1054f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            default:
1064f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel                throw new RuntimeException("Unsupported rotation mode: " + rotationMode);
1074f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            }
1084f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel
1094f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            long toSleep = ROTATION_ANIMATION_TIME_FULL_SCREEN_MS -
1104f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel                    (System.currentTimeMillis() - startTime);
1114f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            if (toSleep > 0) {
1124f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel                SystemClock.sleep(toSleep);
1134f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            }
1144f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        } catch(Exception e) {
1154f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel            throw new RuntimeException(e);
1164f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel        }
1174f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel    }
1184f26c041ad0429710d135d8e179eec8f44077ebeYury Khmel}
119