diff options
Diffstat (limited to 'tests/common/src/com')
9 files changed, 130 insertions, 43 deletions
diff --git a/tests/common/src/com/android/tv/testing/ChannelInfo.java b/tests/common/src/com/android/tv/testing/ChannelInfo.java index af1c9891..946c0b55 100644 --- a/tests/common/src/com/android/tv/testing/ChannelInfo.java +++ b/tests/common/src/com/android/tv/testing/ChannelInfo.java @@ -16,9 +16,11 @@ package com.android.tv.testing; +import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.media.tv.TvContract; +import android.net.Uri; import android.support.annotation.Nullable; import android.util.SparseArray; @@ -38,11 +40,6 @@ public final class ChannelInfo { VIDEO_HEIGHT_TO_FORMAT_MAP.put(4320, TvContract.Channels.VIDEO_FORMAT_4320P); } - /** - * If this is specify for logo, it will be selected randomly including null. - */ - public static final String GENERATE_LOGO = "GEN"; - public static final String[] PROJECTION = { TvContract.Channels.COLUMN_DISPLAY_NUMBER, TvContract.Channels.COLUMN_DISPLAY_NAME, @@ -80,15 +77,20 @@ public final class ChannelInfo { .setOriginalNetworkId(channelNumber); if (context != null) { // tests/input/tools/get_test_logos.sh only stores 1000 logos. - int logo_num = (channelNumber % 1000); - builder.setLogoUrl( - "android.resource://com.android.tv.testinput/drawable/ch_" + logo_num - + "_logo" - ); + builder.setLogoUrl(getUriStringForChannelLogo(context, channelNumber)); } return builder.build(); } + public static String getUriStringForChannelLogo(Context context, int logoIndex) { + int index = (logoIndex % 1000) + 1; + return new Uri.Builder() + .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) + .authority(context.getPackageName()) + .path("drawable") + .appendPath("ch_" + index + "_logo").build().toString(); + } + public static ChannelInfo fromCursor(Cursor c) { // TODO: Fill other fields. Builder builder = new Builder(); diff --git a/tests/common/src/com/android/tv/testing/Utils.java b/tests/common/src/com/android/tv/testing/Utils.java index 66a13466..b2b4036e 100644 --- a/tests/common/src/com/android/tv/testing/Utils.java +++ b/tests/common/src/com/android/tv/testing/Utils.java @@ -19,16 +19,15 @@ package com.android.tv.testing; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; +import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.content.res.Resources; import android.media.tv.TvInputInfo; import android.media.tv.TvInputManager; import android.net.Uri; -import android.os.Looper; import android.util.Log; import com.android.tv.common.TvCommonUtils; -import com.android.tv.util.MainThreadExecutor; import java.io.IOException; import java.io.InputStream; @@ -37,8 +36,6 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.Random; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; /** * An utility class for testing. @@ -101,27 +98,6 @@ public final class Utils { return new Random(DEFAULT_RANDOM_SEED); } - /** - * Executes a call on the main thread, blocking until it is completed. - * - * <p>Useful for doing things that are not thread-safe, such as looking at or modifying the view - * hierarchy. - * - * @param runnable The code to run on the main thread. - */ - public static void runOnMainSync(Runnable runnable) { - if (Looper.myLooper() == Looper.getMainLooper()) { - runnable.run(); - } else { - Future<?> temp = MainThreadExecutor.getInstance().submit(runnable); - try { - temp.get(); - } catch (InterruptedException | ExecutionException e) { - throw new RuntimeException(e); - } - } - } - private static long getSeed() { // Set random seed as the date to track failed test data easily. SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.getDefault()); @@ -131,4 +107,16 @@ public final class Utils { } private Utils() {} + + /** + * Checks whether TvActivity is enabled or not. + */ + public static boolean isTvActivityEnabled(Context context) { + PackageManager pm = context.getPackageManager(); + ComponentName name = new ComponentName("com.android.tv", + "com.android.tv.TvActivity"); + int enabled = pm.getComponentEnabledSetting(name); + return enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED + || enabled == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; + } } diff --git a/tests/common/src/com/android/tv/testing/dvr/RecordingTestUtils.java b/tests/common/src/com/android/tv/testing/dvr/RecordingTestUtils.java index b9def95e..a9bfa97a 100644 --- a/tests/common/src/com/android/tv/testing/dvr/RecordingTestUtils.java +++ b/tests/common/src/com/android/tv/testing/dvr/RecordingTestUtils.java @@ -16,7 +16,7 @@ package com.android.tv.testing.dvr; -import com.android.tv.dvr.ScheduledRecording; +import com.android.tv.dvr.data.ScheduledRecording; import junit.framework.Assert; diff --git a/tests/common/src/com/android/tv/testing/uihelper/Constants.java b/tests/common/src/com/android/tv/testing/uihelper/Constants.java index 8f607fbf..8dd8e14a 100644 --- a/tests/common/src/com/android/tv/testing/uihelper/Constants.java +++ b/tests/common/src/com/android/tv/testing/uihelper/Constants.java @@ -23,6 +23,7 @@ public final class Constants { public static final double EXTRA_TIMEOUT_PERCENT = .05; public static final int MIN_EXTRA_TIMEOUT = 10; public static final long MAX_SHOW_DELAY_MILLIS = 200; + public static final long MAX_FOCUSED_DELAY_MILLIS = 1000; public static final String TV_APP_PACKAGE = "com.android.tv"; public static final BySelector TV_VIEW = By.res(TV_APP_PACKAGE, "main_tunable_tv_view"); public static final BySelector CHANNEL_BANNER = By.res(TV_APP_PACKAGE, "channel_banner_view"); @@ -30,6 +31,8 @@ public final class Constants { public static final BySelector MENU = By.res(TV_APP_PACKAGE, "menu"); public static final BySelector SIDE_PANEL = By.res(TV_APP_PACKAGE, "side_panel"); public static final BySelector PROGRAM_GUIDE = By.res(TV_APP_PACKAGE, "program_guide"); + public static final BySelector DVR_LIBRARY = By.res(TV_APP_PACKAGE, "dvr_frame"); + public static final BySelector DVR_SCHEDULES = By.res(TV_APP_PACKAGE, "dvr_schedules"); public static final BySelector FOCUSED_VIEW = By.focused(true); private Constants() { diff --git a/tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java b/tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java index 6757cf01..1dc0f020 100644 --- a/tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java +++ b/tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java @@ -1,6 +1,7 @@ package com.android.tv.testing.uihelper; import static com.android.tv.testing.uihelper.UiDeviceAsserts.waitForCondition; +import static junit.framework.TestCase.assertTrue; import android.content.Context; import android.content.Intent; @@ -11,6 +12,8 @@ import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.Until; import android.util.Log; +import com.android.tv.testing.Utils; + import junit.framework.Assert; /** @@ -29,6 +32,7 @@ public class LiveChannelsUiDeviceHelper extends BaseUiDeviceHelper { } public void assertAppStarted() { + assertTrue("TvActivity should be enabled.", Utils.isTvActivityEnabled(mContext)); Intent intent = mContext.getPackageManager() .getLaunchIntentForPackage(Constants.TV_APP_PACKAGE); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); // Clear out any previous instances @@ -48,4 +52,11 @@ public class LiveChannelsUiDeviceHelper extends BaseUiDeviceHelper { mUiDevice.pressBack(); } } + + public void assertAppStopped() { + while(mUiDevice.hasObject(By.pkg(Constants.TV_APP_PACKAGE).depth(0))) { + mUiDevice.pressBack(); + mUiDevice.waitForIdle(); + } + } }
\ No newline at end of file diff --git a/tests/common/src/com/android/tv/testing/uihelper/MenuHelper.java b/tests/common/src/com/android/tv/testing/uihelper/MenuHelper.java index ea5360a3..80d53242 100644 --- a/tests/common/src/com/android/tv/testing/uihelper/MenuHelper.java +++ b/tests/common/src/com/android/tv/testing/uihelper/MenuHelper.java @@ -139,6 +139,11 @@ public class MenuHelper extends BaseUiDeviceHelper { R.string.channels_item_program_guide); } + public UiObject2 assertPressDvrLibrary() { + return assertPressMenuItem(R.string.menu_title_channels, + R.string.channels_item_dvr); + } + /** * Navigate to the menu item with the text {@code itemTextResId} in the row with text * {@code rowTitleResId}. @@ -171,7 +176,11 @@ public class MenuHelper extends BaseUiDeviceHelper { public void showMenu() { if (!mUiDevice.hasObject(MENU)) { mUiDevice.pressMenu(); - UiDeviceAsserts.assertWaitForCondition(mUiDevice, Until.hasObject(MENU)); + if (!UiDeviceAsserts.waitForCondition(mUiDevice, Until.hasObject(MENU))) { + // Sometimes animations might block menu key, try again to make sure it's received. + mUiDevice.pressMenu(); + UiDeviceAsserts.assertWaitForCondition(mUiDevice, Until.hasObject(MENU)); + } } } } diff --git a/tests/common/src/com/android/tv/testing/uihelper/SidePanelHelper.java b/tests/common/src/com/android/tv/testing/uihelper/SidePanelHelper.java index 2d4f9b2f..98a19a41 100644 --- a/tests/common/src/com/android/tv/testing/uihelper/SidePanelHelper.java +++ b/tests/common/src/com/android/tv/testing/uihelper/SidePanelHelper.java @@ -47,17 +47,23 @@ public class SidePanelHelper extends BaseUiDeviceHelper { } public UiObject2 assertNavigateToItem(int resId) { - String title = mTargetResources.getString(resId); - return assertNavigateToItem(title); + return assertNavigateToItem(resId, Direction.DOWN); } + public UiObject2 assertNavigateToItem(int resId, Direction direction) { + String title = mTargetResources.getString(resId); + return assertNavigateToItem(title, direction); + } public UiObject2 assertNavigateToItem(String title) { + return assertNavigateToItem(title, Direction.DOWN); + } + + public UiObject2 assertNavigateToItem(String title, Direction direction) { BySelector sidePanelSelector = ByResource.id(mTargetResources, R.id.side_panel_list); UiObject2 sidePanelList = mUiDevice.findObject(sidePanelSelector); Assert.assertNotNull(sidePanelSelector + " not found", sidePanelList); - return UiDeviceAsserts - .assertNavigateTo(mUiDevice, sidePanelList, By.hasDescendant(By.text(title)), - Direction.DOWN); + return UiDeviceAsserts.assertNavigateTo(mUiDevice, sidePanelList, + By.hasDescendant(By.text(title)), direction); } } diff --git a/tests/common/src/com/android/tv/testing/uihelper/UiDeviceAsserts.java b/tests/common/src/com/android/tv/testing/uihelper/UiDeviceAsserts.java index ea9b5460..c096d7d2 100644 --- a/tests/common/src/com/android/tv/testing/uihelper/UiDeviceAsserts.java +++ b/tests/common/src/com/android/tv/testing/uihelper/UiDeviceAsserts.java @@ -17,6 +17,7 @@ package com.android.tv.testing.uihelper; import static com.android.tv.testing.uihelper.Constants.FOCUSED_VIEW; import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertTrue; import android.support.test.uiautomator.By; @@ -38,6 +39,12 @@ public final class UiDeviceAsserts { assertEquals("Has " + bySelector, expected, uiDevice.hasObject(bySelector)); } + public static void assertWaitUntilFocused(UiDevice uiDevice, BySelector bySelector) { + UiObject2 uiObject = uiDevice.findObject(bySelector); + assertNotNull(uiObject); + assertTrue(uiObject.wait(Until.focused(true), Constants.MAX_FOCUSED_DELAY_MILLIS)); + } + /** * Assert that {@code searchCondition} becomes true within * {@value Constants#MAX_SHOW_DELAY_MILLIS} milliseconds. diff --git a/tests/common/src/com/android/tv/testing/uihelper/UiDeviceUtils.java b/tests/common/src/com/android/tv/testing/uihelper/UiDeviceUtils.java index 577559c2..98eff906 100644 --- a/tests/common/src/com/android/tv/testing/uihelper/UiDeviceUtils.java +++ b/tests/common/src/com/android/tv/testing/uihelper/UiDeviceUtils.java @@ -15,8 +15,16 @@ */ package com.android.tv.testing.uihelper; +import static junit.framework.Assert.assertTrue; + +import android.app.Instrumentation; +import android.app.UiAutomation; +import android.os.Build; +import android.os.SystemClock; +import android.support.test.uiautomator.Configurator; import android.support.test.uiautomator.Direction; import android.support.test.uiautomator.UiDevice; +import android.view.InputDevice; import android.view.KeyEvent; /** @@ -51,7 +59,7 @@ public final class UiDeviceUtils { } /** - * Parses the string and sends the corresponding individual key preses. + * Parses the string and sends the corresponding individual key presses. * <p> * <b>Note:</b> only handles 0-9, '.', and '-'. */ @@ -69,6 +77,59 @@ public final class UiDeviceUtils { } } + /** + * Sends the DPAD Center key presses with the {@code repeat} count. + * TODO: Remove instrumentation argument once migrated to JUnit4. + */ + public static void pressDPadCenter(Instrumentation instrumentation, int repeat) { + pressKey(instrumentation, KeyEvent.KEYCODE_DPAD_CENTER, repeat); + } + + private static void pressKey(Instrumentation instrumentation, int keyCode, int repeat) { + UiDevice.getInstance(instrumentation).waitForIdle(); + for (int i = 0; i < repeat; ++i) { + assertPressKeyDown(instrumentation, keyCode, false); + if (i < repeat - 1) { + assertPressKeyUp(instrumentation, keyCode, false); + } + } + // Send last key event synchronously. + assertPressKeyUp(instrumentation, keyCode, true); + } + + private static void assertPressKeyDown(Instrumentation instrumentation, int keyCode, + boolean sync) { + assertPressKey(instrumentation, KeyEvent.ACTION_DOWN, keyCode, sync); + } + + private static void assertPressKeyUp(Instrumentation instrumentation, int keyCode, + boolean sync) { + assertPressKey(instrumentation, KeyEvent.ACTION_UP, keyCode, sync); + } + + private static void assertPressKey(Instrumentation instrumentation, int action, int keyCode, + boolean sync) { + long eventTime = SystemClock.uptimeMillis(); + KeyEvent event = new KeyEvent(eventTime, eventTime, action, keyCode, 0, 0, -1, 0, 0, + InputDevice.SOURCE_KEYBOARD); + assertTrue("Failed to inject key up event:" + event, + injectEvent(instrumentation, event, sync)); + } + + private static boolean injectEvent(Instrumentation instrumentation, KeyEvent event, + boolean sync) { + return getUiAutomation(instrumentation).injectInputEvent(event, sync); + } + + private static UiAutomation getUiAutomation(Instrumentation instrumentation) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + int flags = Configurator.getInstance().getUiAutomationFlags(); + return instrumentation.getUiAutomation(flags); + } else { + return instrumentation.getUiAutomation(); + } + } + private UiDeviceUtils() { } } |