blob: a5c753439653a169e9ad2743e4529c7ebb33c5f9 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.android.tv.tests.jank;
import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
import android.content.res.Resources;
import android.os.SystemClock;
import android.support.test.jank.JankTest;
import android.support.test.jank.JankTestBase;
import android.support.test.jank.JankType;
//import android.support.test.jank.WindowContentFrameStatsMonitor;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.Until;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
import android.util.Log;
import com.android.tv.R;
import com.android.tv.testing.uihelper.ByResource;
import com.android.tv.testing.uihelper.Constants;
import com.android.tv.testing.uihelper.LiveChannelsUiDeviceHelper;
import com.android.tv.testing.uihelper.MenuHelper;
import com.android.tv.testing.uihelper.UiDeviceUtils;
/**
* Jank tests for the program guide.
*/
@MediumTest
@Suppress // http://b/25147411 Tests fail missing classes from tests/common
public class ProgramGuideJankTest extends JankTestBase {
private static final boolean DEBUG = false;
private static final String TAG = "ProgramGuideJank";
private static final String STARTING_CHANNEL = "13";
private static final int EXPECTED_FRAMES = 5;
protected UiDevice mDevice;
protected Resources mTargetResources;
protected MenuHelper mMenuHelper;
protected LiveChannelsUiDeviceHelper mLiveChannelsHelper;
@Override
protected void setUp() throws Exception {
super.setUp();
mDevice = UiDevice.getInstance(getInstrumentation());
mTargetResources = getInstrumentation().getTargetContext().getResources();
mMenuHelper = new MenuHelper(mDevice, mTargetResources);
mLiveChannelsHelper = new LiveChannelsUiDeviceHelper(mDevice, mTargetResources,
getInstrumentation().getContext());
mLiveChannelsHelper.assertAppStarted();
pressKeysForChannelNumber(STARTING_CHANNEL);
}
@JankTest(type= JankType.ANIMATION_FRAMES, expectedFrames = 7,
beforeTest = "warmProgramGuide",
beforeLoop = "selectProgramGuideMenuItem",
afterLoop = "clearProgramGuide")
//@WindowContentFrameStatsMonitor
public void testShowProgramGuide() {
mDevice.pressDPadCenter();
// Full show has two animations.
long delay = mTargetResources.getInteger(R.integer.program_guide_anim_duration) * 2;
waitForIdleAtLeast(delay);
}
@JankTest(type= JankType.ANIMATION_FRAMES, expectedFrames = EXPECTED_FRAMES,
beforeLoop = "showProgramGuide")
//@WindowContentFrameStatsMonitor
public void testClearProgramGuide() {
mDevice.pressBack();
// Full show has two animations.
waitForIdleAtLeast(mTargetResources.getInteger(R.integer.program_guide_anim_duration) * 2);
}
@JankTest(type= JankType.ANIMATION_FRAMES, expectedFrames = EXPECTED_FRAMES,
beforeLoop = "showProgramGuide",
afterLoop = "clearProgramGuide")
//@WindowContentFrameStatsMonitor
public void testScrollDown() {
mDevice.pressDPadDown();
waitForIdleAtLeast(mTargetResources
.getInteger(R.integer.program_guide_table_detail_toggle_anim_duration));
}
@JankTest(type= JankType.ANIMATION_FRAMES, expectedFrames = EXPECTED_FRAMES,
beforeLoop = "showProgramGuide",
afterLoop = "clearProgramGuide")
//@WindowContentFrameStatsMonitor
public void testScrollRight() {
mDevice.pressDPadRight();
waitForIdleAtLeast(mTargetResources
.getInteger(R.integer.program_guide_table_detail_toggle_anim_duration));
}
/**
* {@link UiDevice#waitForIdle() Wait for idle} , then sleep if needed, then wait for idle
* again.
*
* @param delayInMillis The minimum amount of time to delay. This is usually the expected
* duration of the animation.
*/
private void waitForIdleAtLeast(long delayInMillis) {
// This seems to give the most reliable numbers.
// The first wait until idle usually returned in 1ms.
// Sometimes it would take the whole duration. If we sleep after that we get bad fps
// because nothing is happening after the idle ends.
//
// So sleeping only for the remaining about ensure there is at least enough time for the
// animation to complete. If we sleep then wait for idle again. This will usually allow
// the animation to complete.
long startTime = SystemClock.uptimeMillis();
mDevice.waitForIdle();
long idle = SystemClock.uptimeMillis() - startTime;
if (DEBUG) {
Log.d(TAG, "Waited for idle " + (idle) / 1000.0 + " sec");
}
if (idle < delayInMillis) {
long more = delayInMillis - idle;
SystemClock.sleep(more);
Log.d(TAG, "Slept " + (more) / 1000.0 + " sec");
mDevice.waitForIdle();
}
if (DEBUG) {
Log.d(TAG, "Total wait " + (SystemClock.uptimeMillis() - startTime) / 1000.0 + " sec");
}
}
//TODO: move to a mixin/helper
protected void pressKeysForChannelNumber(String channel) {
UiDeviceUtils.pressKeys(mDevice, channel);
mDevice.pressDPadCenter();
}
public void selectProgramGuideMenuItem() {
mMenuHelper.showMenu();
mMenuHelper.assertNavigateToMenuItem(R.string.menu_title_channels,
R.string.channels_item_program_guide);
mDevice.waitForIdle();
}
public void warmProgramGuide() {
// TODO: b/21078199 First time Program Guide is opened there is a noticeable delay
selectProgramGuideMenuItem();
mDevice.pressDPadCenter();
assertWaitForCondition(mDevice, Until.hasObject(Constants.PROGRAM_GUIDE));
mDevice.pressBack();
}
public void clearProgramGuide() {
mDevice.pressBack();
assertWaitForCondition(mDevice, Until.gone(Constants.PROGRAM_GUIDE));
}
public void showProgramGuide() {
selectProgramGuideMenuItem();
mDevice.pressDPadCenter();
assertWaitForCondition(mDevice, Until.hasObject(Constants.PROGRAM_GUIDE));
// If the side panel grid is visible (and thus has focus), move right to clear it.
if (mDevice.hasObject(
ByResource.id(mTargetResources, R.id.program_guide_side_panel_grid_view))) {
mDevice.pressDPadRight();
}
}
}